Files
St.Clair/MLMStripper/bin/Debug/STD/STD_FUNC_DOSAGE_CALC_STOPDTM.mlm

287 lines
9.0 KiB
Plaintext

maintenance:
title: Calculates the stop date/time for an order;;
mlmname: STD_FUNC_DOSAGE_CALC_STOPDTM;;
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: Calculates the stop date for an order that does not have one.
;;
explanation: This MLM will calculate the StopDtm for an order based on
information in the orders{{{SINGLE-QUOTE}}}s frequency.
Stop After (except for Stop after X Times)
<User Schedule>
Daily, Weekly, Irregular
<Variable Interval>
Every M to N UNITS
QnH and QnM templates
Standard Frequencies without a stop after
Every N UNITS
Every M to N UNITS
N Times per UNIT
Does not work for orders that are <Continous> or <EventBased> when
there is no Stop After or Frequency configured.
;;
keywords: single dose; average daily dose; total daily dose; dosage range
;;
knowledge:
type: data-driven;;
data:
// Set to true if logging is needed.
log_execution_info := false;
// Declare C functions to parse the frequency string
func_get_token := interface {char* msvcrt:strtok(char*, char*)};
func_get_str := interface {char* msvcrt:strstr(char*, char*)};
// 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.
DAY_STRING := "day";
HOUR_STRING := "hr";
MINUTE_STRING := "min";
MONTH_STRING := "month";
SECOND_STRING := "s";
WEEK_STRING := "week";
YEAR_STRING := "year";
// Frequency Types
NONE := 0;
N_TIMES_PER_UNIT := 1;
EVERY_N_UNITS := 2;
EVERY_X_TO_Y_UNITS := 3;
STOP_AFTER_DAYS := 1;
STOP_AFTER_HOURS := 2;
STOP_AFTER_MINUTES := 3;
STOP_AFTER_TIMES := 4;
// Parameter list
( FrequencyCode,
StartDtm,
FreqUOM,
FreqFromTime,
FreqToTime,
StopAfterValue,
StopAfterOption,
TaskSchedObj ) := ARGUMENT;
//----------------------------------------------------------
// Load some data first based on the freqency type
//----------------------------------------------------------
// If Irregular, need to retrieve and sort the list of Scheduled Times.
if FrequencyCode = "<User Schedule>"
then
if FreqUom is NULL // = "Irregular"
then
ScheduledDtmList := read { TaskScheduleDefinition: ScheduledDtm referencing TaskSchedObj };
ScheduledDtmList := sort data ScheduledDtmList;
endif;
elseif FrequencyCode = "<Variable Interval>"
then
frequency_type := EVERY_X_TO_Y_UNITS;
time_core_uom := read last
{"SELECT CoreUOM "
|| " FROM CV3UnitOfMeasure"
|| " WHERE Code = " || SQL (FreqUom)
|| " AND Active = 1 " };
else
// Gets the Frequency information from the Enterprise data
// Only gets the Active Frequencies and Active Units of Measures
(frequency_type,
FreqFromTime,
FreqToTime,
time_core_uom):= read last
{"SELECT f.DefinitionType, f.TimeFromValue, f.TimeToValue, u.CoreUOM "
|| " FROM CV3Frequency AS f "
|| " LEFT OUTER JOIN CV3UnitOfMeasure AS u"
|| " ON (f.TimeUom = u.Code and u.Active=1) "
|| " WHERE f.Code = " || SQL (FrequencyCode)
|| " AND f.Active = 1 " };
endif;
// If there is a TO value use it for any calculations
if FreqToTime > 0
then
freq_time := FreqToTime;
else
freq_time := FreqFromTime;
endif;
;;
priority: 50
;;
evoke:
;;
logic:
dateOffset := 0 minutes;
//--------------------------------------------------
// Calculate Stop After Days/Hours/Minutes.
// Does not handle times
// This calculation overrides any other calculation
//--------------------------------------------------
if StopAfterOption > 0
then
if StopAfterOption = STOP_AFTER_DAYS
then dateOffset := StopAfterValue DAYS;
elseif StopAfterOption = STOP_AFTER_HOURS
then dateOffset := StopAfterValue HOURS;
elseif StopAfterOption = STOP_AFTER_MINUTES
then dateOffset := StopAftervalue MINUTES;
elseif StopAfterOption = STOP_AFTER_TIMES // Do not calculate
then dateOffset := 0 DAYS;
endif;
else
// For user scheduled orders
if ( FrequencyCode = "<User Schedule>" )
then
//-------------------------------------
// Calculate Every X UNITS based on
// Frequence of <User Scheduled>
//-------------------------------------
if FreqUOM = "day"
then dateOffset := freq_time DAYS; // Every X days
elseif FreqUOM = "week"
then dateOffset := freq_time WEEKS; // Every X weeks
else calculated_stopDtm := last of ScheduledDtmList; // Irregular
endif;
elseif FrequencyCode = "<Multiple>"
then
; // Do nothing for Multiple
else // All other Frequency Codes
//-------------------------------------------------------
// Frequency <QxH> and <QxM> Template
// Handle frequency templates <qxh> and <qxm> by
// parsing the frequency string
// Set the frequency_type, time_core_uom and freq_time
// values to be passed on to the next calculation
If NOT Exist frequency_type AND dateOffset <= 0 minutes
then
frequency_type := EVERY_N_UNITS ;
// Declare characters used for delimiting the string
// Delimiters are Case Sensitive
q_delim:= "Q";
h_delim:= "H";
m_delim:= "M";
// Determine if the letter in at the back of the string is H or M
get_H:= call func_get_str with (FrequencyCode, h_delim);
get_M:= call func_get_str with (FrequencyCode, m_delim);
// Remove the front Q, so xH or xM is left
trim_Q:= call func_get_token with (FrequencyCode, q_delim);
// Set the time_core_uom
// Remove the H or the M, leaving a string representation of a number
if exist get_H
then
time_core_uom := HOUR_STRING;
freq_num_str := call func_get_token with (trim_Q, h_delim);
elseif exist get_M
then time_core_uom := MINUTE_STRING;
freq_num_str := call func_get_token with (trim_Q, m_delim);
endif; // if exist get_H
// Convert string to number
freq_time := freq_num_str as number;
endif; // If NOT Exist frequency_type
//-----------------------------------------------
// Convert Frequency to Durations
// frequency_type of 1 = N times per UNIT
// 2 = Every N UNITS
// 3 = Every X to Y UNITS (Use Y in calculations)
//-----------------------------------------------
if frequency_type = N_TIMES_PER_UNIT
then
// Assume only a single day
if time_core_uom is in ( DAY_STRING, HOUR_STRING, MINUTE_STRING, SECOND_STRING )
then dateOffset := 1 DAY;
endif;
elseif frequency_type = NONE
then
// If frequency type is NONE then assume a single day.
dateOffset := 1 DAY;
else // Type 2 and 3
// Rounds up to the next whole day
if time_core_uom = DAY_STRING
then dateOffset := ceiling (freq_time DAY / 1 DAY) DAYS;
elseif time_core_uom = HOUR_STRING
then dateOffset := ceiling (freq_time HOUR / 1 DAY) DAYS;
elseif time_core_uom = MINUTE_STRING
then dateOffset := ceiling (freq_time MINUTE / 1 DAY) DAYS;
elseif time_core_uom = SECOND_STRING
then dateOffset := ceiling (freq_time SECOND / 1 DAY) DAYS;
endif;
endif; // Frequency Type
endif; // Frequency Code
endif; // StopAfterOption
//-----------------------------------------------------------
// Calculate the stop date by adding the calculated offset
//-----------------------------------------------------------
if calculated_stopDtm is null AND dateOffset > 0 minutes
then
calculated_stopDtm := (startDtm + dateOffset) - 1 MINUTE;
endif;
conclude true;
;;
action:
return calculated_stopDtm;
;;
Urgency: 50;;
end: