maintenance: title: Alert Messages for the Dosage-Range Checking MLM;; mlmname: STD_FUNC_DOSAGE_MESSAGES;; 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: Creates the alert message for the Dosage-Range checking MLM. ;; explanation: This MLM encapsultes the dosage-range alert messages, so that all the changes to the message can be done in one MLM. ;; keywords: single dose; average daily dose; total daily dose; dosage range Change History: 01.08.2014 JML Added alert for dose of 0.0001 - used when medication not appropriate for age. Previously part of STD_DOSAGE on 07.30.2012. Moved with 6.1 upgrade to this MLM 07.15.2015 TMS Updated with St. clair customization for 15.1. CSR 33555 03.22.2019 TMS Updated with St. Clair customization for 18.4 CSR 37676 ;; 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; // include common data structures std_dosage_includes := MLM {{{SINGLE-QUOTE}}}std_func_dosage_includes{{{SINGLE-QUOTE}}}; include std_dosage_includes; ( 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 ) := ARGUMENT; // Set to true if logging is needed. log_execution_info := false; //Declare function for adding commas into numbers add_commas := MLM {{{SINGLE-QUOTE}}}SYS_FORMAT_NUMBER{{{SINGLE-QUOTE}}}; format_dose_range := MLM {{{SINGLE-QUOTE}}}STD_FUNC_DOSAGE_MSG_FORMAT_DOSE_RANGE{{{SINGLE-QUOTE}}}; // CSS style formatting CCS_MLM := MLM {{{SINGLE-QUOTE}}}STD_FUNC_DOSAGE_CSS{{{SINGLE-QUOTE}}}; //Declare the Missing_Data_Object Missing_Data_Object := OBJECT [ criteria, missing_data_error, details, msg, // message to be shown underneath the header unchecked_dose_range_type_list, // list of dosage types that could not be checked. med_name, // list of medication names affected by missing data issues alert_abstract // holds string appended to the alert abstract ]; //Declare the Cannot_Check_Object Cannot_Check_Object := OBJECT [ med_order_type, med_name_list, route, uom, processed_for_printing, alert_msg_for_cannot_check, alert_abstract // holds string appended to the alert abstract ]; // Warning_Count_Object - counts number of warnings for each medication Warning_Count_Object := OBJECT [ med_name, warning_count ]; // Case Info Object - arrange data by case Case_Info_Object := OBJECT [ case_id, case_type, dosage_range_sort_number, map_sort_number, based_on_text, msg, medication_count, med_name, is_default, is_multum, has_notes, has_date, conditions_text, processed_for_printing, based_on_header_text, // holds "based on" sub-string used text beneath headers route, // we also differentiate cases on the route being displayed creatinine_criteria, patient_age_at_order ]; // Arrange missing data by default/additional condition // and sort by medication name Supplemental_Table_Object := OBJECT [ med_name, is_multum, is_contraindication, route, // contains the route being displayed dosage_range_sort_number, map_sort_number, med_case_count, // remembers the number of medications associated with a case // Used during printing msg, patient_age_at_order ]; // Used to map an order medication unit of measure to the dose range // unit of measures that it could not be converted to. Conversion_Issue_Map_Object := OBJECT [ medication_val, // value specified in the medications unconvertible_val_list, // list of values in dose range that // order value could not be converted to med_name // name of the medication ]; // Initalize Variables average_criteria_type_list := (catalog_drc_type_const.age_average_daily_dose_string, catalog_drc_type_const.BSA_average_daily_dose_string, catalog_drc_type_const.weight_average_daily_dose_string); total_criteria_type_list := (catalog_drc_type_const.age_total_daily_dose_string, catalog_drc_type_const.BSA_total_daily_dose_string, catalog_drc_type_const.weight_total_daily_dose_string); BSA_criteria_type_list := (catalog_drc_type_const.BSA_average_daily_dose_string, catalog_drc_type_const.BSA_total_daily_dose_string, catalog_drc_type_const.Body_Surface_Area_string); AGE_criteria_type_list := (catalog_drc_type_const.age_average_daily_dose_string, catalog_drc_type_const.age_total_daily_dose_string, catalog_drc_type_const.age_string); WEIGHT_criteria_type_list := (catalog_drc_type_const.weight_average_daily_dose_string, catalog_drc_type_const.weight_total_daily_dose_string, catalog_drc_type_const.weight_string); // based_on_criteria_headings and patient_info_criteria_list // These two lists must be in sync to build the "Based On string" // Some criteria have no heading, so, null is used to indicate this. based_on_criteria_headings := ( "age", "gender", "height", "weight", "BSA", "liver", "renal", "creatinine clearance", "route" ); // contraindication_criteria_headings and contraindication_criteria_list // These two lists must be in sync to display contraindication messages contraindication_criteria_headings :=( "Age ", "Route = ", "Weight ", "Gender = ", "Renal = ", "Creatinine Clearance = ", "Liver Disease = "); // get the stop after option strings from CV3EnumReference // sorted by enum value for display in the alert stop_after_type_list := read { "Select ReferenceString " || " FROM CV3EnumReference" || " WHERE ColumnName in ({{{SINGLE-QUOTE}}}StopAfterOption{{{SINGLE-QUOTE}}}) " || " AND EnumValue > 0 " || " ORDER BY EnumValue ASC" }; // Retrieve facility-defined date and time formats (composite_date_format, partial_composite_date_format, time_format) := read last { "select isNull((SELECT e.value FROM HVCEnvProfile e " || "WHERE e.HierarchyCode={{{SINGLE-QUOTE}}}Connect{{{SINGLE-QUOTE}}} AND e.Code={{{SINGLE-QUOTE}}}CompositeDateFormat{{{SINGLE-QUOTE}}}),{{{SINGLE-QUOTE}}}{{{SINGLE-QUOTE}}}) " || "as CompositeDateFormat, " || " isNull((SELECT e.value FROM HVCEnvProfile e " || "WHERE e.HierarchyCode={{{SINGLE-QUOTE}}}Connect{{{SINGLE-QUOTE}}} AND e.Code={{{SINGLE-QUOTE}}}PartialCompositeDateFormat{{{SINGLE-QUOTE}}}),{{{SINGLE-QUOTE}}}{{{SINGLE-QUOTE}}}) " || "as PartialCompositeDateFormat, " || " isNull((SELECT e.value FROM HVCEnvProfile e " || "WHERE e.HierarchyCode={{{SINGLE-QUOTE}}}Connect{{{SINGLE-QUOTE}}} AND e.Code={{{SINGLE-QUOTE}}}TimeFormat{{{SINGLE-QUOTE}}}),{{{SINGLE-QUOTE}}}{{{SINGLE-QUOTE}}}) " || "as TimeFormat " }; // Get the patient{{{SINGLE-QUOTE}}}s birth day and birth time (birthday, birth_month_num, birth_day_num, birthtime ) := read last { ClientInfo: BirthDate, BirthMonthNum, BirthDayNum, BirthTime }; // Get the evoking object{{{SINGLE-QUOTE}}}s visit TimeZone (visit_time_zone) := read last { ClientVisit: TimeZone }; // declare string constants used for string comparisons dose_too_frequent := "too frequent"; dose_frequency_unmapped := "unmapped"; ;; evoke: ;; logic: //////////////////////////////////////////////////// // Populate the display_route property in the dosage_range objects //////////////////////////////////////////////////// has_alert_on_estimated_birthtime := false; for dosage_range in dosage_range_list do //[New born birth-time missing]: check if any alert using estimated birthday if patient_birthday_info_on_order.is_estimated_birthday = true then if ( dosage_range.estimated_age_used = 1 ) then dosage_range.patient_age_at_order := patient_birthday_info_on_order.age_min_inhour_str; has_alert_on_estimated_birthtime := true; elseif ( dosage_range.estimated_age_used = 2 ) then dosage_range.patient_age_at_order := patient_birthday_info_on_order.age_max_inhour_str; has_alert_on_estimated_birthtime := true; endif; endif; // convert to string first because the route_id or the med_route_id // could be either an integer or a string. MLMs don{{{SINGLE-QUOTE}}}t compare strings // and integers implicitly. "123" won{{{SINGLE-QUOTE}}}t be equal to the integer {{{SINGLE-QUOTE}}}123{{{SINGLE-QUOTE}}} dosage_range_med_route_id_str := dosage_range.med_route_id as string; dosage_range_route_id_str := dosage_range.route_id as string; if (dosage_range_med_route_id_str = dosage_range_route_id_str) or (dosage_range_route_id_str = "null") then dosage_range.display_route := dosage_range.med_route; else dosage_range.display_route := dosage_range.route; endif; enddo; //[New born birth-time missing]: estimated hours if has_alert_on_estimated_birthtime = true then estimated_age_hours := int(patient_birthday_info_on_order.age_hour_value); estimated_age_min_hours := int(patient_birthday_info_on_order.age_hour_min_value); endif; //////////////////////////////////////////////////// // Construct the Dose Range tables shown to the user //////////////////////////////////////////////////// if med_data_list[1].is_order then if med_data_list[1].is_outpatient_order then if med_data_list[1].is_script then order_rx := "This Prescription"; else order_rx := "This Home Medication"; endif; else order_rx := "This Order"; endif; else order_rx := "This Prescription"; endif; dose_type_sort_list := ("single", "total", "average"); is_multum_sort_list := (true, false); is_iv_additive := last (med_data_list.is_iv_additive); show_creatinine_clearance_note := exists (dosage_range_list where dosage_range_list.match_found = false AND dosage_range_list.creatinine_criteria is not null); divisor_row := "-----"; dosage_details_tables := ""; // This list contains all the dosage ranges map_dose_range_list := med_dosage_map_list where med_dosage_map_list.dosage_type <> "contraindication"; // This list contains just the contraindications map_contraindication_list := med_dosage_map_list where med_dosage_map_list.dosage_type = "contraindication"; Case_Info_list := (); // list of processed case IDs. Supplemental_Table_List := (); // list of supplemental tables medication_name_list := (); // distinct list of medication names if not exists (dosage_range_list) then // insert medication name into medication_name_list // so that the alert will still be printed medication_name_list := medication_name_list, med_data_list[1].order_med_name; endif; for dosage_range in dosage_range_list do case_id := dosage_range.case_id; med_name := dosage_range.med_name; // populate medication_name_list if med_name not in medication_name_list then medication_name_list := medication_name_list, med_name; endif; if (dosage_range.match_found) then case_type := "dose range"; else if (dosage_range.dosage_type <> "contraindication") then case_type := "missing data for dose"; else case_type := "missing data for contraindication"; endif; endif; // we now group dose ranges by the route being displayed, not by the // route stored in the dosage range dosage_range_for_case := dosage_range_list where ( ( (dosage_range.match_found = true AND dosage_range_list.dosage_type <> "contraindication") // case_type "dose range" OR dosage_range.match_found = false // case_type "missing data for dose", "missing data for contraindication" ) AND dosage_range_list.case_id = dosage_range.case_id AND dosage_range_list.match_found = dosage_range.match_found AND dosage_range_list.med_name = med_name AND dosage_range_list.display_route = dosage_range.display_route AND dosage_range_list.patient_age_at_order = dosage_range.patient_age_at_order ); map_for_case := med_dosage_map_list where ( med_dosage_map_list.dosage_range_sort_number in dosage_range_for_case.sort_number AND ( (case_type = "dose range" AND ( med_dosage_map_list.above_range OR med_dosage_map_list.below_range OR med_dosage_map_list.frequency_issue is not null ) ) OR (case_type = "missing data for dose") OR (case_type = "missing data for contraindication") ) ); dosage_range_for_missing_data := dosage_range_list where ( dosage_range_list.match_found = dosage_range.match_found AND dosage_range.match_found = false AND dosage_range_list.is_multum = dosage_range.is_multum AND dosage_range_list.display_route = dosage_range.display_route AND ( (case_type = "missing data for dose" AND dosage_range_list.dosage_type in ("single", "average", "total")) OR (case_type = "missing data for contraindication" AND dosage_range_list.dosage_type = "contraindication") ) AND dosage_range_list.med_name = med_name AND dosage_range_list.patient_age_at_order = dosage_range.patient_age_at_order AND ( ( dosage_range_list.is_multum = false // item catalog - all match not found OR patient_info.DNum_Grouper is null // DNum_Grouper is NULL if medication mapped to a dose range group OR not patient_info.DNum_Grouper.is_unmapped ) // multum - only match not found with grouper found ) ); map_for_missing_data := med_dosage_map_list WHERE ( med_dosage_map_list.dosage_range_sort_number in dosage_range_for_missing_data.sort_number ); has_notes := any (dosage_range_for_case.recommendation_msg is not null AND dosage_range_for_case.recommendation_msg <> ""); has_date := any (med_data_list.med_order_type = "Complex Order"); // execute following logic if case ID hasn{{{SINGLE-QUOTE}}}t been processed yet and // med_dose_range map objects exist for this particular case matching_case_info := last case_info_list where ( case_info_list.case_type = case_type AND case_Info_list.case_id = case_id AND case_info_list.med_name = med_name AND case_info_list.route = dosage_range.display_route AND case_info_list.patient_age_at_order = dosage_range.patient_age_at_order ); if ( (not exists matching_case_info) AND (count map_for_case > 0) ) then // We want all dose ranges for this case, even if it is within the range map_for_dosage_range_for_case := med_dosage_map_list where ( med_dosage_map_list.dosage_range_sort_number in dosage_range_for_case.sort_number and ( (med_dosage_map_list.dosage_type = "contraindication") OR ( case_type <> "dose range" ) OR ( case_type = "dose range" AND med_dosage_map_list.dosage_type <> "contraindication" AND med_dosage_map_list.adjusted_dose_low >= 0 // check that the value exists - // when frequency is not configured, // the total and average value can be null ) ) ); case_info_instance := new Case_Info_Object; case_info_instance.case_id := case_id; case_info_instance.case_type := case_type; case_info_instance.med_name := med_name; case_info_instance.map_sort_number := map_for_dosage_range_for_case.sort_number; case_info_instance.dosage_range_sort_number := dosage_range_for_case.sort_number; case_info_instance.is_default := dosage_range.is_default; case_info_instance.is_multum := dosage_range.is_multum; case_info_instance.medication_count := 0; case_info_instance.has_notes := has_notes; case_info_instance.has_date := has_date; case_info_instance.conditions_text := ""; case_info_instance.route := dosage_range.display_route; case_info_instance.creatinine_criteria := dosage_range.creatinine_criteria; case_info_instance.patient_age_at_order := dosage_range.patient_age_at_order; Case_Info_list := Case_Info_list, case_info_instance; endif; // if (not exists matching_case_info) AND (count map_for_case > 0) if (dosage_range.match_found = false) then matching_supplemental_table := last supplemental_table_list where ( supplemental_table_list.is_multum = dosage_range.is_multum AND supplemental_table_list.route = dosage_range.display_route AND supplemental_table_list.is_contraindication = (dosage_range.dosage_type = "contraindication") AND supplemental_table_list.med_name = med_name AND supplemental_table_list.patient_age_at_order = dosage_range.patient_age_at_order ); if ((not exists matching_supplemental_table) AND (count map_for_missing_data > 0) ) then for_drug_str := ""; if is_iv_additive then for_drug_str := "For " || med_name || ": "; endif; if (dosage_range.is_multum) then missing_data_based_on := "
" || for_drug_str || "Applicable dosage ranges based on patient " || "age of " || patient_info.Age.value || "" || ", route of " || dosage_range.display_route || ""; else missing_data_based_on := "
" || for_drug_str || "Applicable dosage ranges based on route of " || dosage_range.display_route || ""; endif; // construct the table // print out the header row table_heading := "\n"; if (dosage_range.is_multum) then cat_multum := column_Multum_name; col_span := "3"; else cat_multum := column_catalog_name; col_span := "2"; endif; if (dosage_range.dosage_type = "contraindication") then dose_contra := "Contraindication "; dose_column_header := "" || dose_column_header || "" || dose_contra || cat_multum || ""; missing_data_based_on := missing_data_based_on || " and the following additional conditions:\n"; table_heading := table_heading || "\n"; supplemental_table_instance := new Supplemental_Table_Object; supplemental_table_instance.med_name := med_name; supplemental_table_instance.is_contraindication := dosage_range.dosage_type = "contraindication"; supplemental_table_instance.is_multum := dosage_range.is_multum; supplemental_table_instance.route := dosage_range.display_route; supplemental_table_instance.msg := missing_data_based_on || table_heading; supplemental_table_instance.dosage_range_sort_number := dosage_range_for_missing_data.sort_number; supplemental_table_instance.map_sort_number := map_for_missing_data.sort_number; supplemental_table_instance.med_case_count := 0; supplemental_table_instance.patient_age_at_order := dosage_range.patient_age_at_order; supplemental_table_list := supplemental_table_list, supplemental_table_instance; endif; //if (not exists matching_supplemental_table) endif; // if (dosage_range.match_found = false) enddo; // for dosage_range in dosage_range_list // sort the medication_name_list medication_name_list := sort(medication_name_list); // create the Based On strings for case_item in case_info_list do dosage_range := dosage_range_list[case_item.dosage_range_sort_number[1]]; if dosage_range.BSA_criteria is not null then show_height_criteria := "show height criteria"; show_weight_criteria := "show weight criteria"; else show_height_criteria := null; show_weight_criteria := null; endif; if dosage_range.weight_criteria is not null then show_weight_criteria := dosage_range.weight_criteria; endif; for_iv_drug := ""; if is_iv_additive then for_iv_drug := "For " || case_item.med_name || ": "; endif; patient_BSA_str := null; if patient_info.BSA.value is not null then patient_BSA_str := patient_info.BSA.value || " m2"; endif; // if patient{{{SINGLE-QUOTE}}}s creatinine clearance is null, then, we don{{{SINGLE-QUOTE}}}t display it in the based-on // string even if there is a creatinine clearance criteria in // the dose ranges. patient_creatinine_str := null; if patient_info.Creatinine.value is not null then patient_creatinine_str := patient_info.Creatinine.value || " mL/min"; endif; // we display the string "Liver Disease" in the based-on string // if the patient has liver disease. Otherwise, the string is // suppressed. patient_liver_disease_str := null; if (patient_info.Liver.value = "Yes") then patient_liver_disease_str := "liver disease"; endif; // get the criteria from current dosage being processed at // top-most loop. Should be okay, since we won{{{SINGLE-QUOTE}}}t be // processing case ids more than once. dosage_range_criteria_list := ( dosage_range.age_criteria, dosage_range.gender_criteria, show_height_criteria, // show height value for BSA criteria show_weight_criteria, // show weight value for weight criteria, or BSA criteria dosage_range.BSA_criteria, dosage_range.liver_criteria, dosage_range.renal_criteria, dosage_range.creatinine_criteria, true ); patient_info_criteria_list := ( dosage_range.patient_age_at_order, patient_info.Gender.value, ht_cm || " cm", wt_kg || " kg", patient_BSA_str, patient_liver_disease_str, patient_info.Renal.value, patient_creatinine_str, case_item.route ); // these two lists should have the same number of items printable_based_on_criteria_headers := based_on_criteria_headings where dosage_range_criteria_list is not null; printable_based_on_criteria_list:= patient_info_criteria_list where dosage_range_criteria_list is not null; based_on_case := ""; based_on_case_header := ""; printable_based_on_criteria_count := count(printable_based_on_criteria_list); for printable_based_on_index in (1 seqto printable_based_on_criteria_count) do if (printable_based_on_index > 1) then if (printable_based_on_index < printable_based_on_criteria_count) and ((case_item.case_type = "dose range") or case_item.is_default) then based_on_case := based_on_case || ", "; based_on_case_header := based_on_case_header || ", "; else based_on_case := based_on_case || " and "; based_on_case_header := based_on_case_header || " and "; endif; endif; if (printable_based_on_criteria_headers[printable_based_on_index] is not null) then if (printable_based_on_criteria_headers[printable_based_on_index] not in ("renal", "liver") ) then based_on_case := based_on_case || printable_based_on_criteria_headers[printable_based_on_index] || " of "; endif; based_on_case_header := based_on_case_header || printable_based_on_criteria_headers[printable_based_on_index]; endif; based_on_case := based_on_case || "" || printable_based_on_criteria_list[printable_based_on_index] || ""; enddo; // There is some dosage range that is outside // Start creating the table dose_range_based_on_case := "
" || for_iv_drug || "Based on patient " || based_on_case || ":
\n"; // specify if Catalog or not if (not dosage_range.is_multum) then based_on_case_header := based_on_case_header || " " || column_catalog_name; endif; dose_range_based_on_case_header := "based on patient " || based_on_case_header; // Conditions text if case_item.is_default and case_item.is_multum then case_item.conditions_text := "No Additional Conditions"; else age_criteria := null; if not dosage_range.is_multum then age_criteria := dosage_range.age_criteria; endif; dose_range_criteria_list := ( age_criteria, dosage_range.weight_criteria, dosage_range.BSA_criteria, dosage_range.gender_criteria, dosage_range.liver_criteria, dosage_range.renal_criteria, dosage_range.creatinine_criteria ); if (exists dosage_range.liver_criteria) then liver_disease_str := "Liver Disease"; else liver_disease_str := null; endif; additional_conditions_list := ( "Age " || dosage_range.age_criteria, "Weight " || dosage_range.weight_criteria, "BSA " || dosage_range.BSA_criteria, "Gender " || dosage_range.gender_criteria, liver_disease_str, dosage_range.renal_criteria, "Creatinine Clearance " || dosage_range.creatinine_criteria ); additional_conditions_text := ""; case_condition_count := 0; for cond_ind in (1 seqto count additional_conditions_list) do cond_val := additional_conditions_list[cond_ind]; if exists dose_range_criteria_list[cond_ind] then if (case_condition_count > 0) then additional_conditions_text := additional_conditions_text || ", "; endif; additional_conditions_text := additional_conditions_text || cond_val; case_condition_count := case_condition_count + 1; endif; enddo; case_item.conditions_text := additional_conditions_text; endif; case_item.based_on_text := dose_range_based_on_case; case_item.based_on_header_text := dose_range_based_on_case_header; case_item.msg := ""; enddo; // for case_item in case_info_list // Loop through all the Med_Data_Objects for med_data in med_data_list do if (med_data.processed_for_printing is null) then // Find the matching objects for the SINGLE DOSE 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 ) ) ); // Find the matching objects for the AVERAGE DAILY DOSE found_average := 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 ) ) ); // Find the matching objects for the TOTAL DAILY DOSE found_total := 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 ) ) ); // This is all the maps for the current medication found_dose_map := med_dosage_map_list WHERE ( ( med_dosage_map_list.dosage_type = "single" AND med_dosage_map_list.med_sort_number in found_med_data.sort_number ) OR ( med_dosage_map_list.dosage_type = "average" AND med_dosage_map_list.med_sort_number in found_average.sort_number ) OR ( med_dosage_map_list.dosage_type = "total" AND med_dosage_map_list.med_sort_number in found_total.sort_number) ); // Process the list in reverse order for "supplemental info" section // The out of range section does not matter as the data is stored in the case_info object // TBD: add where condition on med_name reverse_case_indices := reverse (1 seqto (count case_info_list)); for ind in reverse_case_indices do case_info_item := case_info_list[ind]; // Find all the maps for the current case for the current medication found_dose_map_for_case := found_dose_map WHERE (found_dose_map.sort_number in Case_Info_item.map_sort_number); matching_case_found := count found_dose_map_for_case > 0; // for each case, we find all the med-dose maps associated with it // if we encounter this case more than once in this for-loop, then // we need to add a divisor row. if matching_case_found then // When medication changes (medication name, route, or UOM) add a divisor // - for child complex orders, if the uom or route changes the divisor will be added // - if there are multiple IV additives for the same drug and route, but different UOM, the divisor will be added case_info_item.medication_count := case_info_item.medication_count + 1; if case_info_item.medication_count > 1 then case_info_item.msg := case_info_item.msg || divisor_row; endif; dose_supplemental_table_list := supplemental_table_list WHERE (supplemental_table_list.is_contraindication = false); for missing_table in dose_supplemental_table_list do // if this case is associated with unmatched dose ranges // and there exists an "additional conditions" table // associated with map objects that are a associated // with this case, then add a divisor row and increment the numbery // of medications associated with this "additional conditions" table if case_info_item.case_type = "missing data for dose" AND any (missing_table.map_sort_number in found_dose_map_for_case.sort_number) then missing_table.med_case_count := missing_table.med_case_count + 1; if missing_table.med_case_count > 1 // how many cases have been printed for this pair then missing_table.msg := missing_table.msg || divisor_row; endif; endif; enddo; for map_item in found_dose_map_for_case do out_of_range_row := ""; dose_range_item := dosage_range_list[map_item.dosage_range_sort_number]; if (map_item.dosage_type = "single") then med_object := med_data_list[map_item.med_sort_number]; row_type := "Single:"; elseif (map_item.dosage_type = "total") then med_object := total_tracker_list[map_item.med_sort_number]; if ( med_data.med_order_type = "Complex Order" or med_object.dose_range_check_method = "Summed Doses") then row_type := "24-Hr Total:"; else row_type := "Total Daily:"; endif; elseif map_item.dosage_type = "average" then med_object := average_tracker_list[map_item.med_sort_number]; if ( med_data.med_order_type = "Complex Order" or med_object.dose_range_check_method = "Summed Doses") then row_type := "24-Hr Average:"; else row_type := "Total Average:"; endif; endif; // use med_data and each_dose_range objects here to populate // this row if case_info_item.case_type = "dose range" then if map_item.below_range or map_item.above_range then row_name := "outside_dose_"; else row_name := "within_dose_"; endif; else row_name := "missing_dose_"; endif; if case_info_item.is_multum then row_name := row_name || "multum"; else row_name := row_name || "catalog"; endif; out_of_range_row := out_of_range_row || "" || ""; // dosage range column dosage_range_col := call format_dose_range with (dose_range_item.lower_dose, dose_range_item.upper_dose); // dosage_range_col := dosage_range_col || " " || dose_range_item.corrected_uom; //JML - Modification to standard MLM to include patients aged 0 to 3yrs // if (dosage_range_col = "0-0.0001 mg") or (dosage_range_col = "0.0001") then if "0.0001" in dosage_range_col then dosage_range_col := "Medication ordered is not recommended for a patient fitting this profile."; else dosage_range_col := dosage_range_col || " " || dose_range_item.corrected_uom; endif; //End JML Change // Frequency Column - only shown for Multum single dose ranges frequency_col := ""; if case_info_item.is_multum then if (map_item.dosage_type = "single") and dose_range_item.dose_frequency is not null then frequency_col := dose_range_item.dose_frequency; endif; out_of_range_row := out_of_range_row || "" || ""; else out_of_range_row := out_of_range_row || ""; endif; is_duplicate_single_iv := false; if case_info_item.case_type = "dose range" then // SET SINGLE ORDERED DOSE ordered_dosage_col := call format_dose_range with (map_item.adjusted_dose_low, map_item.adjusted_dose_high); ordered_dosage_col := "" || ordered_dosage_col || " " || dose_range_item.corrected_uom || ""; if (map_item.above_range or map_item.below_range) then ordered_dosage_col := "" || ordered_dosage_col || ""; elseif (map_item.match_found and map_item.above_range = false and map_item.below_range = false) then ordered_dosage_col := "" || ordered_dosage_col || ""; endif; if (map_item.adjusted_dose_uom <> map_item.med_dose_uom) then orig_dose := call format_dose_range with (map_item.med_dose_low, map_item.med_dose_high); ordered_dosage_col := ordered_dosage_col || " (" || orig_dose || " " || map_item.med_dose_uom || ")"; endif; ordered_dosage_col := ordered_dosage_col || ""; if (case_info_item.is_multum or ( med_data.med_order_type = "Complex Order" and ( med_data.is_iv_additive is null or not med_data.is_iv_additive ))) and map_item.dosage_type = "single" then freq := med_object.order_med_frequency; if med_object.order_med_frequency is null then freq := "once"; endif; if dose_range_item.frequency_issue is not null and case_info_item.is_multum then ordered_dosage_col := ordered_dosage_col || " " || freq || ""; else ordered_dosage_col := ordered_dosage_col || " " || freq; endif; if med_object.stop_after_value is not null and med_object.stop_after_value > 0 and med_object.stop_after_option_type > 0 then ordered_dosage_col := ordered_dosage_col || " x " || med_object.stop_after_value || " " || stop_after_type_list[med_object.stop_after_option_type]; endif; endif; ordered_dosage_col := ordered_dosage_col || ""; // Order/Prescription dose col out_of_range_row := out_of_range_row || ""; if case_info_item.has_date then if map_item.dosage_type = "single" then if med_data.is_iv_additive then starting_on_col := ""; else starting_on_date := med_object.admin_dtm_list[1]; if starting_on_date is null then starting_on_date := med_object.calcStart_dtm; endif; if show_debug_statements then starting_on_col := starting_on_date formatted with "%.4t"; else starting_on_col := starting_on_date formatted with "%.2t"; endif; endif; elseif map_item.dosage_type in ("average", "total") then if show_debug_statements then starting_on_col := med_object.interval_begin_dtm_list[1] formatted with "%.4t"; else starting_on_col := med_object.interval_begin_dtm_list[1] formatted with "%.2t"; endif; endif; out_of_range_row := out_of_range_row || ""; endif; if case_info_item.has_notes then // recommendation message column if dose_range_item.recommendation_msg is not null then note_col := dose_range_item.recommendation_msg; else note_col := ""; endif; out_of_range_row := out_of_range_row || ""; endif; if show_debug_statements then route_val := ""; if med_data.order_med_route <> dose_range_item.route then route_val := ", Route: " || dose_range_item.route; endif; out_of_range_row := out_of_range_row || ""; endif; out_of_range_row := out_of_range_row || "\n"; if ( map_item.dosage_type = "single" AND med_data.is_iv_additive AND med_data.sort_number <> med_object.sort_number AND med_data.order_med_route <> med_object.order_med_route ) then // change case_type to skip processing duplicate single iv additive is_duplicate_single_iv := true; endif; else // missing data out_of_range_row := out_of_range_row || "\n"; supplemental_table := last (supplemental_table_list WHERE (supplemental_table_list.is_multum = dose_range_item.is_multum AND supplemental_table_list.route = case_info_item.route AND supplemental_table_list.is_contraindication = false AND supplemental_table_list.med_name = dose_range_item.med_name AND supplemental_table_list.patient_age_at_order = dose_range_item.patient_age_at_order )); supplemental_table.msg := supplemental_table.msg || out_of_range_row; endif; // Add the formatted row into the case_info_item // Skip if it{{{SINGLE-QUOTE}}}s a duplicate single IV order (complex iv-additive) if (is_duplicate_single_iv = false) then case_info_item.msg := case_info_item.msg || out_of_range_row; endif; enddo; endif; //matching_case_found then enddo; // ind in reverse_case_indices found_med_data.processed_for_printing := true; endif; enddo; // med_data in med_data_list // Generate the outside dose messages dose_range_case_info_list := case_info_list where (case_info_list.case_type = "dose range"); dosage_outside_range_table_list := (); for case_info_item in dose_range_case_info_list do if case_info_item.processed_for_printing is NULL then dosage_outside_table := case_info_item.based_on_text; found_based_on_multum := dose_range_case_info_list WHERE (dose_range_case_info_list.based_on_text = case_info_item.based_on_text AND dose_range_case_info_list.is_multum); multum_case_count := count found_based_on_multum; if (multum_case_count > 0) then has_notes := any (found_based_on_multum.has_notes); has_date := any (found_based_on_multum.has_date); // Create the table and the header row table_heading := "
"; else dose_contra := "Usual Dose Range "; dose_column_header := ""; endif; // first column heading table_heading := table_heading || "
Additional Conditions
" || row_type || "" || dosage_range_col || "" || frequency_col || "" || dosage_range_col || "" || ordered_dosage_col || "" || starting_on_col || "" || note_col || "" || "Case ID: " || case_info_item.case_id || route_val || "
" || case_info_item.conditions_text || "
\n" || "" || "" || ""; // show start date if there are multiple administrations (complex order) if has_date then table_heading := table_heading || ""; endif; // add Note header if has_notes then table_heading := table_heading || ""; endif; if show_debug_statements then table_heading := table_heading || ""; endif; // finish off the row header table_heading := table_heading || "\n"; // Go through the cases and add the rows table_rows := ""; for ind in (1 seqto multum_case_count) do if (ind > 1) then table_rows := table_rows || divisor_row; endif; table_rows := table_rows || found_based_on_multum[ind].msg; enddo; // Add the multum case table dosage_outside_table := dosage_outside_table || table_heading || table_rows || "
Usual Dose Range " || column_Multum_name || "" || order_rx || "Starting OnNote(Debug)
\n\n"; // Mark the cases as processed found_based_on_multum.processed_for_printing := true; endif; found_based_on_catalog := dose_range_case_info_list WHERE (dose_range_case_info_list.based_on_text = case_info_item.based_on_text AND not dose_range_case_info_list.is_multum); catalog_case_count := count found_based_on_catalog; if (catalog_case_count > 0) then has_notes := any (found_based_on_catalog.has_notes); has_date := any (found_based_on_catalog.has_date); // Create the table and the header row table_heading := "\n" || "" || "" || ""; // show start date if there are multiple administrations (complex order) if has_date then table_heading := table_heading || ""; endif; // add Note header if has_notes then table_heading := table_heading || ""; endif; if show_debug_statements then table_heading := table_heading || ""; endif; // finish off the row header table_heading := table_heading || "\n"; // Go through the cases and add the rows table_rows := ""; for ind in (1 seqto catalog_case_count) do if (ind > 1) then table_rows := table_rows || divisor_row; endif; table_rows := table_rows || found_based_on_catalog[ind].msg; enddo; // Add the catalog case table dosage_outside_table := dosage_outside_table || table_heading || table_rows || "
Usual Dose Range " || column_catalog_name ||"" || order_rx || "Starting OnNote(Debug)
\n\n"; // Mark the cases as processed found_based_on_catalog.processed_for_printing := true; endif; based_on_creatinine_criteria := last (found_based_on_multum.creatinine_criteria where found_based_on_multum.creatinine_criteria is not null); if ( based_on_creatinine_criteria is not null AND based_on_creatinine_criteria <> "") then dosage_outside_table := dosage_outside_table || "NOTE" || " this applies to Creatinine Clearance Range " || based_on_creatinine_criteria || ". The dose could be out of range for other renal " || "conditions; see Supplemental Information.\n"; endif; dosage_outside_range_table_list := dosage_outside_range_table_list, dosage_outside_table; endif; enddo; // Missing data for contraindication missing_contraindication_case_list := case_info_list WHERE (case_info_list.case_type = "missing data for contraindication"); for case_info_item in missing_contraindication_case_list do for ind in case_info_item.dosage_range_sort_number do dose_range_item := dosage_range_list[ind]; supplemental_table := last (supplemental_table_list WHERE (supplemental_table_list.is_multum = dose_range_item.is_multum AND supplemental_table_list.route = case_info_item.route AND supplemental_table_list.is_contraindication = true AND supplemental_table_list.med_name = dose_range_item.med_name AND supplemental_table_list.patient_age_at_order = dose_range_item.patient_age_at_order )); row_name := "missing_data_"; if supplemental_table.is_multum then row_name := row_name || "multum_"; if supplemental_table.is_contraindication then row_name := row_name || "contraindication"; else row_name := row_name || "dose"; endif; else row_name := row_name || "catalog"; endif; supplemental_table.msg := supplemental_table.msg || "" || "" || dose_range_item.contraindication_msg || "" || "" || case_info_item.conditions_text || "" || "\n"; enddo; enddo; // Close table tags for missing data tables for supplemental_table_item in supplemental_table_list do supplemental_table_item.msg := supplemental_table_item.msg || "\n"; enddo; // If there are multiple groupers associated with the dnum, // find out which grouper has corresponding dose ranges supplemental_grouper_names := ""; if patient_info.DNum_Grouper.is_unmapped then missing_data_for_grouper := dosage_range_list where ( dosage_range_list.match_found = false and dosage_range_list.is_multum = true ); grouper_name_rows:= ""; grouper_info_list := patient_info.DNum_Grouper.value; for grouper_info_item in grouper_info_list do grouper_info_item.dosage_range_found := grouper_info_item.grouper_id in missing_data_for_grouper.grouper_id; if grouper_info_item.dosage_range_found then grouper_name_rows := grouper_name_rows || "
  • " || grouper_info_item.grouper_name || "
  • "; endif; enddo; if any grouper_info_list.dosage_range_found then supplemental_grouper_names := "
    " || "This medication has dosage ranges for the following groups of medications:" || "
    \n" || "\n"; endif; endif; //----------------------------------------------------- // Construct Cannot_Check_Object and Missing_Data_Object // Lists. //----------------------------------------------------- // Initialize List Variables cannot_check_list := (); missing_data_list := (); frequency_unchecked_list := (); dnum_match_catalog_dose_range_list := (); // get the catalog dose ranges that match the prescription only at the // dnum level 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; for med_name in medication_name_list do curr_med_data_list := med_data_list WHERE med_data_list.order_med_name = med_name; curr_average_tracker_list := average_tracker_list WHERE average_tracker_list.med_name = med_name; curr_total_tracker_list := total_tracker_list WHERE total_tracker_list.med_name = med_name; //------------------------------------------------------ // Handle Show Irregular Message //------------------------------------------------------ // This message only applies to the Average Daily Dosage Range // when there is a frequency that has an IRREGULAR Schedule. IF show_irregular_message and ANY curr_average_tracker_list.irregular_schedule_used then found_average_list := curr_average_tracker_list where curr_average_tracker_list.irregular_schedule_used; // For Irregular intervals set message about Average calculations irregular_schedule_text := "Issue: Irregular User Schedule

    \n" || "A User Scheduled frequency was selected " || "that used an Irregular schedule. There is an average daily " || "dosage range listed for the medication(s): " || med_name || ". However, for this type of " || "schedule the calculated average daily amount is invalid."; // Create Cannot_Check_Object and Add to List cannot_check := new cannot_check_object; cannot_check_list := cannot_check_list, cannot_check; // Populate Object cannot_check.med_order_type := found_average_list[1].med_order_type; cannot_check.med_name_list := med_name; cannot_check.route := found_average_list[1].route; cannot_check.uom := found_average_list[1].uom; cannot_check.alert_msg_for_cannot_check := irregular_schedule_text; cannot_check.alert_abstract := "Issue: Irregular User Schedule"; endif; //IF show_irregular_message //------------------------------------------------------ // Handle Show WEEKLY Message //------------------------------------------------------ // This message only applies to the Average Daily Dosage Range // when there is a frequency that has an WEEKLY Schedule. IF show_user_scheduled_weekly_message and ANY curr_average_tracker_list.user_scheduled_weekly_used then found_average_list := curr_average_tracker_list where curr_average_tracker_list.user_scheduled_weekly_used; // For WEEKLY intervals set message about Average calculations weekly_schedule_text := "Issue: Weekly User Schedule

    \n" || "A User Scheduled frequency was selected " || "that used a Weekly schedule. There is an " || "average daily dosage range listed for the medication(s): " || med_name || ". However, for this type of " || "schedule the calculated average daily amount is invalid."; // Create Cannot_Check_Object and Add to List cannot_check := new cannot_check_object; cannot_check_list := cannot_check_list, cannot_check; // Populate Object cannot_check.med_order_type := found_average_list[1].med_order_type; cannot_check.med_name_list := med_name; cannot_check.route := found_average_list[1].route; cannot_check.uom := found_average_list[1].uom; cannot_check.alert_msg_for_cannot_check := weekly_schedule_text; cannot_check.alert_abstract := "Issue: Weekly User Schedule"; endif; //IF show_irregular_message //------------------------------------ // Handle Show Under 24-Hour Message //------------------------------------ If show_under_24_hour_message AND (ANY curr_total_tracker_list.met_criteria_under_24_hours or ANY curr_average_tracker_list.met_criteria_under_24_hours ) then // Create Cannot_Check_Object and Add to List cannot_check := new cannot_check_object; cannot_check_list := cannot_check_list, cannot_check; // Populate Cannot_Check Object cannot_check.med_name_list := med_name; // Select the Total and Average Objects Needing the Message found_total_list := curr_total_tracker_list where curr_total_tracker_list.met_criteria_under_24_hours; found_average_list := curr_average_tracker_list where curr_average_tracker_list.met_criteria_under_24_hours; if exist found_total_list then cannot_check.med_order_type := found_total_list[1].med_order_type; cannot_check.route := found_total_list[1].route; cannot_check.uom := found_total_list[1].uom; elseif exist found_average_list then cannot_check.med_order_type := found_average_list[1].med_order_type; cannot_check.route := found_average_list[1].route; cannot_check.uom := found_average_list[1].uom; endif; under_24_hr_duration_msg := "Issue: Under 24-Hour dose

    \n" || "The average daily and total daily dosage cannot be calculated accurately " || "with regards to possible administration times " || "when a medication is given for less than 24 hours. " || "This affects the following medication(s): " || med_name || "\n"; cannot_check.alert_msg_for_cannot_check := under_24_hr_duration_msg; cannot_check.alert_abstract := "Issue: Under 24-Hour dose"; endif; //If show_under_24_hour_message //--------------------------------------- // Handle Show Has Shift based Frequency //--------------------------------------- If show_has_shift_frequency_message AND any curr_med_data_list.isShiftFrequency then // Display the warning for any component that has at least 1 // shift based frequency. shiftData := curr_med_data_list where (curr_med_data_list.isShiftFrequency = true); found_total_list := curr_total_tracker_list where (curr_total_tracker_list.med_order_type = shiftData[1].med_order_type AND curr_total_tracker_list.med_name = shiftData[1].order_med_name AND curr_total_tracker_list.uom = shiftData[1].order_med_units AND curr_total_tracker_list.route = shiftData[1].order_med_route ); found_average_list := curr_average_tracker_list where (curr_average_tracker_list.med_order_type = shiftData[1].med_order_type AND curr_average_tracker_list.med_name = shiftData[1].order_med_name AND curr_average_tracker_list.uom = shiftData[1].order_med_units AND curr_average_tracker_list.route = shiftData[1].order_med_route ); // Create Cannot_Check_Object and Add to List cannot_check := new cannot_check_object; cannot_check_list := cannot_check_list, cannot_check; // Populate Cannot_Check Object cannot_check.med_name_list := med_name; if exist found_total_list then cannot_check.med_order_type := found_total_list[1].med_order_type; cannot_check.route := found_total_list[1].route; cannot_check.uom := found_total_list[1].uom; elseif exist found_average_list then cannot_check.med_order_type := found_average_list[1].med_order_type; cannot_check.route := found_average_list[1].route; cannot_check.uom := found_average_list[1].uom; endif; has_shift_freq_msg := "Issue: Shift based frequency

    \n" || "A shift based frequency was selected for the medication(s): " || med_name || ". " || "The total daily dosage could not be calculated accurately " || "with regards to possible administration times."; cannot_check.alert_msg_for_cannot_check := has_shift_freq_msg; cannot_check.alert_abstract := "Issue: Shift based frequency"; endif; //If show_has_shift_frequency_message //------------------------------------------------------------------------------ // MISSING DATA ALERT //------------------------------------------------------------------------------ // Initialize Variables // string constants used for the header missing_data_str := "missing data"; data_not_current_str := "old data"; unmapped_data_str := "unmapped data"; issues_str := "issues"; // Process multum frequency issue alert messages // This isn{{{SINGLE-QUOTE}}}t placed in the Missing Data block because dose ranges are checked // even though the frequency could not be checked. So, if the dose ranges are valid, // then we avoid executing the statements in the Missing Data block unnecessarily if use_multum_dosage_data and alert_if_missing_flags.unmapped_frequency then // get mapping objects with unmapped frequencies // for the current medication. We only do this for dose ranges // that could be checked. unmapped_frequency_map_list := med_dosage_map_list where med_dosage_map_list.med_name = med_name and med_dosage_map_list.frequency_issue = dose_frequency_unmapped and med_dosage_map_list.dosage_type = "single" and med_dosage_map_list.match_found = true; if exists unmapped_frequency_map_list then // get the medication objects referenced in // the mapping objects unmapped_freq_med_data_list := curr_med_data_list where curr_med_data_list.sort_number in unmapped_frequency_map_list.med_sort_number; // Create missing data objects for frequencies that could not be mapped // in the medication objects if exists unmapped_freq_med_data_list then for unmapped_freq_med_data_item in unmapped_freq_med_data_list do freq := unmapped_freq_med_data_item.order_med_frequency; if unmapped_freq_med_data_item.order_med_frequency is null then freq := "once"; endif; frequency_unchecked_msg := "Unmapped: Frequency
    " || "Notify your system administrator that the Frequency " || freq || " is not mapped"; frequency_unchecked_instance := new Missing_Data_Object; frequency_unchecked_instance.criteria := "Frequency"; frequency_unchecked_instance.missing_data_error := true; frequency_unchecked_instance.details := unmapped_data_str; frequency_unchecked_instance.msg := frequency_unchecked_msg; frequency_unchecked_instance.med_name := med_name; frequency_unchecked_instance.unchecked_dose_range_type_list := ("dose range"); frequency_unchecked_instance.alert_abstract := "Unmapped: Frequency"; frequency_unchecked_list := frequency_unchecked_list, frequency_unchecked_instance; enddo; endif; // if exists unmapped_freq_dose_range_list endif; // if exists unmapped_frequency_map_list endif; // Only Process Missing Patient Data Alert Messages // when the flag is TRUE and there are missing data if (any grouper_info_list.dosage_range_found and alert_if_missing_flags.cannot_check_DNUM_Rx_to_Multum) OR ( alert_if_missing_flags.cannot_check_Rx_to_IC and exists (dnum_match_catalog_dose_range_list)) then // Prescription dose range matching issues // - Multiple Multum DRC groups found for given DNum // - Multiple catalog dose ranges found for given DNum rx_matching_issue_list := ("Multum", "Catalog"); for rx_matching_issue in rx_matching_issue_list do if rx_matching_issue = "Multum" then print_rx_matching_issue := ( any grouper_info_list.dosage_range_found and alert_if_missing_flags.cannot_check_DNUM_Rx_to_Multum ); missing_data_detail_msg := "Issue: Cannot determine which dosage range to check
    \n" || "Please select the full name with strength and form " || "of the medication in Prescription Writer"; else print_rx_matching_issue := ( alert_if_missing_flags.cannot_check_Rx_to_IC and exists (dnum_match_catalog_dose_range_list) ); missing_data_detail_msg := "Issue: Could not determine which dosage range to check " || column_catalog_name || "
    \n" || "This medication has dosage ranges defined."; endif; // if rx_matching_issue if print_rx_matching_issue then missing_data_type := issues_str; missing_data_instance := new Missing_Data_Object; missing_data_instance.criteria := "Rx Dnum"; missing_data_instance.missing_data_error := true; missing_data_instance.details := missing_data_type; missing_data_instance.unchecked_dose_range_type_list := ("dose range", "contraindication"); missing_data_instance.med_name := med_name; missing_data_instance.alert_abstract := "Issue: Cannot determine which dosage range to check"; missing_data_instance.msg := missing_data_detail_msg; missing_data_list := missing_data_list, missing_data_instance; endif; // if print_rx_matching_issue enddo; // for rx_matching_issue in rx_matching_issue_list ////////////////////////////////////////////////////////////////// // End prescription-only section ////////////////////////////////////////////////////////////////// elseif (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.Gender.is_unmapped and alert_if_missing_flags.unmapped_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 (any curr_med_data_list.missing_route and alert_if_missing_flags.route) OR (any curr_med_data_list.unmapped_route and alert_if_missing_flags.unmapped_route) OR (any curr_med_data_list.uom_conversion_issue and alert_if_missing_flags.uom_conversion) OR (any curr_med_data_list.missing_uom and alert_if_missing_flags.uom) OR (any curr_med_data_list.unmapped_uom and alert_if_missing_flags.unmapped_uom) OR (any curr_med_data_list.unmapped_drug and alert_if_missing_flags.unmapped_drug) OR (any curr_med_data_list.unmapped_grouper and alert_if_missing_flags.unmapped_grouper) OR (any curr_med_data_list.generic_route and alert_if_missing_flags.cannot_check_generic_route) OR (any (curr_med_data_list.generic_route = false) and alert_if_missing_flags.inapplicable_route) then //-------------------------------- // CHECK FOR MISSING PATIENT DATA //-------------------------------- // retrieve the list of unchecked dose ranges by medication unchecked_dose_range_list := dosage_range_list where ( dosage_range_list.med_name = med_name and dosage_range_list.match_found = false ); // Determine if missing/unmapped Age alert is needed // Cannot run multum check without age, so no multum dose ranges exist age_item_cat_unchecked_dose_range_list := unchecked_dose_range_list WHERE unchecked_dose_range_list.age_criteria is not null; // Determine if missing AGE alert is needed if patient_info.Age.is_missing and alert_if_missing_flags.patient_age and ( exists age_item_cat_unchecked_dose_range_list or use_multum_dosage_data ) then missing_data_instance := new Missing_Data_Object; missing_data_instance.criteria := "Age"; missing_data_instance.missing_data_error := true; missing_data_instance.details := ( "single catalog" || (any age_item_cat_unchecked_dose_range_list.dosage_type = "single"), "average catalog" || (any age_item_cat_unchecked_dose_range_list.dosage_type = "average"), "total catalog" || (any age_item_cat_unchecked_dose_range_list.dosage_type = "total"), "multum " || use_multum_dosage_data ); missing_data_instance.msg := "Missing data: Age
    " || "Please enter a complete BIRTHDAY for this patient"; missing_data_instance.med_name := med_name; // all medications are affected missing_data_instance.details.unchecked_dose_range_type_list := ("dose range"); missing_data_instance.alert_abstract := "Missing data: Age"; missing_data_list := missing_data_list, missing_data_instance; endif; //if patient_info.Age.is_missing // Determine if missing/unmapped GENDER alert is needed gender_unchecked_dose_range_list := unchecked_dose_range_list WHERE unchecked_dose_range_list.gender_criteria is not null; if ( ( ( patient_info.Gender.is_missing or patient_info.Gender.unknown_other ) and alert_if_missing_flags.patient_gender ) or ( patient_info.Gender.is_unmapped and alert_if_missing_flags.unmapped_gender ) ) and exists gender_unchecked_dose_range_list then missing_data_type := ""; missing_data_msg := ""; missing_data_alert_abstract := ""; if patient_info.Gender.unknown_other then missing_data_msg := "Issue: Unknown Gender
    " || "This patient{{{SINGLE-QUOTE}}}s gender is " || patient_info.Gender.value || ". Only a gender of " || "MALE or FEMALE can be checked for dosage range."; missing_data_alert_abstract := "Issue: Unknown Gender"; missing_data_type := issues_str; elseif patient_info.Gender.is_unmapped then missing_data_msg := "Unmapped: Gender
    " || "Notify your system administrator that the Gender, " || patient_info.Gender.value || " is not mapped"; missing_data_alert_abstract := "Unmapped: Gender"; missing_data_type := unmapped_data_str; elseif patient_info.Gender.is_missing then missing_data_alert_abstract := "Missing data: Gender"; missing_data_msg := "Missing data: Gender"; missing_data_type := missing_data_str; endif; // is the data missing for a contraindication or a dose range? unchecked_dose_range_type_list := ( "dose range" where any gender_unchecked_dose_range_list.dosage_type in ("single", "average", "total"), "contraindication" where any gender_unchecked_dose_range_list.dosage_type in ("contraindication") ); missing_data_instance := new Missing_Data_Object; missing_data_instance.criteria := "Gender"; missing_data_instance.missing_data_error := true; missing_data_instance.details := missing_data_type; missing_data_instance.msg := missing_data_msg; missing_data_instance.med_name := med_name; missing_data_instance.unchecked_dose_range_type_list := unchecked_dose_range_type_list; missing_data_instance.alert_abstract := missing_data_alert_abstract; missing_data_list := missing_data_list, missing_data_instance; endif; //if missing_gender // Determine if missing HEIGHT alert is needed height_unchecked_dose_range_list := unchecked_dose_range_list WHERE ( unchecked_dose_range_list.height_criteria is not null OR unchecked_dose_range_list.Is_PER_M2 is not null ); if ( patient_info.Height.is_missing or patient_info.Height.not_current ) and alert_if_missing_flags.patient_height and exists height_unchecked_dose_range_list then missing_data_type := ""; missing_data_msg := ""; missing_data_alert_abstract := ""; if patient_info.Height.is_missing then missing_data_type := missing_data_str; missing_data_msg := "Missing data: Height"; missing_data_alert_abstract := "Missing data: Height"; elseif patient_info.Height.not_current then missing_data_type := data_not_current_str; missing_data_msg := "Data not current: Height"; missing_data_alert_abstract := "Data not current: Height"; endif; // is the data missing for a contraindication or a dose range? unchecked_dose_range_type_list := ( "dose range" where any height_unchecked_dose_range_list.dosage_type in ("single", "average", "total"), "contraindication" where any height_unchecked_dose_range_list.dosage_type in ("contraindication") ); missing_data_instance := new Missing_Data_Object; missing_data_instance.criteria := "Height"; missing_data_instance.missing_data_error := true; missing_data_instance.details := missing_data_type; missing_data_instance.unchecked_dose_range_type_list := unchecked_dose_range_type_list; missing_data_instance.msg := missing_data_msg; missing_data_instance.med_name := med_name; missing_data_instance.alert_abstract := missing_data_alert_abstract; missing_data_list := missing_data_list, missing_data_instance; endif; //if patient_info.Height.is_missing // Determine if missing WEIGHT alert is needed weight_unchecked_dose_range_list := unchecked_dose_range_list WHERE ( unchecked_dose_range_list.weight_criteria is not null OR unchecked_dose_range_list.Is_PER_M2 is not null OR unchecked_dose_range_list.Is_PER_WT is not null ); if ( patient_info.Weight.is_missing or patient_info.Weight.not_current ) and alert_if_missing_flags.patient_weight and exists weight_unchecked_dose_range_list then missing_data_type := ""; missing_data_msg := ""; missing_data_alert_abstract := ""; if patient_info.Weight.is_missing then missing_data_type := missing_data_str; missing_data_msg := "Missing data: Weight"; missing_data_alert_abstract := "Missing data: Weight"; elseif patient_info.Weight.not_current then //data_not_current_header_list := data_not_current_header_list, "Weight"; missing_data_type := data_not_current_str; missing_data_msg := "Data not current: Weight"; missing_data_alert_abstract := "Data not current: Weight"; endif; // is the data missing for a contraindication or a dose range? unchecked_dose_range_type_list := ( "dose range" where any weight_unchecked_dose_range_list.dosage_type in ("single", "average", "total"), "contraindication" where any weight_unchecked_dose_range_list.dosage_type in ("contraindication") ); missing_data_instance := new Missing_Data_Object; missing_data_instance.criteria := "Weight"; missing_data_instance.missing_data_error := true; missing_data_instance.details := missing_data_type; missing_data_instance.msg := missing_data_msg; missing_data_instance.med_name := med_name; missing_data_instance.unchecked_dose_range_type_list := unchecked_dose_range_type_list; missing_data_instance.alert_abstract := missing_data_alert_abstract; missing_data_list := missing_data_list, missing_data_instance; endif; //if patient_info.Weight.is_missing // display alert for unmapped/missing drug if ( any curr_med_data_list.unmapped_drug and alert_if_missing_flags.unmapped_drug) then missing_data_detail_msg := "Unmapped: Drug
    " || "Notify your system administrator that the Drug " || med_name || " is not mapped."; missing_data_instance := new Missing_Data_Object; missing_data_instance.criteria := "Unmapped Drug"; missing_data_instance.missing_data_error := true; missing_data_instance.details := ""; missing_data_instance.msg := missing_data_detail_msg; missing_data_instance.med_name := med_name; missing_data_instance.unchecked_dose_range_type_list := ("Dose Range"); missing_data_instance.alert_abstract := "Unmapped: Drug"; missing_data_list := missing_data_list, missing_data_instance; endif; // if ( any med_data_list.unmapped_drug and alert_if_missing_flags.unmapped_drug) // Determine if missing route alert is needed // Since a complex order with IV additives can have child orders or IV additives // with different routes, it{{{SINGLE-QUOTE}}}s possible for multiple routes to be both unmapped and missing. if ( any curr_med_data_list.missing_route and alert_if_missing_flags.route ) then missing_data_instance := new Missing_Data_Object; missing_data_instance.criteria := "Missing Route"; missing_data_instance.missing_data_error := true; missing_data_instance.details := med_name; missing_data_instance.msg := "Missing data: Route"; missing_data_instance.med_name := med_name; missing_data_instance.details.unchecked_dose_range_type_list := ("dose range"); missing_data_instance.alert_abstract := "Missing data: Route"; missing_data_list := missing_data_list, missing_data_instance; endif; //if missing_route // Determine if unmapped route alert is needed // Since a complex order with IV additives can have child orders or IV additives // with different routes, it{{{SINGLE-QUOTE}}}s possible for multiple routes to be both unmapped and missing. if ( any curr_med_data_list.unmapped_route and alert_if_missing_flags.unmapped_route ) then // get the sorted list of routes that are unmapped unmapped_routes_med_list := curr_med_data_list where curr_med_data_list.unmapped_route = true; if exists (unmapped_routes_med_list) then missing_data_detail_msg := "Unmapped: Route
    " || "Notify your system administrator that the"; unmapped_routes_list := sort (unmapped_routes_med_list.order_med_route); // filter out duplicates unique_unmapped_routes_list := (); for item in unmapped_routes_list do if item not in unique_unmapped_routes_list then unique_unmapped_routes_list := unique_unmapped_routes_list, item; endif; enddo; num_routes := count (unique_unmapped_routes_list); if num_routes > 1 then missing_data_detail_msg := missing_data_detail_msg || " Routes "; else missing_data_detail_msg := missing_data_detail_msg || " Route "; endif; for ind in (1 seqto num_routes) do if ind > 1 then if ind < num_routes then missing_data_detail_msg := missing_data_detail_msg || ", "; else missing_data_detail_msg := missing_data_detail_msg || "and "; endif; endif; missing_data_detail_msg := missing_data_detail_msg || "" || unique_unmapped_routes_list[ind] || ""; enddo; if num_routes > 1 then missing_data_detail_msg := missing_data_detail_msg || " are not mapped."; else missing_data_detail_msg := missing_data_detail_msg || " is not mapped."; endif; missing_data_instance := new Missing_Data_Object; missing_data_instance.criteria := "Unmapped Route"; missing_data_instance.missing_data_error := true; missing_data_instance.details := unique_unmapped_routes_list; missing_data_instance.msg := missing_data_detail_msg; missing_data_instance.med_name := med_name; missing_data_instance.details.unchecked_dose_range_type_list := ("dose range"); missing_data_instance.alert_abstract := "Unmapped: Route"; missing_data_list := missing_data_list, missing_data_instance; endif; endif; //if unmapped_route // Route conversion issue // - unrecognized route // - inapplicable route route_conversion_issue_list := ("Unrecognized", "Inapplicable"); for route_conversion_issue in route_conversion_issue_list do if route_conversion_issue = "Unrecognized" then unrecognized_route_dose_range_list := unchecked_dose_range_list WHERE ( unchecked_dose_range_list.unrecognized_route_conversion_issue = true ); print_route_issue := (exists unrecognized_route_dose_range_list and alert_if_missing_flags.cannot_check_generic_route); route_conversion_dose_range_list := unrecognized_route_dose_range_list; else inapplicable_route_dose_range_list := unchecked_dose_range_list WHERE ( unchecked_dose_range_list.inapplicable_route_conversion_issue= true ); print_route_issue :=(exists inapplicable_route_dose_range_list and alert_if_missing_flags.inapplicable_route ); route_conversion_dose_range_list := inapplicable_route_dose_range_list; endif; if print_route_issue then missing_data_type := issues_str; // Unregonized route route_conversion_issue_map := med_dosage_map_list WHERE (med_dosage_map_list.dosage_range_sort_number in route_conversion_dose_range_list.sort_number); // is the data missing for a contraindication or a dose range? unchecked_dose_range_type_list := ( "dose range" where any route_conversion_dose_range_list.dosage_type in ("single", "average", "total"), "contraindication" where any route_conversion_dose_range_list.dosage_type in ("contraindication") ); // create the route conversion issue message route_conversion_map_list := (); for map_item in route_conversion_issue_map do // NOTE - DO NOT USE THE curr_med_data_list or curr_total_tracker_list, curr_average_tracker_list // here as we are using indexes to look up the item if (map_item.dosage_type in ("single", "contraindication")) then medication_route := med_data_list[map_item.med_sort_number].order_med_route; elseif (map_item.dosage_type = "total") then medication_route := total_tracker_list[map_item.med_sort_number].route; elseif map_item.dosage_type = "average" then medication_route := average_tracker_list[map_item.med_sort_number].route; endif; // get the Conversion_Issue_Map_Object from route_conversion_map_list // for this medication route_conversion_issue_map_obj := first (route_conversion_map_list where route_conversion_map_list.medication_val = medication_route and route_conversion_map_list.med_name = med_name); if route_conversion_issue_map_obj is null then route_conversion_issue_map_obj := new Conversion_Issue_Map_Object; route_conversion_issue_map_obj.med_name := med_name; route_conversion_issue_map_obj.medication_val:= medication_route; route_conversion_issue_map_obj.unconvertible_val_list := (); route_conversion_map_list := route_conversion_map_list, route_conversion_issue_map_obj; endif; dose_range_item := dosage_range_list[map_item.dosage_range_sort_number]; dose_range_route := dose_range_item.route; if dose_range_route not in route_conversion_issue_map_obj.unconvertible_val_list then route_conversion_issue_map_obj.unconvertible_val_list := route_conversion_issue_map_obj.unconvertible_val_list, dose_range_route; endif; enddo; // print out the unrecognized routes in alphabetical order // for the drug sorted_routes_list := sort(route_conversion_map_list.medication_val); for sorted_route in sorted_routes_list do sorted_route_map_obj := first (route_conversion_map_list where route_conversion_map_list.medication_val = sorted_route); sorted_unconvertible_route_list := sort(sorted_route_map_obj.unconvertible_val_list); sorted_unconvertible_route_str := ""; num_unconvertible_routes := count sorted_unconvertible_route_list; for ind in (1 seqto num_unconvertible_routes) do if ind > 1 then if ind < num_unconvertible_routes then sorted_unconvertible_route_str := sorted_unconvertible_route_str || ", "; else sorted_unconvertible_route_str := sorted_unconvertible_route_str || " and "; endif; endif; sorted_unconvertible_route_str := sorted_unconvertible_route_str || "" || sorted_unconvertible_route_list[ind] || ""; enddo; // for ind in (1 seqto num_unconvertible_routes) // Generate the message if route_conversion_issue = "Unrecognized" then missing_data_detail_msg := "Issue: Unrecognized Route
    " || "Please see below dosage ranges for " || sorted_unconvertible_route_str || " routes of administering the " || sorted_route || "."; else missing_data_detail_msg := "Issue: Inapplicable Route
    " || "Dosage range information is not available for " || "" || sorted_route || " route." || " Please see below dosage ranges for " || sorted_unconvertible_route_str || " routes of administration."; endif; missing_data_instance := new Missing_Data_Object; missing_data_instance.criteria := route_conversion_issue || " Route"; missing_data_instance.missing_data_error := true; missing_data_instance.details := route_conversion_map_list; missing_data_instance.msg := missing_data_detail_msg; missing_data_instance.med_name := med_name; missing_data_instance.alert_abstract := "Issue: " || route_conversion_issue ||" Route"; missing_data_instance.details.unchecked_dose_range_type_list := unchecked_dose_range_type_list; missing_data_list := missing_data_list, missing_data_instance; enddo; // for sorted_route in sorted_routes_list endif; //if print_route_issue enddo; // route_conversion_issue // display unmapped dose range group alert if ( any curr_med_data_list.unmapped_grouper and alert_if_missing_flags.unmapped_grouper) then // create one missing_data_object for each string. missing_data_detail_msg := "Unmapped: Dose Range Group
    " || "Notify your system administrator that " || med_name || " is not mapped to a Dose Range Group."; missing_data_instance := new Missing_Data_Object; missing_data_instance.criteria := "Unmapped Grouper"; missing_data_instance.missing_data_error := true; missing_data_instance.details := med_name; missing_data_instance.msg := missing_data_detail_msg; missing_data_instance.med_name := med_name; missing_data_instance.alert_abstract := "Unmapped: Dose Range Group"; missing_data_instance.unchecked_dose_range_type_list := ("Dose Range"); missing_data_list := missing_data_list, missing_data_instance; endif; // if unmapped_grouper // Determine if missing uom alert is needed missing_uom_med := curr_med_data_list where curr_med_data_list.missing_uom = true; missing_uom_med_dose_range_map := med_dosage_map_list where med_dosage_map_list.med_sort_number in missing_uom_med.sort_number and med_dosage_map_list.match_found = false; if ( any curr_med_data_list.missing_uom and alert_if_missing_flags.uom and exists missing_uom_med_dose_range_map ) then // is the data missing for a contraindication or a dose range? unchecked_dose_range_type_list := ( "dose range" where any missing_uom_med_dose_range_map.dosage_type in ("single", "average", "total"), "contraindication" where any missing_uom_med_dose_range_map.dosage_type in ("contraindication") ); missing_data_instance := new Missing_Data_Object; missing_data_instance.criteria := "Missing UOM"; missing_data_instance.missing_data_error := true; missing_data_instance.details := med_name; missing_data_instance.msg := "Missing data: Unit of Measure"; missing_data_instance.med_name := med_name; missing_data_instance.alert_abstract := "Missing data: Unit of Measure"; missing_data_instance.details.unchecked_dose_range_type_list := unchecked_dose_range_type_list; missing_data_list := missing_data_list, missing_data_instance; endif; //if missing_uom // Determine if unmapped uom alert is needed unmapped_uom_med := curr_med_data_list where curr_med_data_list.unmapped_uom = true; unmapped_uom_med_dose_range_map := med_dosage_map_list where med_dosage_map_list.med_sort_number in unmapped_uom_med.sort_number and med_dosage_map_list.match_found = false; if ( any curr_med_data_list.unmapped_uom and alert_if_missing_flags.unmapped_uom and exists unmapped_uom_med_dose_range_map ) then // is the data missing for a contraindication or a dose range? unchecked_dose_range_type_list := ( "dose range" where any unmapped_uom_med_dose_range_map.dosage_type in ("single", "average", "total"), "contraindication" where any unmapped_uom_med_dose_range_map.dosage_type in ("contraindication") ); missing_data_detail_msg := "Unmapped: Unit of Measure
    " || "Notify your system administrator that the"; // get the sorted list of uoms that are unmapped unmapped_uom_list := curr_med_data_list where curr_med_data_list.unmapped_uom = true; unmapped_uom_list := sort (unmapped_uom_list.order_med_units); // filter out duplicates unique_unmapped_uom_list := (); for item in unmapped_uom_list do if item not in unique_unmapped_uom_list then unique_unmapped_uom_list := unique_unmapped_uom_list, item; endif; enddo; num_uoms := count (unique_unmapped_uom_list); if num_uoms > 1 then missing_data_detail_msg := missing_data_detail_msg || " Unit of Measures "; else missing_data_detail_msg := missing_data_detail_msg || " Unit of Measure "; endif; for ind in (1 seqto num_uoms) do if ind > 1 then if ind < num_uoms then missing_data_detail_msg := missing_data_detail_msg || ", "; else missing_data_detail_msg := missing_data_detail_msg || "and "; endif; endif; missing_data_detail_msg := missing_data_detail_msg || "" || unique_unmapped_uom_list[ind] || ""; enddo; if num_uoms > 1 then missing_data_detail_msg := missing_data_detail_msg || " are not mapped."; else missing_data_detail_msg := missing_data_detail_msg || " is not mapped."; endif; missing_data_instance := new Missing_Data_Object; missing_data_instance.criteria := "Unmapped UOM"; missing_data_instance.missing_data_error := true; missing_data_instance.details := unique_unmapped_uom_list; missing_data_instance.msg := missing_data_detail_msg; missing_data_instance.med_name := med_name; missing_data_instance.alert_abstract := "Unmapped: Unit of Measure"; missing_data_instance.unchecked_dose_range_type_list := unchecked_dose_range_type_list; missing_data_list := missing_data_list, missing_data_instance; endif; //if unmapped_uom // Determine if conversion problem uom alert is needed uom_issue_dose_range_list := unchecked_dose_range_list WHERE ( unchecked_dose_range_list.uom_conversion_issue = true); if ( alert_if_missing_flags.uom_conversion and exists uom_issue_dose_range_list ) then // populate the header criteria uom_issue_med_dose_range_map := med_dosage_map_list where ( med_dosage_map_list.match_found = false and med_dosage_map_list.dosage_range_sort_number in uom_issue_dose_range_list.sort_number ); // is the data missing for a contraindication or a dose range? unchecked_dose_range_type_list := ( "dose range" where any uom_issue_med_dose_range_map.dosage_type in ("single", "average", "total"), "contraindication" where any uom_issue_med_dose_range_map.dosage_type in ("contraindication") ); // create the unit of measure conversion issue message uom_conversion_map_list := (); for map_item in uom_issue_med_dose_range_map do if (map_item.dosage_type = "single") then medication_unit := med_data_list[map_item.med_sort_number].order_med_units; elseif (map_item.dosage_type = "total") then medication_unit := total_tracker_list[map_item.med_sort_number].uom; elseif map_item.dosage_type = "average" then medication_unit := average_tracker_list[map_item.med_sort_number].uom; endif; // get the Conversion_Issue_Map_Object from uom_conversion_map_list // for this medication uom_conversion_issue_map_obj := first (uom_conversion_map_list where uom_conversion_map_list.medication_val = medication_unit); if uom_conversion_issue_map_obj is null then uom_conversion_issue_map_obj := new Conversion_Issue_Map_Object; uom_conversion_map_list := uom_conversion_map_list, uom_conversion_issue_map_obj; uom_conversion_issue_map_obj.medication_val:= medication_unit; uom_conversion_issue_map_obj.unconvertible_val_list := (); endif; dose_range_item := dosage_range_list[map_item.dosage_range_sort_number]; dose_range_uom := dose_range_item.unit_of_measure; if dose_range_uom not in uom_conversion_issue_map_obj.unconvertible_val_list then uom_conversion_issue_map_obj.unconvertible_val_list := uom_conversion_issue_map_obj.unconvertible_val_list, dose_range_uom; endif; enddo; // construct the messages in alphabetical order sorted_order_med_units_list := sort(uom_conversion_map_list.medication_val); for sorted_order_med_unit in sorted_order_med_units_list do sorted_uom_conversion_map_obj := first (uom_conversion_map_list where uom_conversion_map_list.medication_val = sorted_order_med_unit); missing_data_detail_msg := "Issue: Unit of measure conversion
    " || "The current Unit of Measure, " || sorted_order_med_unit || " cannot be converted to "; sorted_unconvertible_uom_list := sort(sorted_uom_conversion_map_obj.unconvertible_val_list); num_unconvertible_uoms := count sorted_unconvertible_uom_list; for ind in (1 seqto num_unconvertible_uoms) do if ind > 1 then if ind < num_unconvertible_uoms then missing_data_detail_msg := missing_data_detail_msg || ", "; else missing_data_detail_msg := missing_data_detail_msg || " or "; endif; endif; missing_data_detail_msg := missing_data_detail_msg || "" || sorted_unconvertible_uom_list[ind] || ""; enddo; enddo; missing_data_instance := new Missing_Data_Object; missing_data_instance.criteria := "UOM Conversion Issue"; missing_data_instance.missing_data_error := true; missing_data_instance.details := uom_conversion_map_list; missing_data_instance.unchecked_dose_range_type_list := unchecked_dose_range_type_list; missing_data_instance.msg := missing_data_detail_msg; missing_data_instance.alert_abstract := "Issue: Unit of measure conversion"; missing_data_instance.med_name := med_name; missing_data_list := missing_data_list, missing_data_instance; endif; //if unit of conversion issue endif; //if patient_info.Age.is_missing enddo; // for med_name in medication_name_list //---------------------------------------- // Assemble the BODY of the Alert Message //---------------------------------------- // Initialize Variable alert_detail_text := ""; //------------------------------------------- // Assemble the HEADER of the Alert Message //------------------------------------------- // Prevent NULL from printing in the Frequency //-------------------------------------------- if exist med_data_list[1].order_med_frequency then printable_order_med_frequency := " " || med_data_list[1].order_med_frequency; if med_data_list[1].stop_after_value is not null and med_data_list[1].stop_after_value > 0 and med_data_list[1].stop_after_option_type > 0 then printable_order_med_frequency := printable_order_med_frequency || " x " || med_data_list[1].stop_after_value || " " || stop_after_type_list[med_data_list[1].stop_after_option_type]; endif; else printable_order_med_frequency := ""; endif; // if exist order_med_frequency if exists med_data_list[1].order_med_route then printable_order_med_route := med_data_list[1].order_med_route; else printable_order_med_route := ""; endif; // Set Dosage_Ordered //-------------------- // If the lower dose and the upper dose are the same, print a singleton value // If the lower dose adn the upper dose are not equal, then print a range if exists med_data_list[1].order_med_units then printable_order_med_units := med_data_list[1].order_med_units; else printable_order_med_units := ""; endif; if med_data_list[1].order_med_dose_low = med_data_list[1].order_med_dose_high then formated_order_med_dose_low := call add_commas with (,med_data_list[1].order_med_dose_low); dosage_ordered:= formated_order_med_dose_low || " " || printable_order_med_units; elseif order_med_dose_low <> order_med_dose_high then formated_order_med_dose_low := call add_commas with (,med_data_list[1].order_med_dose_low); formated_order_med_dose_high := call add_commas with (,med_data_list[1].order_med_dose_high); dosage_ordered:= formated_order_med_dose_low || " - " || formated_order_med_dose_high || " " || printable_order_med_units; else dosage_ordered:= ""; endif; //if med_data_list[1].order_med_dose_low //------------------------------------------------------------------------------ // [New born birth-time missing]: Construct Missing birth time table //------------------------------------------------------------------------------ birthtime_missing_detail_msg := ""; if has_alert_on_estimated_birthtime = true then if estimated_age_hours < 24 then estimated_birthtimes := "Less than " || estimated_age_hours || " hour(s)"; else estimated_birthtimes := "Between " || estimated_age_min_hours || "-" || estimated_age_hours || " hour(s)"; endif; birthtime_missing_detail_msg := "Missing data: Birth-time" || "" || "" || "" || "" || "" || "" || "" || "
    Estimated newborn ageBirth-time
    " || estimated_birthtimes || "Unknown


    "; endif; //------------------------------------------------------------------------------ // Construct Contraindications table //------------------------------------------------------------------------------ contraindication_detail_msg := ""; if any med_data_list.contraindication_found then patient_criteria_list := ( patient_info.Age, (new Patient_Property_Obj with "Route"), // dummy entry to help build the table patient_info.Weight, patient_info.Gender, patient_info.Renal, patient_info.Creatinine, patient_info.Liver ); contraindication_dosage_range_list := dosage_range_list where (dosage_range_list.match_found = true and dosage_range_list.dosage_type in ("contraindication") ); for contraindication_dosage_range in contraindication_dosage_range_list do for_drug_str := ""; if is_iv_additive then for_drug_str := "For " || contraindication_dosage_range.med_name || ": "; endif; //-------------------------------------------------------- // construct the contraindication detail message contraindication_detail_msg := contraindication_detail_msg || for_drug_str || contraindication_dosage_range.contraindication_msg; // contraindication_criteria_headings and contraindication_criteria_list // These two lists must be in sync contraindication_criteria_list := ( contraindication_dosage_range.age_criteria, contraindication_dosage_range.route, contraindication_dosage_range.weight_criteria, contraindication_dosage_range.gender_criteria, contraindication_dosage_range.renal_criteria, contraindication_dosage_range.creatinine_criteria, contraindication_dosage_range.liver_criteria ); if exist contraindication_criteria_list then // conditions table and patient info table contraindication_detail_msg := contraindication_detail_msg || "" || "" || "" || "" || ""; indices := 1 seqto count contraindication_criteria_list; for ind in indices do criteria_heading := contraindication_criteria_headings[ind]; criteria_val := contraindication_criteria_list[ind]; patient_info_obj := patient_criteria_list[ind]; patient_criteria_val := ""; // Create contraindication criteria listing // e.g. "Age: <=12 years" if exists criteria_val then if exist patient_info_obj then patient_criteria_val := ""; if (patient_info_obj.Type = "Route") then patient_criteria_val := patient_criteria_val || med_data_list[1].order_med_route; elseif( patient_info_obj.TYPE = "Age" and (contraindication_dosage_range.estimated_age_used = 1 or contraindication_dosage_range.estimated_age_used = 2) ) then //Using AgeMin or AgeMax in hours patient_criteria_val := patient_criteria_val || contraindication_dosage_range.patient_age_at_order; else patient_criteria_val := patient_criteria_val || patient_info_obj.Value; endif; if patient_info_obj.TYPE = "Weight" then patient_criteria_val := patient_criteria_val || " kg"; endif; if patient_info_obj.TYPE = "Creatinine" then patient_criteria_val := patient_criteria_val || " mL/min"; endif; patient_criteria_val := patient_criteria_val || ""; if (patient_info_obj.type not in ("Gender", "Age")) and patient_info_obj.Date is not null then // convert patient info date/time to evoking object{{{SINGLE-QUOTE}}}s visit time zone to support MTZ patient_criteria_val := patient_criteria_val || "(" || (patient_info_obj.Date AS TIME visit_time_zone) formatted with "%.4t" || ")"; endif; endif; // fix this later when have time to go through contraindication headings contraindication_detail_msg := contraindication_detail_msg || "" || ""; endif; enddo; contraindication_detail_msg := contraindication_detail_msg || "
    ConditionsThis Patient
    " || criteria_heading || criteria_val || "" || patient_criteria_val || "
    "; endif; // if exist contraindication_criteria_list contraindication_detail_msg := contraindication_detail_msg || "

    "; enddo; endif; //////////////////////////////////////////// // Construct alert message headings and // alert abstract components //////////////////////////////////////////// // initialize warning count list warning_count_list := (); //[New born birth-time missing]: add warning object for estimated age warning if has_alert_on_estimated_birthtime = true then if warning_count_instance_estimated_age is null then if medication_name_list is not null then med_name := medication_name_list[1]; endif; warning_count_instance_estimated_age := new Warning_Count_Object; warning_count_instance_estimated_age.med_name := med_name; warning_count_instance_estimated_age.warning_count := 1; warning_count_list := warning_count_list, warning_count_instance_estimated_age; endif; endif; // construct the "dose range and contraindications could not be checked" header dose_range_not_checked_header := ""; alert_abstract_dose_range_not_checked := ""; if exists missing_data_list or exists cannot_check_list then dose_range_not_checked_header := "
    DOSE RANGE "; alert_abstract_dose_range_not_checked := "DOSE RANGE "; if any missing_data_list.unchecked_dose_range_type_list in ("contraindication") then dose_range_not_checked_header := dose_range_not_checked_header || "and CONTRAINDICATIONS "; alert_abstract_dose_range_not_checked := alert_abstract_dose_range_not_checked || "and CONTRAINDICATIONS "; endif; dose_range_not_checked_header := dose_range_not_checked_header || "could NOT be CHECKED
    \n" || "
      "; alert_abstract_dose_range_not_checked := alert_abstract_dose_range_not_checked || "could NOT be CHECKED. "; // add messages in missing_data_list underneath header // as a bulleted list for med_name in medication_name_list do // print drug name if multiple drugs are being checked for_drug_str := ""; alert_abstract_for_drug_str := ""; if is_iv_additive then for_drug_str := "For " || med_name || ": "; alert_abstract_for_drug_str := "For " || med_name || ": "; endif; // print out the missing data objects for this medication med_missing_data_list := missing_data_list where missing_data_list.med_name = med_name; for missing_data_item in med_missing_data_list do dose_range_not_checked_header := dose_range_not_checked_header || "
    • " || for_drug_str || missing_data_item.msg || "
    • "; alert_abstract_dose_range_not_checked := alert_abstract_dose_range_not_checked || alert_abstract_for_drug_str || missing_data_item.alert_abstract || ". "; enddo; // print out the cannot check objects for this medication med_cannot_check_list := cannot_check_list where cannot_check_list.med_name_list = med_name; for cannot_check_item in med_cannot_check_list do dose_range_not_checked_header := dose_range_not_checked_header || "
    • " || for_drug_str || cannot_check_item.alert_msg_for_cannot_check || "
    • "; alert_abstract_dose_range_not_checked := alert_abstract_dose_range_not_checked || alert_abstract_for_drug_str || cannot_check_item.alert_abstract || ". "; enddo; // increment the warning count warning_count_instance := last (warning_count_list where warning_count_list.med_name = med_name); if warning_count_instance is null then warning_count_instance := new Warning_Count_Object; warning_count_instance.med_name := med_name; warning_count_instance.warning_count := 0; warning_count_list := warning_count_list, warning_count_instance; endif; warning_count_instance.warning_count := warning_count_instance.warning_count + count(med_missing_data_list) + count(med_cannot_check_list); enddo; dose_range_not_checked_header := dose_range_not_checked_header || "
    "; endif; // construct the "Frequency could not be checked" header frequency_not_checked_header := ""; alert_abstract_frequency_not_checked := ""; if exists frequency_unchecked_list then frequency_not_checked_header := "
    FREQUENCY " || "could NOT be CHECKED
    \n" || "
      "; alert_abstract_frequency_not_checked := "FREQUENCY could NOT be CHECKED. "; // add messages in missing_data_list underneath header // as a bulleted list for med_name in medication_name_list do // print drug name if multiple drugs are being checked for_drug_str := ""; alert_abstract_for_drug_str := ""; if is_iv_additive then for_drug_str := "For " || med_name || ": "; alert_abstract_for_drug_str := "For " || med_name || ": "; endif; // print out the missing data objects for this medication med_frequency_unchecked_list := frequency_unchecked_list where frequency_unchecked_list.med_name = med_name; for med_frequency_unchecked_item in med_frequency_unchecked_list do frequency_not_checked_header := frequency_not_checked_header || "
    • " || for_drug_str || med_frequency_unchecked_item.msg || "
    • "; alert_abstract_frequency_not_checked := alert_abstract_frequency_not_checked || alert_abstract_for_drug_str || med_frequency_unchecked_item.alert_abstract || ". "; enddo; // increment the warning count warning_count_instance := last (warning_count_list where warning_count_list.med_name = med_name); if warning_count_instance is null then warning_count_instance := new Warning_Count_Object; warning_count_instance.med_name := med_name; warning_count_instance.warning_count := 0; warning_count_list := warning_count_list, warning_count_instance; endif; warning_count_instance.warning_count := warning_count_instance.warning_count + count(med_frequency_unchecked_list); enddo; frequency_not_checked_header := frequency_not_checked_header || "
    "; endif; //[New born birth-time missing]: determine if alert is using estimated age estimated_birthtime_header := ""; alert_abstract_estimated_birthtime := ""; if has_alert_on_estimated_birthtime = true then if estimated_age_hours < 24 then estimated_birthtimes := "less than " || estimated_age_hours || " hour(s)"; else estimated_birthtimes := estimated_age_min_hours || "-" || estimated_age_hours || " hour(s)"; endif; estimated_birthtime_header := estimated_birthtime_header || "
    NEWBORN EXACT AGE IS ESTIMATED
      " || "
    • Missing data: Birth-time
      Dose range checked using estimated ages of " || estimated_birthtimes || ".
      " || "The details of which age the alert applies to, is provided later in the alert message.
    "; alert_abstract_estimated_birthtime := alert_abstract_estimated_birthtime || "NEWBORN EXACT AGE IS ESTIMATED. " || "Missing data: Birth-time. Dose range checked using estimated ages of " || estimated_birthtimes || ". " || "The details of which age the alert applies to, is provided later in the alert message."; endif; // CONTRAINDICATED header contraindicated_header := ""; alert_abstract_contraindicated := ""; if any med_data_list.contraindication_found then contraindicated_header := "
    CONTRAINDICATED
      \n"; alert_abstract_contraindicated := "CONTRAINDICATED. "; // for each medication, print out the contraindications for med_name in medication_name_list do for_drug_str := ""; alert_abstract_for_drug_str := ""; if is_iv_additive then for_drug_str := "For " || med_name || ": "; alert_abstract_for_drug_str := "For " || med_name || ": "; endif; contraindication_list := dosage_range_list where dosage_range_list.dosage_type = "contraindication" and dosage_range_list.med_name = med_name and dosage_range_list.match_found = true; for contraindication_item in contraindication_list do contraindicated_header := contraindicated_header || "
    • " || for_drug_str || contraindication_item.contraindication_msg || "
    • "; alert_abstract_contraindicated := alert_abstract_contraindicated || alert_abstract_for_drug_str || contraindication_item.contraindication_msg || ". "; enddo; // increment the warning count warning_count_instance := last (warning_count_list where warning_count_list.med_name = med_name); if warning_count_instance is null then warning_count_instance := new Warning_Count_Object; warning_count_instance.med_name := med_name; warning_count_instance.warning_count := 0; warning_count_list := warning_count_list, warning_count_instance; endif; warning_count_instance.warning_count := warning_count_instance.warning_count + count(contraindication_list); enddo; contraindicated_header := contraindicated_header || "
    \n"; endif; // Too Frequent header too_frequent_header := ""; alert_abstract_too_frequent := ""; if any (med_dosage_map_list.frequency_issue = dose_too_frequent) then too_frequent_header := too_frequent_header || "
    FREQUENCY INTERVAL TOO SHORT
      "; alert_abstract_too_frequent := alert_abstract_too_frequent || "FREQUENCY INTERVAL TOO SHORT. "; // get the case item objects for multum dose ranges. case_list := Case_Info_list where Case_Info_list.case_type = "dose range" and Case_Info_list.is_multum = true; for case_item in case_list do // get all the med-dose range map objects attached to the case // for the specified medication case_map_list := med_dosage_map_list where med_dosage_map_list.sort_number in case_item.map_sort_number and med_dosage_map_list.dosage_type in ("single") and med_dosage_map_list.match_found = true and med_dosage_map_list.frequency_issue = dose_too_frequent; if exists case_map_list then too_frequent_str := ""; alert_abstract_too_frequent_str := ""; // get the list of frequencies from the map objects frequency_list := case_map_list.dose_frequency; for_drug_str := ""; alert_abstract_for_drug_str := ""; if is_iv_additive then for_drug_str := "For " || case_item.med_name || ": "; alert_abstract_for_drug_str := "For " || case_item.med_name || ": "; endif; // add frequency warnings to the header for frequency_item in frequency_list do too_frequent_header := too_frequent_header || "
    • " || for_drug_str || "Frequency: This dosing interval should not be more frequent than " || "" || frequency_item || " " || case_item.based_on_header_text || "
    • "; alert_abstract_too_frequent := alert_abstract_too_frequent || alert_abstract_for_drug_str || "This dosing interval should not be more frequent than " || frequency_item || " " || case_item.based_on_header_text || ". "; enddo; // increment the warning count with number of frequency warnings warning_count_instance := last (warning_count_list where warning_count_list.med_name = case_item.med_name); // get the warning item for this med object // and add number of warnings to the total if warning_count_instance is null then warning_count_instance := new Warning_Count_Object; warning_count_instance.med_name := case_item.med_name; warning_count_instance.warning_count := 0; warning_count_list := warning_count_list, warning_count_instance; endif; warning_count_instance.warning_count := warning_count_instance.warning_count + count(frequency_list); endif; enddo; too_frequent_header := too_frequent_header || "
    \n"; endif; // OUTSIDE USUAL DOSE RANGE header outside_dose_range_header := ""; alert_abstract_outside_dose_range := ""; if any med_dosage_map_list.above_range or any med_dosage_map_list.below_range then outside_dose_range_header := outside_dose_range_header || "
    OUTSIDE USUAL DOSE RANGE
      "; alert_abstract_outside_dose_range := alert_abstract_outside_dose_range || "OUTSIDE USUAL DOSE RANGE. "; // get the case item objects for dose ranges case_list := Case_Info_list where Case_Info_list.case_type = "dose range"; for case_item in case_list do // get all the med-dose range map objects attached to the case // for the specified medication case_map_list := med_dosage_map_list where med_dosage_map_list.sort_number in case_item.map_sort_number and med_dosage_map_list.dosage_type <> "contraindication" and med_dosage_map_list.match_found = true and ( med_dosage_map_list.above_range or med_dosage_map_list.below_range); if exist case_map_list then exceeds_and_below_str := ""; alert_abstract_exceeds_and_below_str := ""; if all case_map_list.above_range then exceeds_and_below_str := "Exceeds maximum "; alert_abstract_exceeds_and_below_str := "Exceeds maximum "; elseif all case_map_list.below_range then exceeds_and_below_str := "Below minimum "; alert_abstract_exceeds_and_below_str := "Below minimum "; elseif ( any case_map_list.above_range AND any case_map_list.below_range) then // if both exceed and below range, then, it{{{SINGLE-QUOTE}}}s a special case if (any (med_data_list.med_order_type = "Complex Order")) then exceeds_and_below_str := "Exceeds and Below ranges "; alert_abstract_exceeds_and_below_str := "Exceeds and Below ranges "; else // construct the dose-type string for Exceeds sub-string exceeds_dose_type_str := ""; if exists (case_map_list where case_map_list.above_range and case_map_list.dosage_type = "single") then exceeds_dose_type_str := "Single Dose"; endif; if exists (case_map_list where case_map_list.above_range and case_map_list.dosage_type = "total") then if exceeds_dose_type_str <> "" then exceeds_dose_type_str := exceeds_dose_type_str || ", "; endif; exceeds_dose_type_str := exceeds_dose_type_str || "Total Daily Dose"; endif; if exists (case_map_list where case_map_list.above_range and case_map_list.dosage_type = "average") then if exceeds_dose_type_str <> "" then exceeds_dose_type_str := exceeds_dose_type_str || ", "; endif; exceeds_dose_type_str := exceeds_dose_type_str || "Average Daily Dose"; endif; // construct the dose-type string for Below sub-string below_dose_type_str := ""; // append single, total and daily strings if exists (case_map_list where case_map_list.below_range and case_map_list.dosage_type = "single") then below_dose_type_str := "Single Dose"; endif; if exists (case_map_list where case_map_list.below_range and case_map_list.dosage_type = "total") then if below_dose_type_str <> "" then below_dose_type_str := below_dose_type_str || ", "; endif; below_dose_type_str := below_dose_type_str || "Total Daily Dose"; endif; if exists (case_map_list where case_map_list.below_range and case_map_list.dosage_type = "average") then if below_dose_type_str <> "" then below_dose_type_str := below_dose_type_str || ", "; endif; below_dose_type_str := below_dose_type_str || "Average Daily Dose"; endif; // finish constructing the entire string exceeds_and_below_str := "Exceeds maximum " || exceeds_dose_type_str || " and Below minimum " || below_dose_type_str || " "; alert_abstract_exceeds_and_below_str := "Exceeds maximum " || exceeds_dose_type_str || " and Below minimum " || below_dose_type_str || " "; endif; endif; for_drug_str := ""; alert_abstract_for_drug_str := ""; if is_iv_additive then for_drug_str := "For " || case_item.med_name || ": "; alert_abstract_for_drug_str := "For " || case_item.med_name || ": "; endif; outside_dose_range_header := outside_dose_range_header || "
    • " || for_drug_str || exceeds_and_below_str || case_item.based_on_header_text || "
    • "; alert_abstract_outside_dose_range := alert_abstract_outside_dose_range || alert_abstract_for_drug_str || alert_abstract_exceeds_and_below_str || case_item.based_on_header_text || ". "; // increment the warning count warning_count_instance := last (warning_count_list where warning_count_list.med_name = case_item.med_name); // get the warning item for this med object // and add number of warnings to the total if warning_count_instance is null then warning_count_instance := new Warning_Count_Object; warning_count_instance.med_name := case_item.med_name; warning_count_instance.warning_count := 0; warning_count_list := warning_count_list, warning_count_instance; endif; warning_count_instance.warning_count := warning_count_instance.warning_count + 1; endif; //if exist case_map_list enddo; outside_dose_range_header := outside_dose_range_header || "
    \n"; endif; //------------------------------ // Create Medication Description with warning count //------------------------------ alert_med_description:= ""; // stores warnings to be appended to the alert abstract text alert_abstract_warnings := ""; if any (med_data_list.med_order_type in ("Complex Order", "IV-Additive")) then if any (med_data_list.med_order_type in ("Complex Order")) then // get the complex order item med_complex_order := last ( med_data_list where med_data_list.med_order_type = "Complex Order" and ( med_data_list.is_iv_additive is null or med_data_list.is_iv_additive = false ) ); // get the number of warnings for this med object warning_count_instance := last (warning_count_list where warning_count_list.med_name = med_complex_order.order_med_name); warning_msg := warning_count_instance.warning_count as string; if (warning_count_instance.warning_count > 1) then warning_msg := warning_msg || " warnings for "; else warning_msg := warning_msg || " warning for "; endif; // Create a COMPLEX ORDER header message alert_med_description:= alert_med_description || "" || warning_msg || "" || med_complex_order.order_med_name || ""; alert_abstract_warnings := alert_abstract_warnings || warning_msg || med_complex_order.order_med_name || ". "; endif; // Check if it is a Complex Order with IV-Additives in the Master Order alert_abstract_iv_additive := ""; if any (med_data_list.is_iv_additive = true) then iv_solution_med_description := ""; // get the base solution single order med_iv_base_soln := last ( med_data_list where med_data_list.med_order_type = "IV-Additive" and ( med_data_list.is_iv_additive is null or med_data_list.is_iv_additive = false ) ); iv_additives_list := med_data_list where (med_data_list.is_iv_additive = true); // build a list containing unique iv additive items sorted // by name iv_additives_list := sort (iv_additives_list.order_med_name); //Create an IV-ADDITIVE header message num_additives := count(iv_additives_list); for iv_additives_ind in (1 seqto num_additives) do iv_additive_header_modified := false; if iv_additives_ind = 1 then iv_solution_med_description:= iv_solution_med_description || "" || iv_additives_list[iv_additives_ind] || ""; alert_abstract_iv_additive := alert_abstract_iv_additive || iv_additives_list[iv_additives_ind]; iv_additive_header_modified := true; elseif ( ( iv_additives_ind > 1 ) and ( iv_additives_list[iv_additives_ind] <> iv_additives_list[iv_additives_ind - 1] ) ) then if ( iv_additives_list[iv_additives_ind] = iv_additives_list[num_additives] ) then iv_solution_med_description:= iv_solution_med_description || " and "; alert_abstract_iv_additive := alert_abstract_iv_additive || " and "; elseif (iv_additives_ind < num_additives) then iv_solution_med_description:= iv_solution_med_description || ", "; alert_abstract_iv_additive := alert_abstract_iv_additive || ", "; endif; iv_solution_med_description:= iv_solution_med_description || "" || iv_additives_list[iv_additives_ind] || ""; alert_abstract_iv_additive := alert_abstract_iv_additive || iv_additives_list[iv_additives_ind]; iv_additive_header_modified := true; endif; enddo; if (alert_med_description <> "") then alert_med_description := alert_med_description || "
    "; endif; // add up the number of warnings for the iv additives iv_additive_warning_total := sum (warning_count_list.warning_count where warning_count_list.med_name in iv_additives_list); warning_msg := iv_additive_warning_total as string; if (iv_additive_warning_total > 1) then warning_msg := warning_msg || " warnings for "; else warning_msg := warning_msg || " warning for "; endif; alert_med_description:= alert_med_description || "" || warning_msg || "" || iv_solution_med_description || " in " || med_iv_base_soln.order_med_name; alert_abstract_warnings := alert_abstract_warnings || warning_msg || alert_abstract_iv_additive || " in " || med_iv_base_soln.order_med_name; if med_iv_base_soln.order_med_frequency is not null then alert_med_description:= alert_med_description || " " || med_iv_base_soln.order_med_frequency; alert_abstract_warnings := alert_abstract_warnings || " " || med_iv_base_soln.order_med_frequency; if med_iv_base_soln.stop_after_value is not null and med_iv_base_soln.stop_after_value > 0 and med_iv_base_soln.stop_after_option_type > 0 then alert_med_description := alert_med_description || " x " || med_iv_base_soln.stop_after_value || " " || stop_after_type_list[med_iv_base_soln.stop_after_option_type]; alert_abstract_warnings := alert_abstract_warnings || " x " || med_iv_base_soln.stop_after_value || " " || stop_after_type_list[med_iv_base_soln.stop_after_option_type]; endif; endif; // if exist order_med_frequency alert_med_description:= alert_med_description || ""; alert_abstract_warnings := alert_abstract_warnings || ". "; endif; //if any (med_data_list.med_order_type = "IV-Additive") else // Regular orders and prescriptions warning_msg := warning_count_instance[1].warning_count as string; if (warning_count_instance.warning_count > 1) then warning_msg := warning_msg || " warnings for "; else warning_msg := warning_msg || " warning for "; endif; // Create a REGULAR medication header message alert_med_description:= "" || warning_msg || "" || med_data_list[1].order_med_name || "" || " " || dosage_ordered || " " || printable_order_med_route || printable_order_med_frequency || ""; alert_abstract_warnings := alert_abstract_warnings || warning_msg || med_data_list[1].order_med_name || " " || dosage_ordered || " " || printable_order_med_route || printable_order_med_frequency || ". "; endif; // if med_order_type is in ("IV-Additive", "Complex Order") //---------------------------------------------- // Put the pieces of the Header Message together //---------------------------------------------- // insert warning message at top of alert alert_heading_text := alert_med_description || "
    " || estimated_birthtime_header || contraindicated_header || outside_dose_range_header || dose_range_not_checked_header || frequency_not_checked_header || too_frequent_header || "

    "; //---------------------------------------------- // Put the pieces of the Alert Abstract together //---------------------------------------------- alert_abstract := alert_abstract_warnings || alert_abstract_estimated_birthtime || alert_abstract_contraindicated || alert_abstract_outside_dose_range || alert_abstract_dose_range_not_checked || alert_abstract_frequency_not_checked || alert_abstract_too_frequent; //------------------------------------------- // Assemble the Patient Details //------------------------------------------- patient_details_header_text := "
    SUPPLEMENTAL INFORMATION:
    " || "If entering a medication for a future date, note that the dose calculation " || "is based on the following information available at the time of entry.

    "; // display the patient{{{SINGLE-QUOTE}}}s birthday and birth time patient_birthdate_str := ""; patient_birthtime_str := ""; if exists birthday then PatientBirthDateObj := birthday as {{{SINGLE-QUOTE}}}System.DateTime{{{SINGLE-QUOTE}}}; if (birth_month_num = 0) then // only display the year if there is no month patient_birthdate_str := call PatientBirthDateObj.ToString with "yyyy"; elseif (birth_day_num = 0) then // in this case, the month and year will exist patient_birthdate_str := call PatientBirthDateObj.ToString with partial_composite_date_format; else // in this case, the entire date will exist patient_birthdate_str := call PatientBirthDateObj.ToString with composite_date_format; endif; patient_details_header_text := patient_details_header_text || "Birthdate = " || patient_birthdate_str; // only show the birth time if the age is less than one month patient_age_in_months := (Now - birthday)/(1 month); if exists birthtime and patient_age_in_months < 1 then // Update the birthday to include birthtime birth_time := (birthtime as time); PatientBirthTimeObj := birth_time as {{{SINGLE-QUOTE}}}System.DateTime{{{SINGLE-QUOTE}}}; patient_birthtime_str := call PatientBirthTimeObj.ToString with time_format; patient_details_header_text := patient_details_header_text || " at " || patient_birthtime_str || " (birth time)"; endif; patient_details_header_text := patient_details_header_text || "
    "; endif; patient_properties := ( patient_info.Weight, patient_info.Height, patient_info.BSA, patient_info.Gender, patient_info.Liver, patient_info.Renal, patient_info.Creatinine, patient_info.ICD9_List); patient_other_details_txt := ""; for patient_property in patient_properties do if exists patient_property and exists patient_property.value then patient_other_details_txt := patient_other_details_txt || "
    "; // display the type of patient info property if patient_property.type = "Creatinine" then patient_other_details_txt := patient_other_details_txt || "Creatinine Clearance = "; else patient_other_details_txt := patient_other_details_txt || patient_property.type || " = "; endif; patient_other_details_txt := patient_other_details_txt || patient_property.value; // add units to end of patient info property value if required if (patient_property.type = "Weight") then patient_other_details_txt := patient_other_details_txt || " kg"; elseif (patient_property.type = "Height") then patient_other_details_txt := patient_other_details_txt || " cm"; elseif (patient_property.type = "BSA") then patient_other_details_txt := patient_other_details_txt || " M2"; elseif (patient_property.type = "Creatinine") then patient_other_details_txt := patient_other_details_txt || " mL/min"; endif; if (patient_property.type not in ("Gender", "BSA") and patient_property.date is not null) then // convert patient property date/time to evoking object{{{SINGLE-QUOTE}}}s visit time zone to support MTZ patient_other_details_txt := patient_other_details_txt || " (" || (patient_property.date AS TIME visit_time_zone) formatted with "%.4t" || ")"; endif; patient_other_details_txt := patient_other_details_txt || "
    \n"; endif; enddo; patient_details_text := patient_details_header_text || patient_other_details_txt; //-------------------------------- // Assemble Entire Alert Message //-------------------------------- dosage_outside_range_details := "\n"; for dosage_outside_range_table in dosage_outside_range_table_list do dosage_outside_range_details := dosage_outside_range_details || dosage_outside_range_table || "

    "; enddo; supplemental_data := ""; if (patient_info.DNum_Grouper.is_unmapped and alert_if_missing_flags.cannot_check_DNUM_Rx_to_Multum ) then supplemental_data := "

    " || supplemental_grouper_names; endif; if exists supplemental_table_list then supplemental_data := supplemental_data || "

    "; for supplemental_table_item in supplemental_table_list do supplemental_data := supplemental_data || supplemental_table_item.msg || "

    "; enddo; endif; standard_ccs := call CCS_MLM; alert_detail_text := "" || standard_ccs || "\n" || alert_heading_text || birthtime_missing_detail_msg || contraindication_detail_msg || dosage_outside_range_details || patient_details_text || supplemental_data || "\n"; // Always Conclude True conclude true; ;; action: return alert_detail_text, missing_data_list, cannot_check_list, alert_abstract; ;; end: