maintenance: title: Checks the Single, Average-Daily, and Total-Daily Dose Ranges;; mlmname: STD_FUNC_DOSAGE_RULES;; 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: The MLM assists the STD_Dosage MLM to determine if a medication dose may be out of range. ;; explanation: This MLM, the STD_FUNC_DOSAGE_CAT MLM and the STD_Func_Dosage_Multum contain the rules that determine if the SINGLE DOSE, AVERAGE DAILY DOSE, or the TOTAL DAILY DOSE are out of range. ;; keywords: single dose; average daily dose; total daily dose; dosage range ;; knowledge: type: data-driven;; data: // include common data structures std_dosage_includes := MLM {{{SINGLE-QUOTE}}}std_func_dosage_includes{{{SINGLE-QUOTE}}}; include std_dosage_includes; ( chart_guid, user_data_code, user_value, user_data_touched_when, use_multum_dosage_data, use_item_catalog_dosage_data, catalog_drc_type_const, core_uom_const, ht_cm, show_irregular_message, show_under_24_hour_message, show_has_shift_frequency_message, show_user_scheduled_weekly_message, intentionally_unmapped_frequency_list, alert_if_missing_flags, med_data_list, patient_info, valid_height_days_for_age, valid_weight_days_for_age, Creatinine_Clearance_Result_name, Creatinine_Clearance_Result_valid_days, EstCrCl_equation_preference, EstCrC_calculate_with_BSA_preference, show_Debug_statements, column_catalog_name, column_Multum_name ) := ARGUMENT; /*******************Make Changes To Spelling And Flags In This Section***************/ // Set to true if logging is needed. log_execution_info := false; /*************************************************************************************/ // DO NOT CHANGE the following System-defined values dose_per_string:= "Dose Per"; dose_reg_string:= "Dose Reg"; /*=================================================================================*/ /* Declare the MLMs that can be called */ calc_BSA := MLM {{{SINGLE-QUOTE}}}sys_calc_BSA{{{SINGLE-QUOTE}}}; func_dosage_cat := MLM {{{SINGLE-QUOTE}}}STD_func_dosage_cat{{{SINGLE-QUOTE}}}; func_dosage_messages := MLM {{{SINGLE-QUOTE}}}STD_func_dosage_messages{{{SINGLE-QUOTE}}}; func_dosage_tracker := MLM {{{SINGLE-QUOTE}}}STD_func_dosage_tracker{{{SINGLE-QUOTE}}}; func_dosage_trim := MLM {{{SINGLE-QUOTE}}}STD_func_dosage_trim{{{SINGLE-QUOTE}}}; func_dosage_trim_adjusted := MLM {{{SINGLE-QUOTE}}}STD_func_dosage_trim_adjusted{{{SINGLE-QUOTE}}}; func_dosage_multum := MLM {{{SINGLE-QUOTE}}}STD_func_dosage_multum{{{SINGLE-QUOTE}}}; func_calc_est_crcl := MLM {{{SINGLE-QUOTE}}}SYS_CALC_EST_CRCL{{{SINGLE-QUOTE}}}; dosage_range_list := (); med_dosage_map_list := (); /* Get current visit timezone. */ (visit_timezone) := read last {ClientVisit: timezone }; /* Get the patient{{{SINGLE-QUOTE}}}s birthday and other relevant data */ (client_guid, birthdatetime, birthday, birthMonthNum, birthDayNum, birthtime, patient_gender, intl_patient_gender, client_info_obj ) := read last { ClientInfo: GUID, BirthdateTime, Birthdate, BirthMonthNum, BirthDayNum, BirthTime, GenderCode, GenderTypeIntlCode, this, }; //MTZ: set birthday with evoking object visit time zone birthday := birthday as Time OVERRIDETIMEZONE visit_timezone; // Get the BSA calculation preference used by the MLMS: // SYS_CALC_BSA MLM and SYS_CALC_EST_CRCL BSA_formula_preference := read last {"SELECT Value " || " FROM HVCEnvProfile " || " WHERE Code = {{{SINGLE-QUOTE}}}BSAFormula{{{SINGLE-QUOTE}}} " || " AND HierarchyCode = {{{SINGLE-QUOTE}}}Client Info{{{SINGLE-QUOTE}}} " }; /* Get the Units of Measure info */ (uom_facility_code, uom_sys_code, uom_drug_catalog_key):= read {"SELECT Code, CoreUOM, DrugCatalogKey " || " FROM CV3UnitOfMeasure" || " WHERE Active = 1" }; if use_multum_dosage_data then /* Get the patient dialysis type*/ /* Retrieve the facility{{{SINGLE-QUOTE}}}s scope preference for dialysis type */ general_scope_for_dialysis := read last {"SELECT CASE WHEN ScopeLevel = 3 THEN 1 ELSE 0 END " || " FROM CV3PhysicalNoteType " || " WHERE Code = " || SQLEX("Dialysis")}; /* Set the scope to retrieve the Dialysis */ if general_scope_for_dialysis = 1 then dialysis_patient_chart_str:= ""; else dialysis_patient_chart_str:= " AND ChartGUID = " || SQLEX(chart_guid); endif; /* Retrieve from database*/ /* Warning--keep SQL in synch with business rules on patient height */ (dialysis_type_str, dialysis_date) := read last {"SELECT Text, TouchedWhen " || " FROM CV3PhysicalNoteDeclaration" || " WHERE ClientGUID = " || SQLEX(client_guid) || dialysis_patient_chart_str || " AND Active = 1 " || " AND TypeCode = " || SQLEX("DIALYSIS") || " AND Status = " || SQLEX("Active") , PrimaryTime = TouchedWhen }; /* Retrieve the facility{{{SINGLE-QUOTE}}}s scope preference for has liver disease*/ general_scope_for_liver := read last {"SELECT CASE WHEN ScopeLevel = 3 THEN 1 ELSE 0 END " || " FROM CV3PhysicalNoteType " || " WHERE Code = " || SQLEX("LIVERFUNC")}; /* Set the scope to retrieve the has liver disease string */ if general_scope_for_liver = 1 then liver_patient_chart_str:= ""; else liver_patient_chart_str:= " AND ChartGUID = " || SQLEX(chart_guid); endif; /* Retrieve from database*/ /* Warning--keep SQL in synch with business rules on patient liver disease */ (has_liver_disease_str, has_liver_disease_date) := read last {"SELECT Text, TouchedWhen " || " FROM CV3PhysicalNoteDeclaration" || " WHERE ClientGUID = " || SQLEX(client_guid) || liver_patient_chart_str || " AND Active = 1 " || " AND TypeCode = " || SQLEX("LIVERFUNC") || " AND Status = " || SQLEX("Active") , PrimaryTime = TouchedWhen }; // patient info obj property value for liver disease patient_info.Liver := new Patient_Property_Obj; patient_info.Liver.type := "Liver Disease"; patient_info.Liver.date := has_liver_disease_date; if has_liver_disease_str is null then has_liver_disease_str:= "Unknown"; patient_info.Liver.is_missing := true; endif; /* if has_liver_disease_str */ // set has_liver_disease_bit if has_liver_disease_str = "Yes" then has_liver_disease_bit := 1; elseif has_liver_disease_str = "No" then has_liver_disease_bit := 0; else has_liver_disease_bit := null; endif; patient_info.Liver.value := has_liver_disease_str; // If Dialysis is HEMO or Peritoneal then do not need to retrieve Creatinine if ( dialysis_type_str in ("Hemo", "Peritoneal")) then patient_info.Renal := new Patient_Property_Obj; patient_info.Renal.type := "Renal"; if (dialysis_type_str = "Hemo") then patient_info.Renal.value := "hemodialysis"; else patient_info.Renal.value := "peritoneal dialysis"; endif; patient_info.Renal.date := dialysis_date; else creatinine_OBJECT := object [ value, enteredDate, isSerum ]; creatinine_list := (); creatinine_on_order_form := false; // Get the creatinine values from the Order entry form if the control exists // This value will always be assumed to be the correct and latest // Code first checks for the Creatinine Clearance values and if not found then looks for // the Serum Creatinine. //MTZ: when building data initial time, the enteredDate will be enterprise tz and convert to visit tz later creatinine_order_str := first (user_value where user_data_code = "CreatCrClValue_ECLP") as String; if creatinine_order_str <> "null" and length of creatinine_order_str > 0 then //creatinine_order_date := first (user_value where user_data_code = "CreatCrClEntered_ECLP"); creatinine_order_date := now; // Assume now since Order User Data has priority over the DB creatinine_clearance_order := new creatinine_OBJECT; creatinine_clearance_order.Value := creatinine_order_str as number; time of creatinine_clearance_order := creatinine_order_date; creatinine_clearance_order.enteredDate := creatinine_order_date; creatinine_clearance_order.isSerum := false; creatinine_on_order_form := true; creatinine_list := creatinine_list, creatinine_clearance_order; else creatinine_order_str := first (user_value where user_data_code = "CreatSCRValue_ECLP") as String; if creatinine_order_str <> "null" and length of creatinine_order_str > 0 then //creatinine_order_date := first (user_value where user_data_code = "CreatSCREntered_ECLP"); creatinine_order_date := now; // Assume now since Order User Data has priority over the DB serum_creatinine_order := new creatinine_OBJECT; serum_creatinine_order.Value := creatinine_order_str as number; time of serum_creatinine_order := creatinine_order_date; serum_creatinine_order.enteredDate := creatinine_order_date; serum_creatinine_order.isSerum := true; creatinine_on_order_form := true; creatinine_list := creatinine_list, serum_creatinine_order; endif; endif; // If there is no Creatinine defined on the order form then need to check // the database. if not creatinine_on_order_form then // Get the Serum result name and valid days from the Environment Profile (Serum_Creatinine_Result_Name, Serum_Creatinine_Result_valid_days) := read last { "select ( select value from HVCEnvProfile " || " where HierarchyCode={{{SINGLE-QUOTE}}}CDS|Expert Drug Profile{{{SINGLE-QUOTE}}} AND " || " Code={{{SINGLE-QUOTE}}}Serum Creatinine Result Name{{{SINGLE-QUOTE}}}) as Name, " || " ( select value from HVCEnvProfile " || " where HierarchyCode={{{SINGLE-QUOTE}}}CDS|Expert Drug Profile{{{SINGLE-QUOTE}}} AND " || " Code={{{SINGLE-QUOTE}}}Valid Serum Creatinine Days{{{SINGLE-QUOTE}}}) as ValidDays" }; // Retrieve a serum creatinine from the Physical Note Declaration. Make sure // it is still valid. validDate := now - (Serum_Creatinine_Result_valid_days as number) days; isFromPhysicalNote := 1; (creatinine_physicalNote_str, creatinine_physicalNote_date) := read last { "EXEC SCMSerumCreatinineOrClearanceSelPR " || SQLEX(client_guid) || " ," || SQLEX("SCR") || " ," || SQL(validDate) || " ," //no need to convert to datetimeoffset || SQLEX(isFromPhysicalNote ) , PrimaryTime = PerformedDtm}; //PerformedDtm is CV3PhysicalNoteDeclaration.TouchedWhen if creatinine_physicalNote_str is not null then creatinine_physicalNote := new creatinine_OBJECT; creatinine_physicalNote.value := creatinine_physicalNote_str as number; time of creatinine_physicalNote := creatinine_physicalNote_date; creatinine_physicalNote.enteredDate := creatinine_physicalNote_date; creatinine_physicalNote.isSerum := true; creatinine_list := creatinine_list, creatinine_physicalNote; endif; if Serum_Creatinine_Result_Name is not null then validDate := now - (Serum_Creatinine_Result_valid_days as number) days; isFromPhysicalNote := 0; (creatinine_result_str, creatinine_result_date) := read last { "EXEC SCMSerumCreatinineOrClearanceSelPR " || SQLEX(client_guid) || " ," || SQLEX(Serum_Creatinine_Result_Name) || " ," || SQL(validDate) || " ," // no need to convert to datetimeoffset || SQLEX(isFromPhysicalNote) , PrimaryTime = PerformedDtm}; //PerformedDtm is CV3BasicObservationView.PerformedDtm if creatinine_result_str is not null then creatinine_result := new creatinine_OBJECT; creatinine_result.value := creatinine_result_str as number; time of creatinine_result := creatinine_result_date; creatinine_result.enteredDate := creatinine_result_date; creatinine_result.isSerum := true; creatinine_list := creatinine_list, creatinine_result; endif; endif; if Creatinine_Clearance_Result_name is not null then validDate := now - (Creatinine_Clearance_Result_valid_days as number) days; isFromPhysicalNote := 0; (creatinine_clearance_result_str, creatinine_clearance_result_date) := read last { "EXEC SCMSerumCreatinineOrClearanceSelPR " || SQLEX(client_guid) || " ," || SQLEX(Creatinine_Clearance_Result_name) || " ," || SQL(validDate) || " ," // no need to convert to datetimeoffset || SQLEX(isFromPhysicalNote) , PrimaryTime = PerformedDtm}; //PerformedDtm is CV3BasicObservationView.PerformedDtm if creatinine_clearance_result_str is not null then creatinine_clearance_result := new creatinine_OBJECT; creatinine_clearance_result.value := creatinine_clearance_result_str as number; time of creatinine_clearance_result := creatinine_clearance_result_date; creatinine_clearance_result.enteredDate := creatinine_clearance_result_date; creatinine_clearance_result.isSerum := false; creatinine_list := creatinine_list, creatinine_clearance_result; endif; endif; endif; calc_needed := false; patient_info.Creatinine := new Patient_Property_Obj; patient_info.Creatinine.type := "Creatinine"; latest_creatinine := creatinine_list[last index maximum 1 from (creatinine_list.enteredDate)]; // Need to calculate the estimated creatinine clearance if the latest creatinine value // retrieved is a serum. if latest_creatinine.isSerum then ( error_message, EstCrCl_number_rounded, EstCrCl_formula, weight_used, BSA_used ) := call func_calc_est_crcl with EstCrCl_equation_preference, BSA_formula_preference, patient_info.Height.value, patient_info.Weight.value, latest_creatinine.value, EstCrC_calculate_with_BSA_preference, client_Info_obj; if error_message is not null AND length of error_message > 0 then patient_info.Creatinine.value := null; patient_info.Creatinine.is_missing := true; else patient_info.Creatinine.value := EstCrCl_number_rounded; patient_info.Creatinine.is_missing := false; endif; else patient_info.Creatinine.value := latest_creatinine.value; endif; //MTZ: convert enteredDate to visit time zone from enterprise patient_info.Creatinine.date := latest_creatinine.enteredDate as time visit_timezone; endif; endif; // Check to see if gender is required for any dose critiera patient_info.Gender := new Patient_Property_Obj; patient_info.Gender.type := "Gender"; patient_info.Gender.value := patient_gender; if not exist patient_gender then patient_info.Gender.is_missing := TRUE; else patient_info.Gender.is_missing := FALSE; endif; //if not exist patient_gender if intl_patient_gender = "U" or intl_patient_gender = "O" then patient_info.Gender.unknown_other := TRUE; else patient_info.Gender.unknown_other := FALSE; endif; //if intl_patient_gender = "U" or "O" if exist patient_gender and not exist intl_patient_gender then patient_info.Gender.is_unmapped := TRUE; else patient_info.Gender.is_unmapped := FALSE; endif; //Create objects that summarize data needed for //Total Daily Dose and Average Daily Dose checking (total_tracker_list, average_tracker_list ) := call func_dosage_tracker with med_data_list; ;; evoke: ;; logic: //------------------------------------------------ // Process each Medication in the Med_Data Object //------------------------------------------------ for med_data in med_data_list do missing_data_msg := ""; drug_name := med_data.order_med_name ; catalog_item_obj:= med_data.order_catalog_item_obj; // Significant_date is important in several calculations and cannot // be NULL. Set it to be the first calculated admin time. If this // is null then take the calcStart_dtm. if med_data.order_med_significant_date is null then med_data.order_med_significant_date := first med_data.admin_dtm_list; if med_data.order_med_significant_date is null then med_data.order_med_significant_date := med_data.calcStart_dtm; endif; endif; //----------------------------------------------------- // Determine if DOSE PER or DOSE REG Should be Used for Range Check //----------------------------------------------------- // The SINGLE dose should always be checked with the setting from the order. single_order_calc_per_uom := med_data.updated_calc_med_per_uom; // Complex Order should have their AVERAGE and TOTAL doses check with DOSE REG. // by setting the variable below to NULL. // All other orders should use the setting from the order. If med_data.med_order_type = "Complex Order" then average_order_calc_per_uom := NULL; total_order_calc_per_uom := NULL; else average_order_calc_per_uom := med_data.updated_calc_med_per_uom; total_order_calc_per_uom := med_data.updated_calc_med_per_uom; endif; /*----------------------------------------------------------------*/ /* Set the WEIGHT and associated data for the Dosage Range Checks */ /*----------------------------------------------------------------*/ calc_text := med_data.calc_text; dose_basis := med_data.dose_basis; wt_kg := med_data.wt_kg; //--------------------------- // Calculate the Patient Age //--------------------------- // A valid birthday is required for the appropriate age calculation // The age of adults and older children can be calculated with the birth-year // when the month and day are not available. // However, the age of an infant can be over-estimated based solely // on the birth-year. Therefore infant must have // a valid birth-month and birth-year before an age calculation is attempted. // If the patient{{{SINGLE-QUOTE}}}s birth month is 0, // then only the birth-year is available for the age calculation. // In this case, don{{{SINGLE-QUOTE}}}t use the age-based dosage range data for // infants or children under age 4 years. if birthday is time then has_valid_birthdate:= true; patient_birthday_info_on_order := new Patient_Birthday_Info_Obj; order_significant_date := med_data.order_med_significant_date; age_value:= (order_significant_date-birthday)/(1 year); if birthMonthNum = 0 and age_value < 4 then has_valid_birthdate:= false; endif; month_value := (order_significant_date-birthday)/(1 month); if has_valid_birthdate and BirthDayNum = 0 and month_value < 4 then has_valid_birthdate:= false; endif; // Calculate the patient age in days // Patient age in days patient_age_in_days := (order_significant_date - birthday)/(1 day); // if patient age < 4 days, then recalculate total using formula: // Order.SignificantDtm (Birthday at 00:00 + HH:MM of birth time from CV3Client.BirthTime) if has_valid_birthdate and patient_age_in_days < 4 then if not exists birthtime then //[New born birth-time missing]: check on birth time range, Birthday "from" and "to" value will be needed. //Birthday To value set to 23:59: if patient_age_in_days >= 1 then birth_time_to := ("23:59:00" as time); estimated_birthday_to := birthday + (birth_time_to - (day floor of birth_time_to)); else estimated_birthday_to := now as time visit_timezone; endif; else // Update the birthday to include birthtime when baby is less than 4 days old birthday := birthdatetime; Endif; endif; sig_extract_year := extract year order_significant_date; birthday_extract_year := extract year birthday; sig_extract_month := extract month order_significant_date; birthday_extract_month := extract month birthday; sig_extract_day := extract day order_significant_date; birthday_extract_day := extract day birthday; had_birthday := true; if (sig_extract_month = birthday_extract_month) then if (sig_extract_day < birthday_extract_day) then had_birthday := false; endif; elseif (sig_extract_month < birthday_extract_month) then had_birthday := false; endif; age_years_value := sig_extract_year - birthday_extract_year; if (had_birthday = false) then age_years_value := age_years_value - 1; endif; // construct the string used to display the age age_months_value := (order_significant_date - birthday) / (1 month); age_days_value := (order_significant_date - birthday) / (1 day); age_hours_value := (order_significant_date - birthday) / (1 hour); age_str := ""; if (age_years_value >= 1) then age_str := age_years_value formatted with "%d" || " year(s)"; elseif (age_months_value >= 1) then age_str := age_months_value formatted with "%d" || " month(s)"; elseif (age_days_value >= 1) then age_str := age_days_value formatted with "%d" || " day(s)"; elseif (age_hours_value >= 1) then age_str := age_hours_value formatted with "%d" || " hour(s)"; endif; //[New born birth-time missing]: fillup birthday related info structure patient_birthday_info_on_order.birthday := birthday; patient_birthday_info_on_order.age_str := age_str; patient_birthday_info_on_order.age_year_value := age_years_value; patient_birthday_info_on_order.age_month_value := age_months_value; patient_birthday_info_on_order.age_week_value := (order_significant_date - birthday) / (1 week); patient_birthday_info_on_order.age_day_value := age_days_value; patient_birthday_info_on_order.age_hour_value := age_hours_value; patient_birthday_info_on_order.age_max_inhour_str := patient_birthday_info_on_order.age_hour_value formatted with "%d" || " hour(s)"; if estimated_birthday_to is not null then patient_birthday_info_on_order.is_estimated_birthday := true; patient_birthday_info_on_order.estimated_birthday_to := estimated_birthday_to; patient_birthday_info_on_order.age_year_min_value := (order_significant_date - estimated_birthday_to) / (1 year); patient_birthday_info_on_order.age_month_min_value := (order_significant_date - estimated_birthday_to) / (1 month); patient_birthday_info_on_order.age_week_min_value := (order_significant_date - estimated_birthday_to) / (1 week); patient_birthday_info_on_order.age_day_min_value := (order_significant_date - estimated_birthday_to) / (1 day); patient_birthday_info_on_order.age_hour_min_value := (order_significant_date - estimated_birthday_to) / (1 hour); patient_birthday_info_on_order.age_min_inhour_str := patient_birthday_info_on_order.age_hour_min_value formatted with "%d" || " hour(s)"; endif; else has_valid_birthdate := false; endif; //----------------------------------------- // Perform weight/height currentness check //----------------------------------------- if has_valid_birthdate then patient_age := order_significant_date - birthday; // Perform weight validity check valid_weight_duration := last (valid_weight_days_for_age.duration where (valid_weight_days_for_age.FromAge <= patient_age and valid_weight_days_for_age.ToAge > patient_age )); // compute weight duration weight_duration := now - patient_info.Weight.date; // Weight is not current, set it to zero if (weight_duration > valid_weight_duration) then wt_kg := null; endif; // Perform height validity check valid_height_duration := last (valid_height_days_for_age.duration where (valid_height_days_for_age.FromAge <= patient_age and valid_height_days_for_age.ToAge > patient_age )); // compute the height duration height_duration := now - patient_info.Height.date; // if height is not current, set it to zero if (height_duration > valid_height_duration) then ht_cm := null; endif; // Update the is missing flag if (wt_kg is number and wt_kg > 0) then patient_info.Weight.not_current := FALSE; else patient_info.Weight.not_current := TRUE; endif; //if wt_kg is number // Check to see if height is present if ht_cm is number and ht_cm > 0 then patient_info.Height.not_current := FALSE; else patient_info.Height.not_current := TRUE; endif; //if ht_cm is number endif; //------------------- // Calculate the BSA //------------------- if ht_cm is number and wt_kg is number and ht_cm > 0 and wt_kg > 0 then BSA_number_rounded:= Call calc_BSA with BSA_formula_preference, ht_cm, wt_kg, client_info_obj; patient_info.BSA := new Patient_Property_Obj; patient_info.BSA.type := "BSA"; patient_info.BSA.value := BSA_number_rounded; patient_info.BSA.is_missing := ((BSA_number_rounded is NULL) or (BSA_number_rounded = 0)); endif; /* if ht_cm is number */ //---------------------------------- // Check SINGLE Dosage Range //---------------------------------- // Find the SINGLE Dose medications with the same Name, UOM, Route, and PerUOM // OR both PerUOM are NULL. //----------------------------------------------------------------------------- found_med_data := med_data_list where (med_data_list.med_order_type = med_data.med_order_type AND med_data_list.order_med_name = med_data.order_med_name AND (med_data_list.order_med_units = med_data.order_med_units OR (med_data_list.order_med_units is null AND med_data.order_med_units is null)) AND ( med_data_list.order_med_route = med_data.order_med_route OR (med_data_list.order_med_route is null AND med_data.order_med_route is null) ) AND ((med_data_list.calc_med_per_uom = med_data.calc_med_per_uom) OR (med_data_list.calc_med_per_uom is null AND med_data.calc_med_per_uom is null)) AND (med_data_list.order_med_dose_low is not null AND med_data.order_med_dose_low is not null ) AND // If complex order (complex order or complex order with IV additive), don{{{SINGLE-QUOTE}}}t process the master complex order ( ( (any (med_data_list.med_order_type = "Complex Order")) AND (med_data.sort_number > 1)) OR (not any (med_data_list.med_order_type = "Complex Order")) // not a complex order ) AND med_data_list.order_med_significant_date = med_data.order_med_significant_date ); // Find the dosage range for the SINGLE DOSE //------------------------------------------ // Only retreive the dosage range data once for each Item-Catalog/Multum // by checking to see if the dosage range data has already been retrieved if (not exist med_data.retrieved_dose_range_data and exist med_data.order_med_dose_low ) then if use_item_catalog_dosage_data then (item_cat_dosage_range_list, item_cat_missing_route, item_cat_unmapped_route, item_cat_missing_uom, item_cat_unmapped_uom, item_cat_uom_conversion_issue ):= call func_dosage_cat with ( drug_name, med_data.is_order, catalog_item_obj, med_data.grouper_id, med_data.multum_dnum, med_data.multum_mmdc, med_data.order_med_route, med_data.order_med_route_id, med_data.generic_route, med_data.order_med_significant_date, med_data.order_med_units, med_data.order_med_uom_id, single_order_calc_per_uom, average_order_calc_per_uom, total_order_calc_per_uom, patient_birthday_info_on_order, has_valid_birthdate, wt_kg, BSA_number_rounded, intl_patient_gender, core_uom_const, alert_if_missing_flags, patient_info ); // Performed item catalog dosage look up for the medication found_med_data.retrieved_dose_range_data := true; found_med_data.missing_route := found_med_data.missing_route or item_cat_missing_route; found_med_data.unmapped_route := found_med_data.unmapped_route or item_cat_unmapped_route; found_med_data.missing_uom := found_med_data.missing_uom or item_cat_missing_uom; found_med_data.unmapped_uom := found_med_data.unmapped_uom or item_cat_unmapped_uom; found_med_data.uom_conversion_issue:= found_med_data.uom_conversion_issue or item_cat_uom_conversion_issue; item_cat_dosage_range_list.patient_age_at_order := age_str; // create map between medication and the single or contraindication multum values single_item_cat_dosage_range_list := item_cat_dosage_range_list where (item_cat_dosage_range_list.dosage_type in ("single")); found_single_dose := any (single_item_cat_dosage_range_list where single_item_cat_dosage_range_list.match_found = true); // add the item catalog for single dosage ranges to the dosage range list if ((exists single_item_cat_dosage_range_list) and (count single_item_cat_dosage_range_list > 0)) then single_item_cat_dosage_range_list.dosage_type := "single"; dosage_range_list := dosage_range_list, single_item_cat_dosage_range_list; // update the sort number list_count := count dosage_range_list; dosage_range_list.sort_number := 1 seqto list_count; // create map between medication and the single item catalog dosage range value for single_item_cat_dosage_range in single_item_cat_dosage_range_list do if single_item_cat_dosage_range.match_found then for found_med_data_item in found_med_data do map_item := new Medication_Dosage_Range_Map; med_dosage_map_list := med_dosage_map_list, map_item; map_item.med_sort_number := found_med_data_item.sort_number; map_item.med_name := found_med_data_item.order_med_name; map_item.dosage_range_sort_number := single_item_cat_dosage_range.sort_number; map_item.dosage_type := single_item_cat_dosage_range.dosage_type; map_item.match_found := single_item_cat_dosage_range.match_found; enddo; else // missing data dosage range is just mapped to first occurence of the medication found_med_data_item := last found_med_data[1]; map_item := new Medication_Dosage_Range_Map; med_dosage_map_list := med_dosage_map_list, map_item; map_item.med_sort_number := found_med_data_item.sort_number; map_item.med_name := found_med_data_item.order_med_name; map_item.dosage_range_sort_number := single_item_cat_dosage_range.sort_number; map_item.dosage_type := single_item_cat_dosage_range.dosage_type; map_item.match_found := single_item_cat_dosage_range.match_found; endif; // if single_item_cat_dosage_range.match_found enddo; // for single_item_cat_dosage_range in single_item_cat_dosage_range_list endif; // if (count single_item_cat_dosage_range_list > 0) endif; if ( use_multum_dosage_data and has_valid_birthdate ) then if med_data.is_order then if (catalog_item_obj.DrcGrouperID is null and exists catalog_item_obj.DrugCatalogKey and not catalog_item_obj.DrugCatalogKeyIsIgnored) then found_med_data.unmapped_grouper := true; endif; if (catalog_item_obj.DrugCatalogKey is null and not catalog_item_obj.DrugCatalogKeyIsIgnored) then found_med_data.unmapped_drug := true; endif; endif; // Get the corresponding dosage range data from multum (multum_dosage_range_list, multum_missing_route, multum_unmapped_route, multum_missing_uom, multum_unmapped_uom, multum_uom_conversion_issue ):= call func_dosage_multum with ( med_data.grouper_id, drug_name, med_data.multum_dnum, med_data.multum_mmdc, med_data.order_med_route, med_data.order_med_route_id, med_data.generic_route, med_data.order_med_significant_date, med_data.order_med_units, med_data.order_med_uom_id, med_data.order_med_frequency, med_data.multum_freq_id, med_data.med_order_type, patient_birthday_info_on_order, wt_kg, BSA_number_rounded, intl_patient_gender, has_liver_disease_bit, dialysis_type_str, patient_info.Creatinine.value, intentionally_unmapped_frequency_list, alert_if_missing_flags, med_data.is_order, patient_info, core_uom_const ); // Performed multum dosage range data look up for this medication found_med_data.retrieved_dose_range_data := true; found_med_data.uom_conversion_issue :=found_med_data.uom_conversion_issue or multum_uom_conversion_issue; found_med_data.missing_route := found_med_data.missing_route or multum_missing_route; found_med_data.unmapped_route := found_med_data.unmapped_route or multum_unmapped_route; found_med_data.missing_uom := found_med_data.missing_uom or multum_missing_uom; found_med_data.unmapped_uom := found_med_data.unmapped_uom or multum_unmapped_uom; multum_dosage_range_list.patient_age_at_order := age_str; // add the item catalog for single dosage ranges to the dosage range list if (count multum_dosage_range_list > 0) then dosage_range_list := dosage_range_list, multum_dosage_range_list; // update the sort number list_count := count dosage_range_list; dosage_range_list.sort_number := 1 seqto list_count; // create map between medication and the single or contraindication multum values single_contraindication_multum_dosage_list := multum_dosage_range_list where (multum_dosage_range_list.dosage_type in ("single", "contraindication")); for multum_dosage_range_item in single_contraindication_multum_dosage_list do if ( multum_dosage_range_item.match_found and multum_dosage_range_item.is_range ) then for found_med_data_item in found_med_data do map_item := new Medication_Dosage_Range_Map; med_dosage_map_list := med_dosage_map_list, map_item; map_item.med_sort_number := found_med_data_item.sort_number; map_item.med_name := found_med_data_item.order_med_name; map_item.dosage_range_sort_number := multum_dosage_range_item.sort_number; map_item.dosage_type := multum_dosage_range_item.dosage_type; map_item.match_found := multum_dosage_range_item.match_found; map_item.dose_frequency := multum_dosage_range_item.dose_frequency; map_item.frequency_issue := multum_dosage_range_item.frequency_issue; enddo; else // missing criteria (match not found) or contraindication // These items should be mapped to the medicaiton as dosage comparion will not be done found_med_data_item := last found_med_data[1]; map_item := new Medication_Dosage_Range_Map; med_dosage_map_list := med_dosage_map_list, map_item; map_item.med_sort_number := found_med_data_item.sort_number; map_item.med_name := found_med_data_item.order_med_name; map_item.dosage_range_sort_number := multum_dosage_range_item.sort_number; map_item.dosage_type := multum_dosage_range_item.dosage_type; map_item.match_found := multum_dosage_range_item.match_found; // if match found, and not a range means it{{{SINGLE-QUOTE}}}s a contraindication if (multum_dosage_range_item.match_found and multum_dosage_range_item.dosage_type = "contraindication") then found_med_data_item.contraindication_found := true; endif; endif; // if multum_dosage_range_item.found_match enddo; // for multum_dosage_range_item in single_contraindication_multum_dosage_list endif; //if (count multum_dosage_range_list > 0) // Set the Single Dosage Criteria in the Med_Data objects // that have the same Name, Route, UOM, and PerUOM // OR both PerUOM are NULL. single_dosage_ranges := dosage_range_list where dosage_range_list.dosage_type = "single"; endif; endif; //if not exist med_data.retrieved_dose_range_data // Compare the medication single dose with the dosage range data all_single_dosage_range := dosage_range_list where (dosage_range_list.match_found AND dosage_range_list.dosage_type = "single" ); found_maps := med_dosage_map_list where (med_dosage_map_list.med_sort_number = med_data.sort_number AND med_dosage_map_list.dosage_range_sort_number in all_single_dosage_range.sort_number AND med_dosage_map_list.dosage_type = "single"); for map_item in found_maps do dosage_range := last dosage_range_list[map_item.dosage_range_sort_number]; // Set the Low & High Values for the SINGLE DOSE //---------------------------------------------- // Set compound versus simple // if dosage_range.dose_calc_method = dose_per_string then // Set the single dose for the COMPOUND UOM (xxx/kg or xxx/m2) map_item.med_dose_high := med_data.calc_med_dose_high; map_item.med_dose_low := med_data.calc_med_dose_low; map_item.med_dose_uom := med_data.order_med_units || "/" || med_data.calc_med_per_uom; sample_vals := med_data.calc_med_dose_low, dosage_range.lower_dose, dosage_range.upper_dose; else // Set the single dose for the SIMPLE UOM (mg, cc, etc.) map_item.med_dose_high:= med_data.order_med_dose_high; map_item.med_dose_low:= med_data.order_med_dose_low; map_item.med_dose_uom := med_data.order_med_units; sample_vals := med_data.order_med_dose_low, dosage_range.lower_dose, dosage_range.upper_dose; endif; // if dosage_range.dose_calc_method = dose_per_string // Apply unit conversion if necessary high_low_list := ( map_item.med_dose_high, map_item.med_dose_low); // Call the MLM to trim the decimals rounded_high_low_list := call func_dosage_trim_adjusted with sample_vals, dosage_range.conversion_factor, high_low_list; map_item.adjusted_dose_high := rounded_high_low_list[1]; map_item.adjusted_dose_low := rounded_high_low_list[2]; map_item.adjusted_dose_uom := dosage_range.corrected_uom; // CLINICAL RULE -- Determine if Dose is Out of Range for SINGLE DOSE //-------------------------------------------------------------------- map_item.above_range := false; map_item.below_range := false; if (map_item.adjusted_dose_low < dosage_range.lower_dose) then map_item.below_range := true; elseif (map_item.adjusted_dose_high > dosage_range.upper_dose) then map_item.above_range := true; endif; enddo; med_data.outside_single_dosage_range := any found_maps.above_range or any found_maps.below_range; //---------------------------------- // Check TOTAL-DAILY Dosage Range //---------------------------------- // Find the TOTAL-DAILY Dose medications // with the same Name, UOM, and Route as the SINGLE DOSE //-------------------------------------------------------------------- found_total_tracker := total_tracker_list where (total_tracker_list.med_order_type = med_data.med_order_type AND total_tracker_list.med_name = med_data.order_med_name AND (total_tracker_list.uom = med_data.order_med_units or (total_tracker_list.uom is null and med_data.order_med_units is null)) AND (total_tracker_list.route = med_data.order_med_route or (total_tracker_list.route is null and med_data.order_med_route is null)) AND (total_tracker_list.start_date = med_data.order_med_significant_date)); for total_tracker in found_total_tracker do // Only retreive the TOTAL DAILY dosage range criteria once for each Item-Catalog // by checking to see if the criteria has already been stored in the object if not exist total_tracker.retrieved_dose_range_data AND exist med_data.retrieved_dose_range_data then // Find the dosage range for TOTAL DAILY DOSE //-------------------------------------------- if use_item_catalog_dosage_data then // create map between medication and the total item catalog values total_item_cat_dosage_range_list := item_cat_dosage_range_list where (item_cat_dosage_range_list.dosage_type in ("total")); // Set the Total Dosage Criteria in the Total_Tracker objects //----------------------------------------------------------- // Performed item catalog dosage look up for the medication found_total_tracker.retrieved_dose_range_data := true; // add the item catalog for total dosage ranges to the dosage range list if ((exists total_item_cat_dosage_range_list) and (count total_item_cat_dosage_range_list > 0)) then total_item_cat_dosage_range_list.dosage_type := "total"; dosage_range_list := dosage_range_list, total_item_cat_dosage_range_list; // update the sort number list_count := count dosage_range_list; dosage_range_list.sort_number := 1 seqto list_count; // create map between medication and the total item catalog dosage range value for total_item_cat_dosage_range in total_item_cat_dosage_range_list do if total_item_cat_dosage_range.match_found then for found_total_tracker_item in found_total_tracker do map_item := new Medication_Dosage_Range_Map; med_dosage_map_list := med_dosage_map_list, map_item; map_item.med_sort_number := found_total_tracker_item.sort_number; map_item.med_name := found_total_tracker_item.med_name; map_item.dosage_range_sort_number := total_item_cat_dosage_range.sort_number; map_item.dosage_type := total_item_cat_dosage_range.dosage_type; map_item.match_found := total_item_cat_dosage_range.match_found; enddo; else // missing data dosage range is just mapped to first occurence of the medication found_total_tracker_item := last found_total_tracker[1]; map_item := new Medication_Dosage_Range_Map; med_dosage_map_list := med_dosage_map_list, map_item; map_item.med_sort_number := found_total_tracker_item.sort_number; map_item.med_name := found_total_tracker_item.med_name; map_item.dosage_range_sort_number := total_item_cat_dosage_range.sort_number; map_item.dosage_type := total_item_cat_dosage_range.dosage_type; map_item.match_found := total_item_cat_dosage_range.match_found; endif; // if total_item_cat_dosage_range.match_found enddo; // for total_item_cat_dosage_range in total_item_cat_dosage_range_list endif; // if ((exists total_item_cat_dosage_range_list) and (count total_item_cat_dosage_range_list > 0)) endif; //if use_item_catalog_dosage_data if use_multum_dosage_data then total_dosage_ranges := dosage_range_list where dosage_range_list.dosage_type = "total"; found_total_tracker.retrieved_dose_range_data := true; // create map between medication and the single or contraindication multum values total_multum_dosage_list := multum_dosage_range_list where (multum_dosage_range_list.dosage_type in ("total")); for multum_dosage_range_item in total_multum_dosage_list do if ( multum_dosage_range_item.match_found and multum_dosage_range_item.is_range ) then for found_total_tracker_item in found_total_tracker do map_item := new Medication_Dosage_Range_Map; med_dosage_map_list := med_dosage_map_list, map_item; map_item.med_sort_number := found_total_tracker_item.sort_number; map_item.med_name := found_total_tracker_item.med_name; map_item.dosage_range_sort_number := multum_dosage_range_item.sort_number; map_item.dosage_type := multum_dosage_range_item.dosage_type; map_item.match_found := multum_dosage_range_item.match_found; enddo; else // missing criteria (match not found) // These items should be mapped to the medicaiton as dosage comparion will not be done found_total_tracker_item := last found_total_tracker[1]; map_item := new Medication_Dosage_Range_Map; med_dosage_map_list := med_dosage_map_list, map_item; map_item.med_sort_number := found_total_tracker_item.sort_number; map_item.med_name := found_total_tracker_item.med_name; map_item.dosage_range_sort_number := multum_dosage_range_item.sort_number; map_item.dosage_type := multum_dosage_range_item.dosage_type; map_item.match_found := multum_dosage_range_item.match_found; endif; // if multum_dosage_range_item.found_match enddo; // for multum_dosage_range_item in total_multum_dosage_list endif; // if use_multum_dosage_data found_total_tracker.found_total_daily_dose := any (total_item_cat_dosage_range.match_found) or any (total_multum_dosage_list.match_found); endif; //if not exist total_tracker.retrieved_dose_range_data // Process Clinical Rule Once for each Total Tracker // by checking if it has already been processed // the field outside_total_daily_dose is NULL if it has not been processed. //-------------------------------------------------------------------------- // Compare the medication total dose with the dosage range data all_total_dosage_range := dosage_range_list where (dosage_range_list.match_found AND dosage_range_list.dosage_type = "total" ); found_maps := med_dosage_map_list where (med_dosage_map_list.med_sort_number = total_tracker.sort_number AND med_dosage_map_list.dosage_range_sort_number in all_total_dosage_range.sort_number AND med_dosage_map_list.dosage_type = "total"); for map_item in found_maps do dosage_range := last dosage_range_list[map_item.dosage_range_sort_number]; // Set the Low & High Values for the TOTAL DAILY DOSE //---------------------------------------------------- if dosage_range.dose_calc_method = dose_per_string then // Set the total dose for the COMPOUND UOM (xxx/kg or xxx/m2) // Find the correct conversion factor if dosage_range.calc_per_core_uom = core_uom_const.M2_string then conversion_factor_total := BSA_number_rounded; elseif dosage_range.calc_per_core_uom = core_uom_const.kg_string then conversion_factor_total := wt_kg; elseif dosage_range.calc_per_core_uom = core_uom_const.gm_string then conversion_factor_total := wt_kg * 1000; elseif dosage_range.calc_per_core_uom = core_uom_const.lb_string then conversion_factor_total := wt_kg * 2.2045855 ; elseif dosage_range.calc_per_core_uom = core_uom_const.ounce_string then conversion_factor_total := wt_kg * 2.2045855 * 16 ; else conversion_factor_total := 1 ; endif; //if dosage_range.calc_per_core_uom // Calculate and Set the dose for the COMPOUND UOM order_total_dose_high:= total_tracker.total_dose_high / conversion_factor_total; order_total_dose_low:= total_tracker.total_dose_low / conversion_factor_total; // Round the DOSE-PER number to within 1 decimal point of the criteria. //---------------------------------------------------------------------- // Example: If the upper dose criteria has 2 decimal points, // then round to 3 decimals. // Initalize Variables high_low_list := order_total_dose_high, order_total_dose_low; sample_vals := med_data.calc_med_dose_low, dosage_range.lower_dose, dosage_range.upper_dose; // Call the MLM to trim the decimals rounded_high_low_list := call func_dosage_trim with sample_vals, high_low_list; // Save the Calculated COMPOUND UOM into the Total_Tracker Object total_tracker.total_calc_med_dose_high := rounded_high_low_list[1]; total_tracker.total_calc_med_dose_low := rounded_high_low_list[2]; map_item.med_dose_high := total_tracker.total_calc_med_dose_high; map_item.med_dose_low := total_tracker.total_calc_med_dose_low; map_item.med_dose_uom := med_data.order_med_units || "/" || med_data.calc_med_per_uom; sample_vals := med_data.calc_med_dose_low, dosage_range.lower_dose, dosage_range.upper_dose; else /* Set the total dose for the SIMPLE UOM (mg, cc, etc.) */ order_total_dose_high:= total_tracker.total_dose_high; order_total_dose_low:= total_tracker.total_dose_low; map_item.med_dose_high := total_tracker.total_dose_high; map_item.med_dose_low := total_tracker.total_dose_low; map_item.med_dose_uom := med_data.order_med_units; sample_vals := med_data.order_med_dose_low, dosage_range.lower_dose, dosage_range.upper_dose; endif; // if dosage_range.dose_calc_method = dose_per_string // Apply unit conversion if necessary high_low_list := ( map_item.med_dose_high, map_item.med_dose_low ); // Call the MLM to trim the decimals rounded_high_low_list := call func_dosage_trim_adjusted with sample_vals, dosage_range.conversion_factor, high_low_list; map_item.adjusted_dose_high := rounded_high_low_list[1]; map_item.adjusted_dose_low := rounded_high_low_list[2]; map_item.adjusted_dose_uom := dosage_range.corrected_uom; // CLINICAL RULE -- Determine if Dose is Out of Range for TOTAL DAILY DOSE //------------------------------------------------------------------------- // use the dose values before rounding to compare map_item.above_range := false; map_item.below_range := false; IF (map_item.adjusted_dose_high > dosage_range.upper_dose) then map_item.above_range := true; elseif (map_item.adjusted_dose_low < dosage_range.lower_dose) then // low dose out of range, needs more checking. if total_tracker.has_full_24hrs_doses = false and total_tracker.is_last_24hr_interval = true then if total_tracker.med_order_type <> "Complex Order" then map_item.below_range := true; endif; // if total_tracker.med_order_type <> "Complex Order" else map_item.below_range := true; endif; // if total_tracker.is_24hr_doses = false endif; // if map_item.adjusted_dose_high > dosage_range.upper_dose enddo; // for map_item in found_maps total_tracker.outside_total_daily_dose := any found_maps.above_range or any found_maps.below_range; enddo; // for total_tracker //---------------------------------- // Check AVERAGE-DAILY Dosage Range //---------------------------------- // Average-Daily Dosage Range should be checked for Regular and IV-Additives. // If a Complex Order does NOT have a Total-Daily dosage-range criteria, // then substitute the Average-Daily criteria to do a dosage-range check // for the Total-Daily. if med_data.med_order_type is in ("Regular", "IV-Additive") or (med_data.med_order_type = "Complex Order" and NO (found_total_tracker.found_total_daily_dose where it is present)) // Note: {{{SINGLE-QUOTE}}}where it is present{{{SINGLE-QUOTE}}} assures that the list does not contain // any NULL values before processing it with the NO operator. then // Find the AVERAGE-DAILY Dose medications // with the same Name, UOM, and Route as the SINGLE DOSE //------------------------------------------------------------------- found_average_tracker := average_tracker_list where (average_tracker_list.med_order_type = med_data.med_order_type AND average_tracker_list.med_name = med_data.order_med_name AND (average_tracker_list.uom = med_data.order_med_units OR (average_tracker_list.uom is null and med_data.order_med_units is null)) AND (average_tracker_list.route = med_data.order_med_route OR (average_tracker_list.route is null and med_data.order_med_route is null)) AND (average_tracker_list.start_date = med_data.order_med_significant_date) ); for average_tracker in found_average_tracker do // Only retreive the AVERAGE DAILY dosage range criteria once for each Item-Catalog // by checking to see if the criteria has already been stored in the object if not exist average_tracker.retrieved_dose_range_data AND exist med_data.retrieved_dose_range_data then // Find the dosage range AVERAGE DAILY DOSE //------------------------------------------ if use_item_catalog_dosage_data then // create map between medication and the average item catalog values average_item_cat_dosage_range_list := item_cat_dosage_range_list where (item_cat_dosage_range_list.dosage_type in ("average")); // Set the Total Dosage Criteria in the Average_Tracker objects //-------------------------------------------------------------- found_average_tracker.retrieved_dose_range_data := true; found_average_tracker.found_average_daily_dose := any (average_item_cat_dosage_range_list.match_found); // add the item catalog for average dosage ranges to the dosage range list if ((exists average_item_cat_dosage_range_list) and (count average_item_cat_dosage_range_list > 0)) then average_item_cat_dosage_range_list.dosage_type := "average"; dosage_range_list := dosage_range_list, average_item_cat_dosage_range_list; // update the sort number list_count := count dosage_range_list; dosage_range_list.sort_number := 1 seqto list_count; // create map between medication and the average item catalog dosage range value for average_item_cat_dosage_range in average_item_cat_dosage_range_list do if average_item_cat_dosage_range.match_found then for found_average_tracker_item in found_average_tracker do map_item := new Medication_Dosage_Range_Map; med_dosage_map_list := med_dosage_map_list, map_item; map_item.med_sort_number := found_average_tracker_item.sort_number; map_item.med_name := found_average_tracker_item.med_name; map_item.dosage_range_sort_number := average_item_cat_dosage_range.sort_number; map_item.dosage_type := average_item_cat_dosage_range.dosage_type; map_item.match_found := average_item_cat_dosage_range.match_found; enddo; else // missing data dosage range is just mapped to first occurence of the medication found_average_tracker_item := last found_average_tracker[1]; map_item := new Medication_Dosage_Range_Map; med_dosage_map_list := med_dosage_map_list, map_item; map_item.med_sort_number := found_average_tracker_item.sort_number; map_item.med_name := found_average_tracker_item.med_name; map_item.dosage_range_sort_number := average_item_cat_dosage_range.sort_number; map_item.dosage_type := average_item_cat_dosage_range.dosage_type; map_item.match_found := average_item_cat_dosage_range.match_found; endif; // if average_item_cat_dosage_range.match_found enddo; // for average_item_cat_dosage_range in average_item_cat_dosage_range_list endif; // if ((exists average_item_cat_dosage_range_list) and (count average_item_cat_dosage_range_list > 0)) endif; // if use_item_catalog_dosage_data endif; //if not exist average_tracker.retrieved_dose_range_data // Process Clinical Rule Once for each Average Tracker // by checking if it has already been processed // the field outside_total_daily_dose is NULL if it has not been processed. //-------------------------------------------------------------------------- // Compare the medication average dose with the dosage range data all_average_dosage_range := dosage_range_list where (dosage_range_list.match_found AND dosage_range_list.dosage_type = "average" ); found_maps := med_dosage_map_list where (med_dosage_map_list.med_sort_number = average_tracker.sort_number AND med_dosage_map_list.dosage_range_sort_number in all_average_dosage_range.sort_number AND med_dosage_map_list.dosage_type = "average"); for map_item in found_maps do dosage_range := last dosage_range_list[map_item.dosage_range_sort_number]; // Set the Low & High Values for the AVERAGE DAILY DOSE //------------------------------------------------------ if dosage_range.dose_calc_method = dose_per_string then // Set the average dose for the COMPOUND UOM (xxx/kg or xxx/m2) // Find the correct conversion factor if dosage_range.calc_per_core_uom = core_uom_const.M2_string then conversion_factor_ave := BSA_number_rounded; elseif dosage_range.calc_per_core_uom = core_uom_const.kg_string then conversion_factor_ave := wt_kg; elseif dosage_range.calc_per_core_uom = core_uom_const.gm_string then conversion_factor_ave := wt_kg * 1000; elseif dosage_range.calc_per_core_uom = core_uom_const.lb_string then conversion_factor_ave := wt_kg * 2.2045855 ; elseif dosage_range.calc_per_core_uom = core_uom_const.ounce_string then conversion_factor_ave := wt_kg * 2.2045855 * 16 ; else conversion_factor_ave := 1 ; endif; //if dosage_range.calc_per_core_uom // Calculate and Set the dose for the COMPOUND UOM order_average_dose_high := average_tracker.average_dose_high / conversion_factor_ave; order_average_dose_low := average_tracker.average_dose_low / conversion_factor_ave; // Round the DOSE-PER number to within 1 decimal point of the criteria. //---------------------------------------------------------------------- // Example: If the upper dose criteria has 2 decimal points, // then round to 3 decimals. // Initalize Variables high_low_list := order_average_dose_high, order_average_dose_low; sample_vals := dosage_range.lower_dose, dosage_range.upper_dose; // Call the MLM to round to one extra decimal point based on the low/high numbers for the DRC range. // uom_conversion_factor is the conversion factor between the order dose UOM and dose range UOM. For example, // 1. if order dose is in G, DRC range UOM is G, uom_conversion_factor = 1000; // 2. if order dose is in MG, DRC range UOM is G, uom_conversion_factor = 0.001; // 3. if order dose UOM and DRC range UOM are same, uom_conversion_factor = 1. // "sample_vals / dosage_range.uom_conversion_factor" is used to be the sample values to trim the extra // decimal points. So the rounded values will have one extra decimal point based on the DRC range low/high // number in the scenario where UOM conversion is involved. uom_conversion_factor values are saved in core load // table SXAUnitOfMeasureConversion. Currently the values in this table are all dividable. rounded_high_low_list := call func_dosage_trim with sample_vals / dosage_range.uom_conversion_factor, high_low_list; // Save the Calculated COMPOUND UOM into the Average_Tracker Object average_tracker.average_calc_med_dose_high := rounded_high_low_list[1]; average_tracker.average_calc_med_dose_low := rounded_high_low_list[2]; map_item.med_dose_high := average_tracker.average_calc_med_dose_high; map_item.med_dose_low := average_tracker.average_calc_med_dose_low; map_item.med_dose_uom := med_data.order_med_units || "/" || med_data.calc_med_per_uom; sample_vals := med_data.calc_med_dose_low, dosage_range.lower_dose, dosage_range.upper_dose; else /* Set the average dose for the SIMPLE UOM (mg, cc, etc.) */ order_average_dose_high:= average_tracker.average_dose_high; order_average_dose_low:= average_tracker.average_dose_low; map_item.med_dose_high := order_average_dose_high; map_item.med_dose_low := order_average_dose_low; map_item.med_dose_uom := med_data.order_med_units; high_low_list := ( map_item.med_dose_high, map_item.med_dose_low ); sample_vals := dosage_range.lower_dose, dosage_range.upper_dose; // Call the MLM to round to one extra decimal point based on the low/high numbers for the DRC range. // uom_conversion_factor is the conversion factor between the order dose UOM and dose range UOM. For example, // 1. if order dose is in G, DRC range UOM is G, uom_conversion_factor = 1000; // 2. if order dose is in MG, DRC range UOM is G, uom_conversion_factor = 0.001; // 3. if order dose UOM and DRC range UOM are same, uom_conversion_factor = 1. // "sample_vals / dosage_range.uom_conversion_factor" is used to be the sample values to trim the extra // decimal points. So the rounded values will have one extra decimal point based on the DRC range low/high // number in the scenario where UOM conversion is involved. uom_conversion_factor values are saved in core load // table SXAUnitOfMeasureConversion. Currently the values in this table are all dividable. rounded_high_low_list := call func_dosage_trim with sample_vals / dosage_range.uom_conversion_factor, high_low_list; map_item.med_dose_high := rounded_high_low_list[1]; map_item.med_dose_low := rounded_high_low_list[2]; sample_vals := med_data.order_med_dose_low, dosage_range.lower_dose, dosage_range.upper_dose; endif; // if dosage_range.dose_calc_method = dose_per_string // Apply unit conversion if necessary high_low_list := ( map_item.med_dose_high, map_item.med_dose_low ); // Call the MLM to trim the decimals rounded_high_low_list := call func_dosage_trim_adjusted with sample_vals, dosage_range.conversion_factor, high_low_list; map_item.adjusted_dose_high := rounded_high_low_list[1]; map_item.adjusted_dose_low := rounded_high_low_list[2]; map_item.adjusted_dose_uom := dosage_range.corrected_uom; // CLINICAL RULE -- Determine if Dose is Out of Range for AVERAGE DAILY DOSE //--------------------------------------------------------------------------- map_item.above_range := false; map_item.below_range := false; if map_item.adjusted_dose_high > dosage_range.upper_dose then map_item.above_range := true; elseif (map_item.adjusted_dose_low < dosage_range.lower_dose) then // low dose out of range, needs more checking. if average_tracker.has_full_24hrs_doses = false and average_tracker.is_last_24hr_interval = true then if average_tracker.med_order_type <> "Complex Order" then map_item.below_range := true; endif; // if average_tracker.med_order_type <> "Complex Order" else map_item.below_range := true; endif; // if average_tracker.has_full_24hrs_doses = false and average_tracker.is_last_24hr_interval = true endif; // if order_average_dose_high > dosage_range.upper_dose enddo; //for map_item in found_maps average_tracker.outside_average_daily_dose := any found_maps.below_range or any found_maps.above_range; enddo; //for average_tracker endif; //if med_data.med_order_type is in ("Regular", "IV-Additive") enddo; // for med_data //------------------------------- // Special Creatinine Rules //------------------------------- // Extra creatinine values were retrieved. // We only need to display these values when there{{{SINGLE-QUOTE}}}s a dialysis outside range, or creatinine outside range all_creatinine_dose_ranges := dosage_range_list where (dosage_range_list.creatinine_criteria is not null); patient_criteria_dose_ranges := all_creatinine_dose_ranges where all_creatinine_dose_ranges.crcl_within_range; // Check if there{{{SINGLE-QUOTE}}}s dialysis or creatinine outside range show_other_creatinine_values := count (med_dosage_map_list where med_dosage_map_list.dosage_range_sort_number in patient_criteria_dose_ranges.sort_number AND ( // patient crcl range in supplemental med_dosage_map_list.match_found = false OR // patient crcl range is contraindication med_dosage_map_list.dosage_type = "contraindication" OR // patient crcl range is outside range ( med_dosage_map_list.above_range = true OR med_dosage_map_list.below_range = true) )) > 0; if (count all_creatinine_dose_ranges > 0 and not show_other_creatinine_values) then // When the patient creatinine dose range is within range, remove the default and // other creatinine (these dose ranges already have match_found as false) // When there is no patient creatinine dose range found, remove the other creatinine // values (which already have match_found as false). // - The default range value won{{{SINGLE-QUOTE}}}t exist if there are other dose ranges with match_found is true. // - If the default range is the only one that matches patient critieria, it will have the // match_found as true, and will be kept dose_ranges_to_remove := dosage_range_list where ( dosage_range_list.match_found = false AND ( dosage_range_list.is_default = true OR dosage_range_list.sort_number in all_creatinine_dose_ranges.sort_number ) ); // There{{{SINGLE-QUOTE}}}s no renal outside range // Remove the additional creatinine maps from the map list no_creatinine_med_dosage_map_list := med_dosage_map_list where (med_dosage_map_list.dosage_range_sort_number not in dose_ranges_to_remove.sort_number); med_dosage_map_list := no_creatinine_med_dosage_map_list; endif; //-------------------------------- // CLINICAL RULES -- Missing Data //-------------------------------- patient_info.Age := new Patient_Property_Obj; patient_info.Age.type := "Age"; patient_info.Age.value := age_str; patient_info.Age.is_missing := not has_valid_birthdate; // If any medication has missing route or uom conversion issue set the value missing_route := any med_data_list.missing_route; unmapped_route := any med_data_list.unmapped_route; missing_uom := any med_data_list.missing_uom; unmapped_uom := any med_data_list.unmapped_uom; uom_conversion_issue := any med_data_list.uom_conversion_issue; //------------------------------------------ // Clinical Rule For Weekly //------------------------------------------ // The Average Daily Dose for a Weekly schedule cannot be determined // because there can be days in the week when a patient does not receive any medications. // The formula for Average Daily Dosage assumes that the patient receives // medication each day in order to compute an average. // RULE: Suppress any Average Daily Dose alert // when the Frequency is // and the schedule in "Weekly" if ANY (med_data_list.order_interval = "Weekly" ) and ANY (med_data_list.order_med_frequency = "" ) and ANY (average_tracker_list.found_average_daily_dose ) then // Find all average dosage range and average maps average_dosage_range := dosage_range_list where (dosage_range_list.match_found AND dosage_range_list.dosage_type = "average" ); average_maps := med_dosage_map_list where ( med_dosage_map_list.dosage_type = "average"); // Set Weekly Flag to true average_tracker_list.user_scheduled_weekly_used := TRUE; // Suppress Alert for Outside Average Daily Dose by setting it to false. // And set the Suppress_Alert audit trail flag average_tracker_list.outside_average_daily_dose := FALSE; average_tracker_list.suppress_alert := TRUE; average_dosage_range.match_found := false; average_maps.above_range := false; average_maps.below_range := false; endif; //if ANY (med_data_list.order_interval = "Weekly" ) //--------------------------------------------- // Clinical Rule For Irregular //--------------------------------------------- // If the frequency is // and the type of schedule is "Irregular" // and the order is a "Regular" or "IV-Additive Order" // and there are average-daily dose criteria // and the flag for showing irregular message is true // then show the Alert that average-daily dose could not be checked. // // This rules does not apply to Complex Orders // because we do not check their average-daily doses and // because the user cannot select an "Irregular" schedule if ANY (med_data_list.order_interval = "Irregular" ) and ANY (med_data_list.order_med_frequency = "" ) and ANY (average_tracker_list.found_average_daily_dose ) then // Find all average dosage range and average maps average_dosage_range := dosage_range_list where (dosage_range_list.match_found AND dosage_range_list.dosage_type = "average" ); average_maps := med_dosage_map_list where ( med_dosage_map_list.dosage_type = "average"); // Set Irregular Flag to true average_tracker_list.irregular_schedule_used := TRUE; // Suppress Alert for Outside Average Daily Dose // by setting it to false. average_tracker_list.outside_average_daily_dose := FALSE; average_tracker_list.suppress_alert := TRUE; average_dosage_range.match_found := false; average_maps.above_range := false; average_maps.below_range := false; endif; //if ANY (med_data_list.order_interval = "Irregular" ) //---------------------------------------------------- // Clinical Rule For Doses Administered Under 24 Hours //---------------------------------------------------- // DO NOT alert if the order is a loading dose for // a NOW & THEN complex order. This type of order has // a NULL frequency and a time interval of 1 minute. // // If the user has selected StopAfter // and the duration of the order is < 24 hours // and (Total Dose Criteria exists or Average Dose Criteria Exists) // 1. DO NOT alert if the user selected StopAfter X-Times or StopAfter X-Days // because the Total Dose and Average Dose can be determined. // 2. DO Alert if the user selected StopAter X-Minutes or StopAfter X-Hours // that resuls in a duration under 24 hours // because the Total Dose and Average Dose cannot be determined. // // If the user has NOT selected StopAfter // and ((StopDtm - SignificantDtm) < 24 hours // and (Total Dose Criteria exists or Average Dose Criteria Exists) // then Alert Total Dose and/or Average Dose cannot be determined. for med_data in med_data_list do // Initialize Variable met_criteria_under_24_hours := FALSE; //Calculate the Duration of the Order if med_data.stop_after_option_type = 1 then order_duration := med_data.stop_after_value DAY; elseif med_data.stop_after_option_type = 2 then order_duration := med_data.stop_after_value HOUR; elseif med_data.stop_after_option_type = 3 then order_duration := med_data.stop_after_value MINUTE; elseif exist med_data.stop_dtm then order_duration := med_data.stop_dtm - med_data.order_med_significant_date; else order_duration := NULL; endif; // Determine if Order has Met the Criteria for Duration Under 24 Hours if order_duration < 24 hours then if med_data.med_order_type = "Complex Order" and med_data.order_med_frequency is NULL and order_duration = 1 minute then // This is a loading dose for a NOW and THEN order // so do not alert about under 24-hours. met_criteria_under_24_hours := FALSE; elseif med_data.stop_after_option_type = 1 //days or med_data.stop_after_option_type = 4 //times then met_criteria_under_24_hours := FALSE; elseif ( med_data.stop_after_option_type = 2 //hours or med_data.stop_after_option_type = 3 ) //minutes and med_data.admin_dtm_list_calc_method = "MLM" // estimated method then met_criteria_under_24_hours := TRUE; elseif exist med_data.stop_dtm and (med_data.stop_after_option_type = 0 //not a stopafter or med_data.stop_after_option_type is NULL) and med_data.admin_dtm_list_calc_method = "MLM" // estimated method then met_criteria_under_24_hours := TRUE; else met_criteria_under_24_hours := FALSE; // formally TRUE endif; endif; //order_duration < 24 hours // Find the Matching Average Tracker and Total Tracker Objects // That have Average Daily or Total Daily Dose Criteria if met_criteria_under_24_hours then found_average_tracker := average_tracker_list where (average_tracker_list.med_order_type = med_data.med_order_type AND average_tracker_list.med_name = med_data.order_med_name AND average_tracker_list.uom = med_data.order_med_units AND average_tracker_list.route = med_data.order_med_route AND average_tracker_list.found_average_daily_dose ); found_total_tracker := total_tracker_list where (total_tracker_list.med_order_type = med_data.med_order_type AND total_tracker_list.med_name = med_data.order_med_name AND total_tracker_list.uom = med_data.order_med_units AND total_tracker_list.route = med_data.order_med_route AND total_tracker_list.found_total_daily_dose ); all_average_dosage_range := dosage_range_list where (dosage_range_list.match_found AND dosage_range_list.dosage_type = "average" ); found_average_maps := med_dosage_map_list where (med_dosage_map_list.med_sort_number in found_average_tracker.sort_number AND med_dosage_map_list.dosage_range_sort_number in all_average_dosage_range.sort_number AND med_dosage_map_list.dosage_type = "average"); found_average_dosage_range := dosage_range_list where ( dosage_range_list.sort_number in found_average_maps.dosage_range_sort_number); all_total_dosage_range := dosage_range_list where (dosage_range_list.match_found AND dosage_range_list.dosage_type = "total" ); found_total_maps := med_dosage_map_list where (med_dosage_map_list.med_sort_number in found_total_tracker.sort_number AND med_dosage_map_list.dosage_range_sort_number in all_total_dosage_range.sort_number AND med_dosage_map_list.dosage_type = "total"); found_total_dosage_range := dosage_range_list where ( dosage_range_list.sort_number in found_total_maps.dosage_range_sort_number); if exist found_average_tracker then // Set flags in Object found_average_tracker.met_criteria_under_24_hours := met_criteria_under_24_hours; // Suppress Alert for Outside Average Daily Dose by setting it to false. // And setting the Suppress_Alert flag as a audit trail. found_average_tracker.outside_average_daily_dose := FALSE; found_average_tracker.suppress_alert := TRUE; found_average_maps.above_range := false; found_average_maps.below_range := false; found_average_dosage_range.match_found := false; endif; if exist found_total_tracker then // Set flags in Object found_total_tracker.met_criteria_under_24_hours := met_criteria_under_24_hours; // Suppress Alert for Outside Total Daily Dose by setting it to false. // And setting the Suppress_Alert flag as a audit trail. found_total_tracker.outside_total_daily_dose := FALSE; found_total_tracker.suppress_alert := TRUE; found_total_maps.above_range := false; found_total_maps.below_range := false; found_total_dosage_range.match_found := false; endif; endif; // if met_criteria_under_24_hours enddo; //for med_data // If any fequency in the component list is based on shift then // a warning needs to be displayed. if any med_data_list.isShiftFrequency = true then shiftData := med_data_list where (med_data_list.isShiftFrequency = true); // Only warn if an Average or Total warning was calculated. found_average_tracker := average_tracker_list where (average_tracker_list.med_order_type is in (shiftData.med_order_type) AND average_tracker_list.med_name is in (shiftData.order_med_name) AND average_tracker_list.uom is in (shiftData.order_med_units) AND average_tracker_list.route is in (shiftData.order_med_route) AND average_tracker_list.found_average_daily_dose AND average_tracker_list.outside_average_daily_dose ); found_total_tracker := total_tracker_list where (total_tracker_list.med_order_type is in (shiftData.med_order_type) AND total_tracker_list.med_name is in (shiftData.order_med_name) AND total_tracker_list.uom is in (shiftData.order_med_units) AND total_tracker_list.route is in (shiftData.order_med_route) AND total_tracker_list.found_total_daily_dose AND total_tracker_list.outside_total_daily_dose ); all_average_dosage_range := dosage_range_list where (dosage_range_list.match_found AND dosage_range_list.dosage_type = "average" ); found_average_maps := med_dosage_map_list where (med_dosage_map_list.med_sort_number in found_average_tracker.sort_number AND med_dosage_map_list.dosage_range_sort_number in all_average_dosage_range.sort_number AND med_dosage_map_list.dosage_type = "average"); found_average_dosage_range := dosage_range_list where ( dosage_range_list.sort_number in found_average_maps.dosage_range_sort_number); all_total_dosage_range := dosage_range_list where (dosage_range_list.match_found AND dosage_range_list.dosage_type = "total" ); found_total_maps := med_dosage_map_list where (med_dosage_map_list.med_sort_number in found_total_tracker.sort_number AND med_dosage_map_list.dosage_range_sort_number in all_total_dosage_range.sort_number AND med_dosage_map_list.dosage_type = "total"); found_total_dosage_range := dosage_range_list where ( dosage_range_list.sort_number in found_total_maps.dosage_range_sort_number); // If some administration times were generated, they need to be supressed // for the items that used the shift based frequency if exists found_average_tracker then found_average_tracker.met_criteria_has_shift_frequency := true; // Suppress Alert for Outside Average Daily Dose by setting it to false. // And setting the Suppress_Alert flag as a audit trail. found_average_tracker.outside_average_daily_dose := FALSE; found_average_tracker.suppress_alert := TRUE; found_average_maps.above_range := false; found_average_maps.below_range := false; found_average_dosage_range.match_found := false; endif; if exists found_total_tracker then found_total_tracker.met_criteria_has_shift_frequency := true; // Suppress Alert for Outside Total Daily Dose by setting it to false. // And setting the Suppress_Alert flag as a audit trail. found_total_tracker.outside_total_daily_dose := FALSE; found_total_tracker.suppress_alert := TRUE; found_total_maps.above_range := false; found_total_maps.below_range := false; found_total_dosage_range.match_found := false; endif; endif; med_dosage_map_list.sort_number := 1 seqto (count med_dosage_map_list); hard_stop_low_doses := dosage_range_list where dosage_range_list.hard_stop_low = true; hard_stop_high_doses := dosage_range_list where dosage_range_list.hard_stop_high = true; med_with_hard_Stop := exists (med_dosage_map_list where (med_dosage_map_list.dosage_range_sort_number in hard_stop_low_doses.sort_number and med_dosage_map_list.below_range) or (med_dosage_map_list.dosage_range_sort_number in hard_stop_high_doses.sort_number and med_dosage_map_list.above_range) or (med_dosage_map_list.dosage_type = "contraindication" and med_dosage_map_list.match_found = true and (med_dosage_map_list.dosage_range_sort_number in hard_stop_low_doses.sort_number or med_dosage_map_list.dosage_range_sort_number in hard_stop_high_doses.sort_number))); inapplicable_route_found := exists( dosage_range_list where dosage_range_list.inapplicable_route_conversion_issue = true ); map_with_frequency_issue_list := med_dosage_map_list where med_dosage_map_list.dose_frequency not in intentionally_unmapped_frequency_list and med_dosage_map_list.frequency_issue is not null; show_frequency_warning := exists (map_with_frequency_issue_list) and ( ( alert_if_missing_flags.unmapped_frequency and any (map_with_frequency_issue_list.frequency_issue = "unmapped")) or ( any (map_with_frequency_issue_list.frequency_issue = "too frequent"))); // get the catalog dose ranges that match the prescription only at the // dnum level dnum_match_catalog_dose_range_list := (); if (not med_data_list[1].is_order) then dnum_match_catalog_dose_range_list := dosage_range_list where dosage_range_list.match_found = false AND dosage_range_list.is_multum = false AND dosage_range_list.dnum_ic_match_found = true; endif; /*----------------------------------*/ /* Format Alert Range Error Details */ /*----------------------------------*/ if any med_data_list.outside_single_dosage_range OR any med_data_list.contraindication_found OR any average_tracker_list.outside_average_daily_dose OR any total_tracker_list.outside_total_daily_dose OR (any average_tracker_list.user_scheduled_weekly_used and show_user_scheduled_weekly_message ) OR (any average_tracker_list.irregular_schedule_used and show_irregular_message ) OR (any total_tracker_list.met_criteria_under_24_hours and show_under_24_hour_message) OR (any average_tracker_list.met_criteria_under_24_hours and show_under_24_hour_message) OR (any total_tracker_list.met_criteria_has_shift_frequency and show_has_shift_frequency_message) OR (any average_tracker_list.met_criteria_has_shift_frequency and show_has_shift_frequency_message) OR (patient_info.Age.is_missing and alert_if_missing_flags.patient_age) OR (patient_info.Gender.is_missing and alert_if_missing_flags.patient_gender) OR (patient_info.Gender.unknown_other and alert_if_missing_flags.patient_gender) OR ( ( patient_info.Height.is_missing or patient_info.Height.not_current ) and alert_if_missing_flags.patient_height) OR ( ( patient_info.Weight.is_missing or patient_info.Weight.not_current ) and alert_if_missing_flags.patient_weight) OR (missing_route and alert_if_missing_flags.route) OR (unmapped_route and alert_if_missing_flags.unmapped_route) OR (uom_conversion_issue and alert_if_missing_flags.uom_conversion) OR (missing_uom and alert_if_missing_flags.uom) OR (unmapped_uom and alert_if_missing_flags.unmapped_uom) OR (patient_info.Gender.is_unmapped and alert_if_missing_flags.unmapped_gender) OR (any med_data_list.unmapped_drug and alert_if_missing_flags.unmapped_drug) OR (any med_data_list.unmapped_grouper and alert_if_missing_flags.unmapped_grouper) OR (any patient_info.DNum_Grouper.is_unmapped and alert_if_missing_flags.cannot_check_DNUM_Rx_To_Multum) OR (exists (dnum_match_catalog_dose_range_list) and alert_if_missing_flags.cannot_check_Rx_to_IC ) OR (any med_data_list.generic_route and alert_if_missing_flags.cannot_check_generic_route) OR ( inapplicable_route_found and alert_if_missing_flags.inapplicable_route ) OR ( show_frequency_warning ) then (alert_detail_text, missing_data_list, cannot_check_list, alert_abstract ):= call func_dosage_messages with ( ht_cm, wt_kg, patient_info, med_data_list, average_tracker_list, total_tracker_list, dosage_range_list, med_dosage_map_list, alert_if_missing_flags, use_multum_dosage_data, show_irregular_message, show_under_24_hour_message, show_has_shift_frequency_message, show_user_scheduled_weekly_message, show_Debug_statements, column_catalog_name, column_Multum_name, patient_birthday_info_on_order ) ; endif; //if any med_data_list.outside_single_dosage_range /* Always Conclude True to Return Data */ conclude true; ;; action: return (alert_detail_text, average_tracker_list, total_tracker_list, missing_data_list, cannot_check_list, med_with_hard_stop, show_frequency_warning, alert_abstract); ;; end: