3712 lines
133 KiB
Plaintext
3712 lines
133 KiB
Plaintext
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 := "<tr><td>-----</td></tr>";
|
|
|
|
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 := "<b>For " || med_name || ": </b>";
|
|
endif;
|
|
|
|
if (dosage_range.is_multum)
|
|
then
|
|
missing_data_based_on := "<div id={{{SINGLE-QUOTE}}}BasedOnAdditionalInfoMsg{{{SINGLE-QUOTE}}}>"
|
|
|| for_drug_str
|
|
|| "Applicable dosage ranges based on patient "
|
|
|| "age of <i>" || patient_info.Age.value || "</i>"
|
|
|| ", route of <i>" || dosage_range.display_route || "</i>";
|
|
else
|
|
missing_data_based_on := "<div id={{{SINGLE-QUOTE}}}BasedOnAdditionalInfoMsg{{{SINGLE-QUOTE}}}>"
|
|
|| for_drug_str
|
|
|| "Applicable dosage ranges based on route of <i>"
|
|
|| dosage_range.display_route || "</i>";
|
|
endif;
|
|
|
|
// construct the table
|
|
// print out the header row
|
|
table_heading := "<table id={{{SINGLE-QUOTE}}}AdditionalInfoTable{{{SINGLE-QUOTE}}}>\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 := "<th colspan=1 id={{{SINGLE-QUOTE}}}AdditionalInfoColumnHeader{{{SINGLE-QUOTE}}}>";
|
|
else
|
|
dose_contra := "Usual Dose Range ";
|
|
dose_column_header := "<th colspan=" || col_span || " id={{{SINGLE-QUOTE}}}AdditionalInfoColumnHeader{{{SINGLE-QUOTE}}}>";
|
|
endif;
|
|
|
|
// first column heading
|
|
table_heading := table_heading
|
|
|| "<tr>"
|
|
|| dose_column_header
|
|
|| "<u>"
|
|
|| dose_contra
|
|
|| cat_multum
|
|
|| "</u></th>";
|
|
|
|
missing_data_based_on := missing_data_based_on
|
|
|| " and the following additional conditions:</div>\n";
|
|
table_heading := table_heading
|
|
|| "<th id={{{SINGLE-QUOTE}}}AdditionalInfoColumnHeader{{{SINGLE-QUOTE}}}><u>Additional Conditions</u></th></tr>\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 := "<b>For <span id={{{SINGLE-QUOTE}}}MedicationName{{{SINGLE-QUOTE}}}>" || case_item.med_name || "</span>: </b>";
|
|
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
|
|
|| "<b>"
|
|
|| printable_based_on_criteria_list[printable_based_on_index]
|
|
|| "</b>";
|
|
|
|
enddo;
|
|
|
|
// There is some dosage range that is outside
|
|
// Start creating the table
|
|
dose_range_based_on_case := "<div id={{{SINGLE-QUOTE}}}BasedOnMsg{{{SINGLE-QUOTE}}}>"
|
|
|| for_iv_drug
|
|
|| "Based on patient "
|
|
|| based_on_case
|
|
|| ":</div>\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 <med, dose range> 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 <age,route> 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
|
|
|| "<tr name =" || row_name || ">"
|
|
|| "<td valign=top>" || row_type || "</td>";
|
|
|
|
// 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 := "<font size=""2"">Medication ordered is <b>not recommended</b> for a patient fitting this profile.</font>";
|
|
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
|
|
|| "<td valign=top>" || dosage_range_col || "</td>"
|
|
|| "<td id={{{SINGLE-QUOTE}}}TableCellPaddingRight{{{SINGLE-QUOTE}}} valign=top>" || frequency_col || "</td>";
|
|
else
|
|
out_of_range_row := out_of_range_row
|
|
|| "<td id={{{SINGLE-QUOTE}}}TableCellPaddingRight{{{SINGLE-QUOTE}}} valign=top>" || dosage_range_col || "</td>";
|
|
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 := "<b>" || ordered_dosage_col || " " || dose_range_item.corrected_uom || "</b>";
|
|
|
|
if (map_item.above_range or map_item.below_range)
|
|
then
|
|
ordered_dosage_col := "<span id={{{SINGLE-QUOTE}}}OutsideDoseRangeValue{{{SINGLE-QUOTE}}}>" || ordered_dosage_col || "</span>";
|
|
elseif (map_item.match_found
|
|
and map_item.above_range = false
|
|
and map_item.below_range = false)
|
|
then
|
|
ordered_dosage_col := "<span id={{{SINGLE-QUOTE}}}WithinDoseRangeValue{{{SINGLE-QUOTE}}}>" || ordered_dosage_col || "</span>";
|
|
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
|
|
|| "<span id={{{SINGLE-QUOTE}}}MedicationName{{{SINGLE-QUOTE}}}>";
|
|
|
|
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
|
|
|| " <span id={{{SINGLE-QUOTE}}}FrequencyIssue{{{SINGLE-QUOTE}}}>"
|
|
|| freq
|
|
|| "</span>";
|
|
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
|
|
|| "</span>";
|
|
|
|
// Order/Prescription dose col
|
|
out_of_range_row := out_of_range_row
|
|
|| "<td id={{{SINGLE-QUOTE}}}TableCellPaddingRight{{{SINGLE-QUOTE}}} valign=top>" || ordered_dosage_col || "</td>";
|
|
|
|
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
|
|
|| "<td id={{{SINGLE-QUOTE}}}TableCellPaddingRight{{{SINGLE-QUOTE}}} valign=top>" || starting_on_col || "</td>";
|
|
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
|
|
|| "<td id={{{SINGLE-QUOTE}}}TableCellPaddingRight{{{SINGLE-QUOTE}}} valign=top>" || note_col || "</td>";
|
|
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
|
|
|| "<td id={{{SINGLE-QUOTE}}}TableCellPaddingRight{{{SINGLE-QUOTE}}}>"
|
|
|| "Case ID: " || case_info_item.case_id
|
|
|| route_val
|
|
|| "</td>";
|
|
endif;
|
|
|
|
out_of_range_row := out_of_range_row
|
|
|| "</tr>\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
|
|
|| "<td>" || case_info_item.conditions_text || "</td></tr>\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 := "<table id={{{SINGLE-QUOTE}}}OutsideDoseRangeTable{{{SINGLE-QUOTE}}}>\n"
|
|
|| "<tr>"
|
|
|| "<th colspan=3 id={{{SINGLE-QUOTE}}}TableColumnHeader{{{SINGLE-QUOTE}}}><b><u>Usual Dose Range "
|
|
|| column_Multum_name
|
|
|| "</u></b></th>"
|
|
|| "<th id={{{SINGLE-QUOTE}}}TableColumnHeader{{{SINGLE-QUOTE}}}><b><u>" || order_rx || "</u></b></th>";
|
|
|
|
// show start date if there are multiple administrations (complex order)
|
|
if has_date
|
|
then
|
|
table_heading := table_heading
|
|
|| "<th id={{{SINGLE-QUOTE}}}TableColumnHeader{{{SINGLE-QUOTE}}}><b><u>Starting On</u></b></th>";
|
|
endif;
|
|
|
|
// add Note header
|
|
if has_notes
|
|
then
|
|
table_heading := table_heading
|
|
|| "<th id={{{SINGLE-QUOTE}}}TableColumnHeader{{{SINGLE-QUOTE}}}><b><u>Note</u></b></th>";
|
|
endif;
|
|
|
|
if show_debug_statements
|
|
then
|
|
table_heading := table_heading
|
|
|| "<th id={{{SINGLE-QUOTE}}}TableColumnHeader{{{SINGLE-QUOTE}}}><b><u>(Debug)</u></b></th>";
|
|
endif;
|
|
|
|
|
|
// finish off the row header
|
|
table_heading := table_heading || "</tr>\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
|
|
|| "</table>\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 := "<table>\n"
|
|
|| "<tr>"
|
|
|| "<th colspan=2 id={{{SINGLE-QUOTE}}}TableColumnHeader{{{SINGLE-QUOTE}}}><b><u>Usual Dose Range "
|
|
|| column_catalog_name
|
|
||"</u></b></th>"
|
|
|| "<th id={{{SINGLE-QUOTE}}}TableColumnHeader{{{SINGLE-QUOTE}}}><b><u>" || order_rx || "</u></b></th>";
|
|
|
|
// show start date if there are multiple administrations (complex order)
|
|
if has_date
|
|
then
|
|
table_heading := table_heading
|
|
|| "<th id={{{SINGLE-QUOTE}}}TableColumnHeader{{{SINGLE-QUOTE}}}><b><u>Starting On</u></b></th>";
|
|
endif;
|
|
|
|
// add Note header
|
|
if has_notes
|
|
then
|
|
table_heading := table_heading
|
|
|| "<th id={{{SINGLE-QUOTE}}}TableColumnHeader{{{SINGLE-QUOTE}}}><b><u>Note</u></b></th>";
|
|
endif;
|
|
|
|
if show_debug_statements
|
|
then
|
|
table_heading := table_heading
|
|
|| "<th id={{{SINGLE-QUOTE}}}TableColumnHeader{{{SINGLE-QUOTE}}}><b><u>(Debug)</u></b></th>";
|
|
endif;
|
|
|
|
// finish off the row header
|
|
table_heading := table_heading || "</tr>\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
|
|
|| "</table>\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
|
|
|| "<span id={{{SINGLE-QUOTE}}}CreatinineClearanceNote{{{SINGLE-QUOTE}}}><b>NOTE</b></span>"
|
|
|| " 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
|
|
|| "<tr>"
|
|
|| "<td id={{{SINGLE-QUOTE}}}TableCellPaddingRight{{{SINGLE-QUOTE}}}>" || dose_range_item.contraindication_msg || "</td>"
|
|
|| "<td>" || case_info_item.conditions_text || "</td>"
|
|
|| "</tr>\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 || "</table>\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
|
|
|| "<li>"
|
|
|| grouper_info_item.grouper_name
|
|
|| "</li>";
|
|
endif;
|
|
enddo;
|
|
|
|
if any grouper_info_list.dosage_range_found
|
|
then
|
|
supplemental_grouper_names := "<div>"
|
|
|| "This medication has dosage ranges for the following groups of medications:"
|
|
|| "</div>\n"
|
|
|| "<ul>\n"
|
|
|| grouper_name_rows
|
|
|| "</ul>\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 <User Schedule> Irregular Message
|
|
//------------------------------------------------------
|
|
// This message only applies to the Average Daily Dosage Range
|
|
// when there is a <User Schedule> 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 := "<b>Issue: Irregular User Schedule</b><br/><br/>\n"
|
|
|| "A <b>User Scheduled</b> frequency was selected "
|
|
|| "that used an <b>Irregular</b> schedule. There is an average daily "
|
|
|| "dosage range listed for the medication(s): "
|
|
|| med_name || ". However, for this type of "
|
|
|| "schedule the calculated <b>average daily</b> 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 <User Schedule> WEEKLY Message
|
|
//------------------------------------------------------
|
|
// This message only applies to the Average Daily Dosage Range
|
|
// when there is a <User Schedule> 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 := "<b>Issue: Weekly User Schedule</b><br/><br/>\n"
|
|
|| "A <b>User Scheduled</b> frequency was selected "
|
|
|| "that used a <b>Weekly</b> schedule. There is an "
|
|
|| "average daily dosage range listed for the medication(s): "
|
|
|| med_name || ". However, for this type of "
|
|
|| "schedule the calculated <b>average daily</b> 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 := "<b>Issue: Under 24-Hour dose</b><br/><br/>\n"
|
|
|| "The <b>average daily</b> and <b>total daily</b> 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 := "<b>Issue: Shift based frequency</b><br/><br/>\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 := "<b>Unmapped: Frequency</b><br/>"
|
|
|| "Notify your system administrator that the Frequency <b>"
|
|
|| freq
|
|
|| "</b> 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 := "<b>Issue: Cannot determine which dosage range to check</b><br/>\n"
|
|
|| "Please select the <b>full name</b> with <b>strength</b> and <b>form</b> "
|
|
|| "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 := "<b>Issue: Could not determine which dosage range to check "
|
|
|| column_catalog_name || "</b><br/>\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 := "<b>Missing data: Age</b><br/>"
|
|
|| "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 := "<b>Issue: Unknown Gender</b><br/>"
|
|
|| "This patient{{{SINGLE-QUOTE}}}s gender is <b>"
|
|
|| patient_info.Gender.value
|
|
|| "</b>. 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 := "<b>Unmapped: Gender</b><br/>"
|
|
|| "Notify your system administrator that the Gender, <b>"
|
|
|| patient_info.Gender.value
|
|
|| "</b> 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 := "<b>Missing data: Gender</b>";
|
|
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 := "<b>Missing data: Height</b>";
|
|
missing_data_alert_abstract := "Missing data: Height";
|
|
elseif patient_info.Height.not_current
|
|
then
|
|
missing_data_type := data_not_current_str;
|
|
missing_data_msg := "<b>Data not current: Height</b>";
|
|
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 := "<b>Missing data: Weight</b>";
|
|
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 := "<b>Data not current: Weight</b>";
|
|
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 := "<b>Unmapped: Drug</b><br/>"
|
|
|| "Notify your system administrator that the Drug <b>"
|
|
|| med_name
|
|
|| "</b> 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 := "<b>Missing data: Route</b>";
|
|
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 := "<b>Unmapped: Route</b><br/>"
|
|
|| "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
|
|
|| "<b>"
|
|
|| unique_unmapped_routes_list[ind]
|
|
|| "</b>";
|
|
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
|
|
|| "<b>"
|
|
|| sorted_unconvertible_route_list[ind]
|
|
|| "</b>";
|
|
enddo; // for ind in (1 seqto num_unconvertible_routes)
|
|
|
|
// Generate the message
|
|
if route_conversion_issue = "Unrecognized"
|
|
then
|
|
missing_data_detail_msg := "<b>Issue: Unrecognized Route</b><br/>"
|
|
|| "Please see below dosage ranges for "
|
|
|| sorted_unconvertible_route_str
|
|
|| " routes of administering the <b>"
|
|
|| sorted_route
|
|
|| "</b>.";
|
|
else
|
|
missing_data_detail_msg := "<b>Issue: Inapplicable Route</b><br/>"
|
|
|| "Dosage range information is not available for "
|
|
|| "<b>"
|
|
|| sorted_route
|
|
|| "</b> 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 := "<b>Unmapped: Dose Range Group</b><br/>"
|
|
|| "Notify your system administrator that <b>"
|
|
|| med_name
|
|
|| "</b> 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 := "<b>Missing data: Unit of Measure</b>";
|
|
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 := "<b>Unmapped: Unit of Measure</b><br/>"
|
|
|| "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
|
|
|| "<b>"
|
|
|| unique_unmapped_uom_list[ind]
|
|
|| "</b>";
|
|
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 := "<b>Issue: Unit of measure conversion</b><br/>"
|
|
|| "The current Unit of Measure, <b>"
|
|
|| sorted_order_med_unit
|
|
|| "</b> 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
|
|
|| "<b>"
|
|
|| sorted_unconvertible_uom_list[ind]
|
|
|| "</b>";
|
|
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"
|
|
|| "<table id={{{SINGLE-QUOTE}}}MissingBirthtimeTable{{{SINGLE-QUOTE}}}>"
|
|
|| "<tr>"
|
|
|| "<th id={{{SINGLE-QUOTE}}}TableColumnHeader{{{SINGLE-QUOTE}}}><u><b>Estimated newborn age</b></u></th>"
|
|
|| "<th id={{{SINGLE-QUOTE}}}TableColumnHeader{{{SINGLE-QUOTE}}}><u><b>Birth-time</b></u></th>"
|
|
|| "</tr>"
|
|
|| "<tr><td id={{{SINGLE-QUOTE}}}TableCellPaddingRight{{{SINGLE-QUOTE}}}>"
|
|
|| estimated_birthtimes
|
|
|| "</td>"
|
|
|| "<td><span id={{{SINGLE-QUOTE}}}ContraindicationPatientInfo{{{SINGLE-QUOTE}}}><b>Unknown</b></span></td></tr>"
|
|
|| "</table><br/><br/>";
|
|
|
|
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 := "<b>For <span id={{{SINGLE-QUOTE}}}MedicationName{{{SINGLE-QUOTE}}}>"
|
|
|| contraindication_dosage_range.med_name
|
|
|| "</span>: </b>";
|
|
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
|
|
|| "<table id={{{SINGLE-QUOTE}}}ContraindicationTable{{{SINGLE-QUOTE}}}>"
|
|
|| "<tr>"
|
|
|| "<th id={{{SINGLE-QUOTE}}}TableColumnHeader{{{SINGLE-QUOTE}}}><u><b>Conditions</b></u></th>"
|
|
|| "<th id={{{SINGLE-QUOTE}}}TableColumnHeader{{{SINGLE-QUOTE}}}><u><b>This Patient</b></u></th>"
|
|
|| "</tr>";
|
|
|
|
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 := "<span id={{{SINGLE-QUOTE}}}ContraindicationPatientInfo{{{SINGLE-QUOTE}}}><b>";
|
|
|
|
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
|
|
|| "</b></span>";
|
|
|
|
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
|
|
|| "<span id={{{SINGLE-QUOTE}}}PaddingLeft{{{SINGLE-QUOTE}}}>(" || (patient_info_obj.Date AS TIME visit_time_zone) formatted with "%.4t" || ")</span>";
|
|
|
|
endif;
|
|
|
|
endif;
|
|
|
|
// fix this later when have time to go through contraindication headings
|
|
contraindication_detail_msg := contraindication_detail_msg
|
|
|| "<tr><td id={{{SINGLE-QUOTE}}}TableCellPaddingRight{{{SINGLE-QUOTE}}}>"
|
|
|| criteria_heading
|
|
|| criteria_val
|
|
|| "</td>"
|
|
|| "<td>"
|
|
|| patient_criteria_val
|
|
|| "</td></tr>";
|
|
endif;
|
|
enddo;
|
|
|
|
contraindication_detail_msg := contraindication_detail_msg
|
|
|| "</table>";
|
|
|
|
endif; // if exist contraindication_criteria_list
|
|
|
|
contraindication_detail_msg := contraindication_detail_msg || "<br/><br/>";
|
|
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 := "<div id={{{SINGLE-QUOTE}}}Title{{{SINGLE-QUOTE}}}><b>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 <u>NOT</u> be CHECKED</b></div>\n"
|
|
|| "<ul>";
|
|
|
|
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 := "<b>For <span id={{{SINGLE-QUOTE}}}MedicationName{{{SINGLE-QUOTE}}}>"
|
|
|| med_name
|
|
|| "</span>: </b>";
|
|
|
|
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
|
|
|| "<li>"
|
|
|| for_drug_str
|
|
|| missing_data_item.msg
|
|
|| "</li>";
|
|
|
|
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
|
|
|| "<li>"
|
|
|| for_drug_str
|
|
|| cannot_check_item.alert_msg_for_cannot_check
|
|
|| "</li>";
|
|
|
|
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
|
|
|| "</ul>";
|
|
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 := "<div id={{{SINGLE-QUOTE}}}Title{{{SINGLE-QUOTE}}}><b>FREQUENCY "
|
|
|| "could <u>NOT</u> be CHECKED</b></div>\n"
|
|
|| "<ul>";
|
|
|
|
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 := "<b>For <span id={{{SINGLE-QUOTE}}}MedicationName{{{SINGLE-QUOTE}}}>"
|
|
|| med_name
|
|
|| "</span>: </b>";
|
|
|
|
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
|
|
|| "<li>"
|
|
|| for_drug_str
|
|
|| med_frequency_unchecked_item.msg
|
|
|| "</li>";
|
|
|
|
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
|
|
|| "</ul>";
|
|
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
|
|
|| "<div id={{{SINGLE-QUOTE}}}Title{{{SINGLE-QUOTE}}}><b>NEWBORN EXACT AGE IS ESTIMATED</b></div><ul>"
|
|
|| "<li><b>Missing data: Birth-time</b><br/>Dose range checked using estimated ages of "
|
|
|| estimated_birthtimes
|
|
|| ".<br/>"
|
|
|| "The details of which age the alert applies to, is provided later in the alert message.</li></ul>";
|
|
|
|
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 := "<div id={{{SINGLE-QUOTE}}}Title{{{SINGLE-QUOTE}}}><b>CONTRAINDICATED</b></div><ul>\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 <span id={{{SINGLE-QUOTE}}}MedicationName{{{SINGLE-QUOTE}}}>"
|
|
|| med_name
|
|
|| "</span>: ";
|
|
|
|
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
|
|
|| "<li><b>"
|
|
|| for_drug_str
|
|
|| contraindication_item.contraindication_msg
|
|
|| "</b></li>";
|
|
|
|
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
|
|
|| "</ul>\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
|
|
|| "<div id={{{SINGLE-QUOTE}}}Title{{{SINGLE-QUOTE}}}><b>FREQUENCY INTERVAL TOO SHORT</b></div><ul>";
|
|
|
|
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 := "<b>For <span id={{{SINGLE-QUOTE}}}MedicationName{{{SINGLE-QUOTE}}}>"
|
|
|| case_item.med_name
|
|
|| "</span>: </b>";
|
|
|
|
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
|
|
|| "<li>"
|
|
|| for_drug_str
|
|
|| "<b>Frequency</b>: This dosing interval should not be more frequent than "
|
|
|| "<span id={{{SINGLE-QUOTE}}}FrequencyIssue{{{SINGLE-QUOTE}}}>"
|
|
|| frequency_item
|
|
|| "</span> "
|
|
|| case_item.based_on_header_text
|
|
|| "</li>";
|
|
|
|
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
|
|
|| "</ul>\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
|
|
|| "<div id={{{SINGLE-QUOTE}}}Title{{{SINGLE-QUOTE}}}><b>OUTSIDE USUAL DOSE RANGE</b></div><ul>";
|
|
|
|
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 := "<b>Exceeds</b> maximum ";
|
|
alert_abstract_exceeds_and_below_str := "Exceeds maximum ";
|
|
elseif all case_map_list.below_range
|
|
then
|
|
exceeds_and_below_str := "<b>Below</b> 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 := "<b>Exceeds</b> and <b>Below ranges</b> ";
|
|
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 := "<b>Exceeds</b> maximum "
|
|
|| exceeds_dose_type_str
|
|
|| " and <b>Below</b> 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 := "<b>For <span id={{{SINGLE-QUOTE}}}MedicationName{{{SINGLE-QUOTE}}}>"
|
|
|| case_item.med_name
|
|
|| "</span>: </b>";
|
|
|
|
alert_abstract_for_drug_str := "For "
|
|
|| case_item.med_name
|
|
|| ": ";
|
|
endif;
|
|
|
|
|
|
outside_dose_range_header := outside_dose_range_header
|
|
|| "<li>"
|
|
|| for_drug_str
|
|
|| exceeds_and_below_str
|
|
|| case_item.based_on_header_text
|
|
|| "</li>";
|
|
|
|
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
|
|
|| "</ul>\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
|
|
|| "<b>"
|
|
|| warning_msg
|
|
|| "<span id={{{SINGLE-QUOTE}}}MedicationHeader{{{SINGLE-QUOTE}}}>"
|
|
|| med_complex_order.order_med_name
|
|
|| "</span></b>";
|
|
|
|
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
|
|
|| "<b>"
|
|
|| iv_additives_list[iv_additives_ind]
|
|
|| "</b>";
|
|
|
|
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
|
|
|| "<span id={{{SINGLE-QUOTE}}}NormalText{{{SINGLE-QUOTE}}}> and </span>";
|
|
|
|
alert_abstract_iv_additive := alert_abstract_iv_additive
|
|
|| " and ";
|
|
|
|
elseif (iv_additives_ind < num_additives)
|
|
then
|
|
iv_solution_med_description:= iv_solution_med_description
|
|
|| "<span id={{{SINGLE-QUOTE}}}MedicationName{{{SINGLE-QUOTE}}}>, </span>";
|
|
|
|
alert_abstract_iv_additive := alert_abstract_iv_additive
|
|
|| ", ";
|
|
endif;
|
|
|
|
iv_solution_med_description:= iv_solution_med_description
|
|
|| "<b>"
|
|
|| iv_additives_list[iv_additives_ind]
|
|
|| "</b>";
|
|
|
|
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
|
|
|| "<br/>";
|
|
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
|
|
|| "<b>"
|
|
|| warning_msg
|
|
|| "</b><span id={{{SINGLE-QUOTE}}}MedicationHeader{{{SINGLE-QUOTE}}}>"
|
|
|| 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
|
|
|| "</span>";
|
|
|
|
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:= "<b>"
|
|
|| warning_msg
|
|
|| "<span id={{{SINGLE-QUOTE}}}MedicationHeader{{{SINGLE-QUOTE}}}>"
|
|
|| med_data_list[1].order_med_name
|
|
|| "</b>"
|
|
|| " " || dosage_ordered
|
|
|| " " || printable_order_med_route
|
|
|| printable_order_med_frequency
|
|
|| "</span>";
|
|
|
|
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
|
|
|| "<br/>"
|
|
|| estimated_birthtime_header
|
|
|| contraindicated_header
|
|
|| outside_dose_range_header
|
|
|| dose_range_not_checked_header
|
|
|| frequency_not_checked_header
|
|
|| too_frequent_header
|
|
|| "<br/><br/>";
|
|
|
|
|
|
//----------------------------------------------
|
|
// 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 := "<div><u>SUPPLEMENTAL INFORMATION:</u><br/>"
|
|
|| "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.<br/><br/></div>";
|
|
|
|
// 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
|
|
|| "<br>";
|
|
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
|
|
|| "<div>";
|
|
|
|
// 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
|
|
|| "<span id={{{SINGLE-QUOTE}}}PaddingLeft{{{SINGLE-QUOTE}}}> (" || (patient_property.date AS TIME visit_time_zone) formatted with "%.4t" || ")</span>";
|
|
|
|
endif;
|
|
|
|
patient_other_details_txt := patient_other_details_txt
|
|
|| "</div>\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
|
|
|| "<br/><br/>";
|
|
enddo;
|
|
|
|
supplemental_data := "";
|
|
|
|
if (patient_info.DNum_Grouper.is_unmapped
|
|
and alert_if_missing_flags.cannot_check_DNUM_Rx_to_Multum
|
|
)
|
|
then
|
|
supplemental_data := "<br/><br/>"
|
|
|| supplemental_grouper_names;
|
|
endif;
|
|
|
|
if exists supplemental_table_list
|
|
then
|
|
supplemental_data := supplemental_data || "<br/><br/>";
|
|
for supplemental_table_item in supplemental_table_list
|
|
do
|
|
supplemental_data := supplemental_data
|
|
|| supplemental_table_item.msg
|
|
|| "<br/><br/>";
|
|
enddo;
|
|
endif;
|
|
|
|
standard_ccs := call CCS_MLM;
|
|
alert_detail_text := "<head>" || standard_ccs || "</head>\n<body>"
|
|
|| alert_heading_text
|
|
|| birthtime_missing_detail_msg
|
|
|| contraindication_detail_msg
|
|
|| dosage_outside_range_details
|
|
|| patient_details_text
|
|
|| supplemental_data
|
|
|| "</body>\n";
|
|
|
|
// Always Conclude True
|
|
conclude true;
|
|
;;
|
|
action:
|
|
return
|
|
alert_detail_text,
|
|
missing_data_list,
|
|
cannot_check_list,
|
|
alert_abstract;
|
|
;;
|
|
end:
|