1453 lines
61 KiB
Plaintext
1453 lines
61 KiB
Plaintext
maintenance:
|
|
|
|
title: Calculate Dosage Based on Actual, Ideal or Adjusted Weight or BSA or AUC;;
|
|
mlmname: SYS_CALC_DOSAGE;;
|
|
arden: version 2.5;;
|
|
version: 18.4;;
|
|
institution: Allscripts, System 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: Calculates medication per dose based on a Dose Basis. Dose Basis can be Actual,
|
|
Ideal or Adjusted weight in Kg or Actual, Ideal or Adjusted BSA. In addition,
|
|
the Dose Basis list has expanded to include the Area Under the Curve (AUC) using
|
|
measured or Estimated Creatinine Clearance (EstCrCl). EstCrCl can be computed
|
|
with Jelliffe or Cockcroft-Gault formulas, or a measured value can be entered by
|
|
the user.
|
|
|
|
This MLM calculates one of the following combinations:
|
|
|
|
- Ordered amounts per DOSE (and optionally Total Daily Dose)
|
|
from Requested amount per Dose Basis per DOSE
|
|
- Ordered amount per DOSE (and optionally Total Daily Dose)
|
|
from Requested amount per Dose Basis per DAY
|
|
|
|
- Actual amount per DOSE per Dose Basis (and optionally Total Daily Dose)
|
|
from Ordered amount per DOSE
|
|
- Actual amount per DAY per Dose Basis (and optionally Total Daily Dose)
|
|
from Ordered amount per DOSE
|
|
|
|
;;
|
|
explanation:
|
|
This MLM is called from C++ code which passes in:
|
|
- ht_val - height from order form or height/weight dialog in kilograms (kg)
|
|
- wt_val - weight from order form or height/weight dialog in centimeters (cm)
|
|
- BSA_val - BSA calculated by SYS_CALC_BSA based on height, weight, and formula
|
|
- format_type - Either {{{SINGLE-QUOTE}}}Order{{{SINGLE-QUOTE}}} or {{{SINGLE-QUOTE}}}Additive{{{SINGLE-QUOTE}}}, used to prepare text for the
|
|
CalcInfo field
|
|
- calc_type - Indicates what field should be calculated
|
|
- {{{SINGLE-QUOTE}}}Ordered{{{SINGLE-QUOTE}}} - tells MLM to use {{{SINGLE-QUOTE}}}requested_dose{{{SINGLE-QUOTE}}} to compute ordered
|
|
amount per DOSE from requested per DOSE
|
|
- {{{SINGLE-QUOTE}}}Actual{{{SINGLE-QUOTE}}} - tells MLM to use {{{SINGLE-QUOTE}}}dose{{{SINGLE-QUOTE}}} to compute actual amounts per DOSE from
|
|
ordered per DOSE
|
|
- {{{SINGLE-QUOTE}}}TotalOrdered - tells MLM to use {{{SINGLE-QUOTE}}}requested_dose{{{SINGLE-QUOTE}}} to compute ordered
|
|
amount per DOSE from requested per DAY
|
|
- {{{SINGLE-QUOTE}}}TotalActual - tells MLM to use {{{SINGLE-QUOTE}}}dose{{{SINGLE-QUOTE}}} to compute actual amounts per DAY from
|
|
ordered per DOSE
|
|
- calculating_total, - indicates if total daily dose should be calculated
|
|
- TRUE = calculate total after checking for Frequency
|
|
- FALSE = do not calculate total, Frequency can be NULL
|
|
- dose - Dose entered by user into {{{SINGLE-QUOTE}}}Ordered{{{SINGLE-QUOTE}}} or {{{SINGLE-QUOTE}}}Requested{{{SINGLE-QUOTE}}} field to be used
|
|
in Calculations
|
|
- route - used by dose rounding mlm
|
|
- frequency - Frequency entered by user to be used in calculations. Frequency is
|
|
required for daily totals and for computing the ordered and actual amounts
|
|
when the requested/ordered amount is entered in the daily dose dialog
|
|
- dose_uom - Unit of measure for medication
|
|
- dose_basis - Dose Basis as in per weight or BSA, or target AUC. Valid values include:
|
|
kg
|
|
kg (ideal)
|
|
kg (adjusted)
|
|
m2
|
|
m2 (ideal)
|
|
m2 (adjusted)
|
|
AUC (Cockcroft-Gault)
|
|
AUC (Cockcroft-Gault ideal)
|
|
AUC (Cockcroft-Gault adjusted)
|
|
AUC (Jelliffe)
|
|
AUC (Jelliffe ideal)
|
|
AUC (Jelliffe adjusted)
|
|
AUC (Jelliffe no BSA)
|
|
AUC (measured CrCl)
|
|
AUC (St. Jude{{{SINGLE-QUOTE}}}s Modified-Peds)
|
|
Flat Dose
|
|
|
|
- EstCrCl_equation_preference - from Creatinine Clearance control, or reset by mlm
|
|
- serum_creatinine - from Creatinine Clearance control or database
|
|
- creat_clearance - from Creatinine Clearance control or database, or computed by mlm
|
|
- is_actual_CrCl - state of "Actual" button on Creatinine Clearance control
|
|
- requested_dose - Original dose from {{{SINGLE-QUOTE}}}Requested{{{SINGLE-QUOTE}}} field is not used in
|
|
the Calculations but is used in the CalcInfo string sent back
|
|
- client_info_obj - Arden ClientInfo object
|
|
- order_obj - Arden Order Object
|
|
- weight_type - type of weight used in calculation: "Dry", "Pre-Dialysis" etc.
|
|
- dose_cap - the maximum dose allowed for the order.
|
|
From DoseCap field on the order form.
|
|
- previous_ordered_dose - the "Ordered Amount Per Dose" from the previous call to the MLM.
|
|
Is the {{{SINGLE-QUOTE}}}uncapped dose{{{SINGLE-QUOTE}}} when the DoseCap was exceeded.
|
|
See current_order_dose variable definition in the RETURN section below.
|
|
- override_flag - a flag indicating whether the Dose Calc UI is in the override state.
|
|
- override_reason - if the override reason is entered, the text is sent to the MLM.
|
|
|
|
|
|
and returns the following strings(note numbers cannot contain commas):
|
|
- error string - containing an error message, if there is one, NULL if no error
|
|
- new_dose - containing the ordered dose
|
|
- dose_string - containing text for CalcInfo field
|
|
- total_daily_dose - containing the daily dose total
|
|
- actual_dose - contains the actual dose either per dose or per day
|
|
- dose_basis_message - contains the message "based on BSA (ideal) of #.## m2"
|
|
or other appropriate message.
|
|
- current_ordered_dose - the {{{SINGLE-QUOTE}}}Ordered Amount Per Dose{{{SINGLE-QUOTE}}}.
|
|
If the dose was reset due to exceeding the DoseCap limit,
|
|
then the dose is the one BEFORE the reset.
|
|
This value to resent as the {{{SINGLE-QUOTE}}}previous_ordered_dose{{{SINGLE-QUOTE}}} argument in the
|
|
next call to the MLM.
|
|
|
|
;;
|
|
keywords: Dosage Calculation
|
|
;;
|
|
knowledge:
|
|
type: data-driven;;
|
|
data:
|
|
|
|
/* Arguments are passed in as STRINGS from the calling C++ or .NET program */
|
|
(ht_val,
|
|
wt_val,
|
|
BSA_val,
|
|
format_type,
|
|
calc_type,
|
|
calculating_total,
|
|
dose,
|
|
route,
|
|
frequency,
|
|
dose_uom,
|
|
dose_basis,
|
|
EstCrCl_equation_preference,
|
|
serum_creatinine,
|
|
creat_clearance,
|
|
is_actual_CrCl,
|
|
requested_dose,
|
|
client_info_obj,
|
|
order_obj,
|
|
weight_type,
|
|
dose_cap,
|
|
previous_ordered_dose,
|
|
override_flag,
|
|
override_reason
|
|
) := argument;
|
|
|
|
|
|
/*******************Make Changes To Spelling And Flags In This Section*******************/
|
|
|
|
/* Set to true if logging is needed.*/
|
|
log_execution_info := false;
|
|
|
|
/* AUC dose basis strings are used in Area Under Curve dose calculation */
|
|
AUC_cg_string := ("AUC (Cockcroft-Gault)", "AUC (Cockcroft-Gault ideal)",
|
|
"AUC (Cockcroft-Gault adjusted)");
|
|
AUC_jlf_string := ("AUC (Jelliffe)", "AUC (Jelliffe ideal)",
|
|
"AUC (Jelliffe adjusted)", "AUC (Jelliffe no BSA)");
|
|
AUC_mCrCl_string := ("AUC (measured CrCl)", "AUC (St. Jude{{{SINGLE-QUOTE}}}s Modified-Peds)");
|
|
measured_string := "AUC (measured CrCl)";
|
|
AUC_strings := (AUC_cg_string, AUC_jlf_string, AUC_mCrCl_string);
|
|
|
|
/* Used to check the dose basis string(xxx/kg or xxx/m2)from DoseCalcUOM field: */
|
|
/* KG means calculate using the weight, M2 means calculate using BSA. */
|
|
/* AUC means calculate using an Area Under the Curve formula involving weight or BSA. */
|
|
/* FLAT DOSE means do not calculate, return the same value the user entered. */
|
|
kg_string:= ("kg", "kg (ideal)","kg (adjusted)");
|
|
M2_string:= ("M2", "m2 (ideal)","m2 (adjusted)");
|
|
calc_wt_dose_basis_string:= ("kg (ideal)","kg (adjusted)","AUC (Cockcroft-Gault ideal)",
|
|
"AUC (Cockcroft-Gault adjusted)");
|
|
calc_BSA_dose_basis_string:= ("m2 (ideal)","m2 (adjusted)","AUC (Jelliffe ideal)",
|
|
"AUC (Jelliffe adjusted)", "AUC (St. Jude{{{SINGLE-QUOTE}}}s Modified-Peds)");
|
|
ideal_string := ("kg (ideal)","m2 (ideal)","AUC (Cockcroft-Gault ideal)",
|
|
"AUC (Jelliffe ideal)");
|
|
adjusted_string := ("kg (adjusted)","m2 (adjusted)", "AUC (Cockcroft-Gault adjusted)",
|
|
"AUC (Jelliffe adjusted)");
|
|
dose_basis_not_requiring_weight_string := ("Flat Dose", "AUC (measured CrCl)",
|
|
"AUC (St. Jude{{{SINGLE-QUOTE}}}s Modified-Peds)");
|
|
flat_dose_string := "Flat Dose";
|
|
|
|
/* Used in the freetext message */
|
|
spacing_string:= " ";
|
|
|
|
/* Error messages can be changed inside the quote marks. */
|
|
error_invalid_dose_basis :=
|
|
"Type of units in the {{{SINGLE-QUOTE}}}per{{{SINGLE-QUOTE}}} field cannot be used for dosage calculation. ";
|
|
|
|
error_not_KG:= "Type of units in the {{{SINGLE-QUOTE}}}per{{{SINGLE-QUOTE}}} field is not Kg. ";
|
|
|
|
error_missing_xxx_unit := "The units of measure (UOM) for the medication is missing "
|
|
|| "and is necessary to perform the calculation. ";
|
|
|
|
error_missing_dose_basis := "The dose basis in the {{{SINGLE-QUOTE}}}per{{{SINGLE-QUOTE}}} for the medication is missing "
|
|
|| "and is necessary to perform the calculation. ";
|
|
|
|
error_dose_calc:= "The dose amount must be entered to perform the calculation. ";
|
|
|
|
error_dose_calc_invalid:=
|
|
"Invalid entry in the dose field. Please enter a positive number. ";
|
|
|
|
error_req_dose_calc_empty :=
|
|
"The requested dose is empty, please provide the value.";
|
|
|
|
error_ordered_dose_calc_empty :=
|
|
"The ordered dose is empty, please provide the value.";
|
|
|
|
error_invalid_weight:= "Weight must be entered to perform the calculation. ";
|
|
|
|
error_invalid_height:= "Height must be entered to perform the calculation. ";
|
|
|
|
error_missing_frequency:= "Frequency must be entered to perform the calculation. ";
|
|
|
|
error_missing_lab_value := "Missing a Serum Creatinine or Creatinine Clearance "
|
|
|| "needed to determine AUC dose. ";
|
|
|
|
error_wrong_type_lab_value := "Actual or Measured CrCl is required to determine AUC dose. ";
|
|
|
|
error_ordered_dose_exceeds_four_decimals :=
|
|
"The {{{SINGLE-QUOTE}}}Ordered Amount Per Dose{{{SINGLE-QUOTE}}} cannot exceed four decimals. ";
|
|
|
|
/***************************************************************************************/
|
|
|
|
/* Declares a C function that prevents the display of a number in scientific notation */
|
|
convert_big_num := interface {char* msvcrt:_itoa(long, char*, long)};
|
|
|
|
/* MLM to get the ideal or adjusted weight. */
|
|
func_calc_weight := MLM {{{SINGLE-QUOTE}}}SYS_CALC_WT{{{SINGLE-QUOTE}}};
|
|
|
|
/* MLM to get the ideal or adjusted BSA. */
|
|
func_calc_BSA := MLM {{{SINGLE-QUOTE}}}SYS_CALC_BSA{{{SINGLE-QUOTE}}};
|
|
|
|
/* MLM to calculate the Area Under the Curve dose */
|
|
func_calc_AUC_coef := MLM {{{SINGLE-QUOTE}}}SYS_CALC_AUC_COEF{{{SINGLE-QUOTE}}};
|
|
|
|
/* MLM to get the number of occurrences in a day for the specified frequency. */
|
|
func_calc_frequency_multiplier := MLM {{{SINGLE-QUOTE}}}SYS_CALC_FREQMULT_DAILY{{{SINGLE-QUOTE}}};
|
|
|
|
/* MLM to apply consistent rounding rules to dosages. */
|
|
func_round_dosage := MLM {{{SINGLE-QUOTE}}}SYS_ROUND_DOSAGE{{{SINGLE-QUOTE}}};
|
|
|
|
/* Declare function MLM for adding commas into numbers */
|
|
add_commas := MLM {{{SINGLE-QUOTE}}}SYS_FORMAT_NUMBER{{{SINGLE-QUOTE}}};
|
|
|
|
;;
|
|
evoke:
|
|
;;
|
|
logic:
|
|
/*---------------------------------------------------------------*/
|
|
/* Saves the Values of the Arguments BEFORE any code resets them */
|
|
/*---------------------------------------------------------------*/
|
|
// Only saves values that are NOT objects.
|
|
ht_val_saved_arg := ht_val ;
|
|
wt_val_saved_arg := wt_val ;
|
|
BSA_val_saved_arg := BSA_val ;
|
|
format_type_saved_arg := format_type ;
|
|
calc_type_saved_arg := calc_type ;
|
|
calculating_total_saved_arg := calculating_total ;
|
|
dose_saved_arg := dose ;
|
|
route_saved_arg := route ;
|
|
frequency_saved_arg := frequency ;
|
|
dose_uom_saved_arg := dose_uom ;
|
|
dose_basis_saved_arg := dose_basis ;
|
|
EstCrCl_equation_preference_saved_arg := EstCrCl_equation_preference ;
|
|
serum_creatinine_saved_arg := serum_creatinine ;
|
|
creat_clearance_saved_arg := creat_clearance ;
|
|
is_actual_CrCl_saved_arg := is_actual_CrCl ;
|
|
requested_dose_saved_arg := requested_dose ;
|
|
weight_type_saved_arg := weight_type ;
|
|
dose_cap_saved_arg := dose_cap ;
|
|
previous_ordered_dose_saved_arg := previous_ordered_dose ;
|
|
override_flag_saved_arg := override_flag ;
|
|
override_reason_saved_arg := override_reason ;
|
|
|
|
|
|
|
|
/*--------------------------------------------------------------------*/
|
|
/* Avoid errors by converting an empty list to NULL before processing */
|
|
/*--------------------------------------------------------------------*/
|
|
if not exist ht_val and ht_val is list then ht_val := null; endif;
|
|
if not exist wt_val and wt_val is list then wt_val := null; endif;
|
|
if not exist BSA_val and BSA_val is list then BSA_val := null; endif;
|
|
if not exist format_type and format_type is list then format_type := null; endif;
|
|
if not exist calc_type and calc_type is list then calc_type := null; endif;
|
|
if not exist dose and dose is list then dose := null; endif;
|
|
if not exist route and route is list then route := null; endif;
|
|
if not exist frequency and frequency is list then frequency := null; endif;
|
|
if not exist dose_uom and dose_uom is list then dose_uom := null; endif;
|
|
if not exist dose_basis and dose_basis is list then dose_basis := null; endif;
|
|
if not exist EstCrCl_equation_preference and EstCrCl_equation_preference is list then
|
|
EstCrCl_equation_preference := null; endif;
|
|
if not exist serum_creatinine and serum_creatinine is list then
|
|
serum_creatinine := null; endif;
|
|
if not exist serum_creatinine_uom and serum_creatinine_uom is list then
|
|
serum_creatinine_uom := null; endif;
|
|
if not exist creat_clearance and creat_clearance is list then
|
|
creat_clearance := null; endif;
|
|
if not exist is_actual_CrCl and is_actual_CrCl is list then is_actual_CrCl := null; endif;
|
|
if not exist requested_dose and requested_dose is list then requested_dose := null; endif;
|
|
if not exist dose_cap and dose_cap is list then dose_cap := null; endif;
|
|
if not exist previous_ordered_dose and previous_ordered_dose is list
|
|
then previous_ordered_dose := null; endif;
|
|
if not exist override_flag and override_flag is list then override_flag := null; endif;
|
|
if not exist override_reason and override_reason is list then override_reason := null; endif;
|
|
|
|
/*-----------------------------------------------------------------------------*/
|
|
/* Avoid errors by converting an empty string or "0" to NULL before processing */
|
|
/*-----------------------------------------------------------------------------*/
|
|
if exist ht_val and (ht_val = "" or ht_val = "0") then ht_val := null; endif;
|
|
if exist wt_val and (wt_val = "" or wt_val = "0") then wt_val := null; endif;
|
|
if exist BSA_val and (BSA_val = "" or BSA_val = "0") then BSA_val := null; endif;
|
|
if exist format_type and format_type = "" then format_type := null; endif;
|
|
if exist calc_type and calc_type = "" then calc_type := null; endif;
|
|
if exist dose and (dose = "" or dose = "0") then dose := null; endif;
|
|
if exist route and route = "" then route := null; endif;
|
|
if exist frequency and frequency = "" then frequency := null; endif;
|
|
if exist dose_uom and dose_uom = "" then dose_uom := null; endif;
|
|
if exist dose_basis and dose_basis = "" then dose_basis := null; endif;
|
|
if exist EstCrCl_equation_preference and EstCrCl_equation_preference = "" then
|
|
EstCrCl_equation_preference := null; endif;
|
|
if exist serum_creatinine and (serum_creatinine = "" or serum_creatinine = "0")
|
|
then serum_creatinine := null; endif;
|
|
if exist serum_creatinine_uom and serum_creatinine_uom = "" then
|
|
serum_creatinine_uom := null; endif;
|
|
if exist creat_clearance and (creat_clearance = "" or creat_clearance = "0")
|
|
then creat_clearance := null; endif;
|
|
if exist requested_dose and requested_dose = "" then requested_dose := null; endif;
|
|
//Only convert "" to null for dose_cap. The "0" is a valid entry.
|
|
if exist dose_cap and dose_cap = "" then dose_cap := null; endif;
|
|
if exist previous_ordered_dose
|
|
and (previous_ordered_dose = "" or ((previous_ordered_dose AS Number) = 0))
|
|
then previous_ordered_dose := null; endif;
|
|
if exist override_flag and override_flag = "" then override_flag := null; endif;
|
|
if exist override_reason and override_reason = "" then override_reason := null; endif;
|
|
|
|
/*----------------------------------------------------------------*/
|
|
/* Convert a string representation of a number to an Arden number */
|
|
/*----------------------------------------------------------------*/
|
|
ht_val := ht_val as number;
|
|
wt_val := wt_val as number;
|
|
BSA_val := BSA_val as number;
|
|
dose := dose as number;
|
|
serum_creatinine := serum_creatinine as number;
|
|
creat_clearance := creat_clearance as number;
|
|
dose_cap := dose_cap as number;
|
|
previous_ordered_dose := previous_ordered_dose as number;
|
|
requested_dose := requested_dose as number;
|
|
|
|
/*----------------------------------------------*/
|
|
/* Copy data originally passed in as arguments */
|
|
/*----------------------------------------------*/
|
|
// The following data were passed as arguments to the MLM
|
|
// and then converted from a string to a number.
|
|
// The data can be changed by the MLM
|
|
// So their values are copied to another variable.
|
|
|
|
wt_val_original := wt_val; //Modified by AUC calcs
|
|
dose_original := dose; //Modified by Dose Cap calcs
|
|
|
|
|
|
/*----------------------*/
|
|
/* Initialize Variables */
|
|
/*----------------------*/
|
|
exceeded_dose_cap := false;
|
|
|
|
/*------------------*/
|
|
/* Check for Errors */
|
|
/*------------------*/
|
|
error_message:= "";
|
|
fatal_error:= false;
|
|
minor_error:= false;
|
|
|
|
/* DOSE PER UNITS UOM IS NOT KG or M2 or AUC or Flat Dose */
|
|
if dose_basis is not in (kg_string, M2_string, AUC_strings, flat_dose_string )
|
|
then error_message:= error_message || error_invalid_dose_basis;
|
|
fatal_error:= true;
|
|
endif;
|
|
|
|
/* MEDICATION UOM IS MISSING xxx (xxx/KG or xxx/M2) */
|
|
if not exist dose_uom
|
|
then error_message:= error_message || error_missing_xxx_unit ;
|
|
fatal_error:= true;
|
|
endif;
|
|
|
|
/* MEDICATION DOSE BASIS IS MISSING */
|
|
if not exist dose_basis
|
|
then error_message:= error_message || error_missing_dose_basis ;
|
|
fatal_error:= true;
|
|
endif;
|
|
|
|
/* DOSE IS REQUIRED and MUST BE GREATER THAN ZERO*/
|
|
if dose is not number
|
|
then
|
|
if calc_type is in ( "Actual", "TotalActual" )
|
|
then error_message:= error_message || error_ordered_dose_calc_empty;
|
|
else
|
|
error_message:= error_message || error_req_dose_calc_empty;
|
|
endif;
|
|
fatal_error:= true;
|
|
elseif dose < 0
|
|
then error_message:= error_message || error_dose_calc_invalid;
|
|
fatal_error:= true;
|
|
endif;
|
|
|
|
if dose = 0
|
|
then error_message:= error_message || error_dose_calc;
|
|
fatal_error:= true;
|
|
endif;
|
|
|
|
/* WEIGHT IS REQUIRED - except when using ideal weights or flat dose */
|
|
if (wt_val is not number OR wt_val <= 0)
|
|
AND dose_basis is not in ideal_string
|
|
AND dose_basis is not in measured_string
|
|
AND dose_basis <> flat_dose_string
|
|
then error_message:= error_message || error_invalid_weight;
|
|
fatal_error:= true;
|
|
endif;
|
|
|
|
/* HEIGHT IS REQUIRED--when BSA dosing is requested with M2 uom or when using ideal weights */
|
|
if (dose_basis is in M2_string OR dose_basis is in ideal_string
|
|
OR dose_basis is in adjusted_string)
|
|
and (ht_val is not number OR ht_val <=0 )
|
|
then error_message:= error_message || error_invalid_height;
|
|
fatal_error:= true;
|
|
endif;
|
|
|
|
/* FREQUENCY IS REQUIRED--when calculating total daily or ordered from requested daily*/
|
|
if (calculating_total = "TRUE"
|
|
OR calc_type = "TotalOrdered" OR calc_type = "TotalActual")
|
|
AND not exist frequency
|
|
then
|
|
error_message:= error_message || error_missing_frequency;
|
|
fatal_error:= true;
|
|
endif;
|
|
|
|
/* LAB VALUE IS REQUIRED - Serum Creatinine or Creatinine Clearance */
|
|
/* must exist for AUC dose calcs */
|
|
if dose_basis is in AUC_strings
|
|
then
|
|
if (((not exist serum_creatinine) or (serum_creatinine <= 0))
|
|
and ((not exist creat_clearance) or (creat_clearance <= 0)))
|
|
then
|
|
error_message := error_message || error_missing_lab_value;
|
|
fatal_error:= true;
|
|
elseif (dose_basis is in AUC_mCrCl_string) and (is_Actual_CrCl = false)
|
|
then
|
|
error_message := error_message || error_wrong_type_lab_value;
|
|
fatal_error:= true;
|
|
endif;
|
|
endif;
|
|
|
|
/* {{{SINGLE-QUOTE}}}ORDERED AMOUNT PER DOSE{{{SINGLE-QUOTE}}} EXCEEDED FOUR DECIMALS-- when user enters the value in this field */
|
|
if calc_type is in ("Actual", "TotalActual")
|
|
and dose is number
|
|
then
|
|
// Format the dose to eliminate Scientific Notation
|
|
result := dose formatted with "%.10f";
|
|
|
|
// Extract the digits and characters into a list
|
|
chars := extract characters result;
|
|
|
|
// Loop through chars, and determine if there are trailing zeros
|
|
trailing_pos := 0;
|
|
found_trailing := false;
|
|
found_decimal := false;
|
|
pos := 0;
|
|
|
|
for ch in chars do
|
|
if (ch = ".") then
|
|
found_decimal := true;
|
|
found_trailing := true;
|
|
trailing_pos := pos;
|
|
elseif (ch = "0") and (found_decimal = true) and (found_trailing = false) then
|
|
found_trailing := true;
|
|
trailing_pos := pos;
|
|
elseif (ch <> "0") and (found_trailing = true) then
|
|
found_trailing := false;
|
|
endif;
|
|
pos := pos + 1;
|
|
enddo; //for ch
|
|
|
|
// Remove the Trailing Zeros in the decimals
|
|
if found_trailing then
|
|
result := string (first trailing_pos from chars);
|
|
endif;
|
|
|
|
//Count the number of decimals by looping through the characters
|
|
number_of_decimals := 0;
|
|
located_decimal := false;
|
|
character_list := extract characters result;
|
|
|
|
for CCC in character_list do
|
|
if (CCC = ".") then
|
|
located_decimal := true;
|
|
elseif located_decimal then
|
|
number_of_decimals := number_of_decimals + 1;
|
|
endif;
|
|
enddo; //for CCC
|
|
|
|
// Generate error if more than 4 decimals
|
|
if located_decimal
|
|
and number_of_decimals > 4
|
|
then
|
|
error_message:= error_message || error_ordered_dose_exceeds_four_decimals;
|
|
fatal_error:= true;
|
|
endif;
|
|
endif; //if calc_type is in ("Actual", "TotalActual")
|
|
|
|
|
|
/* Only calculate dosage when there is no error */
|
|
if NOT fatal_error
|
|
then
|
|
|
|
/*-----------------------------------------------------------*/
|
|
/* Calculate Weight to use when Ideal or Adjusted weight */
|
|
/* is needed and formulate the dose basis message */
|
|
/*-----------------------------------------------------------*/
|
|
if dose_basis is in calc_wt_dose_basis_string
|
|
and exist ht_val
|
|
and ht_val > 0
|
|
then
|
|
if dose_basis = "kg (ideal)" OR dose_basis = "AUC (Cockcroft-Gault ideal)"
|
|
then
|
|
(wt_val, Tooltip_formula, display_message) := call func_calc_weight
|
|
with "Ideal", ht_val, wt_val, client_info_obj;
|
|
|
|
if exist wt_val and wt_val > 0
|
|
then
|
|
dose_basis_message := "based on kg (ideal) of "|| wt_val;
|
|
else
|
|
error_message := "Dosage cannot be calculated with kg (ideal) "
|
|
|| "unless Ideal weight has been calculated.";
|
|
fatal_error := TRUE;
|
|
endif; // if exist wt_val and wt_val > 0
|
|
|
|
elseif dose_basis = "kg (adjusted)" OR dose_basis = "AUC (Cockcroft-Gault adjusted)"
|
|
and exist wt_val
|
|
and wt_val > 0
|
|
then
|
|
(wt_val, Tooltip_formula, display_message) := call func_calc_weight
|
|
with "Adjusted", ht_val, wt_val, client_info_obj;
|
|
|
|
if exist wt_val and wt_val > 0
|
|
then
|
|
dose_basis_message := "based on kg (adjusted) of "|| wt_val;
|
|
else
|
|
error_message := "Dosage cannot be calculated with kg (adjusted) "
|
|
|| "unless Adjusted weight has been calculated.";
|
|
fatal_error := TRUE;
|
|
endif; // if exist wt_val and wt_val > 0
|
|
endif; // if dose_basis is kg (ideal) or kg (adjusted)
|
|
|
|
/*-----------------------------------------------------------*/
|
|
/* Calculate BSA to use when Ideal or Adjusted BSA */
|
|
/* is needed and formulate the dose basis message */
|
|
/*-----------------------------------------------------------*/
|
|
elseif dose_basis is in calc_BSA_dose_basis_string
|
|
and exist ht_val
|
|
and ht_val > 0
|
|
then
|
|
if dose_basis = "m2 (ideal)" OR dose_basis = "AUC (Jelliffe ideal)"
|
|
then
|
|
(BSA_val, BSA_formula, wt_used) := call func_calc_BSA
|
|
with "Ideal", ht_val, wt_val, client_info_obj;
|
|
|
|
if exist BSA_val and BSA_val > 0
|
|
then
|
|
dose_basis_message := "based on BSA (ideal) of "|| BSA_val ||" m2";
|
|
else
|
|
error_message := "Dosage cannot be calculated with m2 (ideal) "
|
|
|| "unless Ideal weight has been calculated.";
|
|
fatal_error := TRUE;
|
|
endif; // if exist BSA_val and BSA_val > 0
|
|
|
|
elseif dose_basis = "m2 (adjusted)" OR dose_basis = "AUC (Jelliffe adjusted)"
|
|
and exist wt_val
|
|
and wt_val > 0
|
|
then
|
|
(BSA_val, BSA_formula, wt_used) := call func_calc_BSA
|
|
with "Adjusted", ht_val, wt_val, client_info_obj;
|
|
|
|
if exist BSA_val and BSA_val > 0
|
|
then
|
|
dose_basis_message := "based on BSA (adjusted) of "|| BSA_val ||" m2";
|
|
else
|
|
error_message := "Dosage cannot be calculated with m2 (adjusted) "
|
|
|| "unless Adjusted weight has been calculated.";
|
|
fatal_error := TRUE;
|
|
endif; // if exist BSA_val and BSA_val > 0
|
|
|
|
endif; // dose_basis is BSA ideal or adjusted
|
|
|
|
elseif dose_basis = flat_dose_string
|
|
then
|
|
dose_basis_message := "based on Flat Dose";
|
|
else
|
|
dose_basis_message := "based on actual measurements";
|
|
|
|
endif; //if dose_basis in calc_wt_dose_basis_string
|
|
|
|
/*--------------------------------------------------*/
|
|
/* Add weight type to dose basis message, if needed */
|
|
/*--------------------------------------------------*/
|
|
|
|
if wt_val > 0
|
|
AND dose_basis is not in ideal_string
|
|
AND dose_basis is not in measured_string
|
|
AND dose_basis <> flat_dose_string
|
|
AND (weight_type <> "Weight")
|
|
then
|
|
dose_basis_message := dose_basis_message || " using weight of type "
|
|
|| weight_type || ". ";
|
|
endif;
|
|
|
|
/*-----------------------------------------*/
|
|
/* Calculate Multiple to use for Frequency */
|
|
/*-----------------------------------------*/
|
|
if exist frequency
|
|
then
|
|
daily_dose_multiplier := call func_calc_frequency_multiplier with (frequency);
|
|
endif;
|
|
|
|
/*-----------------------------------------*/
|
|
/* Determine if Dose Cap should be checked */
|
|
/*-----------------------------------------*/
|
|
|
|
//Rule 1-- General Rule of Thumb
|
|
if exist dose_cap
|
|
and format_type = "Order"
|
|
then
|
|
check_dose_cap := true;
|
|
else
|
|
check_dose_cap := false;
|
|
endif;
|
|
|
|
//Rule 2 -- Override Exception
|
|
if override_flag
|
|
and format_type = "Order"
|
|
and calc_type is in ( "Actual", "TotalActual" )
|
|
and exist dose_cap
|
|
and previous_ordered_dose > dose_cap
|
|
then
|
|
check_dose_cap := false;
|
|
endif;
|
|
|
|
|
|
/*-------------------------------------*/
|
|
/* Calculate dose for AUC dose basis */
|
|
/*-------------------------------------*/
|
|
if dose_basis is in AUC_strings
|
|
and ((exist serum_creatinine and serum_creatinine > 0 )
|
|
or (exist creat_clearance and creat_clearance > 0 ))
|
|
then
|
|
(AUC_calc_error_message,
|
|
AUC_coef, AUC_dose_calc_formula) := call func_calc_AUC_coef
|
|
with ht_val, wt_val_original, BSA_val, dose, dose_basis,
|
|
serum_creatinine, creat_clearance, is_actual_CrCl,
|
|
client_info_obj;
|
|
|
|
if not (exist AUC_coef and AUC_coef > 0) // only continue if no error
|
|
then
|
|
error_message := AUC_calc_error_message;
|
|
fatal_error := true;
|
|
|
|
else
|
|
if calc_type = "Ordered"
|
|
then
|
|
temp_dose := AUC_coef * dose;
|
|
actual_dose := dose;
|
|
|
|
(rounding_error_message,
|
|
new_dose):= call func_round_dosage with
|
|
(temp_dose, route );
|
|
if new_dose is null
|
|
then
|
|
error_message := rounding_error_message;
|
|
fatal_error := true;
|
|
elseif (new_dose is not null) and (rounding_error_message is not null)
|
|
then
|
|
error_message := rounding_error_message;
|
|
minor_error := true;
|
|
else
|
|
current_ordered_dose := new_dose ;
|
|
if check_dose_cap
|
|
and new_dose > dose_cap
|
|
then
|
|
exceeded_dose_cap := true;
|
|
new_dose := dose_cap;
|
|
dose := dose_cap/AUC_coef;
|
|
actual_dose := dose_cap/AUC_coef;
|
|
endif; // check dose_cap
|
|
endif; // new_dose is null
|
|
|
|
elseif calc_type = "Actual"
|
|
then
|
|
current_ordered_dose := dose ;
|
|
if check_dose_cap
|
|
and dose > dose_cap
|
|
then
|
|
exceeded_dose_cap := true;
|
|
new_dose := dose_cap;
|
|
dose := dose_cap;
|
|
actual_dose := dose_cap / AUC_coef;
|
|
else
|
|
actual_dose := dose / AUC_coef;
|
|
endif; // check dose_cap
|
|
|
|
elseif calc_type = "TotalOrdered" and exist daily_dose_multiplier
|
|
then
|
|
temp_dose:= (dose * AUC_coef)/daily_dose_multiplier;
|
|
actual_dose := dose;
|
|
|
|
(rounding_error_message,
|
|
new_dose):= call func_round_dosage with
|
|
(temp_dose, route );
|
|
if new_dose is null
|
|
then
|
|
error_message := rounding_error_message;
|
|
fatal_error := true;
|
|
elseif (new_dose is not null) and (rounding_error_message is not null)
|
|
then
|
|
error_message := rounding_error_message;
|
|
minor_error := true;
|
|
else
|
|
current_ordered_dose := new_dose ;
|
|
if check_dose_cap
|
|
and new_dose > dose_cap
|
|
then
|
|
exceeded_dose_cap := true;
|
|
new_dose := dose_cap;
|
|
dose := (dose_cap * daily_dose_multiplier)/ AUC_coef;
|
|
actual_dose := (dose_cap * daily_dose_multiplier)/ AUC_coef;
|
|
endif; // check dose_cap
|
|
endif; // new_dose is null
|
|
|
|
elseif calc_type = "TotalActual" and exist daily_dose_multiplier
|
|
then
|
|
current_ordered_dose := dose ;
|
|
if check_dose_cap
|
|
and dose > dose_cap
|
|
then
|
|
exceeded_dose_cap := true;
|
|
new_dose := dose_cap;
|
|
dose := dose_cap;
|
|
actual_single_dose := dose_cap / AUC_coef;
|
|
else
|
|
actual_single_dose := dose / AUC_coef;
|
|
endif; // check dose_cap
|
|
|
|
actual_dose := actual_single_dose * daily_dose_multiplier;
|
|
|
|
endif; //if calc_type
|
|
endif; // exist AUC_coef
|
|
endif; // dose_basis is in AUC_strings
|
|
|
|
/*-----------------------*/
|
|
/* Calculate Dose by BSA */
|
|
/*-----------------------*/
|
|
if dose_basis is in M2_string
|
|
and exist dose_uom
|
|
and exist BSA_val
|
|
and BSA_val > 0
|
|
and dose > 0
|
|
then
|
|
if calc_type = "Ordered"
|
|
then
|
|
temp_dose := BSA_val * dose;
|
|
actual_dose := dose;
|
|
|
|
(rounding_error_message,
|
|
new_dose):= call func_round_dosage with
|
|
(temp_dose, route );
|
|
if new_dose is null
|
|
then
|
|
error_message := rounding_error_message;
|
|
fatal_error := true;
|
|
elseif (new_dose is not null) and (rounding_error_message is not null)
|
|
then
|
|
error_message := rounding_error_message;
|
|
minor_error := true;
|
|
else
|
|
current_ordered_dose := new_dose ;
|
|
if check_dose_cap
|
|
and new_dose > dose_cap
|
|
then
|
|
exceeded_dose_cap := true;
|
|
new_dose := dose_cap;
|
|
dose := dose_cap/BSA_val;
|
|
actual_dose := dose_cap/BSA_val;
|
|
endif; // check dose_cap
|
|
endif; // new_dose is null
|
|
|
|
elseif calc_type = "Actual"
|
|
then
|
|
current_ordered_dose := dose ;
|
|
if check_dose_cap
|
|
and dose > dose_cap
|
|
then
|
|
exceeded_dose_cap := true;
|
|
new_dose := dose_cap;
|
|
dose := dose_cap;
|
|
actual_dose := dose_cap / BSA_val;
|
|
else
|
|
actual_dose := dose / BSA_val;
|
|
endif; // check dose_cap
|
|
|
|
elseif calc_type = "TotalOrdered" and exist daily_dose_multiplier
|
|
then
|
|
temp_dose:= (dose * BSA_val)/daily_dose_multiplier;
|
|
actual_dose := dose;
|
|
|
|
(rounding_error_message,
|
|
new_dose):= call func_round_dosage with
|
|
(temp_dose, route );
|
|
if new_dose is null
|
|
then
|
|
error_message := rounding_error_message;
|
|
fatal_error := true;
|
|
elseif (new_dose is not null) and (rounding_error_message is not null)
|
|
then
|
|
error_message := rounding_error_message;
|
|
minor_error := true;
|
|
else
|
|
current_ordered_dose := new_dose ;
|
|
if check_dose_cap
|
|
and new_dose > dose_cap
|
|
then
|
|
exceeded_dose_cap := true;
|
|
new_dose := dose_cap;
|
|
dose := (dose_cap * daily_dose_multiplier)/ BSA_val;
|
|
actual_dose := (dose_cap * daily_dose_multiplier)/ BSA_val;
|
|
endif; // check dose_cap
|
|
endif; // new_dose is null
|
|
|
|
elseif calc_type = "TotalActual" and exist daily_dose_multiplier
|
|
then
|
|
current_ordered_dose := dose ;
|
|
if check_dose_cap
|
|
and dose > dose_cap
|
|
then
|
|
exceeded_dose_cap := true;
|
|
new_dose := dose_cap;
|
|
dose := dose_cap;
|
|
actual_single_dose := dose_cap / BSA_val;
|
|
else
|
|
actual_single_dose := dose / BSA_val;
|
|
endif; // check dose_cap
|
|
|
|
actual_dose := actual_single_dose * daily_dose_multiplier;
|
|
|
|
endif; //if calc_type
|
|
endif; /* if dose_basis = M2_string */
|
|
|
|
/*--------------------------*/
|
|
/* Calculate Dose by WEIGHT */
|
|
/*--------------------------*/
|
|
if dose_basis is in kg_string
|
|
and exist wt_val
|
|
and exist dose_uom
|
|
and exist dose
|
|
and wt_val > 0
|
|
and dose > 0
|
|
then
|
|
if calc_type = "Ordered"
|
|
then
|
|
temp_dose := wt_val * dose;
|
|
actual_dose := dose;
|
|
|
|
(rounding_error_message,
|
|
new_dose):= call func_round_dosage with
|
|
(temp_dose, route );
|
|
if new_dose is null
|
|
then
|
|
error_message := rounding_error_message;
|
|
fatal_error := true;
|
|
elseif (new_dose is not null) and (rounding_error_message is not null)
|
|
then
|
|
error_message := rounding_error_message;
|
|
minor_error := true;
|
|
else
|
|
current_ordered_dose := new_dose ;
|
|
if check_dose_cap
|
|
and new_dose > dose_cap
|
|
then
|
|
exceeded_dose_cap := true;
|
|
new_dose := dose_cap;
|
|
dose := dose_cap/wt_val;
|
|
actual_dose := dose_cap/wt_val;
|
|
endif; // check dose_cap
|
|
endif; // new_dose is null
|
|
|
|
elseif calc_type = "Actual"
|
|
then
|
|
current_ordered_dose := dose ;
|
|
if check_dose_cap
|
|
and dose > dose_cap
|
|
then
|
|
exceeded_dose_cap := true;
|
|
new_dose := dose_cap;
|
|
dose := dose_cap;
|
|
actual_dose := dose_cap / wt_val;
|
|
else
|
|
actual_dose := dose / wt_val;
|
|
endif; // check dose_cap
|
|
|
|
elseif calc_type = "TotalOrdered" and exist daily_dose_multiplier
|
|
then
|
|
temp_dose:= (dose * wt_val)/daily_dose_multiplier;
|
|
actual_dose := dose;
|
|
|
|
(rounding_error_message,
|
|
new_dose):= call func_round_dosage with
|
|
(temp_dose, route );
|
|
if new_dose is null
|
|
then
|
|
error_message := rounding_error_message;
|
|
fatal_error := true;
|
|
elseif (new_dose is not null) and (rounding_error_message is not null)
|
|
then
|
|
error_message := rounding_error_message;
|
|
minor_error := true;
|
|
else
|
|
current_ordered_dose := new_dose ;
|
|
if check_dose_cap
|
|
and new_dose > dose_cap
|
|
then
|
|
exceeded_dose_cap := true;
|
|
new_dose := dose_cap;
|
|
dose := (dose_cap * daily_dose_multiplier)/ wt_val;
|
|
actual_dose := (dose_cap * daily_dose_multiplier)/ wt_val;
|
|
endif; // check dose_cap
|
|
endif; // new_dose is null
|
|
|
|
elseif calc_type = "TotalActual" and exist daily_dose_multiplier
|
|
then
|
|
current_ordered_dose := dose ;
|
|
if check_dose_cap
|
|
and dose > dose_cap
|
|
then
|
|
exceeded_dose_cap := true;
|
|
new_dose := dose_cap;
|
|
dose := dose_cap;
|
|
actual_single_dose := dose_cap / wt_val;
|
|
else
|
|
actual_single_dose := dose / wt_val;
|
|
endif; // check dose_cap
|
|
|
|
actual_dose := actual_single_dose * daily_dose_multiplier;
|
|
|
|
endif; //if calc_type
|
|
endif; /* if dose_basis = kg_string */
|
|
|
|
/*-----------------------------*/
|
|
/* Calculate Dose by FLAT DOSE */
|
|
/*-----------------------------*/
|
|
if dose_basis = flat_dose_string
|
|
and exist dose_uom
|
|
and exist dose
|
|
and dose > 0
|
|
then
|
|
if calc_type = "Ordered"
|
|
then
|
|
new_dose := dose;
|
|
current_ordered_dose := new_dose ;
|
|
if check_dose_cap
|
|
and new_dose > dose_cap
|
|
then
|
|
exceeded_dose_cap := true;
|
|
new_dose := dose_cap;
|
|
dose := dose_cap;
|
|
actual_dose := dose_cap;
|
|
else
|
|
actual_dose := dose;
|
|
endif; // check dose_cap
|
|
|
|
elseif calc_type = "Actual"
|
|
then
|
|
current_ordered_dose := dose ;
|
|
if check_dose_cap
|
|
and dose > dose_cap
|
|
then
|
|
exceeded_dose_cap := true;
|
|
new_dose := dose_cap;
|
|
dose := dose_cap;
|
|
actual_dose := dose_cap;
|
|
else
|
|
actual_dose := dose;
|
|
endif; // check dose_cap
|
|
|
|
elseif calc_type = "TotalOrdered" and exist daily_dose_multiplier
|
|
then
|
|
new_dose := dose / daily_dose_multiplier;
|
|
current_ordered_dose := new_dose ;
|
|
if check_dose_cap
|
|
and new_dose > dose_cap
|
|
then
|
|
exceeded_dose_cap := true;
|
|
new_dose := dose_cap;
|
|
dose := dose_cap * daily_dose_multiplier;
|
|
actual_dose := dose_cap * daily_dose_multiplier;
|
|
else
|
|
actual_dose := dose;
|
|
endif; // check dose_cap
|
|
|
|
elseif calc_type = "TotalActual" and exist daily_dose_multiplier
|
|
then
|
|
current_ordered_dose := dose ;
|
|
if check_dose_cap
|
|
and dose > dose_cap
|
|
then
|
|
exceeded_dose_cap := true;
|
|
new_dose := dose_cap;
|
|
dose := dose_cap;
|
|
actual_single_dose := dose_cap;
|
|
else
|
|
actual_single_dose := dose;
|
|
endif; // check dose_cap
|
|
|
|
actual_dose := actual_single_dose * daily_dose_multiplier;
|
|
|
|
endif; //if calc_type
|
|
endif; /* if dose_basis = flat_dose_string */
|
|
|
|
/*---------------------------------*/
|
|
/* Calculate the Total Daily Dose */
|
|
/*---------------------------------*/
|
|
if calculating_total = "TRUE"
|
|
then
|
|
if exist daily_dose_multiplier
|
|
then
|
|
if calc_type = "Ordered"
|
|
then
|
|
total_daily_dose:= new_dose * daily_dose_multiplier ;
|
|
|
|
elseif calc_type = "Actual"
|
|
then
|
|
total_daily_dose:= dose * daily_dose_multiplier ;
|
|
|
|
elseif calc_type = "TotalOrdered"
|
|
then
|
|
total_daily_dose:= new_dose * daily_dose_multiplier;
|
|
|
|
elseif calc_type = "TotalActual"
|
|
then
|
|
total_daily_dose:= dose * daily_dose_multiplier ;
|
|
endif;
|
|
endif;
|
|
endif; /* if calculating total */
|
|
|
|
/*----------------------------*/
|
|
/* Convert Numbers to Strings */
|
|
/* Convert NULL to "" */
|
|
/*----------------------------*/
|
|
// This conversion is done to:
|
|
// (1) format the number for printing purposes, and
|
|
// (2) convert any numeric values to strings before they are returned to the calling program.
|
|
// The Sunrise application is expecting strings to be returned.
|
|
// An assertion or error will occur if a number is returned.
|
|
// After the string conversion, any numeric comparisons with these variables
|
|
// will require an AS NUMBER conversion.
|
|
|
|
if exist dose then
|
|
if dose > 999999
|
|
then
|
|
formatted_dose := call add_commas with (dose);
|
|
dose:= call convert_big_num with (dose, "", 10);
|
|
elseif dose < 1 then
|
|
dose:= dose formatted with "%g";
|
|
formatted_dose := dose;
|
|
else
|
|
formatted_dose := call add_commas with (dose);
|
|
dose := dose as string;
|
|
endif;
|
|
else dose := "";
|
|
endif;
|
|
|
|
if exist new_dose then
|
|
if new_dose > 0
|
|
and dose_basis = flat_dose_string
|
|
then
|
|
//Avoids exceeding 4 decimal points
|
|
formatted_new_dose := call add_commas with (new_dose);
|
|
new_dose := ((new_dose formatted with "%.4f") AS NUMBER) AS STRING;
|
|
elseif new_dose > 999999 then
|
|
formatted_new_dose := call add_commas with (new_dose);
|
|
new_dose:= call convert_big_num with (new_dose, "", 10);
|
|
elseif new_dose < 1 then
|
|
new_dose:= new_dose formatted with "%g";
|
|
formatted_new_dose := new_dose;
|
|
else
|
|
formatted_new_dose := call add_commas with (new_dose);
|
|
new_dose := new_dose as string;
|
|
endif;
|
|
else new_dose := "";
|
|
endif;
|
|
|
|
if exist actual_dose then
|
|
if (calc_type = "TotalOrdered"
|
|
or calc_type = "Ordered")
|
|
and NOT exceeded_dose_cap
|
|
then
|
|
actual_dose := actual_dose as string;
|
|
else
|
|
if actual_dose > 999999 then
|
|
formatted_actual_dose := call add_commas with (actual_dose);
|
|
actual_dose := actual_dose formatted with "%f";
|
|
elseif actual_dose < 0.01 then
|
|
temp_actual_dose := (actual_dose formatted with "%f") AS NUMBER;
|
|
formatted_actual_dose := call add_commas with (temp_actual_dose);
|
|
actual_dose:= actual_dose formatted with "%f";
|
|
elseif actual_dose < 1 then
|
|
temp_actual_dose := (actual_dose formatted with "%.4f") AS NUMBER;
|
|
formatted_actual_dose := call add_commas with (temp_actual_dose);
|
|
actual_dose:= actual_dose formatted with "%.4f";
|
|
else
|
|
temp_actual_dose := (actual_dose formatted with "%.4f") AS NUMBER;
|
|
formatted_actual_dose := call add_commas with (temp_actual_dose);
|
|
actual_dose := actual_dose formatted with "%.4f";
|
|
endif;
|
|
endif;
|
|
else actual_dose := "";
|
|
endif;
|
|
|
|
|
|
if exist total_daily_dose then
|
|
if total_daily_dose > 999999
|
|
then
|
|
formatted_total_daily_dose := call add_commas with (total_daily_dose);
|
|
total_daily_dose:= call convert_big_num with (total_daily_dose, "", 10);
|
|
elseif total_daily_dose < 1 then
|
|
total_daily_dose:= total_daily_dose formatted with "%g";
|
|
formatted_total_daily_dose := total_daily_dose;
|
|
else
|
|
formatted_total_daily_dose := call add_commas with (total_daily_dose);
|
|
total_daily_dose:= total_daily_dose as string ;
|
|
endif;
|
|
else total_daily_dose := "";
|
|
endif;
|
|
|
|
if exist current_ordered_dose then
|
|
if current_ordered_dose > 999999
|
|
then
|
|
formatted_current_ordered_dose := call add_commas with (current_ordered_dose);
|
|
current_ordered_dose:= call convert_big_num with (current_ordered_dose, "", 10);
|
|
elseif current_ordered_dose < 1 then
|
|
current_ordered_dose:= current_ordered_dose formatted with "%g";
|
|
formatted_current_ordered_dose:= current_ordered_dose;
|
|
else
|
|
formatted_current_ordered_dose := call add_commas with (current_ordered_dose);
|
|
current_ordered_dose := current_ordered_dose as string;
|
|
endif;
|
|
else current_ordered_dose := "";
|
|
endif;
|
|
|
|
|
|
formatted_requested_dose := call add_commas with (requested_dose);
|
|
formatted_dose_cap := call add_commas with (dose_cap);
|
|
|
|
|
|
//-------------------------------------------
|
|
// Trim Trailing Zeroes from Dosage Strings
|
|
//-------------------------------------------
|
|
|
|
// Append the dosage strings that need zeroes trimmed into a list
|
|
dosage_list := dose, new_dose, actual_dose, total_daily_dose, current_ordered_dose;
|
|
|
|
// Initialize a list to append the formatted numbers
|
|
formatted_number_list := ();
|
|
|
|
// Process the dosage string list to trim the trailing zeroes
|
|
for one_dose in dosage_list do
|
|
|
|
// Convert the dosage string to a number
|
|
temp_dose_number := one_dose AS NUMBER;
|
|
|
|
if temp_dose_number is not number then
|
|
// Append the value to the list with out processing for trailing zeroes
|
|
formatted_number_list := formatted_number_list, one_dose;
|
|
else
|
|
// Format the dose to eliminate Scientific Notation
|
|
formatted_number := temp_dose_number formatted with "%.10f";
|
|
|
|
// Extract the digits and characters into a list
|
|
chars_list := extract characters formatted_number;
|
|
|
|
// Loop through chars_list, and determine if there are trailing zeros
|
|
trailing_position := 0;
|
|
found_trailing_zero := false;
|
|
found_decimal_point := false;
|
|
character_index := 0;
|
|
|
|
for one_char in chars_list do
|
|
if (one_char = ".") then
|
|
found_decimal_point := true;
|
|
found_trailing_zero := true;
|
|
trailing_position := character_index;
|
|
elseif (one_char = "0") and (found_decimal_point = true)
|
|
and (found_trailing_zero = false) then
|
|
found_trailing_zero := true;
|
|
trailing_position := character_index;
|
|
elseif (one_char <> "0") and (found_trailing_zero = true) then
|
|
found_trailing_zero := false;
|
|
endif;
|
|
character_index := character_index + 1;
|
|
enddo; //for one_char
|
|
|
|
// Remove the Trailing Zeros in the decimals
|
|
if found_trailing_zero then
|
|
// Trim the number and put it on the list of formatted number
|
|
formatted_number := string (first trailing_position from chars_list);
|
|
formatted_number_list := formatted_number_list, formatted_number ;
|
|
else
|
|
//Put the original untrimmed number on the list of formatted number
|
|
formatted_number_list := formatted_number_list, one_dose;
|
|
endif; //if found_trailing_zero
|
|
endif; //if temp_dose_number is not number
|
|
enddo; //for one_dose
|
|
|
|
// Loop through and reset the dosage strings after trimming the trailing zeroes
|
|
// Reset the values using the same variables and same index order
|
|
// that was used to set the dosage_list
|
|
for JJ in (1 seqto (count formatted_number_list)) do
|
|
if JJ = 1 then
|
|
dose := formatted_number_list[JJ];
|
|
elseif JJ = 2 then
|
|
new_dose := formatted_number_list[JJ];
|
|
elseif JJ = 3 then
|
|
actual_dose := formatted_number_list[JJ];
|
|
elseif JJ = 4 then
|
|
total_daily_dose := formatted_number_list[JJ];
|
|
elseif JJ = 5 then
|
|
current_ordered_dose := formatted_number_list[JJ];
|
|
endif; //if JJ
|
|
enddo; //for JJ
|
|
|
|
|
|
/*---------------------------------------*/
|
|
/* Format Dose String for CalcInfo field */
|
|
/*---------------------------------------*/
|
|
|
|
/* Initialize dose_string */
|
|
if not exist dose_string
|
|
then dose_string := "";
|
|
endif;
|
|
|
|
/* Set dose_basis_cut and dose_basis_final for AUC */
|
|
if dose_basis is in AUC_strings
|
|
then
|
|
dose_basis_cut := "AUC";
|
|
if dose_basis = "AUC (Cockcroft-Gault)"
|
|
then dose_basis_final := "AUC(C-G)";
|
|
elseif dose_basis = "AUC (Cockcroft-Gault ideal)"
|
|
then dose_basis_final := "AUC(C-G ideal)";
|
|
elseif dose_basis = "AUC (Cockcroft-Gault adjusted)"
|
|
then dose_basis_final := "AUC(C-G adjusted)";
|
|
elseif dose_basis = "AUC (Jelliffe)"
|
|
then dose_basis_final := "AUC(Jelliffe)";
|
|
elseif dose_basis = "AUC (Jelliffe ideal)"
|
|
then dose_basis_final := "AUC(Jelliffe ideal)";
|
|
elseif dose_basis = "AUC (Jelliffe adjusted)"
|
|
then dose_basis_final := "AUC(Jelliffe adjusted)";
|
|
elseif dose_basis = "AUC (Jelliffe no BSA)"
|
|
then dose_basis_final := "AUC(Jelliffe noBSA)";
|
|
elseif dose_basis = "AUC (measured CrCl)"
|
|
then dose_basis_final := "AUC(measured CrCl)";
|
|
elseif dose_basis = "AUC (St. Jude{{{SINGLE-QUOTE}}}s Modified-Peds)"
|
|
then dose_basis_final := "AUC(St. Jude{{{SINGLE-QUOTE}}}s)";
|
|
endif;
|
|
else
|
|
dose_basis_cut := dose_basis;
|
|
endif;
|
|
|
|
|
|
/* format_type can be "Order" or "Additive" */
|
|
if format_type = "Additive"
|
|
then dose_string:= "[Calculation: " ;
|
|
else dose_string:= "";
|
|
endif;
|
|
|
|
if calc_type = "Ordered" or calc_type = "TotalOrdered"
|
|
then
|
|
dose_string:= dose_string || formatted_dose;
|
|
|
|
elseif calc_type = "Actual" or calc_type = "TotalActual"
|
|
then
|
|
dose_string:= dose_string || formatted_actual_dose;
|
|
endif;
|
|
|
|
if calc_type = "Ordered" or calc_type = "Actual"
|
|
then
|
|
if dose_basis = flat_dose_string
|
|
then
|
|
dose_string:= dose_string || " "
|
|
|| dose_uom || "/DOSE"|| " x ";
|
|
else
|
|
dose_string:= dose_string || " "
|
|
|| dose_uom || "/" || dose_basis_cut || "/DOSE" || " x ";
|
|
endif;
|
|
else /* calc_type = "TotalOrdered" or "TotalActual" */
|
|
if dose_basis = flat_dose_string
|
|
then
|
|
dose_string:= dose_string || " "
|
|
|| dose_uom || "/DAY"|| " x ";
|
|
else
|
|
dose_string:= dose_string || " "
|
|
|| dose_uom || "/" || dose_basis_cut || "/DAY"|| " x ";
|
|
endif;
|
|
endif; //if calc_type = "Ordered" or calc_type = "Actual"
|
|
|
|
if dose_basis is in M2_string
|
|
then dose_string:= dose_string || BSA_val || " " || dose_basis_cut;
|
|
elseif dose_basis is in kg_string
|
|
then dose_string:= dose_string || wt_val || " " || dose_basis_cut;
|
|
elseif dose_basis is in AUC_strings
|
|
then dose_string:= dose_string || AUC_coef || " " || dose_basis_cut;
|
|
elseif dose_basis = flat_dose_string
|
|
then dose_string:= dose_string || "1 " ;
|
|
else
|
|
dose_string:= null;
|
|
endif;
|
|
|
|
if calc_type = "Ordered" or calc_type = "Actual"
|
|
then
|
|
dose_string:= dose_string || " = ";
|
|
else
|
|
dose_string:= dose_string || " "|| frequency || " = ";
|
|
endif;
|
|
|
|
if calc_type = "Ordered" or calc_type = "TotalOrdered"
|
|
then
|
|
dose_string:= dose_string || formatted_new_dose;
|
|
else /* calc_type = "Actual" or "TotalActual" */
|
|
dose_string:= dose_string || formatted_dose;
|
|
endif;
|
|
|
|
dose_string:= dose_string || " " || dose_uom || "/Dose";
|
|
|
|
if exist requested_dose
|
|
then
|
|
if calc_type = "Actual"
|
|
then
|
|
dose_string:= dose_string || spacing_string
|
|
|| "(Requested dose was " || formatted_requested_dose || " " || dose_uom
|
|
|| " per " || dose_basis_cut || ")";
|
|
endif;
|
|
|
|
/* CR 4028 for totalordered type calculation, need to display requested dose in calc info string returned */
|
|
if calc_type = "Ordered"
|
|
then
|
|
dose_string:= dose_string || spacing_string
|
|
|| "(Requested dose was " || formatted_requested_dose || " " || dose_uom
|
|
|| " per " || dose_basis_cut || ")";
|
|
endif;
|
|
|
|
if calc_type = "TotalActual"
|
|
then
|
|
dose_string:= dose_string || spacing_string
|
|
|| "(Requested Daily amount was " || formatted_requested_dose || " " || dose_uom
|
|
|| " per " || dose_basis_cut || ")";
|
|
endif;
|
|
|
|
/* CR 4028 for totalordered type calculation, need to display requested dose in calc info string returned */
|
|
if calc_type = "TotalOrdered"
|
|
then
|
|
dose_string:= dose_string || spacing_string
|
|
|| "(Requested Daily amount was " || formatted_requested_dose || " " || dose_uom
|
|
|| " per " || dose_basis_cut || ")";
|
|
endif;
|
|
|
|
endif; /* if exist requested_dose*/
|
|
|
|
/* Only an Order should have a Daily Total */
|
|
if total_daily_dose <> ""
|
|
and format_type = "Order"
|
|
then dose_string:= dose_string || spacing_string
|
|
|| "(Daily Total is " || formatted_total_daily_dose || " " || dose_uom || ")";
|
|
endif; /* if exist total_daily_dose */
|
|
|
|
if dose_basis is in AUC_strings
|
|
then dose_string := dose_string || " " || dose_basis_final
|
|
|| " " || AUC_dose_calc_formula;
|
|
endif;
|
|
|
|
if wt_val > 0
|
|
AND dose_basis is not in ideal_string
|
|
AND dose_basis is not in measured_string
|
|
AND dose_basis <> flat_dose_string
|
|
AND (weight_type <> "Weight")
|
|
then dose_string := dose_string || " Weight type: " || weight_type;
|
|
endif;
|
|
|
|
if format_type = "Additive"
|
|
then dose_string:= dose_string || "]" ;
|
|
endif;
|
|
|
|
/*-------------------------------------------------*/
|
|
/* Modify Messages When Dose Cap Has been Exceeded */
|
|
/*-------------------------------------------------*/
|
|
if exceeded_dose_cap
|
|
then
|
|
minor_error := true;
|
|
error_message := "The " ||formatted_current_ordered_dose || " " || dose_uom
|
|
|| " dose you requested exceeded the DOSAGE CAP of "
|
|
|| formatted_dose_cap ||" " || dose_uom || ". "
|
|
|| "The amount of the dose was reset to the DOSAGE CAP. "
|
|
|| "To override from the Dose Calculation dialog, "
|
|
|| "reenter the dose in the {{{SINGLE-QUOTE}}}Ordered Amount Per Dose{{{SINGLE-QUOTE}}} field. "
|
|
|| "If necessary, enter an override reason. "
|
|
|| "To override from the Order Form, reenter the dose in the dosage field.";
|
|
dose_basis_message := "based on Dose Cap";
|
|
dose_string:= "DOSE CAP limits dose to " || dose_string ;
|
|
endif; //if exceeded_dose_cap
|
|
|
|
if Not check_dose_cap
|
|
and ((current_ordered_dose AS NUMBER) > dose_cap )
|
|
and format_type = "Order"
|
|
then
|
|
dose_string:= "DOSE CAP limit exceeded. " || dose_string ;
|
|
endif; //if Not check_dose_cap
|
|
|
|
endif; /* if NOT fatal_error */
|
|
|
|
/*---------------*/
|
|
/* Clinical Rule */
|
|
/*---------------*/
|
|
/* Always conclude true to return calculated values or the error message */
|
|
conclude true;
|
|
;;
|
|
action:
|
|
|
|
/* Returns an error message, if there is one */
|
|
/* Otherwise, the calculations are returned as STRING values */
|
|
if fatal_error
|
|
then return error_message;
|
|
elseif minor_error
|
|
then return ( error_message, new_dose, dose_string, total_daily_dose,
|
|
actual_dose, dose_basis_message, current_ordered_dose ) ;
|
|
else
|
|
return ( "", new_dose, dose_string, total_daily_dose, actual_dose,
|
|
dose_basis_message, current_ordered_dose ) ;
|
|
endif;
|
|
;;
|
|
end:
|