266 lines
11 KiB
Plaintext
266 lines
11 KiB
Plaintext
maintenance:
|
|
|
|
title: Round Medication Dosage;;
|
|
mlmname: SYS_ROUND_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: Rounds a medication dose to the appropriate value using the medication route; or
|
|
within the limit of a maximum of 10% variation, regardless of route.
|
|
;;
|
|
explanation: Implements rounding rules in one of three ways. The first two were developed
|
|
by Eclipsys, and the third was developed at Johns Hopkins Hospital using an algorithm
|
|
that limits the rounding so that it never exceeds 10% of the original dose amount. The
|
|
Eclipsys rounding rules are designated as "Standard" and are the default function of
|
|
this MLM. The third rule is designated as "10pctLimit" and can be selected by changing
|
|
the RoundingRule flag in the Spelling and Flags section.
|
|
|
|
The "Standard" rounding rules can be used when the route is supplied. An error message
|
|
is returned if the Dose is NOT a string, or if the Route is NULL, or if the dose amount
|
|
is smaller than 0.005:
|
|
(1) The Parenteral Rounding Rules are used whenever the route matches the routes
|
|
listed in the Parenteral_Route_List variable.
|
|
(2) The Other Rounding Rules are used whenever a route exists and does NOT match
|
|
the routes listed in the Parenteral_Route_List variable.
|
|
|
|
PARENTERAL ROUNDING RULES
|
|
For values < 0.005, return Error_Message
|
|
For values <= 1, round to the nearest 0.01
|
|
For values > 1 and <= 5, round to the nearest 0.1
|
|
For values > 5 and <= 50, round to the nearest 1 (integer)
|
|
For values > 50 and <= 100, round to the nearest 2 (even number)
|
|
For values > 100 and <= 500, round to the nearest 10 (integer)
|
|
For values > 500 and <= 2000, round to the nearest 50 (integer)
|
|
For values > 2000, round to the nearest 100 (integer)
|
|
|
|
OTHER ROUNDING RULES
|
|
For values < 0.005, return Error_Message
|
|
For values <= 1, round to the nearest 0.01
|
|
For values >= 1 and <= 10, round to the nearest 0.1
|
|
For values >= 10 and <= 50, round to the nearest integer
|
|
For values > 50, round to the nearest 5
|
|
|
|
The "10pctLimit" rule implements the requirement that rounding shall not exceed 10% of the original
|
|
amount. It rounds to values that are always within 1 log value of the dose, as in the chart below.
|
|
It will not evaluate a Route nor return a route error message. To conform with the functional limits
|
|
of the Sunrise application, it will return: 1) an error message and NULL for the rounded dose if
|
|
the dose amount is less than 0.00005; 2) a warning message and a rounded dose that may exceed the
|
|
10% limit if 0.00005 <= dose < 0.0005; or 3) a NULL message and a rounded dose within the 10% limit
|
|
for all other dose values.
|
|
. .
|
|
. .
|
|
(error) any smaller <= Dose < 0.00005 -> return Error_Message
|
|
0.00005 <= Dose < 0.0005 -> Round to the nearest 0.0001, return warning_message
|
|
0.0005 <= Dose < 0.005 -> Round to the nearest 0.0001
|
|
0.005 <= Dose < 0.05 -> Round to the nearest 0.001
|
|
0.05 <= Dose < 0.5 -> Round to the nearest 0.01
|
|
(A) 0.5 <= Dose < 5 -> Round to the nearest 0.1
|
|
(B) 5 <= Dose < 50 -> Round to the nearest 1
|
|
50 <= Dose < 500 -> Round to the nearest 10
|
|
500 <= Dose < 5000 -> Round to the nearest 100
|
|
5000 <= Dose < 50000 -> Round to the nearest 1000
|
|
50000 <= Dose < 500000 -> Round to the nearest 10000
|
|
500000 <= Dose < 5000000 -> Round to the nearest 100000
|
|
5000000 <= Dose < 50000000 -> Round to the nearest 1000000
|
|
.
|
|
.
|
|
.
|
|
METHOD:
|
|
1) The Dose is normalized by moving the decimal point so that
|
|
1 <= (normalized value) < 10. This is done by taking the log of the Dose.
|
|
2) Because the normalized Dose satisfies 1 <= (normalized Dose) < 10, we apply
|
|
rule (A) above if the normalized Dose is < 5 and rule (B) above otherwise.
|
|
3) The decimal point is moved back to its former location (denormalized).
|
|
|
|
A facility can modify this MLM if a different rounding is preferred.
|
|
;;
|
|
keywords:
|
|
;;
|
|
knowledge:
|
|
type: data-driven;;
|
|
data:
|
|
/***************** Make Changes To Spelling And Flags In This Section ******************/
|
|
// The rounding rule type to be applied by the MLM. Current valid values are
|
|
// "Standard" (the default) and "10pctLimit"
|
|
|
|
RoundingRule := "Standard";
|
|
|
|
// The list of PARENTERAL ROUTES that will be used to round the
|
|
// dose using the "Dose Rounding Rules for Parenteral Routes."
|
|
// The strings must match entries in your Route Dictionary.
|
|
// If there any entries that are NOT in your Route Dictionary, remove them.
|
|
Parenteral_Route_List := ("IM", "IM or IV", "IV", "IV push",
|
|
"IVPB", "SC", "Subcutaneous");
|
|
|
|
/* Set to true if logging is needed.*/
|
|
log_execution_info := false;
|
|
|
|
/***************************************************************************************/
|
|
/*-----------*/
|
|
/* ARGUMENTS */
|
|
/*-----------*/
|
|
(dose, // A number that is the amount of the dose.
|
|
route) // A string that is from the Route Dictionary.
|
|
:= Argument;
|
|
|
|
/* Set Return Variables to NULL */
|
|
rounded_dose := NULL;
|
|
error_message := NULL;
|
|
|
|
/* Set Round, Dose and Route errors to blank */
|
|
round_error := "";
|
|
dose_error := "";
|
|
route_error := "";
|
|
|
|
/* Assume no errors to start */
|
|
fatal_error := false;
|
|
minor_error := false;
|
|
|
|
if dose is not number then
|
|
/*------------------------------------------------------*/
|
|
/* Create Error Message for non-numerical dose argument */
|
|
/*------------------------------------------------------*/
|
|
fatal_error := true;
|
|
dose_error := " the Dose is NOT a number.";
|
|
|
|
else
|
|
/*----------------------------------------------*/
|
|
/* proceed if we have numeric argument for dose */
|
|
/*----------------------------------------------*/
|
|
if (RoundingRule is null or RoundingRule = "Standard") then
|
|
if not exist Route then
|
|
fatal_error := true;
|
|
route_error := " the Route is missing or invalid.";
|
|
|
|
elseif dose < 0.005 then
|
|
fatal_error := true;
|
|
dose_error := " the Dose amount is less than the {{{SINGLE-QUOTE}}}Standard{{{SINGLE-QUOTE}}} rounding lower limit (0.005).";
|
|
|
|
else // process only if we have a route
|
|
if route is in Parenteral_Route_List then
|
|
/*---------------------------*/
|
|
/* PARENTERAL Rounding Rules */
|
|
/*---------------------------*/
|
|
if dose <=1 then
|
|
/* For values <= 1, round to the nearest 0.01 */
|
|
rounded_dose:= (int((dose + 0.0051)*100))/100;
|
|
elseif dose <= 5 then
|
|
/* For values > 1 and <= 5, round to the nearest 0.1 */
|
|
rounded_dose:= (int((dose + 0.051)*10))/10;
|
|
elseif dose <= 50 then
|
|
/* For values > 5 and <= 50, round to the nearest 1 (integer) */
|
|
rounded_dose:= int(dose + 0.51);
|
|
elseif dose <= 100 then
|
|
/* For values > 50 and <= 100, round to the nearest 2 (even number) */
|
|
rounded_dose:= int((dose/2)+ 0.5)* 2;
|
|
elseif dose <= 500 then
|
|
/* For values > 100 and <= 500, round to the nearest 10 (integer) */
|
|
rounded_dose:= int((dose/10)+ 0.5)* 10;
|
|
elseif dose <= 2000 then
|
|
/* For values > 500 and <= 2000, round to the nearest 50 (integer) */
|
|
rounded_dose:= int((dose/50)+ 0.5)* 50;
|
|
elseif dose > 2000 then
|
|
/* For values > 2000, round to the nearest 100 (integer) */
|
|
rounded_dose:= int((dose/100)+ 0.5)* 100;
|
|
endif; // dose ranges (Parenteral route)
|
|
|
|
else
|
|
/*---------------------------------------------*/
|
|
/* OTHER (non-parenteral Route) Rounding Rules */
|
|
/*---------------------------------------------*/
|
|
if dose <= 1 then
|
|
/*For values <= 1, round to the nearest 0.01*/
|
|
rounded_dose:= (int((dose + 0.0051)*100))/100;
|
|
elseif dose < 10 then
|
|
/* For values >= 1 and <= 10, round to the nearest 0.1 */
|
|
rounded_dose:= (int((dose + 0.051)*10))/10;
|
|
elseif dose <= 50 then
|
|
/* For values >= 10 and <= 50, round to the nearest integer */
|
|
rounded_dose:= int(dose + 0.51);
|
|
else
|
|
/* For values > 50, round to the nearest 5 */
|
|
rounded_dose:= int((dose/5)+ 0.51)* 5;
|
|
endif; // dose ranges (non-Parenteral route)
|
|
endif; // Route is in parenteral list
|
|
endif; // not exist Route (for Standard rounding)
|
|
|
|
elseif RoundingRule = "10pctLimit" then
|
|
/* the number of decimal places is found by the log base 10 */
|
|
decimal_offset := int(log10(dose));
|
|
|
|
/* shift decimal point to "normalize" dose */
|
|
dose_normalized := dose / (10**decimal_offset);
|
|
/*-----------------------------------*/
|
|
/* now 1 <= dose_normalized < 10 */
|
|
/*-----------------------------------*/
|
|
if (dose < 0.00005) then
|
|
fatal_error := true;
|
|
dose_error := " the Dose amount is less than the {{{SINGLE-QUOTE}}}10pctLimit{{{SINGLE-QUOTE}}} "
|
|
|| "rounding lower limit (0.00005).";
|
|
|
|
elseif (0.00005 <= dose) and (dose < 0.0005) then
|
|
rounded_dose := dose formatted with "%.4f";
|
|
rounded_dose := rounded_dose as number;
|
|
if (abs(rounded_dose - dose) / dose) > 0.1 then
|
|
minor_error := true;
|
|
round_error := " rounded dose is outside the 10% limit "
|
|
|| "due to number of decimal places.";
|
|
endif; // rounded dose is outside 10%
|
|
|
|
else
|
|
/* round value below 5 to nearest 10th */
|
|
if dose_normalized < 5 then
|
|
rounded_dose_normalized := int((dose_normalized + 0.051)*10)/10;
|
|
else
|
|
/* or round to next higher integer */
|
|
rounded_dose_normalized := int(dose_normalized + 0.51);
|
|
endif;
|
|
/* restore decimal point */
|
|
rounded_dose := rounded_dose_normalized * (10**decimal_offset);
|
|
endif; // (dose < 0.00005) (10pctLimit)
|
|
|
|
/*----------------------------------*/
|
|
/* Insert other Rounding Rules here */
|
|
/*----------------------------------*/
|
|
endif; // Rounding Rule is Standard or 10pctLimit (or other)
|
|
|
|
endif; /* dose is number */
|
|
;;
|
|
evoke:
|
|
;;
|
|
logic:
|
|
if fatal_error then
|
|
error_message := "Unable to round dose because" || dose_error || route_error;
|
|
elseif minor_error then
|
|
error_message := "Warning: " || round_error;
|
|
endif;
|
|
|
|
/* Always conclude true to return a value */
|
|
conclude true;
|
|
;;
|
|
action:
|
|
return error_message, rounded_dose;
|
|
;;
|
|
end:
|