836 lines
30 KiB
Plaintext
836 lines
30 KiB
Plaintext
maintenance:
|
|
|
|
title: Total Daily Dose Exceeded warning;;
|
|
mlmname: STD_TOTAL_DAILY_DOSE_EXCEEDED;;
|
|
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: Provides a warning if the current dose being scanned will exceed the daily total
|
|
allowed for this medication order item for this patient.
|
|
;;
|
|
explanation:
|
|
Total Daily Dose Limit Exceeded Warnings are based on Dosage Range Criteria defined
|
|
for the Order Item compared to the current dose to be administered summed with the
|
|
previous doses given in the past 24 hours. Based on settings this MLM will not alert
|
|
if the entering provider was issued a Dosage Alert at Order Entry and the order was
|
|
verified by Pharmacy. The MLM can also be set not to alert for patients with missing
|
|
physical characteristic data or for patients at particular locations.
|
|
|
|
REQUIRED FIELDS:
|
|
(When an appropriate criteria cannot be found, there will not be an alert.)
|
|
|
|
- The patient data must be present for:
|
|
* Age
|
|
* Height
|
|
* Weight
|
|
* Gender
|
|
|
|
- The task occurrence form fields must include:
|
|
* TaskDose
|
|
* TaskUOM
|
|
* TaskRoute
|
|
|
|
- The facility must map the following "Core UOM" to their "Dictionary Code"
|
|
in the Unit Of Measure Dictionary:
|
|
* BSA: M2
|
|
* Weight: kg, g, lb, oz
|
|
* Age: year, month, week, day
|
|
|
|
NOTE THE FOLLOWING ARE NOT INCLUDED IN MEDICATION DOSE RANGE CHECKING:
|
|
- This MLM is NOT currently using Base Solution, Base Solution UOM,
|
|
IV Rate, or IV Rate UOM fields to perform Dose Range checking on order entry
|
|
or modification.
|
|
|
|
- Generic item matches are NOT included.
|
|
The only TASKs that are checked include those tasks that orignate from matching
|
|
Catalog Order Items. That is they are the same medication in the Item Catalog.
|
|
At this release Tasks and Occurrences that orginate from the same
|
|
OrderCatalogMasterItem will have a matching CatalogItemTaskGUID and there is
|
|
a one to one relationship between OrderCatalogMasterItem and CatalogItemTask.
|
|
|
|
- Tasks with diffrernt uom are NOT included in the calculations.
|
|
Only Tasks with matching units of measure will be totaled since there is means of
|
|
converting units of measure. There is no Conversion table available in this
|
|
release.
|
|
|
|
- IV-ADDITIVES are NOT considered when doing dosage range checks; concentrations
|
|
and amounts are entered on flowsheets, not on IV tasks.
|
|
|
|
To calculate the {{{SINGLE-QUOTE}}}Total Dose Daily Dose Allowed{{{SINGLE-QUOTE}}}, the Dose Range Criteria for the parent
|
|
order of this task occurrence will be examined. The MLM will determine if a dose range
|
|
has been specified in the item catalog for one of the following {{{SINGLE-QUOTE}}}Total Daily" criteria
|
|
types:
|
|
- BSA - Total Daily
|
|
- Weight - Total Daily
|
|
- Age - Total Daily
|
|
|
|
If data are available for more than one criteria type, the priority will be in the order
|
|
listed above.
|
|
An alert will be generated for the first method encountered where the total dose is
|
|
outside of the recommended Total Daily dose.
|
|
|
|
If a matching criteria is found, the total daily dose determined. Calculations are
|
|
performed if a PER method is defined such as per kg or per M2.
|
|
|
|
The following patient characteristics will be used to determine if the specified total
|
|
daily dose is appropriate:
|
|
(1) patient body surface area (BSA),
|
|
(2) patient weight, and
|
|
(3) patient age
|
|
(4) gender, if listed on the Total Daily dose criteria
|
|
|
|
Absence of a patient characteristic required to perform the calculation will result in
|
|
an alert warning that the calculation cannot be determined due to missing data.
|
|
|
|
SPECIAL CONSIDERATIONS:
|
|
a. The SYS_CALC_BSA.mlm calculates the Body Surface Area (BSA) for
|
|
Dosage Range MLMs. SYS_CALC_BSA.mlm has two BSA formulas (standard or pediatric).
|
|
If patient is 18.0 years or younger, Pediatric BSA formula is used.
|
|
|
|
If age of patient cannot be determined due to missing birth year,
|
|
facility{{{SINGLE-QUOTE}}}s preference in the enterprise profile for BSAFormula.
|
|
Should facility{{{SINGLE-QUOTE}}}s preference be needed and BSAFormula has not been set, then
|
|
Standard BSA formula will be used. In addition, calculated BSA value
|
|
is rounded to two decimal places.
|
|
|
|
b. When patient has a partial birthday (missing birth month), then
|
|
dosage range check by AGE will not be done if patient is less than
|
|
3 years old (an age based on the birth year).
|
|
|
|
c. The MLM uses data from Unit of Measure dictionary and Dosage Range panel in
|
|
the Item-Catalog. The Unit of Measure dictionary maps facility-defined UOM called
|
|
"Dictionary Code" to System-defined UOM called "Core UOM." "Dictionary Codes" in
|
|
Dosage Range panel of item-catalog.
|
|
When calculating dose-ranges, only "Criteria Unit" and "Dosage Per-Wt-or-M2"
|
|
fields are converted from facility-defined UOM (Dictionary Code) to System-defined
|
|
"Core UOM";
|
|
d. "Dosage Unit" is not converted. For example if one tasks dosage is in grains and
|
|
one in umg, the doses are not converted to the same unit of measure.
|
|
|
|
f. The absence of an alert can mean one of the following:
|
|
* The all the doses were within the acceptable range.
|
|
* The appropriate criteria could not be found; so the Dosage could not be checked.
|
|
* No item matches were found for the item in this task.
|
|
|
|
|
|
;;
|
|
keywords: total daily dose, exceeded
|
|
;;
|
|
citations:
|
|
{{+B}}Development{{-B}}: Allscripts Healthcare Solutions, Inc. Clinical Information can be customized and configured by local facility.
|
|
{{+B}}Funding{{-B}}: None specific to the development of this alert
|
|
{{+B}}Release{{-B}}: None
|
|
{{+B}}Revision Date{{-B}}: 2012-11-07
|
|
|
|
{{+B}}Citations{{-B}}: None
|
|
;;
|
|
knowledge:
|
|
type: data-driven;;
|
|
data:
|
|
/*******************Make Changes To Spelling And Flags In This Section*******************/
|
|
|
|
/* Set to true if a decision.log is needed.*/
|
|
log_execution_info := false;
|
|
|
|
/* Set these flags to limit alerting.*/
|
|
no_alert_if_RxVerified := TRUE; // no alerts if Rx has verified all the orders
|
|
alert_if_patient_data_missing := TRUE; // issue alert if patient data is missing
|
|
alert_limited_locations := FALSE; // no alerts for particular patient locations
|
|
|
|
|
|
/* Insert the CV3Location.Code for each location that will not issue alerts in this list */
|
|
no_alert_locations := ("NGH |1C |","NGH |2A |");
|
|
|
|
|
|
/* The facility must map its Dictionary Codes to the Core UOM in the Units of Measure */
|
|
/* Dictionary. The MLM converts the facility-defined units of measure to the System- */
|
|
/* defined values in the Unit of Measure Dictionary called CoreUOM. */
|
|
lb_string:= "lb";
|
|
gm_string:= "g";
|
|
kg_string:= "kg";
|
|
M2_string:= "M2";
|
|
ounce_string:= "oz";
|
|
day_string:= "day";
|
|
month_string:= "month";
|
|
week_string:= "week";
|
|
year_string:= "year";
|
|
|
|
|
|
/* Change the message within the quotes if a different short-message is needed.*/
|
|
dose_exceeded_alert := destination { Alert: Warning, "Daily Dosage Exceeded", high,
|
|
chart, "Dosage Administration Alert", 5010,"DoNotSend",
|
|
"Must Acknowledge and Comment" };
|
|
|
|
/* Called on scanning event for Tasks */
|
|
medication_scan := event {OrderTaskOccurrenceIntendToAdmin User OrderTaskOccurrence :
|
|
WHERE OrderTask.TaskSeqNum = 0};
|
|
|
|
/***************************************************************************************/
|
|
|
|
/* DO NOT CHANGE the following System-defined values */
|
|
|
|
age_total_daily_dose_string:= "Age - Total Daily";
|
|
BSA_total_daily_dose_string:= "BSA - Total Daily";
|
|
weight_total_daily_dose_string:= "Weight - Total Daily";
|
|
|
|
continue_processing := TRUE;
|
|
found_range:= FALSE;
|
|
found_total_daily_dose:= FALSE;
|
|
|
|
more_than_one_task_in_sum := FALSE;
|
|
first_dose_given := FALSE;
|
|
|
|
mismatched_occ_uom_found := FALSE;
|
|
mismatched_med_uom_found := FALSE;
|
|
missing_data_error := FALSE;
|
|
missing_age := FALSE;
|
|
missing_weight := FALSE;
|
|
missing_height := FALSE;
|
|
|
|
past_administered_doses := 0;
|
|
|
|
pharmacy_verified_current := FALSE;
|
|
pharmacy_verified_all_past := FALSE;
|
|
|
|
err_msg := "";
|
|
missing_data_msg := "";
|
|
mismatched_past_occurrences_msg := "";
|
|
mismatched_occ_uom_msg := "";
|
|
mismatched_med_uom_msg := "";
|
|
alert_detail_text := "";
|
|
alert_msg := "none";
|
|
|
|
|
|
/* Execute only when this MLM is called by the editor */
|
|
if called_by_editor then
|
|
task_obj:= read last
|
|
{OrderTaskOccurrence: This,
|
|
WHERE TaskName = "Ampicillin Dosage:500"
|
|
and EXIST TaskDose
|
|
// AND SignificantDtm = 2004-11-17T15:00:00
|
|
AND TaskStatusCode = "Performed"
|
|
};
|
|
EvokingObject:= task_obj;
|
|
endif;
|
|
|
|
/* Declare MLMs which can be called */
|
|
find_daily_dose_range := MLM {{{SINGLE-QUOTE}}}std_func_total_daily_dose_cat{{{SINGLE-QUOTE}}} ;
|
|
calculate_BSA:= MLM {{{SINGLE-QUOTE}}}sys_calc_BSA{{{SINGLE-QUOTE}}};
|
|
/* Declare function for adding commas into numbers */
|
|
add_commas := MLM {{{SINGLE-QUOTE}}}SYS_FORMAT_NUMBER{{{SINGLE-QUOTE}}};
|
|
|
|
/**************************************************************************************/
|
|
/* Check Client location immediately if if client in "no alert" location, if so, exit */
|
|
/**************************************************************************************/
|
|
if alert_limited_locations
|
|
then
|
|
|
|
/* Get the patient{{{SINGLE-QUOTE}}}s current location, assigned or temporary */
|
|
if called_by_editor then
|
|
patient_loc_guid:= read last
|
|
{ClientVisit: BusinessRuleLocationGUID };
|
|
else
|
|
patient_loc_guid:= read last
|
|
{ClientVisit: BusinessRuleLocationGUID};
|
|
|
|
endif; /* if called by editor */
|
|
|
|
|
|
/* Get the Code for the GUID */
|
|
patient_loc_code:= read last
|
|
{"SELECT Code "
|
|
|| " FROM CV3Location "
|
|
|| " WHERE GUID = "|| SQL (patient_loc_guid)
|
|
, PrimaryTime = TouchedWhen };
|
|
endif; /* if alert_limited_locations */
|
|
|
|
if (patient_loc_code in no_alert_locations) AND alert_limited_locations
|
|
then
|
|
continue_processing := FALSE;
|
|
else
|
|
|
|
/*******************************************************(****************/
|
|
/* Get current task occurrence data - use to get Dose Range Criteria */
|
|
/************************************************************************/
|
|
|
|
/* Get information from the Current Evoking OrderTaskOccurrence */
|
|
(occurrence_name,
|
|
occurrence_guid,
|
|
occurrence_client_guid,
|
|
occurrence_summary_line,
|
|
occurrence_dose,
|
|
occurrence_uom,
|
|
occurrence_route,
|
|
occurrence_status_code,
|
|
occurrence_catalog_item_task_guid,
|
|
occurrence_order_guid,
|
|
occurrence_significant_dtm,
|
|
occurrence_performed_from_dtm,
|
|
order_obj,
|
|
order_task_obj,
|
|
back_up_obj ) := read last
|
|
{OrderTaskOccurrence: TaskName, GUID, ClientGUID, SummaryLine,
|
|
TaskDose, TaskUOM, TaskRouteCode, TaskStatusCode,
|
|
CatalogItemTaskGUID, OrderGUID, SignificantDtm,
|
|
PerformedFromDtm, Order, OrderTask, Backup
|
|
REFERENCING EvokingObject};
|
|
|
|
|
|
/* Get the reference to the current order{{{SINGLE-QUOTE}}}s Dosage Information */
|
|
(order_name,
|
|
order_med_uom,
|
|
order_med_route,
|
|
order_med_frequency,
|
|
order_med_significant_date,
|
|
chart_guid,
|
|
order_guid,
|
|
order_catalog_item_obj,
|
|
order_component_obj,
|
|
order_CMI_GUID,
|
|
order_GUID ) := read last
|
|
{ Order: Name, UOM, OrderRouteCode,
|
|
FrequencyCode, SignificantDtm, ChartGUID, GUID,
|
|
OrderCatalogMasterItem, OrderComponent,
|
|
OrderCatalogMasterItemGUID, GUID
|
|
REFERENCING order_obj};
|
|
|
|
/* Get the reference to the CatalogItemDosage object */
|
|
ordercatalog_item_dosage_obj:= read last
|
|
{OrderCatalogMasterItem: CatalogItemDosage REFERENCING order_catalog_item_obj };
|
|
|
|
/* Get the dosage range HIGH info from the item-catalog. */
|
|
/* Match to the order route and one of the Total Daily Dose Criteria Type Codes. */
|
|
(total_daily_range_high_codes,
|
|
total_daily_range_units,
|
|
total_daily_range_units_per,
|
|
total_daily_criteria_lows,
|
|
total_daily_criteria_highs,
|
|
total_daily_criteria_units,
|
|
total_daily_gender_code):= read { CatalogItemDosage:
|
|
RangeHigh,
|
|
RangeUom,
|
|
RangePerUom,
|
|
CriteriaTypeLow,
|
|
CriteriaTypeHigh,
|
|
CriteriaTypeUom,
|
|
GenderCode
|
|
REFERENCING ordercatalog_item_dosage_obj
|
|
WHERE RouteCode = order_med_route
|
|
AND CriteriaTypeCode is in (age_total_daily_dose_string,
|
|
BSA_total_daily_dose_string, weight_total_daily_dose_string ) };
|
|
|
|
/* Only retrieve other data if the medication has a Total Daily Dosage range */
|
|
If exist(total_daily_range_high_codes) and any (total_daily_range_high_codes > 0)
|
|
then
|
|
|
|
/* Get the patient{{{SINGLE-QUOTE}}}s birthday and other relevant data */
|
|
(client_guid,
|
|
client_birthdate,
|
|
client_birthMonthNum,
|
|
client_gender,
|
|
client_gender_internal,
|
|
client_info_obj ) := read last
|
|
{ ClientInfo: GUID, BirthDateTime, BirthMonthNum, GenderCode,
|
|
GenderTypeIntlCode, this, };
|
|
|
|
If NOT exists client_birthdate
|
|
then
|
|
missing_age:= TRUE;
|
|
missing_data_msg := missing_data_msg ||"\nPatient{{{SINGLE-QUOTE}}}s age must be entered "
|
|
||"to check Dose Range Limits. ";
|
|
endif;
|
|
|
|
/****************************************************/
|
|
/* Get Site Preferences for height, weight and BSA */
|
|
/****************************************************/
|
|
|
|
/* Get the BSA calculation preference */
|
|
/* This SQL statement will cause a table scan */
|
|
/* But the table only has 400 rows, so the impact is minimal */
|
|
BSA_formula_preference:= read last
|
|
{"SELECT Value "
|
|
|| " FROM HVCEnvProfile "
|
|
|| " WHERE Code = {{{SINGLE-QUOTE}}}BSAFormula{{{SINGLE-QUOTE}}} "
|
|
|| " AND HierarchyCode = {{{SINGLE-QUOTE}}}Client Info{{{SINGLE-QUOTE}}} " };
|
|
|
|
/* Retrieve the facility{{{SINGLE-QUOTE}}}s scope pref for HEIGHT */
|
|
general_scope_for_ht := read last
|
|
{"SELECT case when ScopeLevel = 3 then 1 else 0 end "
|
|
|| " FROM CV3PhysicalNoteType "
|
|
|| " WHERE Code = " || SQL("HEIGHT")};
|
|
|
|
/* Set the scope to retrieve the Height */
|
|
if general_scope_for_ht = 1
|
|
then ht_patient_chart_str:= "";
|
|
else ht_patient_chart_str:= " AND ChartGUID = " || SQL(chart_guid);
|
|
endif;
|
|
|
|
/* Retrieve the facility{{{SINGLE-QUOTE}}}s scope preference for WEIGHT */
|
|
general_scope_for_wt := read last
|
|
{"SELECT case when ScopeLevel = 3 then 1 else 0 end "
|
|
|| " FROM CV3PhysicalNoteType "
|
|
|| " WHERE Code = " || SQL("WEIGHT")};
|
|
|
|
/* Set the scope to retrieve the Weight */
|
|
if general_scope_for_wt = 1
|
|
then wt_patient_chart_str:= "";
|
|
else wt_patient_chart_str:= " AND ChartGUID = " || SQL(chart_guid);
|
|
endif;
|
|
|
|
/****************************************************/
|
|
/* Retrieve height and weight from the database */
|
|
/****************************************************/
|
|
|
|
/* Retrieve Height*/
|
|
/* Warning--keep this SQL in synch with business rules on patient height */
|
|
(ht_cm_str,
|
|
ht_date) := read last
|
|
{"SELECT Text, TouchedWhen "
|
|
|| " FROM CV3PhysicalNoteDeclaration"
|
|
|| " WHERE ClientGUID = " || SQL(client_guid)
|
|
|| ht_patient_chart_str
|
|
|| " AND Active = 1 "
|
|
|| " AND TypeCode = " || SQL("HEIGHT")
|
|
|| " AND Status = " || SQL("Active")
|
|
, PrimaryTime = TouchedWhen };
|
|
|
|
/* Convert height strings to numbers */
|
|
ht_cm:= ht_cm_str as number;
|
|
|
|
|
|
/* Retrieve patient{{{SINGLE-QUOTE}}}s actual current weight (expected in grams) */
|
|
/* Warning--keep this SQL in synch with
|
|
business rules on patient weight */
|
|
(wt_gm_str,
|
|
wt_date) := read last
|
|
{"SELECT Text, TouchedWhen "
|
|
|| " FROM CV3PhysicalNoteDeclaration"
|
|
|| " WHERE ClientGUID = "
|
|
|| SQL(client_guid)
|
|
|| wt_patient_chart_str
|
|
|| " AND Active = 1 "
|
|
|| " AND TypeCode = " || SQL("WEIGHT")
|
|
|| " AND Status = " || SQL("Active")
|
|
, PrimaryTime = TouchedWhen };
|
|
|
|
/* Convert weight string to number and convert grams to kilograms */
|
|
wt_kg := (wt_gm_str as number)/1000;
|
|
|
|
/*------------------------*/
|
|
/* CHECK FOR MISSING DATA */
|
|
/*------------------------*/
|
|
|
|
/* Check to see if height is present */
|
|
if ht_cm is number
|
|
and ht_cm > 0
|
|
then
|
|
missing_height := FALSE;
|
|
else
|
|
missing_height:= TRUE;
|
|
missing_data_msg := missing_data_msg || "\nPatient{{{SINGLE-QUOTE}}}s height must be "
|
|
||"entered to check Dose Range Limits. ";
|
|
endif;
|
|
|
|
/* Check to see if weight is present */
|
|
if wt_kg is number
|
|
and wt_kg > 0
|
|
then
|
|
missing_weight := FALSE;
|
|
else
|
|
missing_weight := TRUE;
|
|
missing_data_msg := missing_data_msg ||"\nPatient{{{SINGLE-QUOTE}}}s weight must be "
|
|
||"entered to check Dose Range Limits. ";
|
|
endif;
|
|
|
|
/* Check to see if gender is required for any dose critiera */
|
|
if any(total_daily_gender_code) <> NULL
|
|
then
|
|
if not exist client_gender
|
|
then
|
|
missing_gender := TRUE;
|
|
missing_data_msg := missing_data_msg ||"\nPatient{{{SINGLE-QUOTE}}}s gender must be "
|
|
||"entered to check Dose Range Limits. ";
|
|
endif;
|
|
endif; /* Check to see if gender is required */
|
|
|
|
/* No point in continuing if critial data is missing */
|
|
If missing_height and missing_weight and missing_age
|
|
then
|
|
missing_data_error := TRUE;
|
|
endif; /* If missing ht,wt, and age */
|
|
|
|
|
|
/*-------------------*/
|
|
/* Calculate the BSA */
|
|
/*-------------------*/
|
|
|
|
If NOT missing_height and NOT missing_weight
|
|
then
|
|
BSA_number_rounded:= Call calculate_BSA with
|
|
BSA_formula_preference,
|
|
ht_cm,
|
|
wt_kg,
|
|
client_info_obj;
|
|
endif; /* If NOT missing height or weight */
|
|
|
|
|
|
/* Get the Units of Measure info */
|
|
(uom_facility_code,
|
|
uom_sys_code):= read
|
|
{"SELECT Code, CoreUOM "
|
|
|| " FROM CV3UnitOfMeasure"
|
|
|| " WHERE Active = 1" };
|
|
|
|
|
|
|
|
/****************************************************************/
|
|
/* Get the first Total Daily range that applies to this patient */
|
|
/****************************************************************/
|
|
|
|
// This paramenter can be blank and return Total Daily criteria.
|
|
order_med_per_uom := "";
|
|
|
|
(found_total_daily_dose,
|
|
total_daily_dose_calc_method,
|
|
total_daily_lower_dose,
|
|
total_daily_upper_dose,
|
|
total_daily_units,
|
|
total_daily_per_uom,
|
|
total_daily_type_name ):= call find_daily_dose_range with
|
|
(age_total_daily_dose_string,
|
|
client_birthdate,
|
|
client_birthmonthnum,
|
|
BSA_number_rounded,
|
|
BSA_total_daily_dose_string,
|
|
order_catalog_item_obj,
|
|
day_string,
|
|
order_name,
|
|
gm_string,
|
|
kg_string,
|
|
lb_string,
|
|
m2_string,
|
|
month_string,
|
|
order_med_per_uom,
|
|
order_med_route,
|
|
order_med_significant_date,
|
|
order_med_uom,
|
|
ounce_string,
|
|
client_gender_internal,
|
|
uom_facility_code,
|
|
uom_sys_code,
|
|
week_string,
|
|
weight_total_daily_dose_string,
|
|
wt_kg,
|
|
year_string);
|
|
|
|
|
|
if found_total_daily_dose
|
|
then
|
|
// check if the order uom mataches the order task occurence uom
|
|
mismatched_med_uom_found := (order_med_uom <> occurrence_uom);
|
|
|
|
/********************************************************************/
|
|
/* Obtain the past administerations based on matching OrderGUID */
|
|
/********************************************************************/
|
|
|
|
/* Set interval to look back for administered doses */
|
|
past_start_time := occurrence_performed_from_dtm - 24 hours;
|
|
|
|
/* Get a list of past 24 hours administrations of this med */
|
|
(past_occurrences_dose_list,
|
|
past_occurrences_UOM_list,
|
|
past_occurrences_route_list,
|
|
past_occurrences_name_list,
|
|
past_occurrences_PerformedDtm_list,
|
|
past_occurrences_OrderGUID_list,
|
|
past_occurrences_order_RxStatusType ):= Read
|
|
{" SELECT oto.TaskDose, "
|
|
|| " oto.TaskUom, "
|
|
|| " oto.TaskRouteCode, "
|
|
|| " oto.TaskName, "
|
|
|| " ConvPerformedFromDtm.TimeValue as PerformedFromDtmOffset, "
|
|
|| " oto.OrderGUID, "
|
|
|| " me.RxStatusType "
|
|
|| " FROM CV3OrderTaskOccurrence oto JOIN CV3MedicationExtension me ON"
|
|
|| " oto.OrderGUID = me.GUID"
|
|
|| " JOIN CV3Order o ON"
|
|
|| " o.ClientGUID = oto.ClientGUID AND o.GUID = oto.OrderGUID"
|
|
|| " JOIN CV3ClientVisit cv ON"
|
|
|| " o.ClientGUID = cv.ClientGUID AND o.ClientVisitGUID = cv.GUID"
|
|
|| " CROSS APPLY dbo.SXADBConvertLocalToOffsetTblFn(cv.TimeZone, oto.PerformedFromDtm) AS ConvPerformedFromDtm "
|
|
|| " WHERE oto.ClientGUID = "
|
|
|| SQL(occurrence_client_guid)
|
|
|| " AND oto.CatalogItemTaskGUID = "
|
|
|| SQL(occurrence_catalog_item_task_guid)
|
|
|| " AND oto.PerformedFromDtm >= "
|
|
|| SQL(past_start_time)
|
|
|| " AND oto.PerformedFromDtm < "
|
|
|| SQL(occurrence_performed_from_dtm)
|
|
|| " order by oto.PerformedFromDtm"};
|
|
|
|
/************************************************************************/
|
|
/* Step through the list to add each to the total or to error message. */
|
|
/************************************************************************/
|
|
|
|
If exist past_occurrences_dose_list
|
|
then
|
|
first_dose_given := FALSE;
|
|
|
|
/* Check to see if all past orders were verified */
|
|
if ANY past_occurrences_order_RxStatusType <> 2
|
|
then
|
|
pharmacy_verified_all_past := FALSE;
|
|
endif; /* if any past type <>2 */
|
|
|
|
// step through the list and sum the past doses with matching uom
|
|
list_index := 1 seqto (count past_occurrences_dose_list);
|
|
for x in list_index do
|
|
temp_dose := first
|
|
(past_occurrences_dose_list where list_index = x);
|
|
temp_uom := first
|
|
(past_occurrences_uom_list where list_index = x);
|
|
temp_route := first
|
|
(past_occurrences_route_list where list_index = x);
|
|
temp_name := first
|
|
(past_occurrences_name_list where list_index = x);
|
|
temp_performed := first
|
|
(past_occurrences_PerformedDtm_list where list_index = x);
|
|
temp_order_GUID := first
|
|
(past_occurrences_OrderGUID_list where list_index = x);
|
|
|
|
|
|
if temp_order_GUID <> occurrence_order_guid
|
|
then
|
|
more_than_one_task_in_sum := TRUE;
|
|
endif;
|
|
|
|
|
|
if temp_uom = occurrence_uom
|
|
then
|
|
temp_dose := temp_dose as number;
|
|
past_administered_doses :=
|
|
past_administered_doses + temp_dose;
|
|
else
|
|
mismatched_occ_uom_found := TRUE;
|
|
temp_occurrence := "\n"||temp_name||" "
|
|
||temp_dose||" "||temp_uom||" "||temp_route
|
|
||" administered on " ||temp_performed;
|
|
mismatched_past_occurrences_msg :=
|
|
mismatched_past_occurrences_msg,temp_occurrence;
|
|
|
|
endif; /* if temp_uom = occurrence_uom */
|
|
|
|
enddo; // step through the list and sum
|
|
|
|
else
|
|
more_than_one_task_in_sum := FALSE;
|
|
first_dose_given := TRUE;
|
|
|
|
endif; /* If exist past_occurrences_dose_list */
|
|
|
|
/* For first dose or single order event, check for alert at order entry */
|
|
if first_dose_given and NOT more_than_one_task_in_sum
|
|
then
|
|
(alert_match_guid):= Read
|
|
{" SELECT CV3AlertDeclaration.GUID"
|
|
|| " FROM CV3AlertDeclaration "
|
|
|| " WHERE CV3AlertDeclaration.pObjectGUID = "
|
|
|| SQL(occurrence_order_guid)
|
|
|| " AND CV3AlertDeclaration.MLMName = {{{SINGLE-QUOTE}}}STD_DOSAGE{{{SINGLE-QUOTE}}}"
|
|
, PrimaryTime = SignificantDtm };
|
|
|
|
if exists alert_match_guid
|
|
then
|
|
alert_at_order := TRUE;
|
|
|
|
/* Check to see if phamacy verified this order */
|
|
(Rx_verify_type_2):= Read
|
|
{" SELECT CV3MedicationExtension.RxStatusType"
|
|
|| " FROM CV3MedicationExtension "
|
|
|| " WHERE CV3MedicationExtension.GUID = "
|
|
|| SQL(occurrence_order_guid)
|
|
|| " AND CV3MedicationExtension.RxStatusType = 2" };
|
|
|
|
|
|
if exists Rx_verify_type_2
|
|
then
|
|
pharmacy_verified_current := TRUE;
|
|
endif;
|
|
endif; /* if exists alert_match_guid */
|
|
|
|
endif; /* if first_dose */
|
|
|
|
|
|
|
|
/* Add the current dose being scanned to the past administered dose */
|
|
total_dose:= (occurrence_dose as number) + past_administered_doses;
|
|
|
|
/* Compose Alert Message now that the data has been obtained. */
|
|
If total_daily_type_name = "Age - Total Daily"
|
|
then
|
|
Alert_msg := "Based on this patient{{{SINGLE-QUOTE}}}s age, ";
|
|
elseIf total_daily_type_name = "Weight - Total Daily"
|
|
then
|
|
Alert_msg := "Based on this patient{{{SINGLE-QUOTE}}}s weight, ";
|
|
else
|
|
Alert_msg := "Based on this patient{{{SINGLE-QUOTE}}}s BSA, ";
|
|
endif; /* If total_daily_type_name */
|
|
|
|
/* Round to the nearest 0.001 */
|
|
total_daily_upper_dose_rounded:= ((((int((total_daily_upper_dose
|
|
+ 0.00051)*1000))/1000 )
|
|
formatted with "%.4f") AS NUMBER);
|
|
|
|
total_daily_upper_dose_rounded := call add_commas
|
|
with ( total_daily_upper_dose_rounded );
|
|
|
|
total_dose_rounded:= ((((int((total_dose
|
|
+ 0.00051)*1000))/1000)
|
|
formatted with "%.4f") AS NUMBER);
|
|
|
|
total_dose_rounded := call add_commas
|
|
with ( total_dose_rounded);
|
|
|
|
|
|
Alert_msg:= Alert_msg || "the Total Daily Dose"
|
|
|| " for a patient fitting this profile and route is: "
|
|
|| total_daily_upper_dose_rounded
|
|
|| " " || order_med_uom || "."
|
|
|| "\nWith this dose, in the past 24 hours this "
|
|
|| "patient will have received : "
|
|
|| "\n {{+B}}{{+C}}Dose Total{{-B}}{{-C}}(in 24 hours): {{+B}}{{+C}}"
|
|
|| total_dose_rounded
|
|
|| " " || occurrence_uom || " {{-B}}{{-C}}" ;
|
|
|
|
|
|
mismatched_occ_uom_msg := "\n{{+B}}The following tasks have a different "
|
|
|| "unit of measure. {{-B}}"
|
|
|| "\nTherefore, they have not been included in calculations. "
|
|
|| "Please manually verify if the current dosage will "
|
|
|| "exceed the Total Daily Dose Range limits."
|
|
|| mismatched_past_occurrences_msg;
|
|
|
|
|
|
If Alert_msg = "none"
|
|
then
|
|
Alert_msg := mismatched_occ_uom_msg;
|
|
|
|
endif; /*If Alert_msg := "none" */
|
|
|
|
If mismatched_med_uom_found
|
|
then
|
|
mismatched_med_uom_msg := "\n\n{{+B}}The administered dose for the current task has a different "
|
|
|| "unit of measure compared to the original medication{{{SINGLE-QUOTE}}}s unit of measure. {{-B}}\n"
|
|
|| "The current task dose unit of measure is {{+B}}{{+C}}" || occurrence_uom || "{{-B}}{{-C}}"
|
|
|| " whereas the medication was ordered in {{+B}}{{+C}}" || order_med_uom || "{{-B}}{{-C}}.\n\n"
|
|
|| "Please manually verify if the current dosage will "
|
|
|| "exceed the Total Daily Dose Range limits.";
|
|
|
|
Alert_msg := Alert_msg || mismatched_med_uom_msg;
|
|
endif;
|
|
|
|
If mismatched_occ_uom_found
|
|
then
|
|
Alert_msg := Alert_msg|| "\n"|| mismatched_occ_uom_msg;
|
|
endif; /* if mismatched_occ_uom_found */
|
|
else
|
|
if missing_height or missing_age or missing_weight or missing_gender
|
|
then
|
|
missing_data_error := TRUE;
|
|
endif;
|
|
endif; /* if found_total_daily_dose ... */
|
|
|
|
else
|
|
// if NO Total Daily Dose criteria then stop processing
|
|
continue_processing:= false;
|
|
endif; /* If exist(total_daily_range_high_codes) */
|
|
|
|
endif; /* if patient_loc_code in no_alert_locations */
|
|
|
|
;;
|
|
|
|
evoke:
|
|
medication_scan;
|
|
;;
|
|
logic:
|
|
/* Stop Processing MLM when continue_processing was false. */
|
|
if NOT continue_processing
|
|
OR (alert_at_order
|
|
AND
|
|
((pharmacy_verified_current AND pharmacy_verified_all_past AND no_alert_if_RxVerified)
|
|
OR(pharmacy_verified_current AND NOT more_than_one_task_in_sum)))
|
|
then
|
|
conclude false;
|
|
endif;
|
|
|
|
If exists total_dose
|
|
AND exists total_daily_upper_dose
|
|
AND (total_dose > (total_daily_upper_dose as number))
|
|
AND order_med_uom = occurrence_uom
|
|
then
|
|
alert_detail_text := "{{+B}}{{+C}}{{+U}}"
|
|
|| "Total Daily Dose Exceeded for " || order_name
|
|
|| "{{-U}}{{-B}}{{-C}}\n\n" || Alert_msg;
|
|
conclude true;
|
|
|
|
elseif missing_data_error AND alert_if_patient_data_missing
|
|
then
|
|
err_msg := "{{+B}}There are dose range limits set for this drug. However, "
|
|
|| "Total Daily Dose Limits could not be checked due to "
|
|
|| "missing patient data:{{-B}} " || missing_data_msg;
|
|
conclude true;
|
|
|
|
elseif mismatched_med_uom_found
|
|
then
|
|
alert_detail_text := "{{+B}}{{+C}}{{+U}}"
|
|
|| "Total Daily Dose Checking Not Performed{{-U}}{{-B}}{{-C}}\n\n"
|
|
|| Alert_msg;
|
|
conclude true;
|
|
|
|
elseif mismatched_occ_uom_found
|
|
then
|
|
alert_detail_text := "{{+B}}{{+C}} {{+U}}"
|
|
|| "Total Daily Dose could not be determined{{-U}}{{-B}}{{-C}}\n\n"
|
|
|| Alert_msg;
|
|
conclude true;
|
|
|
|
else
|
|
conclude false;
|
|
endif;
|
|
|
|
;;
|
|
action:
|
|
/* Create an alert message */
|
|
If missing_data_error then
|
|
write err_msg
|
|
at dose_exceeded_alert;
|
|
else
|
|
write alert_detail_text
|
|
at dose_exceeded_alert;
|
|
endif;
|
|
|
|
;;
|
|
Urgency: 60;;
|
|
end:
|