Initial Checking with all 820 MLMs
This commit is contained in:
4306
MLMStripper/bin/Debug/STD/STD_ALLERGY.mlm
Normal file
4306
MLMStripper/bin/Debug/STD/STD_ALLERGY.mlm
Normal file
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,434 @@
|
||||
maintenance:
|
||||
|
||||
title: Standard Function for setting observation values with
|
||||
supplied parameters;;
|
||||
mlmname: STD_DOC_FUNC_CHART_OBSERVATION_HELPER;;
|
||||
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: MLM standard function that inserts value into an observation in
|
||||
structured note or Flowsheet.
|
||||
;;
|
||||
explanation:
|
||||
|
||||
CONFIGURATION:
|
||||
--------------
|
||||
Supported Document Types:
|
||||
[X] Flowsheets
|
||||
[X] Structured Notes
|
||||
|
||||
MLM Events Supported:
|
||||
[X] ChartObservation
|
||||
[X] DocumentOpening
|
||||
[X] DocumentClosing
|
||||
|
||||
Instructions:
|
||||
------------
|
||||
This function MLM cannot be called directly from flowsheets or structured notes. A calling document MLM would call it.
|
||||
There are some requirements needed in the calling document MLM before calling this function MLM as followed:
|
||||
- Object needed to declare in the calling document MLM
|
||||
SelectedList := OBJECT[ ListGUID, SelectedValues, SuggestedText];
|
||||
|
||||
- Input parameters needed to create in Calling document MLM and pass into STD_DOC_FUNC_CHART_OBSERVATION_HELPER:
|
||||
|
||||
Object:Property
|
||||
----------------------------------------------------------------------------------
|
||||
this_documentCommunication DocumentCommunication
|
||||
|
||||
NewValue String array for FreetextValue
|
||||
DateValue for DateValue
|
||||
NumericValue for NumericValue or DripValue
|
||||
NumbericValue array for IOValue or GeneralDripValue
|
||||
SelectedList for ListValue or ListSetValue
|
||||
|
||||
Parameter parameter object of the target observation
|
||||
|
||||
USAGE EXAMPLE:
|
||||
--------------
|
||||
|
||||
NewValue for inserting it into Charted Observation:
|
||||
--------------------------------------------------
|
||||
- NumericValue
|
||||
NewValue := <NumericValue>; eg. NewValue := 24.5;
|
||||
- DateValue
|
||||
NewValue := <DateValue>; eg. NewValue := NOW;
|
||||
- FreeTextValue
|
||||
NewValue := (<String1>, <String2>);
|
||||
eg. NewValue := ("This is an example of writing to a free text value.", "Replace");
|
||||
NewValue[1] is Text for FreeText field and NewValue[2] Update Type for either "Replace" or "Append".
|
||||
- IOValue
|
||||
NewValue := (<NumericValue1>, <NumericValue1>); eg. NewValue := (24.5, 20.4);
|
||||
NewValue[1] is InValue and NewValue[2] OutValue.
|
||||
- GenericDripValue
|
||||
NewValue := (<NumericValue1>, <NumericValue1>); eg. NewValue := (1000, 50);
|
||||
NewValue[1] is DoseValue and NewValue[2] RateValue.
|
||||
- DripValue
|
||||
NewValue := <NumericValue>; eg. NewValue := (20);
|
||||
- ListSetValue and ListValue
|
||||
NewValue := (<SelectedList1>, <SelectedList2>, <SelectedList3>,...);
|
||||
e.g NewValue := (ItemList1) for ListValue (There is only one SelectedList for ListValue)
|
||||
NewValue := (ItemList1, List2,... Listn) for ListSetValue;
|
||||
ItemList1 := NEW SelectedList;
|
||||
ItemList1.ListGUID := 208488439439; // List Identification - Required
|
||||
ItemList1.SelectedValues := ("Yellow", "Green", "Blue") // Selected Values - Required
|
||||
ItemList1.SuggestedText := "Neither black nor white"; // List{{{SINGLE-QUOTE}}}s SugguestedTextValue - Optional - Can be null
|
||||
............................................................
|
||||
|
||||
NewValue for clearing Charted Observation.
|
||||
-----------------------------------------
|
||||
This functionality is for most datatypes, except ListSetValue and ListValue.
|
||||
The NewValue for clearing charted observation is an empty string.
|
||||
- NumericValue, DateValue, and DripValue
|
||||
NewValue := "";
|
||||
- FreeTextValue, IOValue and GenericDripValue
|
||||
NewValue := ("", "");
|
||||
|
||||
This MLM can also clear the current or existing SuggestedText(s) of ListSetValue and ListValue.
|
||||
If ItemListN.SuggestedText is set to an empty string e.g. ItemListN.SuggestedText := "";.
|
||||
|
||||
Calling this MLM:
|
||||
----------------
|
||||
Sample codes:
|
||||
called_DOM_mlm := MLM {{{SINGLE-QUOTE}}}STD_FUNC_CHART_OBSERVATION_HELPER{{{SINGLE-QUOTE}}};
|
||||
this_documentCommunication := CALL called_DOM_mlm WITH (this_documentCommunication, NewValue, Parameter);
|
||||
;;
|
||||
keywords: Called MLM Function
|
||||
;;
|
||||
knowledge:
|
||||
type: data-driven;;
|
||||
data:
|
||||
|
||||
(this_documentCommunication, newValue, parameter) := argument; //v230478
|
||||
//(this_documentCommunication, newValue, parameterName) := argument;
|
||||
/*******************Make Changes To Spelling And Flags In This Section******************/
|
||||
/* Set to true if a decision.log is needed.*/
|
||||
log_execution_info := false;
|
||||
Debug := FALSE;
|
||||
|
||||
/***************************************************************************************/
|
||||
//*** Variable and Constant Declaration ***//
|
||||
// Document Types
|
||||
FLOWSHEET := "Flowsheet";
|
||||
STRUCTUREDNOTE := "StructuredNote";
|
||||
// Event Types
|
||||
//DOCUMENTOPENING := "DocumentOpening";
|
||||
//CHARTOBSERVATION := "ChartObservation";
|
||||
//DOCUMENTCLOSING := "DocumentClosing";
|
||||
|
||||
// Parameter Types
|
||||
NUMERICVALUE := "NumericValue";
|
||||
FREETEXTVALUE := "FreeTextValue";
|
||||
LISTVALUE := "ListValue";
|
||||
LISTSETVALUE := "ListSetValue";
|
||||
DATEVALUE := "DateValue";
|
||||
IOVALUE := "IOValue" ;
|
||||
GENERICDRIPVALUE := "GenericDripValue" ;
|
||||
DRIPVALUE := "DripValue" ;
|
||||
//*** Data Structures ***//
|
||||
//The following data structures can be used to create new objects within the
|
||||
//MLM itself. Not all data structures are represented here, only ones that can be
|
||||
//created in the MLM.
|
||||
//
|
||||
ObservationType := OBJECT [ObservationGUID, ClientDocumentGUID, ParameterGUID, DataType, ValueObj];
|
||||
DateValueType := OBJECT [Value];
|
||||
FreeTextValueType := OBJECT [Value];
|
||||
ListValueType := OBJECT [ListGUID, ListItemsList, SuggestedTextValue];
|
||||
ListValueListItemType := OBJECT [ListItemGUID, Value, IsSelected];
|
||||
NumericValueType := OBJECT [Value];
|
||||
IOValueType := OBJECT [InValue, OutValue, DayRunningValue, BagNumber, BagInitialVolume];
|
||||
GenericDripValueType := OBJECT [DoseValue, RateValue];
|
||||
DripValueType := OBJECT [Value, BagNumber, BagInitialVolume];
|
||||
ListSetValueType := OBJECT [ListValuesList];
|
||||
//SelectedList := OBJECT[ ListGUID, SelectedValues, SuggestedTextValue];
|
||||
|
||||
(this_parameters) := NULL;
|
||||
messageDebug := "";
|
||||
(this_chartedObservationsList) := NULL;
|
||||
|
||||
IF this_documentCommunication.DocumentType = FLOWSHEET THEN
|
||||
(this_flowsheetDoc) := this_documentCommunication.DocumentConfigurationObj;
|
||||
(this_CurrentColumn) := this_flowsheetDoc.CurrentColumn;
|
||||
this_parameters := this_flowsheetDoc.ParametersList;
|
||||
this_chartedObservationsList := this_CurrentColumn.ChartedObservationsList;
|
||||
(client_document_guid) := this_CurrentColumn.ClientDocumentGUID;
|
||||
messageDebug := messageDebug || "Flowsheet";
|
||||
|
||||
ELSEIF this_documentCommunication.DocumentType = STRUCTUREDNOTE THEN
|
||||
(this_structuredNoteDoc) := this_documentCommunication.DocumentConfigurationObj;
|
||||
this_parameters := this_structuredNoteDoc.ParametersList;
|
||||
this_chartedObservationsList := this_structuredNoteDoc.ChartedObservationsList;
|
||||
(client_document_guid) := this_structuredNoteDoc.ClientDocumentGUID;
|
||||
messageDebug := messageDebug || "Structured Note";
|
||||
ENDIF;
|
||||
(this_currentObj) := this_documentCommunication.CurrentObservationObj;
|
||||
|
||||
obsExisted := TRUE;
|
||||
IF EXISTS parameter THEN
|
||||
messageDebug := messageDebug || "\n Parameter is available.";
|
||||
obs := FIRST OF (this_ChartedObservationsList WHERE this_ChartedObservationsList.parameterGUID = parameter.parameterGUID);
|
||||
IF NOT EXISTS obs THEN
|
||||
|
||||
obsExisted := FALSE;
|
||||
messageDebug := messageDebug || "\n Charted Observation is not existed. Creating one.";
|
||||
//Create a new Observation for the list
|
||||
obs := NEW ObservationType;
|
||||
obs.ObservationGUID:= 0; //v230478
|
||||
obs.ClientDocumentGUID := client_document_guid;
|
||||
obs.ParameterGUID := parameter.ParameterGUID;
|
||||
obs.DataType := parameter.DataType;
|
||||
// Based on the parameter.DataType create the ValueObj Type and set the valueObj.value for (FREETEXTVALUETYPE,DATEVALUETYPE,NUMERICVALUETYPE)
|
||||
// If the DataType is LISTVALUE then creat the valueObj of LISTVALUETYPE ABD ASSIGN THE paramter.configurationObj.ListGUID
|
||||
IF parameter.DataType = FREETEXTVALUE THEN
|
||||
obs.ValueObj := NEW FreeTextValueType;
|
||||
ELSEIF parameter.DataType = DATEVALUE THEN
|
||||
obs.ValueObj := NEW DateValueType;
|
||||
ELSEIF parameter.DataType = DRIPVALUE THEN
|
||||
obs.ValueObj := NEW DripValueType;
|
||||
ELSEIF parameter.DataType = NUMERICVALUE THEN
|
||||
obs.ValueObj := NEW NumericValueType;
|
||||
ELSEIF parameter.DataType = LISTVALUE THEN
|
||||
obs.ValueObj := NEW ListValueType;
|
||||
obs.ValueObj.ListGUID := parameter.ConfigurationObj.ListGUID;
|
||||
ELSEIF parameter.DataType = LISTSETVALUE THEN
|
||||
obs.ValueObj := NEW ListSetValueType;
|
||||
ELSEIF parameter.DataType = IOVALUE THEN
|
||||
obs.ValueObj := NEW IOValueType;
|
||||
ELSEIF parameter.DataType = GENERICDRIPVALUE THEN
|
||||
obs.ValueObj := NEW GenericDripValueType;
|
||||
ENDIF; // creating obs.ValueObj
|
||||
|
||||
ELSE
|
||||
messageDebug := messageDebug || "\n Charted Observation is existed.";
|
||||
ENDIF; // IF NOT EXISTS obs
|
||||
|
||||
// Setting Value
|
||||
IF parameter.DataType = FREETEXTVALUE THEN
|
||||
Text := STRING newValue[1];
|
||||
UpdateType := STRING newValue[2];
|
||||
IF EXISTS Text AND Text <> "" THEN
|
||||
IF LENGTH of obs.ValueObj.Value > 0 AND UpdateType = "Append" THEN
|
||||
obs.ValueObj.Value := obs.ValueObj.Value || "\n" || Text;
|
||||
messageDebug := messageDebug || "\n Append free text - " || parameter.Name || " - " || Text;
|
||||
ELSE
|
||||
obs.ValueObj.Value := Text;
|
||||
ENDIF;
|
||||
ELSE
|
||||
IF EXISTS obs.ValueObj.Value THEN
|
||||
obs.ValueObj.Value := "";
|
||||
ENDIF;
|
||||
messageDebug := messageDebug || "\n Set free text To Empty String";
|
||||
ENDIF;
|
||||
ELSEIF parameter.DataType IN(DATEVALUE,NUMERICVALUE, DRIPVALUE) THEN
|
||||
IF EXISTS newValue AND newValue <> "" THEN
|
||||
obs.ValueObj.Value := newValue;
|
||||
messageDebug := messageDebug || "\n Set " || parameter.DataType || " - " || parameter.Name || " - " ||newValue;
|
||||
ELSE
|
||||
obs.ValueObj := NULL;
|
||||
messageDebug := messageDebug || "\n Deleted " || parameter.DataType;
|
||||
ENDIF;
|
||||
ELSEIF parameter.DataType = IOVALUE THEN
|
||||
// newValue[1] is InValue and newValue[2] OutValue
|
||||
IF EXISTS newValue[1] AND newValue[1] <> "" THEN
|
||||
messageDebug := messageDebug || "\n Set IOValue IN - " || parameter.Name || " - " || newValue[1];
|
||||
obs.ValueObj.InValue := newValue[1];
|
||||
ELSE
|
||||
messageDebug := messageDebug || "\n Deleted IOValue";
|
||||
obs.ValueObj := NULL;
|
||||
ENDIF;
|
||||
IF EXISTS newValue[2] AND newValue[2] <> "" THEN
|
||||
messageDebug := messageDebug || "\n Set IOValue OUT - " || parameter.Name || " - " ||newValue[2];
|
||||
obs.ValueObj.OutValue := newValue[2];
|
||||
ELSE
|
||||
messageDebug := messageDebug || "\n Deleted IOValue";
|
||||
obs.ValueObj := NULL;
|
||||
ENDIF;
|
||||
ELSEIF parameter.DataType = GENERICDRIPVALUE THEN
|
||||
// newValue[1] is DoseValue and newValue[2] RateValue
|
||||
IF EXISTS newValue[1] AND newValue[1] <> "" THEN
|
||||
messageDebug := messageDebug || "\n Set GenericDripValue DoseValue - " || parameter.Name || " - " ||newValue[1];
|
||||
obs.ValueObj.DoseValue := newValue[1];
|
||||
ELSE
|
||||
messageDebug := messageDebug || "\n Deleted GenericDripValue DoseValue";
|
||||
obs.ValueObj := NULL;
|
||||
ENDIF;
|
||||
IF EXISTS newValue[2] AND newValue[2] <> "" THEN
|
||||
messageDebug := messageDebug || "\n Set GenericDripValue RateValue - " || parameter.Name || " - " ||newValue[2];
|
||||
obs.ValueObj.RateValue := newValue[2];
|
||||
ELSE
|
||||
messageDebug := messageDebug || "\n Deleted GenericDripValue";
|
||||
obs.ValueObj := NULL;
|
||||
ENDIF;
|
||||
ELSEIF parameter.DataType IN (LISTVALUE, LISTSETVALUE) THEN
|
||||
IF obsExisted = TRUE THEN
|
||||
ListValues := ();
|
||||
IF parameter.DataType = LISTVALUE THEN
|
||||
ListValues := (ListValues, Obs.ValueObj);
|
||||
messageDebug := messageDebug || "\n Selected Items of LISTVALUE - " || parameter.Name;
|
||||
ELSE
|
||||
ListValues := Obs.ValueObj.ListValuesList;
|
||||
messageDebug := messageDebug || "\n Selected Items of LISTSETVALUE - " || parameter.Name;
|
||||
ENDIF;
|
||||
|
||||
FOR itemsList in ListValues DO
|
||||
selList := newValue WHERE newValue.ListGUID = itemsList.ListGUID;
|
||||
IF parameter.DataType = LISTVALUE THEN
|
||||
listConfiguration := parameter.ConfigurationObj;
|
||||
ELSE
|
||||
listConfiguration := FIRST OF (parameter.ConfigurationObj.ListConfigurationList
|
||||
WHERE parameter.ConfigurationObj.ListConfigurationList.ListGUID = itemsList.ListGUID);
|
||||
ENDIF;
|
||||
|
||||
selValues := ();
|
||||
IF EXIST selList THEN
|
||||
FOR selvalue in selList.SelectedValues DO
|
||||
selValues := (selValues, selvalue);
|
||||
ENDDO;
|
||||
IF EXISTS selList.SuggestedTextValue THEN
|
||||
suggText := STRING selList.SuggestedTextValue;
|
||||
ENDIF;
|
||||
ENDIF;
|
||||
|
||||
IF listConfiguration.AllowsSuggestedText = TRUE THEN
|
||||
itemsList.SuggestedTextValue := suggText;
|
||||
ENDIF;
|
||||
|
||||
multiSelect := TRUE;
|
||||
FOR item IN itemsList.ListItemsList DO
|
||||
IF item.Value IN selValues AND multiSelect = TRUE THEN
|
||||
item.IsSelected := TRUE;
|
||||
IF listConfiguration.IsMultiSelect = FALSE THEN
|
||||
multiSelect := FALSE;
|
||||
ENDIF;
|
||||
messageDebug := messageDebug || "\n " || Item.Value || " selected";
|
||||
ELSE
|
||||
messageDebug := messageDebug || "\n " || Item.Value || " de-selected";
|
||||
ENDIF;
|
||||
ENDDO;
|
||||
ENDDO;
|
||||
//obs did not exist, aka: param was not charted on prior to this mlm being called
|
||||
ELSE
|
||||
listConfigurations := ();
|
||||
IF parameter.DataType = LISTVALUE THEN
|
||||
listConfigurations := (listConfigurations, parameter.ConfigurationObj);
|
||||
ELSE
|
||||
listConfigurations := parameter.ConfigurationObj.ListConfigurationList;
|
||||
ENDIF;
|
||||
FOR itemsList IN listConfigurations DO
|
||||
IF parameter.DataType = LISTVALUE THEN
|
||||
newlistValue := obs.ValueObj;
|
||||
ELSE
|
||||
newlistValue := NEW ListValueType;
|
||||
newlistValue.ListGUID := itemsList.ListGUID;
|
||||
ENDIF;
|
||||
//selList is the passed in list contained in newValue
|
||||
selList := newValue WHERE newListValue.ListGUID = itemsList.ListGUID;
|
||||
|
||||
selValues := ();
|
||||
IF EXIST selList THEN
|
||||
FOR selvalue in selList.SelectedValues DO
|
||||
selValues := (selValues, selvalue);
|
||||
ENDDO;
|
||||
IF EXISTS selList.SuggestedTextValue THEN
|
||||
suggText := STRING selList.SuggestedTextValue;
|
||||
ENDIF;
|
||||
ENDIF;
|
||||
IF itemsList.AllowsSuggestedText = TRUE THEN
|
||||
newListValue.SuggestedTextValue := suggText;
|
||||
ENDIF;
|
||||
multiSelect := TRUE;
|
||||
FOR item IN itemsList.ListItemsList DO
|
||||
// Create a list item object for the selected list item
|
||||
newItem := NEW ListValueListItemType;
|
||||
newItem.ListItemGUID := item.ListItemGUID;
|
||||
newItem.Value := item.Value;
|
||||
|
||||
IF item.Value IN selValues AND multiSelect = TRUE THEN
|
||||
newItem.IsSelected := TRUE;
|
||||
IF itemsList.IsMultiSelect = FALSE THEN
|
||||
multiSelect := FALSE;
|
||||
ENDIF;
|
||||
messageDebug := messageDebug || "\n New ListItem - " || item.Value || " selected";
|
||||
ELSE
|
||||
// This is To Select any Single select List value. // Start-- Added By Ganesh
|
||||
IF newValue = item.Value THEN
|
||||
newItem.IsSelected := TRUE;
|
||||
ELSE
|
||||
// Multiselect list value
|
||||
IF item.Value IN newValue THEN
|
||||
newItem.IsSelected := TRUE;
|
||||
ELSE
|
||||
newItem.IsSelected := FALSE;
|
||||
ENDIF;
|
||||
//END Ganesh Changes
|
||||
ENDIF;
|
||||
messageDebug := messageDebug || "\n New ListItem - " || item.Value || " de-selected";
|
||||
ENDIF;
|
||||
// Arden list append statement appending the new object to the listItems object
|
||||
newListValue.ListItemsList := (newListValue.ListItemsList, newItem);
|
||||
ENDDO;
|
||||
IF parameter.DataType = LISTSETVALUE THEN
|
||||
Obs.ValueObj.ListValuesList := (Obs.ValueObj.ListValuesList, newListValue);
|
||||
ELSE
|
||||
Obs.ValueObj := newListValue;
|
||||
ENDIF;
|
||||
ENDDO;
|
||||
ENDIF;
|
||||
ENDIF; // END Setting value
|
||||
IF obsExisted = FALSE THEN
|
||||
IF exists this_chartedObservationsList THEN
|
||||
IF this_documentCommunication.DocumentType = FLOWSHEET THEN
|
||||
this_CurrentColumn.ChartedObservationsList := (this_chartedObservationsList, obs);
|
||||
ELSEIF this_documentCommunication.DocumentType = STRUCTUREDNOTE THEN
|
||||
this_structuredNoteDoc.ChartedObservationsList:= (this_chartedObservationsList, obs);
|
||||
ENDIF;
|
||||
ELSE
|
||||
IF this_documentCommunication.DocumentType = FLOWSHEET THEN
|
||||
this_CurrentColumn.ChartedObservationsList := (obs as list);
|
||||
ELSEIF this_documentCommunication.DocumentType = STRUCTUREDNOTE THEN
|
||||
this_structuredNoteDoc.ChartedObservationsList:= (obs as list);
|
||||
ENDIF;
|
||||
ENDIF;
|
||||
ENDIF;
|
||||
ELSE
|
||||
messageDebug := messageDebug || "\n Parameter is not available.";
|
||||
ENDIF; // IF EXISTS parameter
|
||||
//Tell DocumentCommunication to Display the Message
|
||||
IF Debug = TRUE THEN
|
||||
this_documentCommunication.DisplayMessage := TRUE;
|
||||
this_documentCommunication.Message := messageDebug;
|
||||
ENDIF;
|
||||
|
||||
;;
|
||||
priority: 50
|
||||
;;
|
||||
evoke:
|
||||
;;
|
||||
logic:
|
||||
conclude true;
|
||||
;;
|
||||
action:
|
||||
return this_documentCommunication;
|
||||
;;
|
||||
Urgency: 50;;
|
||||
end:
|
||||
@@ -0,0 +1,483 @@
|
||||
maintenance:
|
||||
|
||||
title: Standard Function for setting observation values with
|
||||
supplied parameters;;
|
||||
mlmname: STD_DOC_FUNC_CHART_OBSERVATION_HELPER_JAB;;
|
||||
arden: version 2.5;;
|
||||
version: 5.50;;
|
||||
institution: Eclipsys, Function for use with Document Called MLM;;
|
||||
author: Eclipsys Corporartion;;
|
||||
specialist: ;;
|
||||
date: 2010-03-16;;
|
||||
validation: testing;;
|
||||
|
||||
library:
|
||||
purpose: MLM standard function that inserts value into an observation in
|
||||
structured note or Flowsheet.
|
||||
20110203 - JAB edited to allow a passed parameter name.
|
||||
;;
|
||||
explanation:
|
||||
DEPENDENCIES:
|
||||
-------------
|
||||
None
|
||||
|
||||
SOFTWARE REQUIREMENTS:
|
||||
----------------------
|
||||
Requires Sunrise 5.0 SP1
|
||||
|
||||
CONFIGURATION:
|
||||
--------------
|
||||
Supported Document Types:
|
||||
[X] Flowsheets
|
||||
[X] Structured Notes
|
||||
|
||||
MLM Events Supported:
|
||||
[X] ChartObservation
|
||||
[X] DocumentOpening
|
||||
[X] DocumentClosing
|
||||
|
||||
Instructions:
|
||||
------------
|
||||
This function MLM cannot be called directly from flowsheets or structured
|
||||
notes. A calling document MLM would call it. There are some requirements
|
||||
needed in the calling document MLM before calling this function MLM as followes:
|
||||
|
||||
- Object needed to declare in the calling document MLM
|
||||
SelectedList := OBJECT[ ListGUID, SelectedValues, SuggestiveText];
|
||||
|
||||
- Input parameters needed to create in Calling document MLM and pass into
|
||||
STD_DOC_FUNC_CHART_OBSERVATION_HELPER:
|
||||
|
||||
Object:Property
|
||||
----------------------------------------------------------------------------------
|
||||
this_documentCommunication DocumentCommunication
|
||||
|
||||
NewValue String array for FreetextValue
|
||||
DateValue for DateValue
|
||||
NumericValue for NumericValue or DripValue
|
||||
NumbericValue array for IOValue or GeneralDripValue
|
||||
SelectedList for ListValue or ListSetValue
|
||||
|
||||
USAGE EXAMPLE:
|
||||
--------------
|
||||
|
||||
NewValue for inserting it into Charted Observation:
|
||||
--------------------------------------------------
|
||||
- NumericValue
|
||||
NewValue := <NumericValue>; eg. NewValue := 24.5;
|
||||
- DateValue
|
||||
NewValue := <DateValue>; eg. NewValue := NOW;
|
||||
- FreeTextValue
|
||||
NewValue := (<String1>, <String2>);
|
||||
eg. NewValue := ("This is an example of writing to a free text value.",
|
||||
"Replace");
|
||||
NewValue[1] is Text for FreeText field and NewValue[2] Update Type for either
|
||||
"Replace" or "Append".
|
||||
- IOValue
|
||||
NewValue := (<NumericValue1>, <NumericValue1>); eg. NewValue := (24.5, 20.4);
|
||||
NewValue[1] is InValue and NewValue[2] OutValue.
|
||||
- GenericDripValue
|
||||
NewValue := (<NumericValue1>, <NumericValue1>); eg. NewValue := (1000, 50);
|
||||
NewValue[1] is DoseValue and NewValue[2] RateValue.
|
||||
- DripValue
|
||||
NewValue := <NumericValue>; eg. NewValue := (20);
|
||||
- ListSetValue and ListValue
|
||||
NewValue := (<SelectedList1>, <SelectedList2>, <SelectedList3>,...);
|
||||
e.g NewValue := (ItemList1) for ListValue (There is only one SelectedList
|
||||
for ListValue)
|
||||
NewValue := (ItemList1, List2,... Listn) for ListSetValue;
|
||||
ItemList1 := NEW SelectedList;
|
||||
ItemList1.ListGUID := 208488439439; // List Identification - Required
|
||||
ItemList1.SelectedValues := ("Yellow", "Green", "Blue")
|
||||
// Selected Values - Required
|
||||
ItemList1.SuggestiveText := "Neither black nor white";
|
||||
//List{{{SINGLE-QUOTE}}}s SugguestedTextValue - Optional - Can be null
|
||||
............................................................
|
||||
|
||||
NewValue for clearing Charted Observation.
|
||||
-----------------------------------------
|
||||
This functionality is for most datatypes, except ListSetValue and ListValue.
|
||||
The NewValue for clearing charted observation is an empty string.
|
||||
- NumericValue, DateValue, and DripValue
|
||||
NewValue := "";
|
||||
- FreeTextValue, IOValue and GenericDripValue
|
||||
NewValue := ("", "");
|
||||
|
||||
This MLM can also clear the current or existing SuggestiveText(s) of ListSetValue
|
||||
and ListValue. If ItemListN.SuggestiveText is set to an empty string
|
||||
e.g. ItemListN.SuggestiveText := "";.
|
||||
|
||||
Calling this MLM:
|
||||
----------------
|
||||
Sample codes:
|
||||
called_DOM_mlm := MLM {{{SINGLE-QUOTE}}}STD_FUNC_CHART_OBSERVATION_HELPER{{{SINGLE-QUOTE}}};
|
||||
this_documentCommunication := CALL called_DOM_mlm WITH (this_documentCommunication,
|
||||
NewValue);
|
||||
;;
|
||||
keywords: Called MLM Function
|
||||
;;
|
||||
knowledge:
|
||||
type: data-driven;;
|
||||
data:
|
||||
|
||||
(this_documentCommunication,
|
||||
//20110203 - JAB edited to allow a passed parameter name.
|
||||
parameter_name,
|
||||
newValue) := argument;
|
||||
/*******************Make Changes To Spelling And Flags In This Section******************/
|
||||
/* Set to true if a decision.log is needed.*/
|
||||
log_execution_info := true;
|
||||
Debug := false;
|
||||
|
||||
standard_libs := mlm {{{SINGLE-QUOTE}}}std_include_libs{{{SINGLE-QUOTE}}};
|
||||
include standard_libs;
|
||||
using "ObjectsPlusXA.SCM.Forms";
|
||||
using namespace "ObjectsPlusXA.SunriseClinicalManager.Forms";
|
||||
|
||||
|
||||
/***************************************************************************************/
|
||||
//*** Variable and Constant Declaration ***//
|
||||
// Document Types
|
||||
FLOWSHEET := "Flowsheet";
|
||||
STRUCTUREDNOTE := "StructuredNote";
|
||||
// Event Types
|
||||
//DOCUMENTOPENING := "DocumentOpening";
|
||||
//CHARTOBSERVATION := "ChartObservation";
|
||||
//DOCUMENTCLOSING := "DocumentClosing";
|
||||
|
||||
// Parameter Types
|
||||
NUMERICVALUE := "NumericValue";
|
||||
FREETEXTVALUE := "FreeTextValue";
|
||||
LISTVALUE := "ListValue";
|
||||
LISTSETVALUE := "ListSetValue";
|
||||
DATEVALUE := "DateValue";
|
||||
IOVALUE := "IOValue" ;
|
||||
GENERICDRIPVALUE := "GenericDripValue" ;
|
||||
DRIPVALUE := "DripValue" ;
|
||||
//*** Data Structures ***//
|
||||
//The following data structures can be used to create new objects within the
|
||||
//MLM itself. Not all data structures are represented here, only ones that can be
|
||||
//created in the MLM.
|
||||
//
|
||||
ObservationType := OBJECT [ObservationGUID, ClientDocumentGUID, ParameterGUID,
|
||||
DataType, ValueObj];
|
||||
DateValueType := OBJECT [Value];
|
||||
FreeTextValueType := OBJECT [Value];
|
||||
ListValueType := OBJECT [ListGUID, ListItemsList, SuggestedTextValue];
|
||||
ListValueListItemType := OBJECT [ListItemGUID, Value, IsSelected];
|
||||
NumericValueType := OBJECT [Value];
|
||||
IOValueType := OBJECT [InValue, OutValue, DayRunningValue, BagNumber,
|
||||
BagInitialVolume];
|
||||
GenericDripValueType := OBJECT [DoseValue, RateValue];
|
||||
DripValueType := OBJECT [Value, BagNumber, BagInitialVolume];
|
||||
ListSetValueType := OBJECT [ListValuesList];
|
||||
//SelectedList := OBJECT[ ListGUID, SelectedValues, SuggestiveText];
|
||||
|
||||
(this_parameters) := NULL;
|
||||
messageDebug := "";
|
||||
(this_chartedObservationsList) := NULL;
|
||||
|
||||
IF this_documentCommunication.DocumentType = FLOWSHEET THEN
|
||||
(this_flowsheetDoc) := this_documentCommunication.DocumentConfigurationObj;
|
||||
(this_CurrentColumn) := this_flowsheetDoc.CurrentColumn;
|
||||
this_parameters := this_flowsheetDoc.ParametersList;
|
||||
this_chartedObservationsList := this_CurrentColumn.ChartedObservationsList;
|
||||
(client_document_guid) := this_CurrentColumn.ClientDocumentGUID;
|
||||
messageDebug := messageDebug || "Flowsheet";
|
||||
|
||||
ELSEIF this_documentCommunication.DocumentType = STRUCTUREDNOTE THEN
|
||||
(this_structuredNoteDoc) := this_documentCommunication.DocumentConfigurationObj;
|
||||
this_parameters := this_structuredNoteDoc.ParametersList;
|
||||
this_chartedObservationsList := this_structuredNoteDoc.ChartedObservationsList;
|
||||
(client_document_guid) := this_structuredNoteDoc.ClientDocumentGUID;
|
||||
messageDebug := messageDebug || "Structured Note";
|
||||
ENDIF;
|
||||
(this_currentObj) := this_documentCommunication.CurrentObservationObj;
|
||||
parameter := FIRST OF (this_parameters
|
||||
//20110203 - JAB edited to allow a passed parameter name.
|
||||
// WHERE this_parameters.ParameterGUID = this_currentObj.ParameterGUID);
|
||||
WHERE this_parameters.name = parameter_name);
|
||||
//20110203 - JAB END of change
|
||||
obsExisted := TRUE;
|
||||
IF EXISTS parameter THEN
|
||||
messageDebug := messageDebug || "\n Parameter is available.";
|
||||
obs := FIRST OF (this_ChartedObservationsList
|
||||
WHERE this_ChartedObservationsList.parameterGUID = parameter.parameterGUID);
|
||||
IF NOT EXISTS obs THEN
|
||||
|
||||
obsExisted := FALSE;
|
||||
messageDebug := messageDebug
|
||||
|| "\n Charted Observation is not existed. Creating one.";
|
||||
//Create a new Observation for the list
|
||||
obs := NEW ObservationType;
|
||||
obs.ClientDocumentGUID := client_document_guid;
|
||||
obs.ParameterGUID := parameter.ParameterGUID;
|
||||
obs.DataType := parameter.DataType;
|
||||
// Based on the parameter.DataType create the ValueObj Type and set the
|
||||
// valueObj.value for (FREETEXTVALUETYPE,DATEVALUETYPE,NUMERICVALUETYPE)
|
||||
// If the DataType is LISTVALUE then creat the valueObj of LISTVALUETYPE
|
||||
// AND ASSIGN THE paramter.configurationObj.ListGUID
|
||||
IF parameter.DataType = FREETEXTVALUE THEN
|
||||
obs.ValueObj := NEW FreeTextValueType;
|
||||
ELSEIF parameter.DataType = DATEVALUE THEN
|
||||
obs.ValueObj := NEW DateValueType;
|
||||
ELSEIF parameter.DataType = DRIPVALUE THEN
|
||||
obs.ValueObj := NEW DripValueType;
|
||||
ELSEIF parameter.DataType = NUMERICVALUE THEN
|
||||
obs.ValueObj := NEW NumericValueType;
|
||||
ELSEIF parameter.DataType = LISTVALUE THEN
|
||||
obs.ValueObj := NEW ListValueType;
|
||||
obs.ValueObj.ListGUID := parameter.ConfigurationObj.ListGUID;
|
||||
ELSEIF parameter.DataType = LISTSETVALUE THEN
|
||||
obs.ValueObj := NEW ListSetValueType;
|
||||
ELSEIF parameter.DataType = IOVALUE THEN
|
||||
obs.ValueObj := NEW IOValueType;
|
||||
ELSEIF parameter.DataType = GENERICDRIPVALUE THEN
|
||||
obs.ValueObj := NEW GenericDripValueType;
|
||||
ENDIF; // creating obs.ValueObj
|
||||
// APPEND obs to the ChartedObservationsList
|
||||
//this_chartedObservationsList := (this_chartedObservationsList, obs);
|
||||
ELSE
|
||||
messageDebug := messageDebug || "\n Charted Observation is existed.";
|
||||
ENDIF; // IF NOT EXISTS obs
|
||||
|
||||
// Setting Value
|
||||
IF parameter.DataType = FREETEXTVALUE THEN
|
||||
Text := STRING newValue[1];
|
||||
UpdateType := STRING newValue[2];
|
||||
IF EXISTS Text AND Text <> "" THEN
|
||||
//break;
|
||||
IF LENGTH of obs.ValueObj.Value > 0 AND UpdateType = "Append" THEN
|
||||
obs.ValueObj.Value := obs.ValueObj.Value || "\n" || Text;
|
||||
messageDebug := messageDebug || "\n Append free text - "
|
||||
|| parameter.Name || " - " || Text;
|
||||
//break;
|
||||
ELSE
|
||||
obs.ValueObj.Value := Text;
|
||||
messageDebug := messageDebug || "\n Set free text - "
|
||||
|| parameter.Name || " - " || Text;
|
||||
//break;
|
||||
ENDIF;
|
||||
ELSE
|
||||
IF EXISTS obs.ValueObj.Value THEN
|
||||
obs.ValueObj.Value := "";
|
||||
ENDIF;
|
||||
messageDebug := messageDebug || "\n Set free text To Empty String";
|
||||
//break;
|
||||
ENDIF;
|
||||
ELSEIF parameter.DataType IN(DATEVALUE,NUMERICVALUE, DRIPVALUE) THEN
|
||||
IF EXISTS newValue AND newValue <> "" THEN
|
||||
obs.ValueObj.Value := newValue;
|
||||
messageDebug := messageDebug || "\n Set " || parameter.DataType
|
||||
|| " - " || parameter.Name || " - " ||newValue;
|
||||
ELSE
|
||||
obs.ValueObj := NULL;
|
||||
messageDebug := messageDebug || "\n Deleted " || parameter.DataType;
|
||||
//break;
|
||||
ENDIF;
|
||||
ELSEIF parameter.DataType = IOVALUE THEN
|
||||
// newValue[1] is InValue and newValue[2] OutValue
|
||||
IF EXISTS newValue[1] AND newValue[1] <> "" THEN
|
||||
messageDebug := messageDebug || "\n Set IOValue IN - " || parameter.Name
|
||||
|| " - " || newValue[1];
|
||||
obs.ValueObj.InValue := newValue[1];
|
||||
ELSE
|
||||
messageDebug := messageDebug || "\n Deleted IOValue";
|
||||
obs.ValueObj := NULL;
|
||||
ENDIF;
|
||||
IF EXISTS newValue[2] AND newValue[2] <> "" THEN
|
||||
messageDebug := messageDebug || "\n Set IOValue OUT - " || parameter.Name
|
||||
|| " - " ||newValue[2];
|
||||
obs.ValueObj.OutValue := newValue[2];
|
||||
ELSE
|
||||
messageDebug := messageDebug || "\n Deleted IOValue";
|
||||
obs.ValueObj := NULL;
|
||||
ENDIF;
|
||||
ELSEIF parameter.DataType = GENERICDRIPVALUE THEN
|
||||
// newValue[1] is DoseValue and newValue[2] RateValue
|
||||
IF EXISTS newValue[1] AND newValue[1] <> "" THEN
|
||||
messageDebug := messageDebug || "\n Set GenericDripValue DoseValue - "
|
||||
|| parameter.Name || " - " ||newValue[1];
|
||||
obs.ValueObj.DoseValue := newValue[1];
|
||||
ELSE
|
||||
messageDebug := messageDebug || "\n Deleted GenericDripValue DoseValue";
|
||||
obs.ValueObj := NULL;
|
||||
ENDIF;
|
||||
IF EXISTS newValue[2] AND newValue[2] <> "" THEN
|
||||
messageDebug := messageDebug || "\n Set GenericDripValue RateValue - "
|
||||
|| parameter.Name || " - " ||newValue[2];
|
||||
obs.ValueObj.RateValue := newValue[2];
|
||||
ELSE
|
||||
messageDebug := messageDebug || "\n Deleted GenericDripValue";
|
||||
obs.ValueObj := NULL;
|
||||
ENDIF;
|
||||
ELSEIF parameter.DataType IN (LISTVALUE, LISTSETVALUE) THEN
|
||||
IF obsExisted = TRUE THEN
|
||||
ListValues := ();
|
||||
IF parameter.DataType = LISTVALUE THEN
|
||||
ListValues := (ListValues, Obs.ValueObj);
|
||||
messageDebug := messageDebug || "\n Selected Items of LISTVALUE - "
|
||||
|| parameter.Name;
|
||||
ELSE
|
||||
ListValues := Obs.ValueObj.ListValuesList;
|
||||
messageDebug := messageDebug
|
||||
|| "\n Selected Items of LISTSETVALUE - " || parameter.Name;
|
||||
ENDIF;
|
||||
|
||||
FOR itemsList in ListValues DO
|
||||
selList := newValue WHERE newValue.ListGUID = itemsList.ListGUID;
|
||||
IF parameter.DataType = LISTVALUE THEN
|
||||
listConfiguration := parameter.ConfigurationObj;
|
||||
ELSE
|
||||
listConfiguration := FIRST OF
|
||||
(parameter.ConfigurationObj.ListConfigurationList WHERE
|
||||
parameter.ConfigurationObj.ListConfigurationList.ListGUID =
|
||||
itemsList.ListGUID);
|
||||
ENDIF;
|
||||
suggText := NULL;
|
||||
selValues := ();
|
||||
IF EXIST selList THEN
|
||||
FOR selvalue in selList.SelectedValues DO
|
||||
selValues := (selValues, selvalue);
|
||||
ENDDO;
|
||||
suggText := STRING selList.SuggestiveText;
|
||||
ENDIF;
|
||||
IF listConfiguration.AllowsSuggestedText = TRUE THEN
|
||||
IF NOT EXISTS suggText OR suggText = "" THEN
|
||||
IF EXIST itemsList.SuggestedTextValue THEN
|
||||
//break;
|
||||
itemsList.SuggestedTextValue := NULL;
|
||||
//break;
|
||||
ENDIF;
|
||||
ELSE
|
||||
IF EXIST itemsList.SuggestedTextValue THEN
|
||||
//break;
|
||||
itemsList.SuggestedTextValue :=
|
||||
itemsList.SuggestedTextValue || ", " || suggText;
|
||||
//break;
|
||||
ELSE
|
||||
//break;
|
||||
itemsList.SuggestedTextValue := suggText;
|
||||
//break;
|
||||
ENDIF;
|
||||
ENDIF;
|
||||
ENDIF;
|
||||
multiSelect := TRUE;
|
||||
FOR item IN itemsList.ListItemsList DO
|
||||
IF item.Value IN selValues AND multiSelect = TRUE THEN
|
||||
item.IsSelected := TRUE;
|
||||
IF listConfiguration.IsMultiSelect = FALSE THEN
|
||||
multiSelect := FALSE;
|
||||
ENDIF;
|
||||
messageDebug := messageDebug || "\n " || Item.Value
|
||||
|| " selected";
|
||||
ELSE
|
||||
item.IsSelected := FALSE;
|
||||
messageDebug := messageDebug || "\n " || Item.Value
|
||||
|| " de-selected";
|
||||
ENDIF;
|
||||
ENDDO;
|
||||
ENDDO;
|
||||
ELSE
|
||||
listConfigurations := ();
|
||||
IF parameter.DataType = LISTVALUE THEN
|
||||
listConfigurations := (listConfigurations,
|
||||
parameter.ConfigurationObj);
|
||||
ELSE
|
||||
listConfigurations :=
|
||||
parameter.ConfigurationObj.ListConfigurationList;
|
||||
ENDIF;
|
||||
FOR itemsList IN listConfigurations DO
|
||||
IF parameter.DataType = LISTVALUE THEN
|
||||
newlistValue := obs.ValueObj;
|
||||
ELSE
|
||||
newlistValue := NEW ListValueType;
|
||||
newListValue.ListGUID := itemsList.ListGUID;
|
||||
ENDIF;
|
||||
selList := newValue WHERE newValue.ListGUID = itemsList.ListGUID;
|
||||
suggText := NULL;
|
||||
selValues := ();
|
||||
IF EXIST selList THEN
|
||||
FOR selvalue in selList.SelectedValues DO
|
||||
selValues := (selValues, selvalue);
|
||||
ENDDO;
|
||||
suggText := STRING selList.SuggestiveText;
|
||||
ENDIF;
|
||||
IF itemsList.AllowsSuggestedText = TRUE THEN
|
||||
IF EXISTS suggText OR suggText <> "" THEN
|
||||
newListValue.SuggestedTextValue := suggText;
|
||||
ENDIF;
|
||||
ENDIF;
|
||||
multiSelect := TRUE;
|
||||
FOR item IN itemsList.ListItemsList DO
|
||||
// Create a list item object for the selected list item
|
||||
newItem := NEW ListValueListItemType;
|
||||
newItem.ListItemGUID := item.ListItemGUID;
|
||||
newItem.Value := item.Value;
|
||||
|
||||
IF item.Value IN selValues AND multiSelect = TRUE THEN
|
||||
newItem.IsSelected := TRUE;
|
||||
IF itemsList.IsMultiSelect = FALSE THEN
|
||||
multiSelect := FALSE;
|
||||
ENDIF;
|
||||
messageDebug := messageDebug || "\n New ListItem - "
|
||||
|| item.Value || " selected";
|
||||
ELSE
|
||||
newItem.IsSelected := FALSE;
|
||||
messageDebug := messageDebug || "\n New ListItem - "
|
||||
|| item.Value || " de-selected";
|
||||
ENDIF;
|
||||
// Arden list append statement appending the new object to
|
||||
// the listItems object
|
||||
newListValue.ListItemsList :=
|
||||
(newListValue.ListItemsList, newItem);
|
||||
ENDDO;
|
||||
IF parameter.DataType = LISTSETVALUE THEN
|
||||
Obs.ValueObj.ListValuesList := (Obs.ValueObj.ListValuesList,
|
||||
newListValue);
|
||||
ELSE
|
||||
Obs.ValueObj := newListValue;
|
||||
ENDIF;
|
||||
ENDDO;
|
||||
ENDIF;
|
||||
ENDIF; // END Setting value
|
||||
IF obsExisted = FALSE THEN
|
||||
//20110203 - JAB edited to allow a passed parameter name.
|
||||
// this_currentObj := obs;
|
||||
this_chartedObservationsList := (this_chartedObservationsList,
|
||||
// this_currentObj)
|
||||
obs)
|
||||
;
|
||||
IF this_documentCommunication.DocumentType = STRUCTUREDNOTE THEN
|
||||
this_documentCommunication.DocumentConfigurationObj.ChartedObservationsList := (
|
||||
this_documentCommunication.DocumentConfigurationObj.ChartedObservationsList,
|
||||
obs);
|
||||
ELSEIF this_documentCommunication.DocumentType = FLOWSHEET THEN
|
||||
this_documentCommunication.DocumentConfigurationObj.CurrentColumn.ChartedObservationsList:=(
|
||||
this_documentCommunication.DocumentConfigurationObj.CurrentColumn.ChartedObservationsList,
|
||||
Obs );
|
||||
endif;
|
||||
//20110203 - JAB end of change
|
||||
|
||||
ENDIF;
|
||||
ELSE
|
||||
messageDebug := messageDebug || "\n Parameter is not available.";
|
||||
ENDIF; // IF EXISTS parameter
|
||||
//Tell DocumentCommunication to Display the Message
|
||||
IF Debug = TRUE THEN
|
||||
this_documentCommunication.DisplayMessage := TRUE;
|
||||
this_documentCommunication.Message := messageDebug;
|
||||
ENDIF;
|
||||
//this_documentCommunication.FocusParameterGUID := parameter.parameterGUID;
|
||||
//break;
|
||||
;;
|
||||
priority: 50
|
||||
;;
|
||||
evoke:
|
||||
;;
|
||||
logic: conclude true;
|
||||
;;
|
||||
action: return this_documentCommunication;
|
||||
;;
|
||||
Urgency: 50;;
|
||||
end:
|
||||
1333
MLMStripper/bin/Debug/STD/STD_DOSAGE.mlm
Normal file
1333
MLMStripper/bin/Debug/STD/STD_DOSAGE.mlm
Normal file
File diff suppressed because it is too large
Load Diff
2645
MLMStripper/bin/Debug/STD/STD_DRUG_DIAGNOSIS_CONFLICT.mlm
Normal file
2645
MLMStripper/bin/Debug/STD/STD_DRUG_DIAGNOSIS_CONFLICT.mlm
Normal file
File diff suppressed because it is too large
Load Diff
1676
MLMStripper/bin/Debug/STD/STD_DRUG_INTERACTION.mlm
Normal file
1676
MLMStripper/bin/Debug/STD/STD_DRUG_INTERACTION.mlm
Normal file
File diff suppressed because it is too large
Load Diff
792
MLMStripper/bin/Debug/STD/STD_DUPLICATE.mlm
Normal file
792
MLMStripper/bin/Debug/STD/STD_DUPLICATE.mlm
Normal file
@@ -0,0 +1,792 @@
|
||||
maintenance:
|
||||
|
||||
title: Advanced Duplicate Order Checking;;
|
||||
mlmname: STD_DUPLICATE;;
|
||||
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: Provide Advanced Duplicate-Order Checking and Actions on Alerts.
|
||||
The checking will include:
|
||||
1. Orders of the same name or type within a pre-defined date range,
|
||||
which will be varied by patient location.
|
||||
2. Active orders of the same type/class.
|
||||
3. IV-additives.
|
||||
4. Resulted orders of community results of the same name within a pre-defined date range.
|
||||
;;
|
||||
explanation: An Evoking-Order is considered a duplicate of Other-Orders when all of
|
||||
the criteria listed below are met:
|
||||
a. The evoking-order is one of the following events: new order or outpatient order, released from hold,
|
||||
activated from a conditional order, unsuspended, verified, or an order or outpatient order that
|
||||
has been modified.
|
||||
b. If the evoking object is a modified order or outpatient order, only an order with changes to the
|
||||
SignificantDtm or the StopDtm will be checked for duplicate orders.
|
||||
c. The evoking-order has an order status level number between 0-50 (AWPA-AUA10),
|
||||
excluding 15 = HOLD.
|
||||
d. The evoking-order is not excluded from duplicate checking
|
||||
(over-all or by patient location).
|
||||
e. The orders have identical Item Names, or the other-order matches the Item or
|
||||
Class-Name & Value listed in the evoking-order{{{SINGLE-QUOTE}}}s item-catalog
|
||||
duplicate-checking panel.
|
||||
f. The other-orders are within the scoping rules for the patient location listed
|
||||
in the evoking-order{{{SINGLE-QUOTE}}}s Duplicate Policy. The patient{{{SINGLE-QUOTE}}}s location is based on
|
||||
the location-business-rules established by the facility for other parts of
|
||||
Sunrise Clinical Manager.
|
||||
g. The IsConditional status match between the evoking-order and the other-order.
|
||||
h. Neither the evoking-order or the other-order are suspended.
|
||||
i. Neither the evoking-order or the other-order are Master Repeat Orders.
|
||||
j. The evoking-order conflicts with another current/active order,
|
||||
or resources could be wasted if both orders are completed.
|
||||
The radio-buttons in the item-catalog--duplicate panel determine
|
||||
which situation may be occurring.
|
||||
* CONFLICTING ORDER: If the radio-button for
|
||||
"Based on Start and Stop Date (like medication orders)"
|
||||
is selected, then only "current" orders with over-lapping
|
||||
start (significant) & stop-times are considered conflicting orders.
|
||||
Current orders have an order status level number
|
||||
between 0-50, excluding HOLD, CANC, CANP, CAND, CANT, COMPA,
|
||||
HISE, HISI, DISC, DISCD and DISCT.
|
||||
These orders can be unsubmitted orders or orders already in the database.
|
||||
* WASTING RESOURCES: If the radio-button for
|
||||
"Based on Significant Date and Time (like diagnostic orders)"
|
||||
is selected, then other "current, scheduled, or completed" orders within
|
||||
the pre-defined time ranges are potential duplicates that could
|
||||
waste resources. These other-orders will have an order status level
|
||||
number between 0-100, excluding HOLD, CANC, CANP, CAND, CANT, COMPA,
|
||||
HISE, HISI, DISC, DISCD and DISCT.
|
||||
They can be unsubmitted orders or orders already in the database
|
||||
or resulted orders from community
|
||||
k. The evoking-order conflicts with existing orders belonging to the session
|
||||
types as defined in the following list variables (e.g.
|
||||
at_discharge_session_list, at_in_house_session_list,
|
||||
at_historical_session_list, or at_outpatient_session_list).
|
||||
The list variable corresponding to the session type of the entered order is used.
|
||||
l. The facility can set MLM flag to allow the site to determine whether they want to
|
||||
see Duplicate alerts for resulted orders from Community Results upon an order being
|
||||
entered or modified. Set the flag to True to turn on Community Results checking.
|
||||
The default = False;
|
||||
|
||||
enable_community_data_results_alerts := False;
|
||||
|
||||
m. The facility can set MLM flag to allow the site to match the resulted
|
||||
order of community results using the order name if the resulted order cannot
|
||||
be mapped to an item catalog item.
|
||||
The default = False;
|
||||
|
||||
enable_Diagnostic_Duplicate_Check_by_Community_Order_Name := False;
|
||||
|
||||
n. The facility can set MLM flag to allow the site to control the "text" that is displayed in
|
||||
the alert message for Community Results workflows versus Sunrise Orders.
|
||||
The default = "Community". The alert text is configurable.
|
||||
|
||||
community_resultedOrder_alert_text := "Community";
|
||||
|
||||
Once a duplicate-order has been identified, selection of the appropriate message
|
||||
is based on: (1) the defined MESSAGE TYPE in the item-catalog, (2) if appropriate,
|
||||
the time period of the significant date (performed, exact, or scheduled), and
|
||||
(3)if the message type is "exact" and the time period is "performed" or "scheduled,"
|
||||
then a third criteria of "order without specific stop-date" will be added to
|
||||
select the correct message.
|
||||
|
||||
The SEND_ALERT variable indicates whether to send the message or not.
|
||||
The values are:
|
||||
"", or blank = use the {{{SINGLE-QUOTE}}}Send with order{{{SINGLE-QUOTE}}} flag set in the AlertTypes dictionary
|
||||
(NOTE that default setting of flag is unchecked. If the flag is
|
||||
checked and this variable is left blank or "" all of the alerts
|
||||
for this MLM will be sent with the order.)
|
||||
"DoNotSend" = do not send the alert regardless of the AlertTypes dictionary
|
||||
setting for the {{{SINGLE-QUOTE}}}Send with order{{{SINGLE-QUOTE}}} flag
|
||||
"Send" = send the alert regardless of the AlertTypes dictionary setting
|
||||
for the {{{SINGLE-QUOTE}}}Send with order{{{SINGLE-QUOTE}}} flag
|
||||
|
||||
|
||||
The GENERATE_ACTIONS_ON_ALERTS variable indicates whether to generate
|
||||
Actions on Alerts. The values are:
|
||||
* TRUE = Generate Actions on Alerts
|
||||
* FALSE = Do NOT generate Actions on Alerts
|
||||
|
||||
The ORDER STATUS LEVEL FLAGS determine what order statuses are retrieved
|
||||
from the database and the unsubmitted orders. A facility may wish to
|
||||
increase/decrease the order status numbers to retrieve more/less
|
||||
order statuses that should be checked for duplicates.
|
||||
However, increasing the "highest_status_level_for_meds" beyond 50
|
||||
for MEDS may slow performance since large numbers of orders are returned
|
||||
and are eventually discarded because their start and stop dates do not overlap.
|
||||
Examples of setting are:
|
||||
* 0-100 includes all order statuses
|
||||
* 0-50 includes all "active/current" orders
|
||||
* 40-50 includes orders from Pending to Active (excludes Pending Verification)
|
||||
|
||||
|
||||
Complex and Multiple Frequencies Orders:
|
||||
When retrieving unsubmitted and existing database orders, this MLM will consider
|
||||
whether the order is:
|
||||
- that have a start and stop time (like medication orders)
|
||||
- that have a Significant date and time like (diagnositic orders)
|
||||
This configuration is set in the Item Catalog Duplicate Checking option
|
||||
|
||||
Orders that have a start and stop time (like medication orders) will check
|
||||
not check child orders (ComplexOrderType of 2,4,6)that exist in the database
|
||||
or in the unsubmitted orders list.
|
||||
|
||||
Orders that have a Significant date and time like (diagnositic orders) will not
|
||||
check Master orders (ComplexOrderType of 1,3,5) that exist in the database.
|
||||
|
||||
The following ComplexOrderType values define the type of order:
|
||||
0 or NULL - regular order
|
||||
1 - Sequential Complex Dose Master
|
||||
2 - Sequential Complex Dose Child Order
|
||||
3 - Concurrent Complex Dose Master
|
||||
4 - Concurrent Complex Dose Child Order
|
||||
5 - Multiple Frequencies Master
|
||||
6 - Multiple Frequencies Child Order
|
||||
|
||||
|
||||
;;
|
||||
keywords: Duplicate Order;
|
||||
;;
|
||||
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 logging is needed.*/
|
||||
log_execution_info := false;
|
||||
|
||||
/* Set the text for the variable below to indicate whether to send the message or not. */
|
||||
send_alert := "DoNotSend";
|
||||
|
||||
/* Set a flag indicating whether or not Actions on Alerts should be generated */
|
||||
generate_actions_on_alerts := TRUE;
|
||||
|
||||
alert_if_initial_error:= FALSE;
|
||||
|
||||
/* Set the ORDER STATUS LEVEL FLAGS to a different Order Status Level */
|
||||
/* if more or fewer order statuses should be included */
|
||||
lowest_status_level_for_diagnostics:= 0;
|
||||
highest_status_level_for_diagnostics:= 100;
|
||||
lowest_status_level_for_meds:= 0;
|
||||
highest_status_level_for_meds:= 50;
|
||||
|
||||
// The duplicate checking flag for community results is as follows:
|
||||
// Set this flag to TRUE to include resulted orders from community results in the evaluation.
|
||||
// Set this flag to FALSE to exclude resulted orders from community results in the evaluation
|
||||
enable_community_data_results_alerts := false;
|
||||
|
||||
// Set this flag to TRUE to match resulted orders from community results to
|
||||
// the order name if the diagnostic order cannot be mapped to a catalog item.
|
||||
// Set this flag to FALSE to match resulted orders from commmunity results only
|
||||
// if the diagnostic order is mapped to a catalog item. (default)
|
||||
enable_Diagnostic_Duplicate_Check_by_Community_Order_Name := false;
|
||||
|
||||
// Enter the text to differentiate resulted orders from community results in duplicate alerts:
|
||||
// Set this flag to "Community" to include with the resulted order from community results
|
||||
// data for MLM shown in brackets after the community data.
|
||||
community_resultedOrder_alert_text := "Community";
|
||||
|
||||
/* Change the message within the quotes if a different short-message is needed.*/
|
||||
duplicate_order_alert:= destination { Alert: warning,
|
||||
"Duplicate Order", low, chart,
|
||||
"HVC Duplicate", 1005, send_alert };
|
||||
|
||||
/* Change the spelling within the quotes to match the order item-catalog.*/
|
||||
any_new_order:= event {OrderEnter User Order:
|
||||
WHERE OrderStatusLevelNum >= 0
|
||||
AND OrderStatusLevelNum <= 50
|
||||
AND OrderStatusCode <> "HOLD"
|
||||
AND IsSuspended = FALSE };
|
||||
|
||||
any_new_patient_group_order:= event {OrderEnter Batch Order:
|
||||
WHERE OrderStatusLevelNum >= 0
|
||||
AND OrderStatusLevelNum <= 50
|
||||
AND OrderStatusCode <> "HOLD"
|
||||
AND IsSuspended = FALSE
|
||||
AND IsCreatedFromPatientGroupOrderTemplate = TRUE};
|
||||
|
||||
any_modified_order:= event {OrderModify User Order:
|
||||
WHERE OrderStatusLevelNum >= 0
|
||||
AND OrderStatusLevelNum <= 50
|
||||
AND OrderStatusCode <> "HOLD"
|
||||
AND IsSuspended = FALSE };
|
||||
|
||||
any_released_order:= event {OrderRelease User Order:
|
||||
WHERE OrderStatusLevelNum >= 0
|
||||
AND OrderStatusLevelNum <= 50
|
||||
AND OrderStatusCode <> "HOLD"
|
||||
AND IsSuspended = FALSE };
|
||||
|
||||
any_unsuspended_order:= event {OrderUnsuspend User Order:
|
||||
WHERE OrderStatusLevelNum >= 0
|
||||
AND OrderStatusLevelNum <= 50
|
||||
AND OrderStatusCode <> "HOLD"
|
||||
AND IsSuspended = FALSE };
|
||||
|
||||
any_verified_order:= event {OrderVerify User Order:
|
||||
WHERE OrderStatusLevelNum >= 0
|
||||
AND OrderStatusLevelNum <= 50
|
||||
AND OrderStatusCode <> "HOLD"
|
||||
AND IsSuspended = FALSE };
|
||||
|
||||
// --------------------------------------------------
|
||||
// Outpatient Prescription and Home Medication Orders
|
||||
//---------------------------------------------------
|
||||
// Comment out below triggers to exclude checking all Outpatient Orders
|
||||
// To include Home Medications remove the code {{{SINGLE-QUOTE}}}AND OrderAddtionalInfo.IsScript <> FALSE{{{SINGLE-QUOTE}}}
|
||||
outpatient_order_entry_trigger := event {OutpatientOrderEnterNoIVAdditive User Order:
|
||||
WHERE OrderAdditionalInfo.IsScript <> FALSE};
|
||||
|
||||
outpatient_order_modify_trigger := event {OutpatientOrderModify User Order:
|
||||
WHERE OrderAdditionalInfo.IsScript <> FALSE};
|
||||
|
||||
/* Pharmacy Trigger Events */
|
||||
|
||||
any_OrderEnterPharmacyPerfect:= event {OrderEnterPharmacyPerfect Any Order:
|
||||
WHERE OrderStatusLevelNum >= 0
|
||||
AND OrderStatusLevelNum <= 50
|
||||
AND OrderStatusCode <> "HOLD"
|
||||
AND IsSuspended = FALSE };
|
||||
|
||||
any_OrderModifyPharmacyPerfect:= event {OrderModifyPharmacyPerfect Any Order:
|
||||
WHERE OrderStatusLevelNum >= 0
|
||||
AND OrderStatusLevelNum <= 50
|
||||
AND OrderStatusCode <> "HOLD"
|
||||
AND IsSuspended = FALSE };
|
||||
|
||||
any_OrderModifyPharmacy:= event {OrderModifyPharmacy Any Order:
|
||||
WHERE OrderStatusLevelNum >= 0
|
||||
AND OrderStatusLevelNum <= 50
|
||||
AND OrderStatusCode <> "HOLD"
|
||||
AND IsSuspended = FALSE };
|
||||
|
||||
/* Uncomment this section if you would like historical session type orders
|
||||
to evoke this MLM, otherwise keep it commented out and this MLM will
|
||||
ignore historical session type orders. If you uncomment this section make
|
||||
sure to also uncomment the equivalent in the evoke clause.
|
||||
|
||||
order_alternate_enter_IV:= event{OrderAlternateEnterWithIVAdditive User Order:
|
||||
where AlternateOrderType = 1};
|
||||
|
||||
order_alternate_enter_NOIV:= event{OrderAlternateEnterNoIVAdditive User Order:
|
||||
where AlternateOrderType = 1};
|
||||
|
||||
order_alternate_modify:= event{OrderAlternateModify User Order:
|
||||
where AlternateOrderType = 1
|
||||
AND OrderStatusCode <> "HISE"
|
||||
AND OrderStatusCode <> "HISI"}; */
|
||||
|
||||
|
||||
// Set the list variables with the session types of existing orders against which
|
||||
// the current order will be checked. The possible values for these variables are
|
||||
// one or more types from the following list ("Discharge", "Inhouse", "Outpatient Rx", "Outpatient Hx", "Historical").
|
||||
//
|
||||
// The default setting is to check for duplicates between
|
||||
// - current order entered during a discharge session type and existing discharge orders
|
||||
// - current order entered during an in-house session type and existing in-house orders
|
||||
// - current order entered during historical session type and existing historical orders
|
||||
// - current outpatient orders entered and existing outpatient orders
|
||||
|
||||
at_discharge_session_list := ("Discharge");
|
||||
at_in_house_session_list := ("Inhouse");
|
||||
at_historical_session_list := ("Historical");
|
||||
at_outpatient_session_list := ("Outpatient Rx", "Outpatient Hx");
|
||||
|
||||
/********************************************************************************/
|
||||
|
||||
/* Executes only when this MLM is called by the editor */
|
||||
if called_by_editor then
|
||||
/* Get current selected client visit in MLM Editor. */
|
||||
(client_visit_guid,
|
||||
current_visit) := read last {ClientVisit: GUID, This };
|
||||
|
||||
/* Search for example order in the current visit. */
|
||||
EvokingObject:= read last
|
||||
{Order: This
|
||||
WHERE Name = "CBC" AND OrderStatusLevelNum > 40 };
|
||||
endif;
|
||||
|
||||
/* Declares MLMs which can be called */
|
||||
func_dup_message:= MLM {{{SINGLE-QUOTE}}}std_func_dup_messages{{{SINGLE-QUOTE}}};
|
||||
func_check_for_duplicates:= MLM {{{SINGLE-QUOTE}}}std_func_dup_rules{{{SINGLE-QUOTE}}};
|
||||
func_dup_actions := MLM {{{SINGLE-QUOTE}}}Std_Func_Dup_Actions{{{SINGLE-QUOTE}}};
|
||||
|
||||
/* Initialize variable */
|
||||
continue_checking_order := true;
|
||||
|
||||
/* Set the order type to check */
|
||||
complex_child_order_type := (2,4,6);
|
||||
complex_master_order_type := (1,3,5);
|
||||
regular_order_type := (NULL, 0);
|
||||
|
||||
/* Gets the Client GUID */
|
||||
client_guid := read last {ClientInfo: GUID};
|
||||
|
||||
/* Gets information from the evoking Order */
|
||||
(main_order_name,
|
||||
evoking_object_guid,
|
||||
order_status_code,
|
||||
order_level_num,
|
||||
order_summary_line,
|
||||
main_item_catalog_guid,
|
||||
order_catalog_master_item_obj,
|
||||
chart_guid,
|
||||
client_visit_guid,
|
||||
order_significant_date,
|
||||
order_requested_date,
|
||||
order_entered_date,
|
||||
order_stop_date,
|
||||
order_is_conditional,
|
||||
order_component_obj,
|
||||
order_complex_type,
|
||||
order_variable_component_obj,
|
||||
order_is_for_discharge,
|
||||
order_alternate_order_type,
|
||||
evoking_order_additional_info,
|
||||
back_up_obj) := read last
|
||||
{Order: Name, GUID, OrderStatusCode, OrderStatusLevelNum, SummaryLine,
|
||||
OrderCatalogMasterItemGUID, OrderCatalogMasterItem, ChartGUID,
|
||||
ClientVisitGUID, SignificantDtm, RequestedDtm, Entered, StopDtm, IsConditional, OrderComponent,
|
||||
ComplexOrderType, OrderVariableComponent, IsForDischarge, AlternateOrderType, OrderAdditionalInfo,
|
||||
Backup REFERENCING EvokingObject};
|
||||
|
||||
(evoking_order_is_script) := read last {OrderAdditionalInfo: IsScript REFERENCING evoking_order_additional_info};
|
||||
|
||||
if exists EvokingObject
|
||||
and (order_significant_date is null)
|
||||
then
|
||||
alert_if_initial_error := TRUE;
|
||||
endif;
|
||||
|
||||
order_without_specific_stop_date := false;
|
||||
|
||||
if (order_alternate_order_type <> 2) //if not an outpatient order
|
||||
then
|
||||
// Get information about ongoing diagnostic order vs medication order
|
||||
(order_without_specific_stop_date) := read last
|
||||
{OrderCatalogMasterItem: IsOngoingOrder REFERENCING order_catalog_master_item_obj};
|
||||
endif;
|
||||
|
||||
// This is a diagnostic like order
|
||||
if order_without_specific_stop_date
|
||||
then
|
||||
/* Check to see if this is a master order and if so whether children exist */
|
||||
if exists order_complex_type
|
||||
and order_complex_type IS IN complex_master_order_type
|
||||
then
|
||||
/* Gets information from the order variable components */
|
||||
(component_child_order_guid_list) := read
|
||||
{OrderVariableComponent: ChildOrderGUID
|
||||
REFERENCING order_variable_component_obj};
|
||||
|
||||
/* Check to see if children exist */
|
||||
if exists component_child_order_guid_list
|
||||
then
|
||||
child_orders_generated := true;
|
||||
|
||||
/* If children exist, this MLM should not run on Master order on modify or unsuspend */
|
||||
If EvokingEventType = any_modified_order.type
|
||||
OR EvokingEventType = any_unsuspended_order.type
|
||||
then
|
||||
continue_checking_order := false;
|
||||
endif; //If EvokingEventType = any_modified_order.type
|
||||
|
||||
/* This is a master order without children*/
|
||||
else
|
||||
continue_checking_order := true;
|
||||
endif; //if exists component_child_order_guid_list
|
||||
|
||||
|
||||
/* This is a child diagnositic order event continue check for modify, unsuspend... */
|
||||
else
|
||||
continue_checking_order := true;
|
||||
endif; //if exists order_complex_type
|
||||
|
||||
else
|
||||
/* This is a medication like order */
|
||||
/* Check to see if this is a child order and if so stop processing as */
|
||||
/* data will be alerted on at master order update */
|
||||
if exists order_complex_type
|
||||
and order_complex_type IS IN complex_child_order_type
|
||||
then
|
||||
continue_checking_order := false;
|
||||
endif; //if exists order_complex_type
|
||||
|
||||
endif; //if order_without_specific_stop_date
|
||||
|
||||
|
||||
// Determines if a modified order should be checked for duplicates
|
||||
if EvokingEventType = any_modified_order.type
|
||||
or EvokingEventType = any_OrderModifyPharmacy.type
|
||||
or EvokingEventType = order_alternate_modify.type
|
||||
or EvokingEventType = outpatient_order_modify_trigger.type
|
||||
and continue_checking_order
|
||||
then
|
||||
if exist back_up_obj
|
||||
then
|
||||
(back_up_obj_signif_date,
|
||||
back_up_obj_stop_date) := read last
|
||||
{Order: SignificantDtm, StopDtm REFERENCING back_up_obj};
|
||||
|
||||
if (back_up_obj_signif_date <> order_significant_date)
|
||||
OR (back_up_obj_stop_date <> order_stop_date)
|
||||
OR (back_up_obj_stop_date is null and order_stop_date is time)
|
||||
OR (back_up_obj_stop_date is time and order_stop_date is null)
|
||||
then
|
||||
continue_checking_order := true;
|
||||
else
|
||||
continue_checking_order := false;
|
||||
endif;
|
||||
else
|
||||
continue_checking_order := false;
|
||||
endif;
|
||||
endif;
|
||||
|
||||
|
||||
if continue_checking_order
|
||||
then
|
||||
/* Places the main-order on the lists to process */
|
||||
order_list:= ,main_order_name;
|
||||
cat_item_guid_list:= ,main_item_catalog_guid;
|
||||
|
||||
/* Only retrieves data if the Order has IV additives */
|
||||
If exist order_component_obj
|
||||
then
|
||||
/* Gets the catalog item from the order component object */
|
||||
(additive_cat_item_guid_list,
|
||||
additive_name_list) := read
|
||||
{ OrderComponent: OrderCatalogMasterItemGUID, Name
|
||||
REFERENCING order_component_obj
|
||||
where (Dosage AS Number) > 0 };
|
||||
|
||||
/* Places the additive information on the lists to process */
|
||||
order_list:= order_list, additive_name_list;
|
||||
cat_item_guid_list:= cat_item_guid_list, additive_cat_item_guid_list;
|
||||
endif;
|
||||
|
||||
/* Gets the patient{{{SINGLE-QUOTE}}}s location group */
|
||||
If called_by_editor
|
||||
Then
|
||||
/* Get visit information from the current selected visit in MLM Editor. */
|
||||
patient_loc_group:= read last
|
||||
{ ClientVisit: BusinessRuleLocationGUID
|
||||
REFERENCING current_visit};
|
||||
Else
|
||||
patient_loc_group:= read last
|
||||
{ ClientVisit: BusinessRuleLocationGUID };
|
||||
Endif;
|
||||
|
||||
|
||||
endif; /* continue_checking_order */
|
||||
|
||||
;;
|
||||
evoke:
|
||||
/* Uncomment this section if you would like historical session type orders
|
||||
to evoke this mlm,otherwise keep it commented out.
|
||||
If you uncomment this section please make sure to also uncomment the
|
||||
equivalent event clauses
|
||||
|
||||
order_alternate_enter_IV OR
|
||||
order_alternate_enter_NOIV OR
|
||||
order_alternate_modify OR */
|
||||
|
||||
any_new_order;
|
||||
any_new_patient_group_order;
|
||||
any_modified_order;
|
||||
any_released_order;
|
||||
any_unsuspended_order;
|
||||
any_verified_order;
|
||||
outpatient_order_entry_trigger;
|
||||
outpatient_order_modify_trigger;
|
||||
any_OrderEnterPharmacyPerfect;
|
||||
any_OrderModifyPharmacyPerfect;
|
||||
any_OrderModifyPharmacy;
|
||||
;;
|
||||
logic:
|
||||
If EvokingObject is NULL
|
||||
then conclude false;
|
||||
endif;
|
||||
|
||||
if alert_if_initial_error
|
||||
then conclude true; /* generate an alert */
|
||||
endif;
|
||||
|
||||
If NOT continue_checking_order
|
||||
then conclude false;
|
||||
endif;
|
||||
|
||||
|
||||
/* Initialize variables */
|
||||
indent:= " ";
|
||||
dash_line:= "-----";
|
||||
printable_alert_msg:= "";
|
||||
index_list:= 1 SEQTO count(order_list);
|
||||
|
||||
/* Process the main order or the IV-additives */
|
||||
for J in index_list do
|
||||
order_name:= last(first J from order_list);
|
||||
item_catalog_guid:= last(first J from cat_item_guid_list);
|
||||
|
||||
(exact_msg,
|
||||
performed_msg,
|
||||
scheduled_msg,
|
||||
exact_type,
|
||||
subset_type,
|
||||
superset_type,
|
||||
same_order_type,
|
||||
partial_match_type,
|
||||
conflict_type,
|
||||
possible_conflict_type,
|
||||
no_std_message_type,
|
||||
order_without_specific_stop_date,
|
||||
matching_name_list,
|
||||
matching_order_guid_list,
|
||||
matching_significant_date_list,
|
||||
matching_requested_date_list,
|
||||
matching_entered_date_list,
|
||||
matching_stop_date_list,
|
||||
matching_msg_type_list,
|
||||
matching_msg_text_list,
|
||||
matching_time_msg_list,
|
||||
matching_class_list,
|
||||
matching_summary_list,
|
||||
matching_order_status_code_list,
|
||||
matching_order_type_code_list,
|
||||
matching_alternate_order_type_list,
|
||||
matching_is_script_list,
|
||||
matching_aoa_action_item_status_list,
|
||||
matching_aoa_order_guid_list,
|
||||
matching_aoa_order_name_list,
|
||||
matching_aoa_master_guid_list ) := call func_check_for_duplicates with
|
||||
(order_name,
|
||||
evoking_object_guid,
|
||||
order_status_code,
|
||||
order_level_num,
|
||||
order_summary_line,
|
||||
item_catalog_guid,
|
||||
chart_guid,
|
||||
client_visit_guid,
|
||||
order_significant_date,
|
||||
order_requested_date,
|
||||
order_entered_date,
|
||||
order_stop_date,
|
||||
order_is_conditional,
|
||||
patient_loc_group,
|
||||
lowest_status_level_for_diagnostics,
|
||||
highest_status_level_for_diagnostics,
|
||||
lowest_status_level_for_meds,
|
||||
highest_status_level_for_meds,
|
||||
complex_master_order_type,
|
||||
complex_child_order_type,
|
||||
order_is_for_discharge,
|
||||
order_alternate_order_type,
|
||||
evoking_order_is_script,
|
||||
at_in_house_session_list,
|
||||
at_discharge_session_list,
|
||||
at_historical_session_list,
|
||||
at_outpatient_session_list,
|
||||
enable_community_data_results_alerts,
|
||||
enable_Diagnostic_Duplicate_Check_by_Community_Order_Name,
|
||||
EvokingObject,
|
||||
EvokingEventType);
|
||||
|
||||
/*--------------------------------------------------------------*/
|
||||
/* Calls an MLM to select the appropriate message and format it */
|
||||
/*--------------------------------------------------------------*/
|
||||
If exist matching_name_list
|
||||
then
|
||||
(order_status_msg,
|
||||
alert_msg,
|
||||
matching_short_message_list):= call func_dup_message with
|
||||
(order_name,
|
||||
order_status_code,
|
||||
order_without_specific_stop_date,
|
||||
exact_msg,
|
||||
performed_msg,
|
||||
scheduled_msg,
|
||||
exact_type,
|
||||
subset_type,
|
||||
superset_type,
|
||||
same_order_type,
|
||||
partial_match_type,
|
||||
conflict_type,
|
||||
possible_conflict_type,
|
||||
no_std_message_type,
|
||||
matching_name_list,
|
||||
matching_significant_date_list,
|
||||
matching_requested_date_list,
|
||||
matching_entered_date_list,
|
||||
matching_stop_date_list,
|
||||
matching_msg_type_list,
|
||||
matching_msg_text_list,
|
||||
matching_time_msg_list,
|
||||
matching_class_list,
|
||||
matching_summary_list,
|
||||
matching_order_status_code_list,
|
||||
matching_order_type_code_list,
|
||||
matching_alternate_order_type_list,
|
||||
matching_is_script_list,
|
||||
community_resultedOrder_alert_text);
|
||||
|
||||
/* Format date, removing milliseconds */
|
||||
order_significant_date_formatted := order_significant_date formatted with "%.4t";
|
||||
|
||||
/* Create one long message to print */
|
||||
printable_alert_msg:= printable_alert_msg || alert_msg;
|
||||
|
||||
endif; /* If exist matching_name_list */
|
||||
enddo; /* for J */
|
||||
|
||||
|
||||
/* Create a printable list of additives */
|
||||
if exist additive_name_list
|
||||
then
|
||||
if count(additive_name_list) = 1
|
||||
then additive_message:= indent || "IV-Additives: " || first (additive_name_list)|| "\n";
|
||||
else additive_message:= indent || "IV-Additives: " || additive_name_list || "\n";
|
||||
endif; /* if count */
|
||||
else additive_message:= "";
|
||||
endif; /* if exist additive_name_list */
|
||||
|
||||
/* Set the printable text for the order summary line */
|
||||
if exist order_summary_line
|
||||
then
|
||||
summary_line:= dash_line || order_summary_line;
|
||||
else
|
||||
summary_line:= "";
|
||||
endif; /* if exist order_summary_line */
|
||||
|
||||
|
||||
/*-------------------------------*/
|
||||
/* Create the Actions On Alerts */
|
||||
/*-------------------------------*/
|
||||
// Only create actions for alerts when the flag, generate_actions_on_alerts, is TRUE
|
||||
// and the evoking object is a new order.
|
||||
// Since the MLM Editor does NOT have an evoking trigger,
|
||||
// Check that the EvokingEventType is a new order or the MLM is running the the MLM Editor
|
||||
|
||||
if generate_actions_on_alerts
|
||||
AND exist alert_msg
|
||||
AND (EvokingEventType = any_new_order.type or EvokingEventType = any_new_patient_group_order.type or Called_By_Editor)
|
||||
then
|
||||
// Correct the sort sequence of the SHORT MESSAGES.
|
||||
// The MLM that created the messages places them in the wrong sequence.
|
||||
/* Initialize */
|
||||
matching_aoa_short_message_list := ();
|
||||
position_list := 1 SEQTO count (matching_aoa_order_guid_list);
|
||||
|
||||
// Use the matching_aoa_order_guid_list to place them in the right sequence
|
||||
for GG in position_list do
|
||||
//Get the OrderGUID and the Duplicate{{{SINGLE-QUOTE}}}s Name (order name or additive name)
|
||||
aoa_order_guid := matching_aoa_order_guid_list[GG];
|
||||
aoa_order_name := matching_aoa_order_name_list[GG];
|
||||
|
||||
//Use the GUID and the NAME to find a matching position for a regular order
|
||||
found_match := (matching_order_guid_list = aoa_order_guid
|
||||
and matching_name_list = aoa_order_name);
|
||||
|
||||
//Use just the GUID to find a matching position for orders with IV Additives
|
||||
If NOT ANY found_match
|
||||
then found_match := matching_order_guid_list = aoa_order_guid;
|
||||
endif;
|
||||
|
||||
//Match the position to get the short message
|
||||
temp_message := first (matching_short_message_list where found_match);
|
||||
|
||||
//Put the short message in its correct order in the list
|
||||
matching_aoa_short_message_list := matching_aoa_short_message_list, temp_message;
|
||||
enddo; //for GG
|
||||
|
||||
|
||||
// Call the MLM that Generates the Actions
|
||||
alert_action_object_list := call func_dup_actions WITH
|
||||
evoking_object_guid,
|
||||
matching_aoa_action_item_status_list,
|
||||
matching_aoa_order_guid_list,
|
||||
matching_aoa_order_name_list,
|
||||
matching_aoa_master_guid_list,
|
||||
matching_aoa_short_message_list ;
|
||||
|
||||
// Set a flag to attach the alert to the destination when there are alert actions
|
||||
if exist alert_action_object_list
|
||||
then continue_action := True;
|
||||
else continue_action := False;
|
||||
endif; // if exist
|
||||
endif; //if generate_actions_on_alerts
|
||||
|
||||
/*---------------*/
|
||||
/* Clinical Rule */
|
||||
/*---------------*/
|
||||
If exist alert_msg
|
||||
then conclude true;
|
||||
endif;
|
||||
;;
|
||||
action:
|
||||
|
||||
current_order_alert_msg := "The current ";
|
||||
if (order_alternate_order_type = 2)
|
||||
then
|
||||
if (evoking_order_is_script)
|
||||
then
|
||||
current_order_alert_msg := current_order_alert_msg || "prescription: \n";
|
||||
order_status_msg := order_status_msg || " Prescription";
|
||||
else
|
||||
current_order_alert_msg := current_order_alert_msg || "home medication: \n";
|
||||
order_status_msg := order_status_msg || " Home Medication";
|
||||
endif;
|
||||
else
|
||||
current_order_alert_msg := current_order_alert_msg || "order: \n";
|
||||
order_status_msg := order_status_msg || " Order";
|
||||
endif;
|
||||
|
||||
if alert_if_initial_error
|
||||
then
|
||||
write "Your order for {{+B}}{{+C}}" || main_order_name
|
||||
|| "{{-B}}{{-C}} was{{+B}}{{+R}} not checked for possible duplicates {{-B}}{{-R}}"
|
||||
|| "with other patient medications."
|
||||
|| " Please use an alternate plan to do the check."
|
||||
|| " \n\nThis drug was not checked because it does not have a start date or a stop date."
|
||||
at duplicate_order_alert;
|
||||
else
|
||||
write current_order_alert_msg
|
||||
|| indent || main_order_name || summary_line || "\n"
|
||||
|| indent || "Date: " || order_significant_date_formatted ||"\n"
|
||||
|| indent || "Status: " || order_status_msg || "\n"
|
||||
|| additive_message
|
||||
|| "\n"
|
||||
|| "May be duplicate with: \n\n"
|
||||
|| printable_alert_msg
|
||||
at duplicate_order_alert;
|
||||
|
||||
if continue_action
|
||||
then attach alert_action_object_list to duplicate_order_alert;
|
||||
endif;
|
||||
endif;
|
||||
;;
|
||||
Urgency: 50;;
|
||||
end:
|
||||
2081
MLMStripper/bin/Debug/STD/STD_DUPLICATE_MEDICATION_THERAPY.mlm
Normal file
2081
MLMStripper/bin/Debug/STD/STD_DUPLICATE_MEDICATION_THERAPY.mlm
Normal file
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
221
MLMStripper/bin/Debug/STD/STD_DUPLICATE_ORDER_SET.mlm
Normal file
221
MLMStripper/bin/Debug/STD/STD_DUPLICATE_ORDER_SET.mlm
Normal file
@@ -0,0 +1,221 @@
|
||||
maintenance:
|
||||
|
||||
title: Duplicate Order Set Checking;;
|
||||
mlmname: STD_DUPLICATE_ORDER_SET;;
|
||||
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: Provide Duplicate Order Set Checking.
|
||||
The checking will include:
|
||||
1. Order sets of the same name or type within a pre-defined date range,
|
||||
which will be varied by patient location.
|
||||
2. Active order sets of the same type
|
||||
;;
|
||||
explanation: An Evoking-Order-Set is considered a duplicate of Other-Order-Sets when all of
|
||||
the criteria listed below are met:
|
||||
a. The evoking-order-set is a NEW order set
|
||||
b. The evoking-order-set is not excluded from duplicate checking
|
||||
(over-all or by patient location).
|
||||
c. The order sets have identical Item Names (i.e.Catalog GUIDs),
|
||||
or the other-order-set matches the Sets
|
||||
listed in the evoking-order-set{{{SINGLE-QUOTE}}}s catalog duplicate-checking panel.
|
||||
d. The other-order-sets are within the scoping rules for the patient location listed
|
||||
in the evoking-order-set{{{SINGLE-QUOTE}}}s Duplicate Policy. The patient{{{SINGLE-QUOTE}}}s location is based on
|
||||
the location-business-rules established by the facility for other parts of
|
||||
Sunrise Clinical Manager.
|
||||
|
||||
Once a duplicate order set has been identified, selection of the appropriate message
|
||||
is based on the defined MESSAGE TYPE in the catalog.
|
||||
;;
|
||||
keywords: Duplicate Order Set;
|
||||
;;
|
||||
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 logging is needed.*/
|
||||
log_execution_info := false;
|
||||
|
||||
/* Change the message within the quotes if a different short-message is needed.*/
|
||||
duplicate_order_set_alert:= destination { Alert: warning,
|
||||
"Duplicate Order Set", low, chart,
|
||||
"HVC Duplicate", 2005 };
|
||||
|
||||
/* Event statement does not require a change in this MLM.*/
|
||||
any_new_order_set:= event {OrderSetEnter User OrderSet : where StartDtm is not null};
|
||||
|
||||
|
||||
/********************************************************************************/
|
||||
|
||||
/* Executes only when this MLM is called by the editor */
|
||||
if called_by_editor then
|
||||
/* Get current selected client visit in MLM Editor. */
|
||||
(client_visit_guid,
|
||||
current_visit) := read last
|
||||
{ClientVisit: GUID, This };
|
||||
|
||||
/* Search for example order set in the current visit. */
|
||||
EvokingObject:= read last
|
||||
{OrderSet: This
|
||||
WHERE OrderSetName = "Joyce Linked Parent (w STD & linked)" AND ClientVisitGUID = client_visit_guid
|
||||
};
|
||||
endif;
|
||||
|
||||
/* Declares MLMs which can be called */
|
||||
func_dup_message:= MLM {{{SINGLE-QUOTE}}}std_func_order_set_dup_messages{{{SINGLE-QUOTE}}};
|
||||
func_check_for_duplicates:= MLM {{{SINGLE-QUOTE}}}std_func_order_set_dup_rules{{{SINGLE-QUOTE}}};
|
||||
|
||||
/* Gets the Client GUID */
|
||||
client_guid := read last {ClientInfo: GUID};
|
||||
|
||||
/* Gets information from the evoking order set */
|
||||
(order_set_name,
|
||||
evoking_object_guid,
|
||||
order_set_catalog_guid,
|
||||
chart_guid,
|
||||
client_visit_guid,
|
||||
order_set_start_date ) := read last
|
||||
{OrderSet: OrderSetName, GUID, OrderCatalogSetGUID,
|
||||
ChartGUID, ClientVisitGUID, StartDtm
|
||||
REFERENCING EvokingObject};
|
||||
|
||||
|
||||
/* Gets the patient{{{SINGLE-QUOTE}}}s location group */
|
||||
If called_by_editor
|
||||
Then
|
||||
/* Get visit information from the current selected visit in MLM Editor. */
|
||||
patient_loc_group:= read last
|
||||
{ ClientVisit: BusinessRuleLocationGUID
|
||||
REFERENCING current_visit};
|
||||
Else
|
||||
patient_loc_group:= read last
|
||||
{ ClientVisit: BusinessRuleLocationGUID };
|
||||
Endif;
|
||||
|
||||
;;
|
||||
evoke: any_new_order_set
|
||||
;;
|
||||
logic:
|
||||
//----------------------------------------------------------------
|
||||
// If there is no evoking object then do nothing, this can
|
||||
// only be true for the MLM Editor
|
||||
//----------------------------------------------------------------
|
||||
If EvokingObject is NULL
|
||||
then conclude false;
|
||||
endif;
|
||||
|
||||
If NOT continue_checking_order_set
|
||||
then conclude false;
|
||||
endif;
|
||||
|
||||
|
||||
/* Initialize variables */
|
||||
indent:= " ";
|
||||
dash_line:= "-----";
|
||||
printable_alert_msg:= "";
|
||||
|
||||
/* Process the order_sets for duplicates */
|
||||
|
||||
(exact_msg,
|
||||
performed_msg,
|
||||
scheduled_msg,
|
||||
exact_type,
|
||||
subset_type,
|
||||
superset_type,
|
||||
same_set_type,
|
||||
partial_match_type,
|
||||
no_std_message_type,
|
||||
matching_name_list,
|
||||
matching_order_set_guid_list,
|
||||
matching_start_date_list,
|
||||
matching_msg_type_list,
|
||||
matching_msg_text_list,
|
||||
matching_time_msg_list,
|
||||
matching_order_set_type_code_list ) := call func_check_for_duplicates with
|
||||
(order_set_name,
|
||||
evoking_object_guid,
|
||||
order_set_catalog_guid,
|
||||
chart_guid,
|
||||
client_visit_guid,
|
||||
order_set_start_date,
|
||||
patient_loc_group);
|
||||
|
||||
/*--------------------------------------------------------------*/
|
||||
/* Calls an MLM to select the appropriate message and format it */
|
||||
/*--------------------------------------------------------------*/
|
||||
If exist matching_name_list
|
||||
then
|
||||
(alert_msg,
|
||||
matching_short_message_list):= call func_dup_message with
|
||||
(order_set_name,
|
||||
exact_msg,
|
||||
performed_msg,
|
||||
scheduled_msg,
|
||||
exact_type,
|
||||
subset_type,
|
||||
superset_type,
|
||||
same_set_type,
|
||||
partial_match_type,
|
||||
no_std_message_type,
|
||||
matching_name_list,
|
||||
matching_start_date_list,
|
||||
matching_msg_type_list,
|
||||
matching_msg_text_list,
|
||||
matching_time_msg_list,
|
||||
matching_order_set_type_code_list);
|
||||
|
||||
/* Format date, removing milliseconds */
|
||||
order_set_start_date_formatted := order_set_start_date formatted with "%.4t";
|
||||
|
||||
/* Create one long message to print */
|
||||
printable_alert_msg:= printable_alert_msg || alert_msg;
|
||||
|
||||
endif; /* If exist matching_name_list */
|
||||
|
||||
/*---------------*/
|
||||
/* Clinical Rule */
|
||||
/*---------------*/
|
||||
If exist alert_msg
|
||||
then conclude true;
|
||||
endif;
|
||||
;;
|
||||
action:
|
||||
write "The current Order Set: \n"
|
||||
|| indent || order_set_name || "\n"
|
||||
|| indent || "Date: " || order_set_start_date_formatted ||"\n"
|
||||
|| "\n"
|
||||
|| "May be duplicate with: \n\n"
|
||||
|| printable_alert_msg
|
||||
at duplicate_order_set_alert;
|
||||
;;
|
||||
Urgency: 50;;
|
||||
end:
|
||||
627
MLMStripper/bin/Debug/STD/STD_DUPLICATE_TASK.mlm
Normal file
627
MLMStripper/bin/Debug/STD/STD_DUPLICATE_TASK.mlm
Normal file
@@ -0,0 +1,627 @@
|
||||
maintenance:
|
||||
|
||||
title: Duplicate Task Occurrence Checking;;
|
||||
mlmname: STD_DUPLICATE_TASK;;
|
||||
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: Provide Duplicate Task Occurrence Checking. The checking will include:
|
||||
1. Tasks of the same name or type within a pre-defined date range,
|
||||
which will be varied by patient location.
|
||||
2. Active task of the same type/class.
|
||||
;;
|
||||
explanation:
|
||||
Evoking-Occurrence: This is the Order Task Occurrence that causes the MLM
|
||||
to be triggered (evoked).
|
||||
|
||||
DB-Occurrence: This is an existing Order Task Occurrence from the database
|
||||
or from the cached memory.
|
||||
|
||||
An Evoking-Occurrence is considered a duplicate of a DB-Occurrence when
|
||||
all of the criteria listed below are true:
|
||||
|
||||
1. The Evoking-Occurrence is created by the Order Generation Server,
|
||||
and by a user when marking a task as done at order entry, or adding a completed
|
||||
task, or adding a scheduled task to the worklist, or rescheduling a single
|
||||
instance of a task.
|
||||
|
||||
2. The Evoking-Occurrence is a New occurrence, a Modified occurrence,
|
||||
or a Rescheduled occurrence.
|
||||
|
||||
3. If the Evoking-Occurrence is a Modified occurrence, only an occurrence
|
||||
with changes to ScheduledDtm, EarliestScheduledDtm, or LatestScheduledDtm
|
||||
will be checked for duplicates.
|
||||
|
||||
4. The Evoking-Occurrence must have a CV3OrderTaskOccurrence.CDSOccurrenceType
|
||||
of {10, 11, 20, 30, 31, 40, 41, 90, 91, 110, 111, 120, 130, 131, 140, 141}
|
||||
or is a task that was rescheduled from Clinical Manager to be checked for
|
||||
duplicates. See the Duplicate Task Checking chapter of the CDS Configuration
|
||||
Guide for a detailed definition of each number.
|
||||
|
||||
5. The Evoking-Occurrence must have a CV3OrderTaskOccurrence.TaskStatusCode
|
||||
of {Pending, Rescheduled, Overdue}.
|
||||
|
||||
6. The Evoking-Occurrence must have a CV3OrderTask.ScheduleTypeCode of
|
||||
{Scheduled, Unscheduled, PRN, To Schedule (when 1st given), Continuous}.
|
||||
The Evoking-Occurrence with a ScheduleTypeCode of
|
||||
{To Schedule (manual), Conditional } will be excluded.
|
||||
|
||||
7. The Evoking-Occurrence is not excluded from duplicate checking
|
||||
(over-all or by patient location) in its Duplicate Policy.
|
||||
|
||||
8. The DB-Occurrence must have a CV3OrderTaskOccurrence.TaskStatusCode
|
||||
of { Overdue, Pending, Performed, Rescheduled }. DB-Occurrences that
|
||||
have TaskStatusCodes of Canceled or Not Done will be excluded.
|
||||
|
||||
9. The DB-Occurrence must have a CV3OrderTask.ScheduleTypeCode of
|
||||
{Scheduled, Unscheduled, PRN, To Schedule (manual),
|
||||
To Schedule (when 1st given), Continuous} or a
|
||||
CV3OrderTaskOccurrence.TaskStatusCode of Performed, except in the case of
|
||||
{{{SINGLE-QUOTE}}}Adding a Completed Task{{{SINGLE-QUOTE}}} on the worklist.
|
||||
DB-Occurrences with a ScheduleTypeCode of Conditional will be excluded.
|
||||
|
||||
10. When the Evoking-Occurrence has a ScheduleTypeCode of Continuous,
|
||||
it cannot be a duplicate of DB-Occurrences that are from the
|
||||
same order task (OrderTaskGUID).
|
||||
|
||||
11. The Evoking-Occurrence and the DB-Occurrence have identical Item-Catalog
|
||||
names, or the DB-Occurrence match the Item or Class-Name & Value listed
|
||||
in the Evoking-Occurrence{{{SINGLE-QUOTE}}}s item-catalog-tasks panel.
|
||||
|
||||
12. The DB-Occurrences are within the scoping rules for the patient location
|
||||
listed in the Evoking-Occurrence{{{SINGLE-QUOTE}}}s Duplicate Policy.
|
||||
|
||||
13. The Evoking-Occurrence and the DB-Occurrence have overlapping start
|
||||
and stop dates within the time interval specified in the
|
||||
Evoking-Occurrence{{{SINGLE-QUOTE}}}s Duplicate Policy. See the CDS Configuration and
|
||||
Standard MLM Set up Guide, for a detailed definition of overlapping
|
||||
start and stop dates in the "Setting up Duplicate Task Checking" chapter.
|
||||
|
||||
14. If the Duplicate Policy uses Task % and the MLM is unable to determine
|
||||
a time interval for the Evoking-Occurrence, a default time interval
|
||||
of 24 hours (12 hours before and after the date/time of when the
|
||||
Evoking-Occurrence should be done) will be used to screen for potential
|
||||
duplicate tasks. If a potential duplicate exists, an error alert would
|
||||
be generated, unless the facility has turned off the error flag. The
|
||||
error alert would state that the user should review the task because
|
||||
all the required information is not present to identify duplicate
|
||||
task occurrences.
|
||||
|
||||
15. The combination of a Scheduled Evoking-Occurrence and a
|
||||
Performed DB-Occurrence is considered a HIGH priority alert.
|
||||
All other combinations are considered a MEDIUM priority alert.
|
||||
|
||||
16. To prevent over alerting, an alert will NOT be generated for the
|
||||
same Order Task, if there is a higher priority or equivalent
|
||||
priority alert for one of the Order Task{{{SINGLE-QUOTE}}}s earlier DB-Occurrences.
|
||||
|
||||
;;
|
||||
keywords: Duplicate Task Occurrence;
|
||||
;;
|
||||
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 logging is needed.*/
|
||||
log_execution_info := false;
|
||||
|
||||
/* Change the message within the quotes if a different short-message is needed.*/
|
||||
high_dup_task_alert:= destination { Alert: warning,
|
||||
"Duplicate Task", high, chart,
|
||||
"HVC Duplicate Task", 2005 };
|
||||
|
||||
medium_dup_task_alert:= destination { Alert: warning,
|
||||
"Duplicate Task", medium, chart,
|
||||
"HVC Duplicate Task", 2005 };
|
||||
|
||||
/* Change the spelling within the quotes to match the order item-catalog.*/
|
||||
any_new_task:= event {OrderTaskOccurrenceEnter
|
||||
Any OrderTaskOccurrence:
|
||||
WHERE TaskStatusCode is in
|
||||
("Pending", "Rescheduled", "Overdue" )
|
||||
AND CDSOccurrenceType is in
|
||||
(10,11,20,30,31,40,41,90,91,110,111,120,130,131,140,141)
|
||||
OR
|
||||
(TaskStatusCode is in ("Performed" )
|
||||
AND CDSOccurrenceType = 91)};
|
||||
|
||||
any_modified_task:= event {OrderTaskOccurrenceModify
|
||||
Any OrderTaskOccurrence:
|
||||
WHERE TaskStatusCode is in
|
||||
("Pending", "Rescheduled", "Overdue" )
|
||||
AND CDSOccurrenceType is in
|
||||
(10,11,20,30,31,40,41,90,91,110,111,120,130,131,140,141)};
|
||||
|
||||
any_rescheduled_task_instance:= event {OrderTaskOccurrenceReschedule
|
||||
User OrderTaskOccurrence:
|
||||
WHERE TaskStatusCode is in
|
||||
("Rescheduled")};
|
||||
|
||||
|
||||
/* A flag to determine if the clinical user should be alerted when */
|
||||
/* duplicate task occurrences cannot be checked due to an unknown frequency */
|
||||
/* that is associated with the order task. A time-interval (past-present) */
|
||||
/* for duplicates cannot be calculated. This only affects Duplicate Policies */
|
||||
/* that use the "Task %" unit of measure. */
|
||||
/* True = alert user; False = do not alert user. */
|
||||
|
||||
alert_if_unknown_frequency := true;
|
||||
|
||||
/********************************************************************************/
|
||||
|
||||
/* Execute only when this MLM is called by the editor */
|
||||
|
||||
if called_by_editor then
|
||||
task_obj:= read last
|
||||
{OrderTaskOccurrence: This
|
||||
WHERE TaskName = "Ampicillin 500 mg"
|
||||
//AND SignificantDtm = 2000-09-13T06:00:00
|
||||
//AND CDSOCCURRENCETYPE = 10
|
||||
//and TaskStatusCode = "Rescheduled"
|
||||
//and ScheduleTypeCode = "ToSchedule"
|
||||
};
|
||||
EvokingObject:= task_obj;
|
||||
endif;
|
||||
|
||||
/* Declare MLMs which can be called */
|
||||
func_task_messages:= MLM {{{SINGLE-QUOTE}}}std_func_task_messages{{{SINGLE-QUOTE}}};
|
||||
func_task_rules:= MLM {{{SINGLE-QUOTE}}}std_func_task_rules{{{SINGLE-QUOTE}}};
|
||||
|
||||
|
||||
/* Get the Client GUID */
|
||||
client_guid := read last {ClientInfo: GUID};
|
||||
|
||||
|
||||
/* Get information from the evoking OrderTaskOccurrence */
|
||||
(task_occurrence_name,
|
||||
task_occurrence_guid,
|
||||
task_summary_line,
|
||||
task_status_code,
|
||||
task_cds_occurrence_type,
|
||||
task_catalog_item_guid,
|
||||
task_significant_date,
|
||||
task_scheduled_date,
|
||||
task_earliest_date,
|
||||
task_latest_date,
|
||||
tasks_to_be_canceled_string,
|
||||
order_obj,
|
||||
order_task_obj,
|
||||
back_up_obj ) := read last
|
||||
{OrderTaskOccurrence: TaskName, GUID, SummaryLine,
|
||||
TaskStatusCode, CDSOccurrenceType,
|
||||
CatalogItemTaskGUID, SignificantDtm,
|
||||
ScheduledDtm, EarliestScheduledDtm, LatestScheduledDtm,
|
||||
GUIDList, Order, OrderTask, Backup
|
||||
REFERENCING EvokingObject};
|
||||
|
||||
|
||||
/* Get data from the OrderTask associated with the OrderTaskOccurrence */
|
||||
(schedule_type_code,
|
||||
process_type,
|
||||
order_task_frequency,
|
||||
item_catalog_guid,
|
||||
order_task_guid,
|
||||
order_guid,
|
||||
task_seq_num,
|
||||
application_source ) := read last
|
||||
{OrderTask: ScheduleTypeCode, ProcessType,
|
||||
OrderFrequency, OrderCatalogMasterItemGUID, GUID, OrderGUID, TaskSeqNum, ApplicSource
|
||||
REFERENCING order_task_obj };
|
||||
|
||||
primary_task_sequence_num := 0;
|
||||
if (task_seq_num = primary_task_sequence_num)
|
||||
then
|
||||
is_primary_task := true;
|
||||
else
|
||||
is_primary_task := false;
|
||||
endif;
|
||||
|
||||
/* Determine if the MLM should continue checking for duplicates */
|
||||
/* The evoking-object{{{SINGLE-QUOTE}}}s OrderTask must be Continuous, PRN, Scheduled or Unscheduled */
|
||||
/* OR be ToSchedule (when 1st given). Exclude everything else */
|
||||
|
||||
if (schedule_type_code is in ("Continuous","PRN","Scheduled","Unscheduled" )
|
||||
OR (schedule_type_code = "ToSchedule"
|
||||
AND process_type = 4 )) AND application_source IS NULL
|
||||
then
|
||||
continue_checking_task := true;
|
||||
else
|
||||
continue_checking_task := false;
|
||||
endif;
|
||||
|
||||
|
||||
/* Determine if a modified OrderTaskOccurrence should be checked for duplicates */
|
||||
If EvokingEventType = any_modified_task.type and continue_checking_task
|
||||
then
|
||||
if exist back_up_obj
|
||||
then
|
||||
(backup_scheduled_date,
|
||||
backup_earliest_date,
|
||||
backup_latest_date ) := read last
|
||||
{OrderTaskOccurrence: ScheduledDtm,
|
||||
EarliestScheduledDtm, LatestScheduledDtm
|
||||
REFERENCING back_up_obj };
|
||||
|
||||
/* Continue checking if the ScheduledDtm, EarliestScheduledDtm, */
|
||||
/* or LatestScheduledDtm have been modified */
|
||||
if (backup_scheduled_date <> task_scheduled_date )
|
||||
OR
|
||||
(backup_scheduled_date is null and task_scheduled_date is time)
|
||||
OR
|
||||
(backup_scheduled_date is time and task_scheduled_date is null)
|
||||
OR
|
||||
(backup_earliest_date <> task_earliest_date )
|
||||
OR
|
||||
(backup_earliest_date is null and task_earliest_date is time)
|
||||
OR
|
||||
(backup_earliest_date is time and task_earliest_date is null)
|
||||
OR
|
||||
(backup_latest_date <> task_latest_date )
|
||||
OR
|
||||
(backup_latest_date is null and task_latest_date is time)
|
||||
OR
|
||||
(backup_latest_date is time and task_latest_date is null)
|
||||
then continue_checking_task:= true;
|
||||
endif; /* backup_scheduled_date... */
|
||||
else
|
||||
continue_checking_task:= false;
|
||||
endif; /* if exist back_up_obj */
|
||||
endif; /* If EvokingEvent = any_modified_task */
|
||||
|
||||
|
||||
if continue_checking_task
|
||||
then
|
||||
|
||||
/* Get data from the order associated with the OrderTaskOccurrence */
|
||||
(task_name,
|
||||
chart_guid,
|
||||
client_visit_guid,
|
||||
order_type_code ) := read last
|
||||
{Order: Name, ChartGUID, ClientVisitGUID, TypeCode
|
||||
REFERENCING order_obj };
|
||||
|
||||
/* Gets the patient{{{SINGLE-QUOTE}}}s location group */
|
||||
If called_by_editor
|
||||
Then
|
||||
/* Since the patient has many visits, we must get the one from the Evoking Object */
|
||||
patient_loc_group:= read last
|
||||
{ ClientVisit: BusinessRuleLocationGUID
|
||||
where GUID = client_visit_guid};
|
||||
Else
|
||||
patient_loc_group:= read last
|
||||
{ClientVisit: BusinessRuleLocationGUID};
|
||||
Endif;
|
||||
|
||||
/* Get all the alerts in the CACHED MEMORY for the Std_duplicate_task MLM */
|
||||
(unsub_mlm_name_list,
|
||||
unsub_alert_priority_code_list ):= read
|
||||
{UnsubmittedAlerts: MLMName, PriorityCode
|
||||
where MLMName = "STD_DUPLICATE_TASK" };
|
||||
|
||||
|
||||
/* Stop duplicate checking if a high priority alert exists */
|
||||
/* in the CACHED MEMORY for a the same OrderTask parent in the set */
|
||||
if task_cds_occurrence_type is in (11,31,41,111,131,141)
|
||||
AND "HIGH" is in unsub_alert_priority_code_list
|
||||
then continue_checking_task := false;
|
||||
else
|
||||
/* Get all alerts in the DATABASE for the same OrderTask GUID */
|
||||
(task_name_list,
|
||||
mlm_name_list,
|
||||
alert_priority_code_list,
|
||||
mlm_pobject_name_list,
|
||||
mlm_rule_group_list,
|
||||
mlm_rule_number_list,
|
||||
mlm_alert_create_when_list ) := read
|
||||
{"SELECT t.TaskName, a.MLMName, a.PriorityCode, a.PObjectName,"
|
||||
||" a.RuleGroup, a.RuleNumber, a.CreatedWhen"
|
||||
||" FROM CV3AlertDeclaration AS a JOIN CV3OrderTaskOccurrence AS t"
|
||||
||" ON a.ClientGUID = t.ClientGUID"
|
||||
||" AND t.GUID = a.PObjectGUID "
|
||||
||" WHERE a.ClientGUID = " || SQL(client_guid)
|
||||
||" AND t.ClientGUID = " || SQL(client_guid)
|
||||
||" AND t.OrderTaskGUID = " || SQL(order_task_guid)
|
||||
||" AND a.PObjectName = {{{SINGLE-QUOTE}}}COrderTaskOccurrence{{{SINGLE-QUOTE}}} "
|
||||
||" AND a.MLMName = {{{SINGLE-QUOTE}}}STD_DUPLICATE_TASK{{{SINGLE-QUOTE}}} "
|
||||
||" AND a.Active = 1 "
|
||||
, PrimaryTime = CreatedWhen };
|
||||
|
||||
|
||||
/* Stop duplicate checking if a high priority alert exists */
|
||||
/* in the DATABASE for a the same OrderTask parent in the set */
|
||||
if task_cds_occurrence_type is in (11,31,41,111,131,141)
|
||||
AND "HIGH" is in alert_priority_code_list
|
||||
then continue_checking_task := false;
|
||||
endif; /* if task_cds_occurrence_type */
|
||||
|
||||
endif; /* if task_cds_occurrence_type */
|
||||
endif; /* continue_checking_task */
|
||||
|
||||
;;
|
||||
evoke: any_new_task
|
||||
OR any_modified_task
|
||||
OR any_rescheduled_task_instance;
|
||||
;;
|
||||
logic:
|
||||
If NOT continue_checking_task
|
||||
then conclude false;
|
||||
endif;
|
||||
|
||||
/* Initialize variable */
|
||||
indent:= " ";
|
||||
|
||||
|
||||
/* Determine Frequency Unit to calculate time interval for "Task %" */
|
||||
/* Use the frequency code from the OrderTask object, */
|
||||
if exist order_task_frequency
|
||||
then frequency_unit := order_task_frequency;
|
||||
else
|
||||
frequency_unit := NULL;
|
||||
endif;
|
||||
|
||||
|
||||
/*---------------------------------*/
|
||||
/* Find Duplicate task occurrences */
|
||||
/*---------------------------------*/
|
||||
(has_time_interval,
|
||||
has_unknown_frequency,
|
||||
exact_msg,
|
||||
performed_msg,
|
||||
scheduled_msg,
|
||||
same_item_type,
|
||||
same_therapeutic_class_type,
|
||||
similar_task_type,
|
||||
conflict_type,
|
||||
possible_conflict_type,
|
||||
no_std_message_type,
|
||||
duplicate_policy_guid,
|
||||
matching_task_name_list,
|
||||
matching_significant_date_list,
|
||||
matching_msg_type_list,
|
||||
matching_msg_text_list,
|
||||
matching_time_msg_list,
|
||||
matching_class_list,
|
||||
matching_latest_scheduled_dtm_list,
|
||||
matching_order_name_list,
|
||||
matching_order_type_code_list,
|
||||
matching_performed_to_dtm_list,
|
||||
matching_process_type_list,
|
||||
matching_schedule_type_code_list,
|
||||
matching_task_status_code_list )
|
||||
:= call func_task_rules with
|
||||
(task_name,
|
||||
task_occurrence_guid,
|
||||
task_status_code,
|
||||
task_summary_line,
|
||||
is_primary_task,
|
||||
order_guid,
|
||||
item_catalog_guid,
|
||||
chart_guid,
|
||||
client_visit_guid,
|
||||
task_significant_date,
|
||||
patient_loc_group,
|
||||
task_catalog_item_guid,
|
||||
frequency_unit,
|
||||
tasks_to_be_canceled_string,
|
||||
schedule_type_code,
|
||||
order_task_guid );
|
||||
|
||||
/*-------------------------------------------------------------*/
|
||||
/* Call an MLM to select the appropriate message and format it */
|
||||
/*-------------------------------------------------------------*/
|
||||
If exist matching_task_name_list
|
||||
and (NOT has_unknown_frequency OR schedule_type_code = "continuous")
|
||||
then
|
||||
alert_msg:= call func_task_messages with
|
||||
(task_name,
|
||||
task_status_code,
|
||||
is_primary_task,
|
||||
order_type_code,
|
||||
exact_msg,
|
||||
performed_msg,
|
||||
scheduled_msg,
|
||||
same_item_type,
|
||||
same_therapeutic_class_type,
|
||||
similar_task_type,
|
||||
conflict_type,
|
||||
possible_conflict_type,
|
||||
no_std_message_type,
|
||||
matching_task_name_list,
|
||||
matching_significant_date_list,
|
||||
matching_msg_type_list,
|
||||
matching_msg_text_list,
|
||||
matching_time_msg_list,
|
||||
matching_class_list,
|
||||
matching_latest_scheduled_dtm_list,
|
||||
matching_order_name_list,
|
||||
matching_order_type_code_list,
|
||||
matching_performed_to_dtm_list,
|
||||
matching_process_type_list,
|
||||
matching_schedule_type_code_list,
|
||||
matching_task_status_code_list );
|
||||
|
||||
endif; /* If exist matching_task_name_list */
|
||||
|
||||
/*-------------------------------------*/
|
||||
/* Determine if Alert Message Priority */
|
||||
/*-------------------------------------*/
|
||||
|
||||
if schedule_type_code = "scheduled"
|
||||
and "Performed" is in matching_task_status_code_list
|
||||
then
|
||||
alert_priority := "HIGH";
|
||||
high_priority_alert := true;
|
||||
else
|
||||
alert_priority := "MEDIUM";
|
||||
high_priority_alert := false;
|
||||
endif; /* schedule_type_code */
|
||||
|
||||
|
||||
/*-------------------------------------*/
|
||||
/* Set Variables for the Alert Message */
|
||||
/*-------------------------------------*/
|
||||
if alert_priority = "high"
|
||||
then a1_heading := "Warning";
|
||||
else a1_heading := "Caution";
|
||||
endif; /* if alert_priority */
|
||||
|
||||
// Set task string
|
||||
if is_primary_task
|
||||
then
|
||||
task_string := "task";
|
||||
else
|
||||
task_string := "follow-up task";
|
||||
endif;
|
||||
|
||||
if (is_primary_task
|
||||
and order_type_code = "Medication")
|
||||
then
|
||||
a2_order_type := "medication administration";
|
||||
else
|
||||
a2_order_type := task_string;
|
||||
endif; // if is_primary_task and order_type_code
|
||||
|
||||
if schedule_type_code = "scheduled"
|
||||
then a5_task_schedule_type := "Scheduled";
|
||||
elseif schedule_type_code = "unscheduled"
|
||||
then a5_task_schedule_type := "Unscheduled";
|
||||
elseif schedule_type_code = "PRN"
|
||||
then a5_task_schedule_type := "Pending PRN";
|
||||
elseif schedule_type_code = "continuous"
|
||||
then a5_task_schedule_type := "Pending continuous";
|
||||
elseif schedule_type_code = "ToSchedule" and process_type = 4
|
||||
then a5_task_schedule_type := "To be scheduled starting when first done";
|
||||
else a5_task_schedule_type := schedule_type_code;
|
||||
endif; /* if schedule_type_code */
|
||||
|
||||
if schedule_type_code = "scheduled"
|
||||
then a6_date_label := "Date" ;
|
||||
else a6_date_label := "Earliest Date" ;
|
||||
endif; /* if schedule_type_code */
|
||||
|
||||
|
||||
/*------------------------*/
|
||||
/* Assemble Alert Message */
|
||||
/*------------------------*/
|
||||
complete_alert_msg := "{{+B}}{{+R}}" || a1_heading || "{{-R}}{{-B}}\n"
|
||||
||"This " || a2_order_type || "\n"
|
||||
|| indent ||"{{+B}}{{+C}}"|| task_occurrence_name || "{{-C}}{{-B}}\n"
|
||||
|| indent || "( " || a5_task_schedule_type ||" )\n"
|
||||
|| indent || a6_date_label || ": " || task_significant_date formatted with "%.4t"|| "\n\n";
|
||||
|
||||
if exist matching_task_name_list
|
||||
and exist alert_msg
|
||||
and (NOT has_unknown_frequency OR schedule_type_code = "continuous")
|
||||
then
|
||||
/* Display Regular Alert Message */
|
||||
complete_alert_msg := complete_alert_msg
|
||||
||"{{+B}}May be too close to, or conflict with:{{-B}}\n\n"
|
||||
|| alert_msg;
|
||||
elseif exist matching_task_name_list
|
||||
and has_unknown_frequency
|
||||
and alert_if_unknown_frequency
|
||||
then
|
||||
/* Display Error Message */
|
||||
alert_msg:= true;
|
||||
complete_alert_msg := complete_alert_msg
|
||||
||"Unable to check for duplicate task occurrences"
|
||||
||" because all the required information to do a check, is not available. "
|
||||
||" Please review the tasks at the above time for potential duplicates.";
|
||||
endif; /* exist matching_task_name_list */
|
||||
|
||||
/*------------------*/
|
||||
/* Debug Statements */
|
||||
/*------------------*/
|
||||
xxx1_alert_msg:= exist alert_msg;
|
||||
xxx2_dup_policy_guid:= exist duplicate_policy_guid;
|
||||
xxx3_has_time_interval:= has_time_interval;
|
||||
xxx4_alert_priority:= alert_priority;
|
||||
xxx5_occur_first:= (task_cds_occurrence_type is in (10,20,30,40,110,120,130,140) );
|
||||
xxx6_occur_subsequent:= (task_cds_occurrence_type is in (11,31,41,111,131,141)
|
||||
AND alert_priority is NOT in (alert_priority_code_list,
|
||||
unsub_alert_priority_code_list));
|
||||
xxx7_occur_all:= (
|
||||
/* First task occurrence of the set */
|
||||
(task_cds_occurrence_type is in (10,20,30,40,110,120,130,140) )
|
||||
OR
|
||||
/* Second task occurrence of the set */
|
||||
(task_cds_occurrence_type is in (11,31,41,111,131,141)
|
||||
AND alert_priority is NOT in (alert_priority_code_list,
|
||||
unsub_alert_priority_code_list)));
|
||||
xxx8_previous_alert_priorities:= alert_priority_code_list,
|
||||
unsub_alert_priority_code_list;
|
||||
xxx9_task_cds_occurrence_type:= task_cds_occurrence_type;
|
||||
|
||||
|
||||
/*---------------*/
|
||||
/* Clinical Rule */
|
||||
/*---------------*/
|
||||
If exist alert_msg
|
||||
AND exist duplicate_policy_guid
|
||||
AND
|
||||
(
|
||||
// First task occurrence of the set
|
||||
(task_cds_occurrence_type is in (10,20,30,40,110,120,130,140) )
|
||||
|
||||
OR
|
||||
// Second task occurrence of the set
|
||||
(task_cds_occurrence_type is in (11,31,41,111,131,141)
|
||||
AND alert_priority is NOT in (alert_priority_code_list,
|
||||
unsub_alert_priority_code_list))
|
||||
OR
|
||||
// Added scheduled occurrence to the set
|
||||
(task_cds_occurrence_type = 90)
|
||||
OR
|
||||
// Added performed occurrence to the set
|
||||
(task_cds_occurrence_type = 91)
|
||||
|
||||
OR
|
||||
// Rescheduled an instance in the set
|
||||
(EVOKINGEVENTTYPE = any_rescheduled_task_instance.type)
|
||||
)
|
||||
then conclude true;
|
||||
endif;
|
||||
|
||||
;;
|
||||
action:
|
||||
/* Select the Destination for the Alert{{{SINGLE-QUOTE}}}s Priority */
|
||||
if high_priority_alert
|
||||
then
|
||||
write complete_alert_msg
|
||||
at high_dup_task_alert;
|
||||
else
|
||||
write complete_alert_msg
|
||||
at medium_dup_task_alert;
|
||||
endif; /* if high_priority_alert */
|
||||
;;
|
||||
Urgency: 50;;
|
||||
end:
|
||||
209
MLMStripper/bin/Debug/STD/STD_ESCALATION_EMAIL.mlm
Normal file
209
MLMStripper/bin/Debug/STD/STD_ESCALATION_EMAIL.mlm
Normal file
@@ -0,0 +1,209 @@
|
||||
maintenance:
|
||||
|
||||
title: Second Alert Escalation via Email;;
|
||||
mlmname: STD_ESCALATION_EMAIL;;
|
||||
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: Notifies the Alert Center that the patient{{{SINGLE-QUOTE}}}s Care-Provider has NOT ACKNOWLEDGED
|
||||
an urgent alert within the past 30 minutes.
|
||||
;;
|
||||
explanation:
|
||||
This time-based MLM handles the second (final) phase of Alert Escalation through an Email.
|
||||
It is triggered 30 minutes after the unacknowledged alert is stored into the database.
|
||||
A facility designates which Care-Provider-Role will be paged when an Escalation alert
|
||||
occurs. This designation is set using the "provider_role_string" variable in this MLM.
|
||||
|
||||
When the patient{{{SINGLE-QUOTE}}}s care-provider has not acknowledged the escalated-alert within
|
||||
30 minutes of the page, an Email message is sent to the designated Alert Center,
|
||||
where an alternate care-provider can be contacted by the people at the center.
|
||||
The rule is as follows:
|
||||
|
||||
If an "Escalation" alert-type is stored into the database in an UNACKNOWLEDGED state,
|
||||
and it remains unacknowledged after 30 minutes
|
||||
then an Email message is sent to the Alert Center.
|
||||
;;
|
||||
keywords: Time-based; Escalation; Alert Escalation;;
|
||||
|
||||
knowledge:
|
||||
type: data-driven;;
|
||||
data:
|
||||
/*******************Make Changes To Spelling And Flags In This Section*******************/
|
||||
/* Set to true if logging is needed.*/
|
||||
log_execution_info := false;
|
||||
|
||||
/* The Destination statment is located at the end of the data slot */
|
||||
/* This is due to the use of a variable in the statement, that is set dynamically */
|
||||
|
||||
|
||||
/* Escalation is a core-loaded Alert Type. */
|
||||
/* Recommend that the spelling within the quotes not be modified */
|
||||
unack_escalated_alert:= event {AlertEnter Any Alert:
|
||||
where TypeCode= "Escalation" and Status = "Unack" };
|
||||
|
||||
|
||||
/* Which Care-Provider should be contacted when there is an escalated-alert? */
|
||||
/* Change the provider-role in quotes to match the one in the STD_ESCALATION_PAGER MLM */
|
||||
/* In addition, the Role must exist in the Provider Role dictionary */
|
||||
|
||||
provider_role_string:= "Attending";
|
||||
|
||||
|
||||
/* Where should the Email be sent when the alert remains Unacknowledged for 30 minutes? */
|
||||
/* Change the email address in quotes */
|
||||
/* Recommend that this message be sent to your facility{{{SINGLE-QUOTE}}}s designated Alert Center */
|
||||
email_address:= "AlertCenter";
|
||||
|
||||
/****************************************************************************************/
|
||||
|
||||
/* Execute only when this MLM is called by the editor */
|
||||
if called_by_editor then
|
||||
obj := read last
|
||||
{ Alert: THIS
|
||||
WHERE TypeCode= "Escalation"
|
||||
AND Status = "Unack" };
|
||||
EvokingObject := obj;
|
||||
endif;
|
||||
|
||||
|
||||
/* Get the patient{{{SINGLE-QUOTE}}}s ID and Name */
|
||||
(client_guid,
|
||||
client_name) := read last {ClientInfo: GUID, Name};
|
||||
|
||||
|
||||
/* Get information about the evoking alert */
|
||||
(alert_type,
|
||||
alert_status,
|
||||
client_visit_guid,
|
||||
short_alert_msg,
|
||||
alert_guid,
|
||||
alert_text,
|
||||
alert_has_long_text ):= read last
|
||||
{Alert: TypeCode, Status, ClientVisitGUID, Description, GUID,
|
||||
PlainMessageText, HasLongText,
|
||||
REFERENCING EvokingObject };
|
||||
|
||||
/* Continue processing when there is an Unacknowledged alert. */
|
||||
/* It may be possible that someone has acknowledged the alert, */
|
||||
/* before the time-based MLM could run */
|
||||
|
||||
if alert_status = "unack"
|
||||
then
|
||||
|
||||
/* Get the patient{{{SINGLE-QUOTE}}}s location group (unit) */
|
||||
(current_loc_name,
|
||||
patient_loc_group_name ):= read last
|
||||
{"SELECT cv.CurrentLocation, loc.Name "
|
||||
|| " FROM CV3ClientVisit AS cv JOIN CV3Location AS loc"
|
||||
|| " ON cv.CurrentLocationGUID = loc.GUID "
|
||||
|| " WHERE cv.GUID = " || SQL(client_visit_guid)
|
||||
|| " AND cv.Active = 1 "
|
||||
|| " AND loc.Active = 1 " };
|
||||
|
||||
|
||||
/* Retrieve the current (unexpired) Care Provider information for the patient */
|
||||
/* Only one Care Provider with the designated Care-Provider-Role is retrieved */
|
||||
/* If there are two or more in the database, then the older ones will be ignored */
|
||||
(provider_role_code,
|
||||
provider_status,
|
||||
from_date,
|
||||
to_date,
|
||||
touched_when,
|
||||
provider_name ):= read last
|
||||
{"SELECT cpvr.RoleCode, cpvr.Status, fromDtm.TimeValue AS FromDtm, toDtm.TimeValue AS ToDtm, "
|
||||
||" touchedWhen.TimeValue AS TouchedWhen, cp.DisplayName "
|
||||
||" FROM CV3CareProviderVisitRole AS cpvr JOIN CV3CareProvider AS cp ON cpvr.ProviderGUID = cp.GUID "
|
||||
||" INNER JOIN CV3ClientVisit cv ON cpvr.ClientVisitGUID = cv.GUID "
|
||||
||" CROSS APPLY dbo.SXADBConvertLocalToOffsetForVisitTblFn(cpvr.ClientVisitGUID, cpvr.FromDtm) as fromDtm "
|
||||
||" CROSS APPLY dbo.SXADBConvertLocalToOffsetForVisitTblFn(cpvr.ClientVisitGUID, cpvr.ToDtm) as toDtm "
|
||||
||" CROSS APPLY dbo.SXADBConvertEnterpriseToLocalTblFn(cv.TimeZone, cpvr.TouchedWhen) touchedWhenLocal "
|
||||
||" CROSS APPLY dbo.SXADBConvertLocalToOffsetForVisitTblFn(cv.GUID, touchedWhenLocal.LocalDate) touchedWhen "
|
||||
||" WHERE cpvr.ClientVisitGUID = " || SQL(client_visit_guid)
|
||||
||" AND cpvr.Status = {{{SINGLE-QUOTE}}}Active{{{SINGLE-QUOTE}}} "
|
||||
||" AND cpvr.RoleCode = " || SQL(provider_role_string)
|
||||
||" AND cpvr.FromDtm <= (SELECT TOP 1 LocalDate FROM dbo.SXADBConvertEnterpriseToLocalTblFn(cv.TimeZone, (SELECT CurDate FROM dbo.SXADBGetEnterpriseNowTblFn()))) "
|
||||
||" AND (ISNULL (cpvr.ToDtm, (SELECT TOP 1 LocalDate FROM dbo.SXADBConvertEnterpriseToLocalTblFn(cv.TimeZone, (SELECT CurDate FROM dbo.SXADBGetEnterpriseNowTblFn())))) >= "
|
||||
||" (SELECT TOP 1 LocalDate FROM dbo.SXADBConvertEnterpriseToLocalTblFn(cv.TimeZone, (SELECT CurDate FROM dbo.SXADBGetEnterpriseNowTblFn()))))"
|
||||
, PrimaryTime = TouchedWhen };
|
||||
|
||||
endif; /* if alert_status = "Unack" */
|
||||
|
||||
/*------------------------*/
|
||||
/* DESTINATION STATEMENTS */
|
||||
/*------------------------*/
|
||||
/* Change the message within the quotes if a different short-message is needed.*/
|
||||
/* Do not change the Alert Type to Escalation. This will cause an infinite-loop */
|
||||
|
||||
intermediate_alert:= destination { IntermediateMessage: warning,
|
||||
"Escalation Alert", high, chart,
|
||||
"HVC Saved Escalation Message", 1010 };
|
||||
|
||||
email_alert:= destination { email: warning, "Escalation Alert",
|
||||
high, chart, email_address };
|
||||
|
||||
;;
|
||||
evoke: 30 minutes after time of unack_escalated_alert
|
||||
;;
|
||||
logic:
|
||||
/* Exit the MLM when the alert has already been acknowledged */
|
||||
If alert_status <> "Unack"
|
||||
then conclude false;
|
||||
endif;
|
||||
|
||||
/*---------------*/
|
||||
/* Clinical Rule */
|
||||
/*---------------*/
|
||||
If alert_status = "unack"
|
||||
then conclude true;
|
||||
endif;
|
||||
|
||||
;;
|
||||
action:
|
||||
/* Send message to email */
|
||||
write "The "|| provider_role_code || " ( " ||provider_name || " ) "
|
||||
|| "has not acknowledged an escalated-alert for the patient listed "
|
||||
|| "below in the past 30 minutes. "
|
||||
|| "Due to the urgency of the alert, please contact his/her alternate."
|
||||
|| "\n\nPatient: " || client_name
|
||||
|| "\nLocation: " || patient_loc_group_name
|
||||
|| "\nAlert Title: " || short_alert_msg || " (full text below)"
|
||||
|| "\n\n"
|
||||
|| alert_text
|
||||
at email_alert;
|
||||
|
||||
|
||||
/* Keep a copy of the e-mail message */
|
||||
/* Store it in the database as an intermediate message */
|
||||
write "The "|| provider_role_code || " ( " ||provider_name || " ) "
|
||||
|| "has not acknowledged an escalated-alert for the patient listed "
|
||||
|| "below in the past 30 minutes. "
|
||||
|| "Due to the urgency of the alert, please contact his/her alternate."
|
||||
|| "\n\nPatient: " || client_name
|
||||
|| "\nLocation: " || patient_loc_group_name
|
||||
|| "\nAlert Title: " || short_alert_msg || " (full text below)"
|
||||
|| "\n\n"
|
||||
|| alert_text
|
||||
at intermediate_alert;
|
||||
;;
|
||||
end:
|
||||
288
MLMStripper/bin/Debug/STD/STD_ESCALATION_PAGER.mlm
Normal file
288
MLMStripper/bin/Debug/STD/STD_ESCALATION_PAGER.mlm
Normal file
@@ -0,0 +1,288 @@
|
||||
maintenance:
|
||||
|
||||
title: First Alert Escalation via Pager;;
|
||||
mlmname: STD_ESCALATION_PAGER;;
|
||||
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: Notifies the patient{{{SINGLE-QUOTE}}}s Care-Provider that an urgent alert has occurred.
|
||||
;;
|
||||
explanation:
|
||||
This time-based MLM handles the first phase of Alert Escalation through a pager or email.
|
||||
It is triggered zero minutes after the alert is stored into the database.
|
||||
A facility designates which Care-Provider-Role will be paged when an Escalation alert
|
||||
occurs. This designation is set using the "provider_role_string" variable in this MLM.
|
||||
When the care-provider cannot be paged, an email message is sent to the
|
||||
designated Alert Center, where the appropriate care-provider can be contacted
|
||||
by the people at the Alert Center. The three rules are as follows:
|
||||
|
||||
1. If an "Escalation" alert-type is stored into the database in an UNACKNOWLEDGED state,
|
||||
then the patient{{{SINGLE-QUOTE}}}s care-provider is contacted through an alpha-numeric pager.
|
||||
|
||||
2. When the patient{{{SINGLE-QUOTE}}}s care-provider does not have an alpha-numeric pager,
|
||||
then an email message is sent to the Alert Center.
|
||||
|
||||
3. When the patient does not have a care-provider with a role that can receive the page,
|
||||
then an email message is sent to the Alert Center.
|
||||
;;
|
||||
keywords: Time-based; Escalation; Alert Escalation;;
|
||||
|
||||
knowledge:
|
||||
type: data-driven;;
|
||||
data:
|
||||
/*******************Make Changes To Spelling And Flags In This Section*******************/
|
||||
/* Set to true if logging is needed.*/
|
||||
log_execution_info := false;
|
||||
|
||||
/* The Destination statment is located at the end of the data slot */
|
||||
/* This is due to the use of a variable in the statement, that is set dynamically */
|
||||
|
||||
/* Escalation is a core-loaded Alert Type. */
|
||||
/* Recommend that the spelling within the quotes not be modified */
|
||||
unack_escalated_alert:= event {AlertEnter Any Alert:
|
||||
where TypeCode= "Escalation" and Status= "Unack"};
|
||||
|
||||
/* Change the spelling within the quotes to match a specific dictionary */
|
||||
phone_type_string:= "Pager-AlphaNum"; /* Phone Type (alpha-numeric pager)*/
|
||||
|
||||
/* Which Care-Provider should be contacted when there is an escalated-alert? */
|
||||
/* Change the provider-role in quotes to match a role in the Provider Role dictionary */
|
||||
provider_role_string:= "Attending";
|
||||
|
||||
/* Where should the alert be sent if there is no pager? */
|
||||
/* Change the email address in quotes */
|
||||
/* Recommend that this message be sent to your facility{{{SINGLE-QUOTE}}}s designated Alert Center */
|
||||
email_address:= "AlertCenter";
|
||||
|
||||
/* What is the long-distance country-code for your facility? */
|
||||
/* In the USA and Canada, the code is 1 */
|
||||
country_code:= 1;
|
||||
|
||||
/****************************************************************************************/
|
||||
|
||||
/* This block executes only when this MLM is called by the editor */
|
||||
if called_by_editor then
|
||||
obj := read last
|
||||
{ Alert: THIS
|
||||
WHERE TypeCode= "Escalation"
|
||||
AND Status = "Unack" };
|
||||
EvokingObject := obj;
|
||||
endif;
|
||||
|
||||
/* Get the patient{{{SINGLE-QUOTE}}}s ID and Name */
|
||||
(client_guid,
|
||||
client_name) := read last {ClientInfo: GUID, Name};
|
||||
|
||||
/* Get information about the evoking alert */
|
||||
(alert_type,
|
||||
alert_status,
|
||||
client_visit_guid,
|
||||
short_alert_msg,
|
||||
alert_guid,
|
||||
alert_text,
|
||||
alert_has_long_text ):= read last
|
||||
{Alert: TypeCode, Status, ClientVisitGUID, Description, GUID,
|
||||
PlainMessageText, HasLongText
|
||||
REFERENCING EvokingObject };
|
||||
|
||||
/* Continue processing when there is an Unacknowledged alert. */
|
||||
/* It is possible that someone may have acknowledged the alert */
|
||||
/* before the time-based MLM could run */
|
||||
if alert_status = "Unack"
|
||||
then
|
||||
/* Get the patient{{{SINGLE-QUOTE}}}s location group (unit) */
|
||||
(current_loc_name,
|
||||
patient_loc_group_name ):= read last
|
||||
{"SELECT cv.CurrentLocation, loc.Name "
|
||||
|| " FROM CV3ClientVisit AS cv JOIN CV3Location AS loc"
|
||||
|| " ON cv.CurrentLocationGUID = loc.GUID "
|
||||
|| " WHERE cv.GUID = " || SQL(client_visit_guid)
|
||||
|| " AND cv.Active = 1 "
|
||||
|| " AND loc.Active = 1 " };
|
||||
|
||||
/* Retrieve the current (unexpired) Care Provider for the patient */
|
||||
/* and the provider{{{SINGLE-QUOTE}}}s current (unexpired) Pager and Pin number combination */
|
||||
/* Only one pager and pin number combination is used. */
|
||||
/* If there are two or more in the database, then the older ones will be ignored */
|
||||
(provider_role_code_list,
|
||||
provider_status_list,
|
||||
from_date_list,
|
||||
to_date_list,
|
||||
active_phone_list,
|
||||
phone_type_list,
|
||||
area_code_list,
|
||||
phone_and_pin_list,
|
||||
touched_when_list,
|
||||
provider_name_list ):= read
|
||||
{"SELECT cpvr.RoleCode, cpvr.Status, fromDtm.TimeValue AS FromDtm, toDtm.TimeValue AS ToDtm, "
|
||||
||" p.Active, p.PhoneType, p.AreaCode, p.PhoneNumber, "
|
||||
||" touchedWhen.TimeValue AS TouchedWhen, cp.DisplayName"
|
||||
||" FROM CV3CareProviderVisitRole AS cpvr JOIN CV3CareProvider AS cp "
|
||||
||" ON cpvr.ProviderGUID = cp.GUID "
|
||||
||" INNER JOIN CV3ClientVisit cv ON cpvr.ClientVisitGUID = cv.GUID "
|
||||
||" LEFT OUTER JOIN CV3Phone AS p "
|
||||
||" ON cpvr.ProviderGUID = p.PersonGUID"
|
||||
||" CROSS APPLY dbo.SXADBConvertLocalToOffsetForVisitTblFn(cpvr.ClientVisitGUID, cpvr.FromDtm) as fromDtm "
|
||||
||" CROSS APPLY dbo.SXADBConvertLocalToOffsetForVisitTblFn(cpvr.ClientVisitGUID, cpvr.ToDtm) as toDtm "
|
||||
||" CROSS APPLY dbo.SXADBConvertEnterpriseToLocalTblFn(cv.TimeZone, cpvr.TouchedWhen) touchedWhenLocal "
|
||||
||" CROSS APPLY dbo.SXADBConvertLocalToOffsetForVisitTblFn(cv.GUID, touchedWhenLocal.LocalDate) touchedWhen "
|
||||
||" WHERE cpvr.ClientVisitGUID = " || SQL(client_visit_guid)
|
||||
||" AND cpvr.Status = {{{SINGLE-QUOTE}}}Active{{{SINGLE-QUOTE}}} "
|
||||
||" AND cpvr.RoleCode = " || SQL(provider_role_string)
|
||||
||" AND cpvr.FromDtm <= (SELECT TOP 1 LocalDate FROM dbo.SXADBConvertEnterpriseToLocalTblFn(cv.TimeZone, (SELECT CurDate FROM dbo.SXADBGetEnterpriseNowTblFn()))) "
|
||||
||" AND (ISNULL (cpvr.ToDtm, (SELECT TOP 1 LocalDate FROM dbo.SXADBConvertEnterpriseToLocalTblFn(cv.TimeZone, (SELECT CurDate FROM dbo.SXADBGetEnterpriseNowTblFn())))) >= "
|
||||
||" (SELECT TOP 1 LocalDate FROM dbo.SXADBConvertEnterpriseToLocalTblFn(cv.TimeZone, (SELECT CurDate FROM dbo.SXADBGetEnterpriseNowTblFn()))))"
|
||||
, PrimaryTime = TouchedWhen };
|
||||
|
||||
/*-------------------------------------------------------*/
|
||||
/* Find the AlphaNumeric Pager Number and Associated Info */
|
||||
/*-------------------------------------------------------*/
|
||||
|
||||
/* Find the location of the phone_type in the phone type list */
|
||||
found_phone_type := (phone_type_list = phone_type_string) AND (active_phone_list);
|
||||
|
||||
/* Get the most recent instance of the data if there is a pager */
|
||||
/* using the location of the phone type in found_phone_type */
|
||||
provider_role_code := last (provider_role_code_list where found_phone_type);
|
||||
provider_status := last (provider_status_list where found_phone_type);
|
||||
from_date := last (from_date_list where found_phone_type);
|
||||
to_date := last (to_date_list where found_phone_type);
|
||||
phone_type := last (phone_type_list where found_phone_type);
|
||||
area_code := last (area_code_list where found_phone_type);
|
||||
phone_and_pin := last (phone_and_pin_list where found_phone_type);
|
||||
touched_when := last (touched_when_list where found_phone_type);
|
||||
|
||||
/* Get the provider name */
|
||||
if exist provider_role_code
|
||||
then /* The provider has an alpha-numeric pager */
|
||||
/* Get the provider name associated with the PHONE_TYPE_STRING */
|
||||
provider_name := last (provider_name_list where found_phone_type);
|
||||
else /* The provider does not have an alpha-numeric pager */
|
||||
/* So get the provider name and phone at the end of the lists, */
|
||||
/* sorted by PrimaryTime (CV3Phone.TouchedWhen) */
|
||||
provider_name := last (provider_name_list);
|
||||
if last (active_phone_list) then
|
||||
provider_phone := last (phone_and_pin_list);
|
||||
else
|
||||
provider_phone := "NOT ACTIVE";
|
||||
endif; // last phone is active
|
||||
endif; /* if exist provider_role_code */
|
||||
endif; /* if alert_status = "Unack" */
|
||||
|
||||
/*-----------------------*/
|
||||
/* Assemble Pager Number */
|
||||
/*-----------------------*/
|
||||
If exist country_code
|
||||
and exist area_code
|
||||
and exist phone_and_pin
|
||||
then
|
||||
pager_num_and_pin:= country_code || "-" || area_code || "-" || phone_and_pin;
|
||||
endif; /* If exist country_code */
|
||||
|
||||
/*------------------------*/
|
||||
/* DESTINATION STATEMENTS */
|
||||
/*------------------------*/
|
||||
/* Change the message within the quotes if a different short-message as needed.*/
|
||||
/* Do not change the Alert Type to Escalation. This will cause an infinite loop */
|
||||
intermediate_alert:= destination { IntermediateMessage: warning,
|
||||
"Escalation Alert", high, chart,
|
||||
"HVC Saved Escalation Message", 1005 };
|
||||
|
||||
/* There must be a Care Provider and a Pager with a pin number to send a page */
|
||||
/* Otherwise, Email is sent to a facility{{{SINGLE-QUOTE}}}s designated Alert Center */
|
||||
if exist provider_name and exist pager_num_and_pin
|
||||
then
|
||||
primary_alert:= destination { Pager: warning,
|
||||
"Escalation Alert", high, chart, pager_num_and_pin };
|
||||
else
|
||||
primary_alert:= destination { Email: warning,
|
||||
"Escalation Alert", high, chart, email_address };
|
||||
endif;
|
||||
|
||||
;;
|
||||
evoke: 0 minutes after time of unack_escalated_alert
|
||||
|
||||
;;
|
||||
|
||||
logic:
|
||||
/* Exit the MLM when the alert has already been acknowledged */
|
||||
If alert_status <> "Unack"
|
||||
then conclude false;
|
||||
endif;
|
||||
|
||||
/* Determine the content of the message */
|
||||
If exist provider_name and exist pager_num_and_pin
|
||||
then
|
||||
alert_message:= client_name
|
||||
|| " ("|| patient_loc_group_name || ") " || short_alert_msg;
|
||||
phone_string := "\nPAGER number and pin: " ||pager_num_and_pin;
|
||||
else
|
||||
/* Create the top part of the message */
|
||||
if exist provider_name
|
||||
then
|
||||
alert_message:= "A pager message could not be sent to the "
|
||||
|| provider_role_string || " (" || provider_name || " )"
|
||||
|| " because he or she does not have an alpha-numeric pager. "
|
||||
|| " Please notify him or her that there is an escalated alert"
|
||||
|| " regarding the following patient: " ;
|
||||
phone_string := "\nPHONE number: " || provider_phone;
|
||||
else
|
||||
alert_message:= "A pager message could not be sent because the patient"
|
||||
|| " does not have a care-provider assigned as "
|
||||
|| provider_role_string
|
||||
|| ". Please notify the appropriate person that there is an"
|
||||
|| " escalated alert regarding the following patient: " ;
|
||||
provider_name := "NO CARE PROVIDER ASSIGNED";
|
||||
phone_string := "\nPHONE number: N/A";
|
||||
endif; /* if exist provider_name */
|
||||
|
||||
/* Create the bottom part of the message */
|
||||
alert_message:= alert_message
|
||||
||"\n\nPatient: " || client_name
|
||||
||"\nLocation: " || patient_loc_group_name
|
||||
|| "\nAlert Title: " || short_alert_msg || " (full text below)"
|
||||
||"\n\n"
|
||||
|| alert_text;
|
||||
endif; /* If exist provider_name... */
|
||||
|
||||
/*---------------*/
|
||||
/* Clinical Rule */
|
||||
/*---------------*/
|
||||
If alert_status = "Unack"
|
||||
then conclude true;
|
||||
endif;
|
||||
;;
|
||||
action:
|
||||
/* Send message to pager or email */
|
||||
write alert_message
|
||||
at primary_alert;
|
||||
|
||||
/* Keep a copy of the message and the care-provider{{{SINGLE-QUOTE}}}s ID */
|
||||
/* Store it in the database as an intermediate message */
|
||||
write provider_role_string || ": " ||provider_name
|
||||
|| phone_string
|
||||
|| "\n\n" || alert_message
|
||||
at intermediate_alert;
|
||||
;;
|
||||
end:
|
||||
326
MLMStripper/bin/Debug/STD/STD_FILTER_VPO_ALLERGIES.mlm
Normal file
326
MLMStripper/bin/Debug/STD/STD_FILTER_VPO_ALLERGIES.mlm
Normal file
@@ -0,0 +1,326 @@
|
||||
maintenance:
|
||||
|
||||
title: Fusion filtering criteria for importing community allergy data from dbMotion{{{SINGLE-QUOTE}}}s Client SDK.;;
|
||||
mlmname: STD_FILTER_VPO_ALLERGIES;;
|
||||
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: This standard MLM defines the filtering criteria for community allergies
|
||||
when the respective data is requested from dbMotion.
|
||||
|
||||
This MLM allows specification of either inclusion or exclusion of data to ensure
|
||||
only the minimal volume of data that is necessary for processing to be returned.
|
||||
;;
|
||||
explanation:
|
||||
The use case and respective filtering criteria supported
|
||||
by this MLM may be customized for the limited list of filtering criteria only:
|
||||
|
||||
(1) Last modified date/time to include (criteria: last_modified_from_dtm).
|
||||
For allergy, we do not use this field.
|
||||
ALWAYS set to NULL.
|
||||
|
||||
(2) Site defined Identifiers to exclude (criteria: rejected_id_list)
|
||||
This criteria allows sites to specify a list of identifiers to exclude. These identifiers
|
||||
can specify those records that have rejected by a Sunrise user if the record should
|
||||
never be processed, or to exclude all those identifiers that are sent from a source
|
||||
facility that is a non-trusted source.
|
||||
Defined as a combined list of rejected identifiers from hard coded identifier list
|
||||
and database identifier list.
|
||||
|
||||
Specify hard coded identifier list and/or database identifier list as conditions for
|
||||
this criteria:
|
||||
(a) Hard coded identifier list: specify identifiers formatted as <system OID>.<id>
|
||||
- Specific all identifiers to be excluded, which can be a list of specific
|
||||
identifiers, or as wildcard in the form of "<system OID>.%"
|
||||
e.g. hardcoded_id_list := (
|
||||
"1.3.6.1.4.1.22812.11.0.0.4.10.2.41700060",
|
||||
"1.3.6.1.4.1.22812.11.0.0.4.10.2.39248233",
|
||||
"1.3.6.1.4.1.22812.11.2014.1001.%",
|
||||
"1.3.6.1.4.1.22812.11.2014.9876.%"
|
||||
);
|
||||
(b) Database identifier list: Retrieve community identifiers from database that are
|
||||
rejected by users.
|
||||
e.g.
|
||||
database_id_list := read { "SELECT DISTINCT CommunityRecordID " ||
|
||||
" FROM CV3AllergyDeclaration " ||
|
||||
" WHERE " ||
|
||||
" ClientGUID = " || SQL(client_guid) ||
|
||||
" AND Status in ({{{SINGLE-QUOTE}}}Rejected{{{SINGLE-QUOTE}}}) "
|
||||
|
||||
(3) Field name and value list to include or exclude
|
||||
This criteria allows sites to specify a field name, and indicate an option to include
|
||||
or exclude, along with a list of eligible values. Filtering by the field is only
|
||||
performed if all required elements are specified.
|
||||
|
||||
All data values matching the specified value list will be included or excluded as
|
||||
defined.
|
||||
|
||||
Only 2 fields are supported for Allergies: Status Code, and Intolerance Value.
|
||||
Specify one or both as conditions for the criteria:
|
||||
|
||||
(a) Status Code (criteria: status_code_include_values, status_code_list)
|
||||
- Set status_code_include_values to true to include records with the listed
|
||||
values in the returned result, and false to exclude them.
|
||||
e.g. status_code_include_values := false;
|
||||
- Specify status_code_list formatted as <system OID>.<code> to include or
|
||||
exclude.
|
||||
e.g. status_code_list := (
|
||||
"2.16.840.1.113883.5.14.cancelled"
|
||||
);
|
||||
|
||||
After retrieving from dbMotion, only items with status code as one of the
|
||||
following are processed by the Allergies Summary dialog:
|
||||
o Active (2.16.840.1.113883.6.96.55561003, 2.16.840.1.113883.5.14.active),
|
||||
o Final (2.16.840.1.113883.5.4.F), and
|
||||
o Completed (2.16.840.1.113883.5.4.Completed)
|
||||
o Cancelled (2.16.840.1.113883.5.14.Cancelled)
|
||||
o Entered in Error (2.16.840.1.113883.6.96.185981001)
|
||||
If sites want to filter by status code, specifying to include these status values
|
||||
limit the amount of data returned from dbMotion.
|
||||
(b) Intolerance Value (critiera: intolerance_value_include_values,
|
||||
intolerance_value_list)
|
||||
- Set intolerance_value_include_values to true to include records with the
|
||||
listed valued in the returned result, and false to exclude them.
|
||||
e.g. intolerance_value_include_values := false;
|
||||
- Specify intolerance_value_list formatted as <system OID>.<code> to
|
||||
include or exclude.
|
||||
e.g. intolerance_value_list := (
|
||||
"2.16.840.1.113883.6.96.409137002",
|
||||
"2.16.840.1.113883.6.96.160244002",
|
||||
"2.16.840.1.113883.6.96.429625007",
|
||||
"2.16.840.1.113883.6.96.428607008"
|
||||
);
|
||||
Sites are recommended to filter out all the "No Known" indicators:
|
||||
o No Known Drug Allergies (NKDA), expressed in SNOMED CT as
|
||||
"2.16.840.1.113883.6.96.409137002"
|
||||
o No Known Allergy (NKA), expressed in SNOMED CT as
|
||||
"2.16.840.1.113883.6.96.160244002"
|
||||
o No Known Food Allergies (NKFA), expressed in SNOMED CT as
|
||||
"2.16.840.1.113883.6.96.429625007"
|
||||
o No Known Environmental Allergies (NKEA), expressed in SNOMED CT as
|
||||
"2.16.840.1.113883.6.96.428607008"
|
||||
|
||||
If there are specific RxNorm codes to be filtered, specify in the
|
||||
intolerance_value_list with <system OID> as 2.16.840.1.113883.6.88, and
|
||||
append with relevant RxNorm code in <code>. Similarly, specify UNII
|
||||
codes to filter by setting <system OID> in intolerance_value_list as
|
||||
"2.16.840.1.113883.4.9"
|
||||
(4) Semantic Group filter (criteria: ExcludeMyEHRData, ExcludeSemanticGroup)
|
||||
Sites will be able to indicate that only data records that are semantically different to be returned.
|
||||
There are 2 fields to indicate what the filter should be.
|
||||
(a) Exclude data that alreay exist in current EHR (criteria: ExcludeMyEHRData)
|
||||
- Set ExcludeMyEHRData to true to filter out data that already exists in current EHR, and
|
||||
false to include them.
|
||||
Default: set value to True.
|
||||
e.g. ExcludeMyEHRData := True;
|
||||
(b) Exclude semantic equivalent data (criteria: ExcludeSemanticGroup)
|
||||
- Set ExcludeSemanticGroup to true to filter out data that exists in current EHR based on
|
||||
semantic similarity, and false to include them. For Allergies, data having same
|
||||
group domain or same baseline code or local code are filtered out if set to true.
|
||||
Default: set value to False.
|
||||
e.g. ExcludeSemanticGroup := False;
|
||||
;;
|
||||
keywords: Fusion; Filter; Community Allergies
|
||||
;;
|
||||
citations:
|
||||
;;
|
||||
knowledge:
|
||||
type: data-driven;;
|
||||
data:
|
||||
// Specify which .NET assemblies need to be loaded for ObjectsPlus
|
||||
standard_libs := MLM {{{SINGLE-QUOTE}}}std_include_libs{{{SINGLE-QUOTE}}};
|
||||
|
||||
include standard_libs;
|
||||
|
||||
// Arguments are passed in from the calling C++ program or MLM */
|
||||
(client_guid,
|
||||
visit_guid,
|
||||
last_modified_from_db_str
|
||||
) := argument;
|
||||
|
||||
// ------------------------------------------------------------------
|
||||
// Do not touch this section
|
||||
// ------------------------------------------------------------------
|
||||
error_message := "";
|
||||
fatal_error := false;
|
||||
|
||||
// Declare the MLMs that can be called
|
||||
func_gen_dictionary := MLM {{{SINGLE-QUOTE}}}STD_FUNC_FILTER_VPO_GEN_DICTIONARY{{{SINGLE-QUOTE}}};
|
||||
func_gen_property_dictionary := MLM {{{SINGLE-QUOTE}}}STD_FUNC_FILTER_VPO_GEN_PROPERTY_DICTIONARY{{{SINGLE-QUOTE}}};
|
||||
|
||||
// Set the input from string to time - not used for allergy
|
||||
db_last_modified_from_dtm := last_modified_from_db_str as time;
|
||||
|
||||
// Define the name value object
|
||||
NameValueObject := OBJECT [ field_name, include_flag, value_list ];
|
||||
|
||||
// Define the name value object for properties
|
||||
PropertyValueObject := OBJECT [ field_name, value ];
|
||||
|
||||
// Initialize the id list and set up default value
|
||||
last_modified_from_dtm := null;
|
||||
rejected_id_list := ();
|
||||
hardcoded_id_list := ();
|
||||
database_id_list := ();
|
||||
|
||||
|
||||
//***************Make Changes To Spelling And Flags In This Section************
|
||||
// Set to true if logging is needed.
|
||||
log_execution_info := false;
|
||||
show_Debug_statements := false;
|
||||
|
||||
// Semantic group filter
|
||||
// Specify the flag to indicate whether to include or exclude the data that already exists in
|
||||
// current EHR in criteria ExcludeMyEHRData.
|
||||
// By default, if the entry is mising or value is set to false, no filterng will be performed and
|
||||
// data from current EHR will also be returned.
|
||||
// If entry is set to true, all data that already exists in current EHR are filtered.
|
||||
//
|
||||
ExcludeMyEHRData := true;
|
||||
|
||||
// Specify the flag to indicate whether to include or exclude the data that exists in current EHR
|
||||
// based on semantic similarity in criteria ExcludeSemanticGroup.
|
||||
// By default, if the entry is missing or value is set to false, no filterng will be performed and
|
||||
// data that is semantically similar will also be returned.
|
||||
// If entry is set to true, only the semantic delta list of data is returned.
|
||||
ExcludeSemanticGroup := false;
|
||||
|
||||
// ------------------------------------------------------------------
|
||||
// Please update this section to customize the community data filter
|
||||
// ------------------------------------------------------------------
|
||||
// Specify the list of Ids to exclude in rejected_id_list
|
||||
// The ids can be hard coded, or fetched from the database
|
||||
// or combination of both
|
||||
// By default, the rejected id list is empty
|
||||
/*
|
||||
// comment this in to use hard coded list of ids
|
||||
// specify the ids
|
||||
hardcoded_id_list := ();
|
||||
|
||||
rejected_id_list := rejected_id_list, hardcoded_id_list;
|
||||
*/
|
||||
|
||||
/*
|
||||
// comment this in to use the ids from the database
|
||||
// update the SQL to get the ids you want to exclude
|
||||
database_id_list := read { "SELECT DISTINCT CommunityRecordID " ||
|
||||
" FROM CV3AllergyDeclaration " ||
|
||||
" WHERE " ||
|
||||
" ClientGUID = " || SQL(client_guid) ||
|
||||
" AND Status in ({{{SINGLE-QUOTE}}}Rejected{{{SINGLE-QUOTE}}}) "
|
||||
};
|
||||
rejected_id_list := rejected_id_list, database_id_list;
|
||||
*/
|
||||
|
||||
|
||||
// Field Name value filter
|
||||
// Specify the field name, flag to indicate whether to include or exclude the values, and list of values.
|
||||
// By default, if the entry is missing for the field, or the value list is empty, no filtering
|
||||
// will be performed for the field
|
||||
// If the values are specified, the data matching the specified data will be filtered as specified
|
||||
status_code_include_values := false; // true include listed values in result, false exclude
|
||||
status_code_list := (
|
||||
"2.16.840.1.113883.5.14.cancelled", // cancelled
|
||||
"2.16.840.1.113883.6.96.185981001" // entered-in-error
|
||||
);
|
||||
|
||||
intolerance_value_include_values := false;
|
||||
intolerance_value_list := ();
|
||||
|
||||
// ------------------------------------------------------------------
|
||||
// End of user customization section
|
||||
// ------------------------------------------------------------------
|
||||
//*****************************************************************************
|
||||
;;
|
||||
priority: 50
|
||||
;;
|
||||
evoke:
|
||||
;;
|
||||
logic:
|
||||
/************************* DO NOT UPDATE ****************************************/
|
||||
|
||||
// This section formats the data in a format that is understood by
|
||||
// the caller
|
||||
|
||||
|
||||
// Format the return value as time, so it can be read by the caller
|
||||
if exists last_modified_from_dtm
|
||||
then
|
||||
last_modified_from_dtm := last_modified_from_dtm as time;
|
||||
LastModifiedStartDateTime := last_modified_from_dtm as {{{SINGLE-QUOTE}}}DateTime{{{SINGLE-QUOTE}}};
|
||||
endif;
|
||||
|
||||
// Allergy only has onset (start) date, and no end date, so
|
||||
// we cannot filter by active allergies using effective start time filter
|
||||
EffectiveStartFromDateTime_Not_Used := null;
|
||||
|
||||
//
|
||||
field_value_list := (
|
||||
(new NameValueObject with "statusCode", status_code_include_values, status_code_list),
|
||||
(new NameValueObject with "intoleranceValue", intolerance_value_include_values, intolerance_value_list)
|
||||
);
|
||||
|
||||
// Format the name value pairs into a .Net Dictionary with field name, and a list of values
|
||||
(FieldCriteriaDictionary, FieldValuesListDictionary) := call func_gen_dictionary with field_value_list;
|
||||
|
||||
// Ids to exclude
|
||||
if (count rejected_id_list > 0)
|
||||
then
|
||||
IdsToExcludeList := new net_object {{{SINGLE-QUOTE}}}Collections.Generic.List<String>{{{SINGLE-QUOTE}}};
|
||||
for id in rejected_id_list
|
||||
do
|
||||
id_val := id as {{{SINGLE-QUOTE}}}String{{{SINGLE-QUOTE}}};
|
||||
void := call IdsToExcludeList.Add with id_val;
|
||||
enddo;
|
||||
else
|
||||
IdsToExcludeList := null;
|
||||
endif;
|
||||
|
||||
property_value_list := (
|
||||
(new PropertyValueObject with "ExcludeMyEHRData", ExcludeMyEHRData),
|
||||
(new PropertyValueObject with "ExcludeSemanticGroup", ExcludeSemanticGroup)
|
||||
);
|
||||
|
||||
// Format the name value pairs into a .Net Dictionary
|
||||
PropertyNameDictionary := call func_gen_property_dictionary with property_value_list;
|
||||
|
||||
conclude true;
|
||||
;;
|
||||
action:
|
||||
if fatal_error
|
||||
then
|
||||
return fatal_error, error_message;
|
||||
else
|
||||
return
|
||||
LastModifiedStartDateTime,
|
||||
EffectiveStartFromDateTime_Not_Used,
|
||||
FieldCriteriaDictionary,
|
||||
FieldValuesListDictionary,
|
||||
IdsToExcludeList,
|
||||
PropertyNameDictionary
|
||||
;
|
||||
endif;
|
||||
;;
|
||||
Urgency: 50;;
|
||||
end:
|
||||
443
MLMStripper/bin/Debug/STD/STD_FILTER_VPO_DOCUMENTLIST.mlm
Normal file
443
MLMStripper/bin/Debug/STD/STD_FILTER_VPO_DOCUMENTLIST.mlm
Normal file
@@ -0,0 +1,443 @@
|
||||
maintenance:
|
||||
|
||||
title: ;;
|
||||
mlmname: STD_FILTER_VPO_DOCUMENTLIST;;
|
||||
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) 2017 - 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: This standard MLM defines the filtering criteria for community document list
|
||||
when the respective data is requested from dbMotion.
|
||||
|
||||
This MLM allows specification of either inclusion or exclusion of data to ensure
|
||||
only the minimal volume of data that is necessary for processing to be returned.
|
||||
;;
|
||||
explanation:
|
||||
The use case and respective filtering criteria supported by this MLM may be customized
|
||||
for the limited list of filtering criteria only:
|
||||
(1) Document Create date/time to include (criteria: effective_start_from_dtm)
|
||||
This criteria allows sites to include only documents that have been created since a specified
|
||||
date/time to filter out any redundant data.
|
||||
|
||||
Specify any one of the following conditions:
|
||||
(a) Document Create timestamp for Fusion Documents for the patient in context is
|
||||
used to return only documents that were created since the specified date.
|
||||
- Set value to db_last_modified_from_dtm.
|
||||
e.g. effective_start_from_dtm := db_last_modified_from_dtm;
|
||||
(b) Site specified date or time-offset: allows the site to override the default
|
||||
behavior so that all data that have been modified since a specific date will be
|
||||
provided.
|
||||
- Set value to a date string formatted as "mmm dd yyyy"
|
||||
e.g. effective_start_from_dtm := "Jan 25 2014";
|
||||
- Set value to arden date keyword
|
||||
e.g. effective_start_from_dtm := now;
|
||||
- Default: Set value to time offset in seconds/days/weeks/months/years ago
|
||||
e.g. effective_start_from_dtm := 2 years ago;
|
||||
- Set value as a calculated value using units in
|
||||
seconds/days/weeks/months/years, if applicable.
|
||||
e.g. effective_start_from_dtm := db_last_modified_from_dtm - 6 months
|
||||
(c) Always return all data: allows sites to override the default behavior so that all
|
||||
documents are provided in document list. Using this option can result in an impact
|
||||
to performance.
|
||||
- Set value to NULL.
|
||||
(2) Source Object Identifiers to exclude (criteria: hardcoded_id_list)
|
||||
This criteria allows sites to specify a list of object identifiers to exclude. These object
|
||||
identifiers specifies source facilities that are non-trusted sources.
|
||||
|
||||
Hard coded identifier list: specify identifiers formatted as <system OID>! to exclude.
|
||||
- Specific all object identifiers to be excluded with an exclaimation mark at the end
|
||||
to indicate a source OID value.
|
||||
e.g. hardcoded_id_list := (
|
||||
"1.3.6.1.4.1.22812.11.0.0.4.10.2.41700060!",
|
||||
"1.3.6.1.4.1.22812.11.0.0.4.10.2.39248233!",
|
||||
"1.3.6.1.4.1.22812.11.2014.1001!",
|
||||
"1.3.6.1.4.1.22812.11.2014.9876!"
|
||||
);
|
||||
(3) Field name and value list to include or exclude
|
||||
This criteria allows sites to specify a field name, and indicate an option to include
|
||||
or exclude, along with a list of eligible values. Filtering by the field is only
|
||||
performed if all required elements are specified.
|
||||
|
||||
All data values matching the specified value list will be included or excluded as
|
||||
defined.
|
||||
|
||||
Only 4 fields are supported for Document List: Status Code, Completion Status, Document Type and Media Type.
|
||||
Specify one or more as conditions for the criteria:
|
||||
(a) Status Code (criteria: status_code_include_values, status_code_list)
|
||||
- Set status_code_include_values to true to include records with the listed
|
||||
values in the returned result, and false to exclude them.
|
||||
e.g. status_code_include_values := false;
|
||||
- Specify status_code_list formatted as <system OID>.<code> to include
|
||||
or exclude.
|
||||
e.g. status_code_list := (
|
||||
"2.16.840.1.113883.5.14.new",
|
||||
"2.16.840.1.113883.5.14.suspended",
|
||||
"2.16.840.1.113883.5.14.held",
|
||||
"2.16.840.1.113883.5.14.aborted",
|
||||
"2.16.840.1.113883.5.14.cancelled",
|
||||
"2.16.840.1.113883.6.96.73425007",
|
||||
"2.16.840.1.113883.6.96.185981001"
|
||||
);
|
||||
This example is configured to exclude the statuses with values new, suspended,
|
||||
held, aborted, cancelled, and those with SNOMEDCT code 73425007 and 185981001.
|
||||
(b) Completion Status (criteria: completionStatus_code_include_values, completionStatus_code_list)
|
||||
- Set completionStatus_code_include_values to true to include records with the listed
|
||||
values in the returned result, and false to exclude them.
|
||||
e.g. completionStatus_code_include_values := false;
|
||||
- Specify completionStatus_list formatted as <system OID>.<code> to include
|
||||
or exclude.
|
||||
e.g. completionStatus_list := (
|
||||
"2.16.840.1.113883.5.33.CA", /* canceled */
|
||||
"2.16.840.1.113883.5.33.IN", /* incomplete */
|
||||
"2.16.840.1.113883.5.33.CAN", /* canceled */
|
||||
"2.16.840.1.113883.5.33.IP", /* in progress */
|
||||
"2.16.840.1.113883.5.33.NU" /* nullified document */
|
||||
);
|
||||
This example is configured to exclude completion statuses CA, IN, CAN, IP and NU.
|
||||
(c) Document Type (critiera: documentType_code_include_values, documentType_code_list)
|
||||
- Set documentType_code_include_values to true to include records with the listed
|
||||
valued in the returned result, and false to exclude them.
|
||||
e.g. documentType_code_include_values := true;
|
||||
- Specify documentType_code_list formatted as <system OID>.<code> to include or
|
||||
exclude.
|
||||
e.g. documentType_code_list := (
|
||||
"2.16.840.1.113883.6.1.11334-0", /* History of growth+Development Narrative */
|
||||
"2.16.840.1.113883.6.1.11488-4", /* Consult Note */
|
||||
"2.16.840.1.113883.6.1.11502-2", /* Laboratory Report */
|
||||
"2.16.840.1.113883.6.1.11504-8" /* Provider-unspecified Operation note */
|
||||
);
|
||||
|
||||
(d) Media Type (critiera: mediaType_code_include_values, mediaType_code_list)
|
||||
- Set mediaType_code_include_values to true to include records with the listed
|
||||
valued in the returned result, and false to exclude them.
|
||||
e.g. mediaType_code_include_values := false;
|
||||
- Specify mediaType_code_list formatted as <system OID>.<code> to include or
|
||||
exclude.
|
||||
e.g. mediaType_code_list := (
|
||||
"2.16.840.1.113883.5.79.application/rtf",
|
||||
"2.16.840.1.113883.5.79.text/richtext"
|
||||
);
|
||||
This example is configured to exclude RTF documents and richtext documents.
|
||||
|
||||
Only the following media types are allowed:
|
||||
- application/rtf
|
||||
- text/richtext
|
||||
- application/pdf
|
||||
- text/plain
|
||||
- text/html
|
||||
- image/tiff
|
||||
- image/jpeg
|
||||
- image/png
|
||||
- text/xml
|
||||
|
||||
;;
|
||||
keywords: Fusion; Filter; Community Document List
|
||||
;;
|
||||
citations:
|
||||
;;
|
||||
knowledge:
|
||||
type: data-driven;;
|
||||
data:
|
||||
// Specify which .NET assemblies need to be loaded for ObjectsPlus
|
||||
standard_libs := MLM {{{SINGLE-QUOTE}}}std_include_libs{{{SINGLE-QUOTE}}};
|
||||
|
||||
include standard_libs;
|
||||
|
||||
// Arguments are passed in from the calling C++ program or MLM */
|
||||
(client_guid,
|
||||
visit_guid,
|
||||
last_modified_from_db_str
|
||||
) := argument;
|
||||
|
||||
// ------------------------------------------------------------------
|
||||
// Do not touch this section
|
||||
// ------------------------------------------------------------------
|
||||
error_message := "";
|
||||
fatal_error := false;
|
||||
|
||||
// Declare the MLMs that can be called
|
||||
func_gen_dictionary := MLM {{{SINGLE-QUOTE}}}STD_FUNC_FILTER_VPO_GEN_DICTIONARY{{{SINGLE-QUOTE}}};
|
||||
func_gen_property_dictionary := MLM {{{SINGLE-QUOTE}}}STD_FUNC_FILTER_VPO_GEN_PROPERTY_DICTIONARY{{{SINGLE-QUOTE}}};
|
||||
|
||||
// Set the input from string to time
|
||||
db_last_modified_from_dtm := last_modified_from_db_str as time;
|
||||
|
||||
// Define the name value object
|
||||
NameValueObject := OBJECT [ field_name, include_flag, value_list ];
|
||||
|
||||
// Define the name value object for properties
|
||||
PropertyValueObject := OBJECT [ field_name, value ];
|
||||
|
||||
// Initialize the id list and set up default value
|
||||
last_modified_from_dtm := null;
|
||||
|
||||
rejected_id_list := ();
|
||||
hardcoded_id_list := ();
|
||||
// ------------------------------------------------------------------
|
||||
// Please update this section to customize the community data filter
|
||||
// ------------------------------------------------------------------
|
||||
|
||||
// Set to true if logging is needed.
|
||||
log_execution_info := false;
|
||||
show_Debug_statements := false;
|
||||
|
||||
// By setting up this filter value, we retrieve documents that
|
||||
// are active at this date. The document list contains documents that were created on or before
|
||||
// the effective_start_from_dtm value will be eliminated.
|
||||
// 1. By default, this value is set to 12 months ago
|
||||
// 2. User specified
|
||||
// - null to do no filtering by episode time from
|
||||
// - string effective_start_from_dtm "Jan 25 2014"
|
||||
// e.g. effective_start_from_dtm := "Jan 25 2014";
|
||||
// - arden date keyword: now
|
||||
// e.g. effective_start_from_dtm := now;
|
||||
// - time offset: 3 [seconds|days|weeks|months|years] ago
|
||||
// e.g. effective_start_from_dtm := 3 months ago;
|
||||
// - calculated time: db_last_modified_from_dtm - 3 hours
|
||||
// e.g. effective_start_from_dtm := db_last_modified_from_dtm - 2 weeks;
|
||||
// 3. Both last modified time and created time filter will be applied
|
||||
effective_start_from_dtm := 12 months ago;
|
||||
|
||||
// Field Name value filter
|
||||
// Specify the field name, flag to indicate whether to include or exclude the values, and list of values.
|
||||
// By default, if the entry is missing for the field, or the value list is empty, no filtering
|
||||
// will be performed for the field
|
||||
// If the values are specified, the data matching the specified data will be filtered as specified
|
||||
status_code_include_values := false; // true include listed values in result, false exclude
|
||||
status_code_list := (
|
||||
"2.16.840.1.113883.5.14.cancelled", // cancelled
|
||||
"2.16.840.1.113883.5.14.aborted", // aborted
|
||||
"2.16.840.1.113883.6.96.185981001" // entered-in-error
|
||||
);
|
||||
|
||||
|
||||
// Field Name value filter
|
||||
// Specify the field name, flag to indicate whether to include or exclude the values, and list of values.
|
||||
// By default, if the entry is missing for the field, or the value list is empty, no filtering
|
||||
// will be performed for the field
|
||||
// If the values are specified, the data matching the specified data will be filtered as specified
|
||||
//
|
||||
completionStatus_code_include_values := false; // true include listed values in result, false exclude
|
||||
completionStatus_code_list := (
|
||||
"2.16.840.1.113883.5.33.CA",
|
||||
"2.16.840.1.113883.5.33.IN",
|
||||
"2.16.840.1.113883.5.33.CAN",
|
||||
"2.16.840.1.113883.5.33.IP",
|
||||
"2.16.840.1.113883.5.33.NU"
|
||||
);
|
||||
|
||||
documentType_code_include_values := true;
|
||||
documentType_code_list := (
|
||||
"2.16.840.1.113883.6.1.11334-0", /* History of growth+Development Narrative */
|
||||
"2.16.840.1.113883.6.1.11488-4", /* Consult Note */
|
||||
"2.16.840.1.113883.6.1.11502-2", /* Laboratory Report */
|
||||
"2.16.840.1.113883.6.1.11504-8", /* Provider-unspecified Operation note */
|
||||
"2.16.840.1.113883.6.1.11505-5", /* Physician procedure note */
|
||||
"2.16.840.1.113883.6.1.11506-3", /* Provider-unspecified Progress note */
|
||||
"2.16.840.1.113883.6.1.11522-0", /* Deprecated Cardiac echo study */
|
||||
"2.16.840.1.113883.6.1.11526-1", /* Pathology study */
|
||||
"2.16.840.1.113883.6.1.18736-9", /* Physician Initial evaluation note */
|
||||
"2.16.840.1.113883.6.1.18737-7", /* Podiatry Initial evaluation note */
|
||||
"2.16.840.1.113883.6.1.18744-3", /* Bronchoscopy study */
|
||||
"2.16.840.1.113883.6.1.18748-4", /* Diagnostic imaging study */
|
||||
"2.16.840.1.113883.6.1.18751-8", /* Endoscopy Study */
|
||||
"2.16.840.1.113883.6.1.18752-6", /* Exercise stress test study */
|
||||
"2.16.840.1.113883.6.1.18754-2", /* Holter monitor study */
|
||||
"2.16.840.1.113883.6.1.18761-7", /* Provider-unspecified Transfer summary */
|
||||
"2.16.840.1.113883.6.1.18836-7", /* Cardiac stress study Procedure */
|
||||
"2.16.840.1.113883.6.1.18842-5", /* Discharge summary */
|
||||
"2.16.840.1.113883.6.1.24537-3", /* US Guidance for removal of amniotic fluid from Uterus */
|
||||
"2.16.840.1.113883.6.1.24757-7", /* Coronary arteries CT fast */
|
||||
"2.16.840.1.113883.6.1.25002-7", /* Scrotum and testicle ultrasound */
|
||||
"2.16.840.1.113883.6.1.27899-4", /* Diagnostic Imaging Report */
|
||||
"2.16.840.1.113883.6.1.28570-0", /* Procedure note */
|
||||
"2.16.840.1.113883.6.1.28624-5", /* Podiatry Operation note */
|
||||
"2.16.840.1.113883.6.1.28636-9", /* Initial evaluation note */
|
||||
"2.16.840.1.113883.6.1.29757-2", /* Colposcopy Study */
|
||||
"2.16.840.1.113883.6.1.34095-0", /* Comprehensive history and physical note */
|
||||
"2.16.840.1.113883.6.1.34098-4", /* Conference Note */
|
||||
"2.16.840.1.113883.6.1.34105-7", /* Hospital Discharge Summary Report */
|
||||
"2.16.840.1.113883.6.1.34117-2", /* History and Physical Note */
|
||||
"2.16.840.1.113883.6.1.34121-4", /* Interventional procedure note */
|
||||
"2.16.840.1.113883.6.1.34133-9", /* Summarization of episode note */
|
||||
"2.16.840.1.113883.6.1.34138-8", /* Targeted history and physical note */
|
||||
"2.16.840.1.113883.6.1.34856-5", /* Evaluation and management of anticoagulation note */
|
||||
"2.16.840.1.113883.6.1.34859-9", /* Evaluation and management of hyperlipidemia */
|
||||
"2.16.840.1.113883.6.1.34860-7", /* Evaluation and management of hypertension */
|
||||
"2.16.840.1.113883.6.1.34868-0", /* Orthopaedic surgery Surgical operation note */
|
||||
"2.16.840.1.113883.6.1.34875-5", /* Surgery Postoperative evaluation and management note */
|
||||
"2.16.840.1.113883.6.1.34877-1", /* Urology Surgical operation note */
|
||||
"2.16.840.1.113883.6.1.42348-3", /* Advance directives (narrative)*/
|
||||
"2.16.840.1.113883.6.1.47040-1", /* Consultation 2nd opinion */
|
||||
"2.16.840.1.113883.6.1.47045-0", /* Study report */
|
||||
"2.16.840.1.113883.6.1.47046-8", /* Summary of death note */
|
||||
"2.16.840.1.113883.6.1.47519-4", /* History of Procedures Document */
|
||||
"2.16.840.1.113883.6.1.48765-2", /* Allergies and adverse reactions Document */
|
||||
"2.16.840.1.113883.6.1.51847-2", /* Evaluation + Plan note */
|
||||
"2.16.840.1.113883.6.1.51848-0", /* Evaluation Note */
|
||||
"2.16.840.1.113883.6.1.51849-8", /* Admission history and physical note */
|
||||
"2.16.840.1.113883.6.1.51898-5", /* Risk factors Document */
|
||||
"2.16.840.1.113883.6.1.53242-4", /* Charge ticket or encounter form */
|
||||
"2.16.840.1.113883.6.1.55109-3", /* Complications Document */
|
||||
"2.16.840.1.113883.6.1.55112-7", /* Document summary */
|
||||
"2.16.840.1.113883.6.1.56444-3", /* Healthcare communication Doc */
|
||||
"2.16.840.1.113883.6.1.55112-7", /* Document summary */
|
||||
"2.16.840.1.113883.6.1.56445-0", /* Medication summary Document */
|
||||
"2.16.840.1.113883.6.1.56446-8", /* Appointment summary Document */
|
||||
"2.16.840.1.113883.6.1.56447-6", /* Plan of care note */
|
||||
"2.16.840.1.113883.6.1.57055-6", /* Antepartum summary */
|
||||
"2.16.840.1.113883.6.1.57056-4", /* Labor and delivery admission history and physical */
|
||||
"2.16.840.1.113883.6.1.57057-2", /* Labor and Delivery summary note */
|
||||
"2.16.840.1.113883.6.1.57058-0", /* Maternal Discharge Summary */
|
||||
"2.16.840.1.113883.6.1.57059-8", /* Pregnancy visit summary note Narrative */
|
||||
"2.16.840.1.113883.6.1.57133-1", /* Referral note */
|
||||
"2.16.840.1.113883.6.1.57828-6", /* Prescription List */
|
||||
"2.16.840.1.113883.6.1.57833-6", /* Prescription for medication */
|
||||
"2.16.840.1.113883.6.1.59268-3", /* Neonatal care report */
|
||||
"2.16.840.1.113883.6.1.59282-4", /* Stress cardiac echo study report US */
|
||||
"2.16.840.1.113883.6.1.59283-2", /* Well child visit note */
|
||||
"2.16.840.1.113883.6.1.60591-5", /* Patient summary Document */
|
||||
"2.16.840.1.113883.6.1.64290-0", /* Health insurance card */
|
||||
"2.16.840.1.113883.6.1.66113-2", /* Uterus Pathology biopsy report */
|
||||
"2.16.840.1.113883.6.1.66117-3", /* Prostate Pathology biopsy report */
|
||||
"2.16.840.1.113883.6.1.67851-6", /* Admission evaluation note */
|
||||
"2.16.840.1.113883.6.1.67853-2", /* Plan of care note */
|
||||
"2.16.840.1.113883.6.1.67860-7", /* Post-operative evaluation and management note */
|
||||
"2.16.840.1.113883.6.1.67862-3", /* Pre-operative evaluation and management note */
|
||||
"2.16.840.1.113883.6.1.68563-6", /* Obstetrics and Gynecology procedure note */
|
||||
"2.16.840.1.113883.6.1.68607-1", /* Progress letter */
|
||||
"2.16.840.1.113883.6.1.68608-9", /* Summarization note */
|
||||
"2.16.840.1.113883.6.1.74188-4", /* interRAI Acute Care (AC) Hospital Document */
|
||||
"2.16.840.1.113883.6.1.75477-0", /* Physician resident Note */
|
||||
"2.16.840.1.113883.6.1.77962-9" /* Obstetrics and Gynecology Summary */
|
||||
);
|
||||
|
||||
// Hard coded identifier list: specify identifiers formatted as <system OID>.<ID>
|
||||
// if the <system OID> ends with an ! then any document from that OID will be filtered out.
|
||||
//
|
||||
// This list should contain at minimum the myEHR OID. Use the format "<myEHR OID>!".
|
||||
//
|
||||
// By default, if the entry is missing for the field, or the value list is empty, no filtering
|
||||
// will be performed for the field
|
||||
// If the values are specified, the data matching the specified data will be filtered as specified
|
||||
//
|
||||
|
||||
hardcoded_id_list := (
|
||||
//"1.3.6.1.4.1.22812.4.545.6.1.19.Note_8480", // An exact match against system OID.Document ID
|
||||
//"1.3.6.1.4.1.22812.4.545.6.1!" // An exact match against system OID only.
|
||||
);
|
||||
rejected_id_list := rejected_id_list, hardcoded_id_list;
|
||||
|
||||
// Field Name and Value List are used to specify if values are to be included or excluded.
|
||||
// This criteria allows sites to specify a field name, along with a list of eligible values.
|
||||
// All data values matching the specified value list will be included or excluded as defined.
|
||||
// By default, if the entry is missing for the field, or the value list is empty, no filtering
|
||||
// will be performed for the field
|
||||
// If the values are specified, the data matching the specified data will be filtered as specified
|
||||
//
|
||||
mediaType_code_include_values := false; // Set mediaType_code_include_values to true to include only the list of documents and false to exclude them
|
||||
mediaType_code_list := (
|
||||
//"2.16.840.1.113883.5.79.application/rtf",
|
||||
//"2.16.840.1.113883.5.79.text/richtext",
|
||||
//"2.16.840.1.113883.5.79.application/pdf"
|
||||
);
|
||||
// ------------------------------------------------------------------
|
||||
// End of user customization section
|
||||
// ------------------------------------------------------------------
|
||||
//*****************************************************************************
|
||||
;;
|
||||
priority: 50
|
||||
;;
|
||||
evoke:
|
||||
;;
|
||||
logic:
|
||||
/************************* DO NOT UPDATE ****************************************/
|
||||
|
||||
// This section formats the data in a format that is understood by
|
||||
// the caller
|
||||
|
||||
// Format the return value as time, so it can be read by the caller
|
||||
//
|
||||
if exists last_modified_from_dtm
|
||||
then
|
||||
last_modified_from_dtm := last_modified_from_dtm as time;
|
||||
LastModifiedStartDateTime := last_modified_from_dtm as {{{SINGLE-QUOTE}}}DateTime{{{SINGLE-QUOTE}}};
|
||||
endif;
|
||||
|
||||
if exists effective_start_from_dtm
|
||||
then
|
||||
effective_start_from_dtm := effective_start_from_dtm as time;
|
||||
EffectiveStartFromDateTime := effective_start_from_dtm as {{{SINGLE-QUOTE}}}DateTime{{{SINGLE-QUOTE}}};
|
||||
endif;
|
||||
|
||||
field_value_list := (
|
||||
(new NameValueObject with "statusCode", status_code_include_values, status_code_list),
|
||||
(new NameValueObject with "documentCompletionCode", completionStatus_code_include_values, completionStatus_code_list ),
|
||||
(new NameValueObject with "documentTypeCode", documentType_code_include_values, documentType_code_list),
|
||||
(new NameValueObject with "mediaTypeCode", mediaType_code_include_values, mediaType_code_list)
|
||||
);
|
||||
|
||||
// Format the name value pairs into a .Net Dictionary with field name, and a list of values
|
||||
(FieldCriteriaDictionary, FieldValuesListDictionary) := call func_gen_dictionary with field_value_list;
|
||||
|
||||
// Ids to exclude
|
||||
if (count rejected_id_list > 0)
|
||||
then
|
||||
IdsToExcludeList := new net_object {{{SINGLE-QUOTE}}}Collections.Generic.List<String>{{{SINGLE-QUOTE}}};
|
||||
for id in rejected_id_list
|
||||
do
|
||||
id_val := id as {{{SINGLE-QUOTE}}}String{{{SINGLE-QUOTE}}};
|
||||
void := call IdsToExcludeList.Add with id_val;
|
||||
enddo;
|
||||
else
|
||||
IdsToExcludeList := null;
|
||||
endif;
|
||||
|
||||
// MyEHR and SemanticGroup are not supported for documents, so leave false.
|
||||
property_value_list := (
|
||||
(new PropertyValueObject with "ExcludeMyEHRData", false),
|
||||
(new PropertyValueObject with "ExcludeSemanticGroup", false)
|
||||
);
|
||||
|
||||
// Format the name value pairs into a .Net Dictionary
|
||||
PropertyNameDictionary := call func_gen_property_dictionary with property_value_list;
|
||||
|
||||
conclude true;
|
||||
;;
|
||||
action:
|
||||
if fatal_error
|
||||
then
|
||||
return fatal_error, error_message;
|
||||
else
|
||||
return
|
||||
LastModifiedStartDateTime,
|
||||
EffectiveStartFromDateTime,
|
||||
FieldCriteriaDictionary,
|
||||
FieldValuesListDictionary,
|
||||
IdsToExcludeList,
|
||||
PropertyNameDictionary
|
||||
;
|
||||
endif;
|
||||
;;
|
||||
Urgency: 50;;
|
||||
end:
|
||||
402
MLMStripper/bin/Debug/STD/STD_FILTER_VPO_HEALTH_ISSUES.mlm
Normal file
402
MLMStripper/bin/Debug/STD/STD_FILTER_VPO_HEALTH_ISSUES.mlm
Normal file
@@ -0,0 +1,402 @@
|
||||
maintenance:
|
||||
|
||||
title: Fused Agent filter for importing community health issue data;;
|
||||
mlmname: STD_FILTER_VPO_HEALTH_ISSUES;;
|
||||
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: This standard MLM defines the filtering criteria for community health issues when the
|
||||
respective data is requested from dbMotion.
|
||||
|
||||
This MLM allows specification of either inclusion or exclusion of data to ensure only the
|
||||
minimal volume of data that is necessary for processing to be returned.
|
||||
;;
|
||||
explanation:
|
||||
The use case and respective filtering criteria supported by this MLM may be customized
|
||||
for the limited list of filtering criteria only:
|
||||
(1) Last modified date/time to include (criteria: last_modified_from_dtm)
|
||||
This criteria allows sites to include only data that has been changed since a
|
||||
specified date/time to filter out any redundant data. Specify any one of the
|
||||
following conditions:
|
||||
(a) Last updated timestamp stored in SXACommunityDataStatus for
|
||||
health issues data for the patient in context is used to return only data that
|
||||
has been changed since the last successful request will be returned.
|
||||
- Set value to db_last_modified_from_dtm.
|
||||
e.g. last_modified_from_dtm := db_last_modified_from_dtm;
|
||||
(b) Site specified date or time-offset: allows the site to override the default
|
||||
behavior so that all data that have been modified since a specific date will be
|
||||
provided.
|
||||
- Set value to a date string formatted as "mmm dd yyyy"
|
||||
e.g. last_modified_from_dtm := "Jan 25 2014";
|
||||
- Set value to arden date keyword
|
||||
e.g. last_modified_from_dtm := now;
|
||||
- Set value to time offset in seconds/days/weeks/months/years ago
|
||||
e.g. last_modified_from_dtm := 2 years ago;
|
||||
- Set value as a calculated value using units in
|
||||
seconds/days/weeks/months/years, if applicable.
|
||||
e.g. last_modified_from_dtm := db_last_modified_from_dtm -
|
||||
6 months
|
||||
(c) Default: Always return all data: allows sites to override the default behavior so that all
|
||||
data is provided for reprocessing. This can be useful when processing of
|
||||
previously filtered data is required. Using this option can result in an impact
|
||||
to performance. (Recommended to ensure all data after Patient Merge are returned in VPO)
|
||||
- Set value to NULL.
|
||||
(2) Effective date to include (criteria: effective_start_from_dtm)
|
||||
This criteria allows sites to include only health issues that are active after the
|
||||
specified date. This will return all those health issues that are active before this
|
||||
date and resolved after this date, and active after this date which may/may not
|
||||
be resolved. Any health issues that are resolved on or before the specified date
|
||||
will be excluded.
|
||||
When the condition is specified, if a health issue has either the onset date or a
|
||||
resolved date, then the date is used to determine if the health issue is active on the
|
||||
specified date. A health issue is always included if neither onset date nor
|
||||
resolved date is valued.
|
||||
(a) Default: set value to NULL to indicate no filtering is required, and all items are
|
||||
eligible.
|
||||
(d) Site specified date or time-offset: allows set to override the default behavior
|
||||
so that all data that are active after a specific date will be provided.
|
||||
- Set value to a date string formatted as "mmm dd yyyy"
|
||||
e.g. effective_start_from_dtm := "Jan 01 2014";
|
||||
- Set value to arden date keyword
|
||||
e.g. effective_start_from_dtm := now;
|
||||
- Set value to time offset in seconds/days/weeks/months/years ago
|
||||
e.g. effective_start_from_dtm := 2 years ago;
|
||||
- Set value as a calculated value using units in
|
||||
seconds/days/weeks/months/years, if applicable.
|
||||
e.g. effective_start_from_dtm := db_last_modified_from_dtm -
|
||||
6 months
|
||||
(3) Site defined Identifiers to exclude (criteria: rejected_id_list)
|
||||
This criteria allows sites to specify a list of identifiers to exclude. These identifiers
|
||||
can specify those records that have rejected by a Sunrise user if the record
|
||||
should never be processed, or to exclude all those identifiers that are sent from
|
||||
a source facility that is a non-trusted source, and to exclude all those identifiers
|
||||
that are sent from the current site or facility.
|
||||
Defined as a combined list of rejected identifiers from hard coded identifier list
|
||||
and database identifier list.
|
||||
|
||||
Specify hard coded identifier list and/or database identifier list as conditions for
|
||||
this criteria:
|
||||
(a) Hard coded identifier list: specify identifiers formatted as <system OID>.<id>
|
||||
- Specific all identifiers to be excluded, which can be a list of specific
|
||||
identifiers, or as wildcard in the form of "<system OID>.%".
|
||||
e.g. hardcoded_id_list := (
|
||||
"1.3.6.1.4.1.22812.11.0.0.4.10.2.41700060",
|
||||
"1.3.6.1.4.1.22812.11.0.0.4.10.2.39248233",
|
||||
"1.3.6.1.4.1.22812.11.2014.1001.%",
|
||||
"1.3.6.1.4.1.22812.11.2014.9876.%"
|
||||
);
|
||||
(b) Database identifier list: Retrieve community identifiers from database that
|
||||
are rejected by users.
|
||||
e.g.
|
||||
database_id_list := read { "SELECT DISTINCT CommunityRecordID " ||
|
||||
" FROM CV3HealthIssueDeclaration " ||
|
||||
" WHERE " ||
|
||||
" ClientGUID = " || SQL(client_guid) ||
|
||||
" AND InternalStateType = 2 }"
|
||||
(4) Field name and value list to include or exclude
|
||||
This criteria allows sites to specify a field name, and indicate an option to include
|
||||
or exclude, along with a list of eligible values. Filtering by the field is only
|
||||
performed if all required elements are specified.
|
||||
|
||||
All data values matching the specified value list will be included or excluded as
|
||||
defined.
|
||||
|
||||
Only 2 fields are supported for Health Issues: Status Code, and Observation Value.
|
||||
Specify one or both as conditions for the criteria:
|
||||
(a) Status Code (criteria: status_code_include_values, status_code_list)
|
||||
- Set status_code_include_values to true to include records with the listed
|
||||
values in the returned result, and false to exclude them.
|
||||
e.g. status_code_include_values := false;
|
||||
- Specify status_code_list formatted as <system OID>.<code> to include
|
||||
or exclude.
|
||||
e.g. status_code_list := (
|
||||
"2.16.840.1.113883.5.14.cancelled",
|
||||
"2.16.840.1.113883.6.96.73425007",
|
||||
"2.16.840.1.113883.6.96.103330002"
|
||||
);
|
||||
This example is configured to exclude all those statuses that are
|
||||
identified as cancelled, inactive (SNOMED CT 73425007), or no diagnosis
|
||||
(SNOMED CT 103330002).
|
||||
(b) Observation Value (critiera: observation_include_values, observation_list)
|
||||
- Set observation _include_values to true to include records with the listed
|
||||
valued in the returned result, and false to exclude them.
|
||||
e.g. observation_include_values := false;
|
||||
- Specify observation_list formatted as <system OID>.<code> to include or
|
||||
exclude.
|
||||
e.g. observation_list := (
|
||||
"2.16.840.1.113883.6.103.V%",
|
||||
"2.16.840.1.113883.6.96.160245001",
|
||||
);
|
||||
This example is configured to exclude:
|
||||
o Routine examinations expressed in ICD-9 for all the diagnosis
|
||||
codes that start with V.
|
||||
o No Known Health Problems expressed in SNOMED CT as
|
||||
"2.16.840.1.113883.6.96.160245001"
|
||||
|
||||
If there are specific ICD-9 codes to be filtered, specify in the
|
||||
observation_list with <system OID> as 2.16.840.1.113883.6.103, and
|
||||
append with relevant ICD-9 code in <code>. Similarly, specify ICD-10
|
||||
codes to filter by setting <system OID> in observantion_list as
|
||||
2.16.840.1.113883.6.90, and SNOMED CT codes as 2.16.840.1.113883.6.96.
|
||||
Filtering by specific coding system/code will only apply if the coding
|
||||
system/code pair is available from VPO. As in example above, the
|
||||
filtering condition "2.16.840.1.113883.6.103.V%" will only apply if VPO has
|
||||
returned matching values. Using this condition can result in an impact to
|
||||
performance.
|
||||
(5) Semantic Group filter (criteria: ExcludeMyEHRData, ExcludeSemanticGroup)
|
||||
Sites will be able to indicate that only data records that are semantically different to be returned.
|
||||
There are 2 fields to indicate what the filter should be.
|
||||
(a) Exclude data that alreay exist in current EHR (criteria: ExcludeMyEHRData)
|
||||
- Set ExcludeMyEHRData to true to filter out data that already exists in current EHR, and
|
||||
false to include them.
|
||||
Default: set value to True.
|
||||
e.g. ExcludeMyEHRData := True;
|
||||
(b) Exclude semantic equivalent data (criteria: ExcludeSemanticGroup)
|
||||
- Set ExcludeSemanticGroup to true to filter out data that exists in current EHR based on
|
||||
semantic similarity, and false to include them. For Allergies, data having same
|
||||
group domain or same baseline code or local code are filtered out if set to true.
|
||||
Default: set value to False.
|
||||
e.g. ExcludeSemanticGroup := False;
|
||||
;;
|
||||
keywords: Fusion; Filter; Community Health Issues
|
||||
;;
|
||||
citations:
|
||||
;;
|
||||
knowledge:
|
||||
type: data-driven;;
|
||||
data:
|
||||
// Specify which .NET assemblies need to be loaded for ObjectsPlus
|
||||
standard_libs := MLM {{{SINGLE-QUOTE}}}std_include_libs{{{SINGLE-QUOTE}}};
|
||||
|
||||
include standard_libs;
|
||||
|
||||
// Arguments are passed in from the calling C++ program or MLM */
|
||||
(client_guid,
|
||||
visit_guid,
|
||||
last_modified_from_db_str
|
||||
) := argument;
|
||||
|
||||
// ------------------------------------------------------------------
|
||||
// Do not touch this section
|
||||
// ------------------------------------------------------------------
|
||||
error_message := "";
|
||||
fatal_error := false;
|
||||
|
||||
// Declare the MLMs that can be called
|
||||
func_gen_dictionary := MLM {{{SINGLE-QUOTE}}}STD_FUNC_FILTER_VPO_GEN_DICTIONARY{{{SINGLE-QUOTE}}};
|
||||
func_gen_property_dictionary := MLM {{{SINGLE-QUOTE}}}STD_FUNC_FILTER_VPO_GEN_PROPERTY_DICTIONARY{{{SINGLE-QUOTE}}};
|
||||
|
||||
// Set the input from string to time
|
||||
db_last_modified_from_dtm := last_modified_from_db_str as time;
|
||||
|
||||
// Define the name value object
|
||||
NameValueObject := OBJECT [ field_name, include_flag, value_list ];
|
||||
|
||||
// Define the name value object for properties
|
||||
PropertyValueObject := OBJECT [ field_name, value ];
|
||||
|
||||
// Initialize the id list and set up default value
|
||||
last_modified_from_dtm := db_last_modified_from_dtm;
|
||||
rejected_id_list := ();
|
||||
hardcoded_id_list := ();
|
||||
database_id_list := ();
|
||||
|
||||
//***************Make Changes To Spelling And Flags In This Section************
|
||||
// Set to true if logging is needed.
|
||||
log_execution_info := false;
|
||||
show_Debug_statements := false;
|
||||
|
||||
// ------------------------------------------------------------------
|
||||
// Please update this section to customize the community data filter
|
||||
// ------------------------------------------------------------------
|
||||
// Last Modified from dtm
|
||||
// 1. By Default, value is set to NULL so that no filtering will be
|
||||
// done based on last modified and all the data will come back.
|
||||
// 2. User specified
|
||||
// - set to db_last_modified_from_dtm to use the last successful
|
||||
// retrieval timestamp
|
||||
// - string date time "Jan 25 2014"
|
||||
// e.g. last_modified_from_dtm := "Jan 25 2014";
|
||||
// - arden date keyword: now
|
||||
// e.g. last_modified_from_dtm := now;
|
||||
// - time offset: 3 [seconds|days|weeks|months|years] ago
|
||||
// e.g. last_modified_from_dtm := 3 months ago;
|
||||
// - calculated time: db_last_modified_from_dtm - 3 hours
|
||||
// e.g. last_modified_from_dtm := db_last_modified_from_dtm - 2 weeks;
|
||||
last_modified_from_dtm := NULL;
|
||||
|
||||
// Semantic group filter
|
||||
// Specify the flag to indicate whether to include or exclude the data that already exists in
|
||||
// current EHR in criteria ExcludeMyEHRData.
|
||||
// By default, if the entry is mising or value is set to false, no filterng will be performed and
|
||||
// data from current EHR will also be returned.
|
||||
// If entry is set to true, all data that already exists in current EHR are filtered.
|
||||
//
|
||||
ExcludeMyEHRData := true;
|
||||
|
||||
// Specify the flag to indicate whether to include or exclude the data that exists in current EHR
|
||||
// based on semantic similarity in criteria ExcludeSemanticGroup.
|
||||
// By default, if the entry is missing or value is set to false, no filterng will be performed and
|
||||
// data that is semantically similar will also be returned.
|
||||
// If entry is set to true, only the semantic delta list of data is returned.
|
||||
ExcludeSemanticGroup := false;
|
||||
|
||||
// By setting up this filter value, we retrieve health issues that
|
||||
// are active at this date. Active means not having an end date, or end date
|
||||
// is after the given effective start from dtm
|
||||
// The health issues that are completed on or before
|
||||
// the effective_start_from_dtm value will be eliminated.
|
||||
// This is episode time from time
|
||||
// 1. By default, this value is set to null to do no filtering by episode time from
|
||||
// 2. User specified
|
||||
// - string effective_start_from_dtm "Jan 25 2014"
|
||||
// e.g. effective_start_from_dtm := "Jan 25 2014";
|
||||
// - arden date keyword: now
|
||||
// e.g. effective_start_from_dtm := now;
|
||||
// - time offset: 3 [seconds|days|weeks|months|years] ago
|
||||
// e.g. effective_start_from_dtm := 3 months ago;
|
||||
// - calculated time: db_last_modified_from_dtm - 3 hours
|
||||
// e.g. effective_start_from_dtm := db_last_modified_from_dtm - 2 weeks;
|
||||
// 3. Note if the health issue does not have an episode time, and the episode time
|
||||
// filter is specified, it brings all the health issue without episode time
|
||||
// 4. Both last modified time and episode time filter will be applied
|
||||
effective_start_from_dtm := null;
|
||||
|
||||
// Specify the list of Ids to exclude in rejected_id_list
|
||||
// The ids can be hard coded, or fetched from the database
|
||||
// or combination of both
|
||||
// By default, the rejected id list is empty
|
||||
/*
|
||||
// comment this in to use hard coded list of ids
|
||||
// specify the ids
|
||||
hardcoded_id_list := ();
|
||||
|
||||
rejected_id_list := rejected_id_list, hardcoded_id_list;
|
||||
*/
|
||||
/*
|
||||
// comment this in to use the ids from the database
|
||||
// update the SQL to get the ids you want to exclude
|
||||
database_id_list := read { "SELECT DISTINCT CommunityRecordID " ||
|
||||
" FROM CV3HealthIssueDeclaration " ||
|
||||
" WHERE " ||
|
||||
" ClientGUID = " || SQL(client_guid) ||
|
||||
" AND InternalStateType = 2" // InternalStateType=2 means rejected community health issue
|
||||
};
|
||||
rejected_id_list := rejected_id_list, database_id_list;
|
||||
*/
|
||||
|
||||
// Field Name value filter
|
||||
// Specify the field name, flag to indicate whether to include or exclude the values,
|
||||
// and list of values.
|
||||
// By default, if the entry is missing for the field, or the value list is empty, no filtering
|
||||
// will be performed for the field
|
||||
// If the values are specified, the data matching the specified data will be filtered
|
||||
// as specified
|
||||
status_code_include_values := false; // true include listed values in result, false exclude
|
||||
status_code_list := (
|
||||
"2.16.840.1.113883.5.14.cancelled" // cancelled
|
||||
);
|
||||
|
||||
observation_include_values := true;
|
||||
observation_list := ();
|
||||
|
||||
// ------------------------------------------------------------------
|
||||
// End of user customization section
|
||||
// ------------------------------------------------------------------
|
||||
//*****************************************************************************
|
||||
|
||||
;;
|
||||
priority: 50
|
||||
;;
|
||||
evoke:
|
||||
;;
|
||||
logic:
|
||||
/************************* DO NOT UPDATE ****************************************/
|
||||
|
||||
// This section formats the data in a format that is understood by
|
||||
// the caller
|
||||
|
||||
|
||||
// Format the return value as time, so it can be read by the caller
|
||||
if exists last_modified_from_dtm
|
||||
then
|
||||
last_modified_from_dtm := last_modified_from_dtm as time;
|
||||
LastModifiedStartDateTime := last_modified_from_dtm as {{{SINGLE-QUOTE}}}DateTime{{{SINGLE-QUOTE}}};
|
||||
endif;
|
||||
|
||||
if exists effective_start_from_dtm
|
||||
then
|
||||
effective_start_from_dtm := effective_start_from_dtm as time;
|
||||
EffectiveStartFromDateTime := effective_start_from_dtm as {{{SINGLE-QUOTE}}}DateTime{{{SINGLE-QUOTE}}};
|
||||
endif;
|
||||
|
||||
//
|
||||
field_value_list := (
|
||||
(new NameValueObject with "statusCode", status_code_include_values, status_code_list),
|
||||
(new NameValueObject with "observation", observation_include_values, observation_list)
|
||||
);
|
||||
|
||||
// Format the name value pairs into a .Net Dictionary with field name, and a list of values
|
||||
(FieldCriteriaDictionary, FieldValuesListDictionary) := call func_gen_dictionary with field_value_list;
|
||||
|
||||
// Ids to exclude
|
||||
if (count rejected_id_list > 0)
|
||||
then
|
||||
IdsToExcludeList := new net_object {{{SINGLE-QUOTE}}}Collections.Generic.List<String>{{{SINGLE-QUOTE}}};
|
||||
for id in rejected_id_list
|
||||
do
|
||||
id_val := id as {{{SINGLE-QUOTE}}}String{{{SINGLE-QUOTE}}};
|
||||
void := call IdsToExcludeList.Add with id_val;
|
||||
enddo;
|
||||
else
|
||||
IdsToExcludeList := null;
|
||||
endif;
|
||||
|
||||
property_value_list := (
|
||||
(new PropertyValueObject with "ExcludeMyEHRData", ExcludeMyEHRData),
|
||||
(new PropertyValueObject with "ExcludeSemanticGroup", ExcludeSemanticGroup)
|
||||
);
|
||||
|
||||
// Format the name value pairs into a .Net Dictionary
|
||||
PropertyNameDictionary := call func_gen_property_dictionary with property_value_list;
|
||||
|
||||
conclude true;
|
||||
;;
|
||||
action:
|
||||
if fatal_error
|
||||
then
|
||||
return fatal_error, error_message;
|
||||
else
|
||||
return
|
||||
LastModifiedStartDateTime,
|
||||
EffectiveStartFromDateTime,
|
||||
FieldCriteriaDictionary,
|
||||
FieldValuesListDictionary,
|
||||
IdsToExcludeList,
|
||||
PropertyNameDictionary
|
||||
;
|
||||
endif;
|
||||
;;
|
||||
Urgency: 50;;
|
||||
end:
|
||||
321
MLMStripper/bin/Debug/STD/STD_FILTER_VPO_IMMUNIZATIONS.mlm
Normal file
321
MLMStripper/bin/Debug/STD/STD_FILTER_VPO_IMMUNIZATIONS.mlm
Normal file
@@ -0,0 +1,321 @@
|
||||
maintenance:
|
||||
|
||||
title: Fused Agent filter for importing community Immunizations data;;
|
||||
mlmname: STD_FILTER_VPO_IMMUNIZATIONS;;
|
||||
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: This standard MLM defines the filtering criteria for community immunizations when the
|
||||
respective data is requested from dbMotion.
|
||||
|
||||
This MLM allows specification of either inclusion or exclusion of data to ensure only the
|
||||
minimal volume of data that is necessary for processing to be returned.
|
||||
;;
|
||||
explanation:
|
||||
The use case and respective filtering criteria supported by this MLM may be customized for the limited list of filtering criteria only:
|
||||
(1) Last modified date/time to include (criteria: last_modified_from_dtm)
|
||||
This criteria allows sites to include only data that has been changed since a
|
||||
specified date/time to filter out any redundant data. Specify any one of the
|
||||
following conditions:
|
||||
(a) Last updated timestamp stored in SXACommunityDataStatus for
|
||||
immunization data for the patient in context is used to return only data that
|
||||
has been changed since the last successful request will be returned.
|
||||
- Set value to db_last_modified_from_dtm.
|
||||
e.g. last_modified_from_dtm := db_last_modified_from_dtm;
|
||||
(b) Site specified date or time-offset: allows the site to override the default
|
||||
behavior so that all data that have been modified since a specific date will be
|
||||
provided.
|
||||
- Set value to a date string formatted as "mmm dd yyyy"
|
||||
e.g. last_modified_from_dtm := "Jan 25 2014";
|
||||
- Set value to arden date keyword
|
||||
e.g. last_modified_from_dtm := now;
|
||||
- Set value to time offset in seconds/days/weeks/months/years ago
|
||||
e.g. last_modified_from_dtm := 2 years ago;
|
||||
- Set value as a calculated value using units in
|
||||
seconds/days/weeks/months/years, if applicable.
|
||||
e.g. last_modified_from_dtm := db_last_modified_from_dtm -
|
||||
6 months
|
||||
(c) Default: Always return all data: allows sites to override the default behavior so that all
|
||||
data is provided for reprocessing. This can be useful when processing of
|
||||
previously filtered data is required. Using this option can result in an impact
|
||||
to performance. (Recommended to ensure all data after Patient Merge are returned in VPO)
|
||||
- Set value to NULL.
|
||||
(2) Site defined Identifiers to exclude (criteria: rejected_id_list)
|
||||
This criteria allows sites to specify a list of identifiers to exclude. These identifiers
|
||||
can specify those records that have been processed by a Sunrise user and so no
|
||||
updates would be presented, or to exclude all those
|
||||
identifiers that are sent from a source facility that is a non-trusted source.
|
||||
Defined as a combined list of rejected identifiers from hard coded identifier list
|
||||
and database identifier list.
|
||||
|
||||
Specify hard coded identifier list and/or database identifier list as conditions for
|
||||
this criteria:
|
||||
(a) Hard coded identifier list: specify identifiers formatted as <system OID>.<id>
|
||||
- Specific all identifiers to be excluded, which can be a list of specific
|
||||
identifiers, or as wildcard in the form of "<system OID>.%".
|
||||
e.g. hardcoded_id_list := (
|
||||
"1.3.6.1.4.1.22812.11.0.0.4.10.2.41700060",
|
||||
"1.3.6.1.4.1.22812.11.0.0.4.10.2.39248233",
|
||||
"1.3.6.1.4.1.22812.11.2014.1001.%",
|
||||
"1.3.6.1.4.1.22812.11.2014.9876.%"
|
||||
);
|
||||
(b) Database identifier list: Retrieve community identifiers from database that
|
||||
are already accepted by users, and so updates will not be allowed.
|
||||
e.g.
|
||||
database_id_list := read = { "SELECT DISTINCT CommunityRecordID " ||
|
||||
" FROM SXAHMScheduledEventOccurrence " ||
|
||||
" WHERE ClientGUID = " || SQL(client_guid) ||
|
||||
" AND OccurrenceStatusType NOT in (5,6,9,10) " ||
|
||||
" AND CommunityRecordID IS NOT NULL"
|
||||
};
|
||||
(3) Field name and value list to include or exclude
|
||||
This criteria allows sites to specify a field name, and indicate an option to include
|
||||
or exclude, along with a list of eligible values. Filtering by the field is only
|
||||
performed if all required elements are specified.
|
||||
All data values matching the specified value list will be included or excluded as
|
||||
defined.
|
||||
Only 1 field is supported for Immunizations: Status Code.
|
||||
(a) Status Code (criteria: status_code_include_values, status_code_list)
|
||||
- Set status_code_include_values to true to include records with the listed
|
||||
values in the returned result, and false to exclude them.
|
||||
e.g. status_code_include_values := false;
|
||||
- Specify status_code_list formatted as <system OID>.<code> to include
|
||||
or exclude.
|
||||
e.g. status_code_list := (
|
||||
"2.16.840.1.113883.5.14.cancelled",
|
||||
"2.16.840.1.113883.6.96.185981001" // entered-in-error
|
||||
);
|
||||
This example is configured to exclude all those statuses that are
|
||||
identified as cancelled or completed or with the EIE SNOMEDCT code.
|
||||
(4) Semantic Group filter (criteria: ExcludeMyEHRData, ExcludeSemanticGroup)
|
||||
Sites will be able to indicate that only data records that are semantically different to be returned.
|
||||
There are 2 fields to indicate what the filter should be.
|
||||
(a) Exclude data that already exist in current EHR (criteria: ExcludeMyEHRData)
|
||||
- Set ExcludeMyEHRData to true to filter out data that already exists in current EHR, and
|
||||
false to include them.
|
||||
Default: set value to True.
|
||||
e.g. ExcludeMyEHRData := True;
|
||||
(b) Exclude semantic equivalent data (criteria: ExcludeSemanticGroup)
|
||||
- Set ExcludeSemanticGroup to true to filter out data that exists in current EHR based on
|
||||
semantic similarity, and false to include them. For Immuizations, data having same
|
||||
effective date and same material baseline code or local code are filtered out if set to true.
|
||||
Default: set value to False.
|
||||
e.g. ExcludeSemanticGroup := False;
|
||||
|
||||
;;
|
||||
keywords: Fusion; Filter; Community Immunizations
|
||||
;;
|
||||
citations:
|
||||
;;
|
||||
knowledge:
|
||||
type: data-driven;;
|
||||
data:
|
||||
// Specify which .NET assemblies need to be loaded for ObjectsPlus
|
||||
standard_libs := MLM {{{SINGLE-QUOTE}}}std_include_libs{{{SINGLE-QUOTE}}};
|
||||
|
||||
include standard_libs;
|
||||
|
||||
// Arguments are passed in from the calling C++ program or MLM */
|
||||
(client_guid,
|
||||
visit_guid,
|
||||
last_modified_from_db_str
|
||||
) := argument;
|
||||
|
||||
// ------------------------------------------------------------------
|
||||
// Do not touch this section
|
||||
// ------------------------------------------------------------------
|
||||
error_message := "";
|
||||
fatal_error := false;
|
||||
|
||||
// Declare the MLMs that can be called
|
||||
func_gen_dictionary := MLM {{{SINGLE-QUOTE}}}STD_FUNC_FILTER_VPO_GEN_DICTIONARY{{{SINGLE-QUOTE}}};
|
||||
func_gen_property_dictionary := MLM {{{SINGLE-QUOTE}}}STD_FUNC_FILTER_VPO_GEN_PROPERTY_DICTIONARY{{{SINGLE-QUOTE}}};
|
||||
|
||||
// Set the input from string to time
|
||||
db_last_modified_from_dtm := last_modified_from_db_str as time;
|
||||
|
||||
// Set the default last modified value
|
||||
last_modified_from_dtm := db_last_modified_from_dtm;
|
||||
|
||||
// Define the name value object
|
||||
NameValueObject := OBJECT [ field_name, include_flag, value_list ];
|
||||
|
||||
// Define the name value object for properties
|
||||
PropertyValueObject := OBJECT [ field_name, value ];
|
||||
|
||||
// Initialize the id list
|
||||
rejected_id_list := ();
|
||||
hardcoded_id_list := ();
|
||||
database_id_list := ();
|
||||
|
||||
//***************Make Changes To Spelling And Flags In This Section************
|
||||
// Set to true if logging is needed.
|
||||
log_execution_info := false;
|
||||
show_Debug_statements := false;
|
||||
|
||||
// Semantic group filter
|
||||
// Specify the flag to indicate whether to include or exclude the data that already exists in
|
||||
// current EHR in criteria ExcludeMyEHRData.
|
||||
// By default, if the entry is missing or value is set to false, no filtering will be performed and
|
||||
// data from current EHR will also be returned.
|
||||
// If entry is set to true, all data that already exists in current EHR are filtered.
|
||||
ExcludeMyEHRData := true;
|
||||
|
||||
// Specify the flag to indicate whether to include or exclude the data that exists in current EHR
|
||||
// based on semantic similarity in criteria ExcludeSemanticGroup.
|
||||
// By default, if the entry is missing or value is set to false, no filtering will be performed and
|
||||
// data that is semantically similar will also be returned.
|
||||
// If entry is set to true, only the semantic delta list of data is returned.
|
||||
ExcludeSemanticGroup := false;
|
||||
|
||||
// ------------------------------------------------------------------
|
||||
// Please update this section to customize the community data filter
|
||||
// ------------------------------------------------------------------
|
||||
// Last Modified from dtm
|
||||
// 1. By Default, value is set to NULL so that no filtering will be
|
||||
// done based on last modified and all the data will come back.
|
||||
// 2. User specified
|
||||
// - set to db_last_modified_from_dtm to use the last successful
|
||||
// retrieval timestamp
|
||||
// - string date time "Jan 25 2014"
|
||||
// e.g. last_modified_from_dtm := "Jan 25 2014";
|
||||
// - arden date keyword: now
|
||||
// e.g. last_modified_from_dtm := now;
|
||||
// - time offset: 3 [seconds|days|weeks|months|years] ago
|
||||
// e.g. last_modified_from_dtm := 3 months ago;
|
||||
// - calculated time: db_last_modified_from_dtm - 3 hours
|
||||
// e.g. last_modified_from_dtm := db_last_modified_from_dtm - 2 weeks;
|
||||
last_modified_from_dtm := NULL;
|
||||
|
||||
// Specify the list of Ids to exclude in rejected_id_list
|
||||
// The ids can be hard coded, or fetched from the database
|
||||
// or combination of both
|
||||
// By default, the rejected id list is empty
|
||||
|
||||
/*
|
||||
// comment this in to use hard coded list of ids
|
||||
// specify the ids
|
||||
hardcoded_id_list := ();
|
||||
|
||||
rejected_id_list := rejected_id_list, hardcoded_id_list;
|
||||
*/
|
||||
|
||||
/*
|
||||
// comment this in to use the ids from the database
|
||||
// update the SQL to get the ids you want to exclude
|
||||
database_id_list := read { "SELECT DISTINCT CommunityRecordID " ||
|
||||
" FROM SXAHMScheduledEventOccurrence " ||
|
||||
" WHERE ClientGUID = " || SQL(client_guid) ||
|
||||
" AND OccurrenceStatusType NOT in (5,6,9,10) " ||
|
||||
" AND CommunityRecordID IS NOT NULL"
|
||||
};
|
||||
rejected_id_list := rejected_id_list, database_id_list;
|
||||
*/
|
||||
|
||||
// Field Name value filter
|
||||
// Specify the field name, flag to indicate whether to include or exclude the values, and list of values.
|
||||
// By default, if the entry is missing for the field, or the value list is empty, no filtering
|
||||
// will be performed for the field
|
||||
// If the values are specified, the data matching the specified data will be filtered as specified
|
||||
status_code_include_values := false; // true include listed values in result, false exclude
|
||||
status_code_list := (
|
||||
"2.16.840.1.113883.5.14.cancelled", // cancelled
|
||||
"2.16.840.1.113883.6.96.185981001" // entered-in-error
|
||||
);
|
||||
|
||||
// ------------------------------------------------------------------
|
||||
// End of user customization section
|
||||
// ------------------------------------------------------------------
|
||||
//*****************************************************************************
|
||||
;;
|
||||
priority: 50
|
||||
;;
|
||||
evoke:
|
||||
;;
|
||||
logic:
|
||||
/************************* DO NOT UPDATE ****************************************/
|
||||
|
||||
// This section formats the data in a format that is understood by
|
||||
// the caller
|
||||
|
||||
|
||||
// Format the return value as time, so it can be read by the caller
|
||||
if exists last_modified_from_dtm
|
||||
then
|
||||
last_modified_from_dtm := last_modified_from_dtm as time;
|
||||
LastModifiedStartDateTime := last_modified_from_dtm as {{{SINGLE-QUOTE}}}DateTime{{{SINGLE-QUOTE}}};
|
||||
endif;
|
||||
|
||||
// Immunization only has performed date, and no end date, so
|
||||
// we cannot filter by active immunizations using effective start time filter
|
||||
EffectiveStartFromDateTime_Not_Used := null;
|
||||
|
||||
// Only the statusCode field is supported for Immunizations
|
||||
field_value_list := (
|
||||
(new NameValueObject with "statusCode", status_code_include_values, status_code_list)
|
||||
);
|
||||
|
||||
// Format the name value pairs into a .Net Dictionary with field name, and a list of values
|
||||
(FieldCriteriaDictionary, FieldValuesListDictionary) := call func_gen_dictionary with field_value_list;
|
||||
|
||||
// Ids to exclude
|
||||
if (count rejected_id_list > 0)
|
||||
then
|
||||
IdsToExcludeList := new net_object {{{SINGLE-QUOTE}}}Collections.Generic.List<String>{{{SINGLE-QUOTE}}};
|
||||
for id in rejected_id_list
|
||||
do
|
||||
id_val := id as {{{SINGLE-QUOTE}}}String{{{SINGLE-QUOTE}}};
|
||||
void := call IdsToExcludeList.Add with id_val;
|
||||
enddo;
|
||||
else
|
||||
IdsToExcludeList := null;
|
||||
endif;
|
||||
|
||||
property_value_list := (
|
||||
(new PropertyValueObject with "ExcludeMyEHRData", ExcludeMyEHRData),
|
||||
(new PropertyValueObject with "ExcludeSemanticGroup", ExcludeSemanticGroup)
|
||||
);
|
||||
|
||||
// Format the name value pairs into a .Net Dictionary
|
||||
PropertyNameDictionary := call func_gen_property_dictionary with property_value_list;
|
||||
|
||||
conclude true;
|
||||
;;
|
||||
action:
|
||||
if fatal_error
|
||||
then
|
||||
return fatal_error, error_message;
|
||||
else
|
||||
return
|
||||
LastModifiedStartDateTime,
|
||||
EffectiveStartFromDateTime_Not_Used,
|
||||
FieldCriteriaDictionary,
|
||||
FieldValuesListDictionary,
|
||||
IdsToExcludeList,
|
||||
PropertyNameDictionary
|
||||
;
|
||||
endif;
|
||||
;;
|
||||
Urgency: 50;;
|
||||
end:
|
||||
370
MLMStripper/bin/Debug/STD/STD_FILTER_VPO_MEDICATIONS.mlm
Normal file
370
MLMStripper/bin/Debug/STD/STD_FILTER_VPO_MEDICATIONS.mlm
Normal file
@@ -0,0 +1,370 @@
|
||||
maintenance:
|
||||
|
||||
title: Fused Agent filter for importing community Medications data;;
|
||||
mlmname: STD_FILTER_VPO_MEDICATIONS;;
|
||||
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: This standard MLM defines the filtering criteria for community medications when the
|
||||
respective data is requested from dbMotion.
|
||||
|
||||
This MLM allows specification of either inclusion or exclusion of data to ensure only the
|
||||
minimal volume of data that is necessary for processing to be returned.
|
||||
;;
|
||||
explanation:
|
||||
The use case and respective filtering criteria supported by this MLM may be customized for the limited list of filtering criteria only:
|
||||
(1) Last modified date/time to include (criteria: last_modified_from_dtm)
|
||||
This criteria allows sites to include only data that has been changed since a
|
||||
specified date/time to filter out any redundant data. Specify any one of the
|
||||
following conditions:
|
||||
(a) Last updated timestamp stored in SXACommunityDataStatus for
|
||||
health issues data for the patient in context is used to return only data that
|
||||
has been changed since the last successful request will be returned.
|
||||
- Set value to db_last_modified_from_dtm.
|
||||
e.g. last_modified_from_dtm := db_last_modified_from_dtm;
|
||||
(b) Site specified date or time-offset: allows the site to override the default
|
||||
behavior so that all data that have been modified since a specific date will be
|
||||
provided.
|
||||
- Set value to a date string formatted as "mmm dd yyyy"
|
||||
e.g. last_modified_from_dtm := "Jan 25 2014";
|
||||
- Set value to arden date keyword
|
||||
e.g. last_modified_from_dtm := now;
|
||||
- Set value to time offset in seconds/days/weeks/months/years ago
|
||||
e.g. last_modified_from_dtm := 2 years ago;
|
||||
- Set value as a calculated value using units in
|
||||
seconds/days/weeks/months/years, if applicable.
|
||||
e.g. last_modified_from_dtm := db_last_modified_from_dtm -
|
||||
6 months
|
||||
(c) Default: Always return all data: allows sites to override the default behavior so that all
|
||||
data is provided for reprocessing. This can be useful when processing of
|
||||
previously filtered data is required. Using this option can result in an impact
|
||||
to performance. (Recommended to ensure all data after Patient Merge are returned in VPO)
|
||||
- Set value to NULL.
|
||||
(2) Effective date to include (criteria: effective_start_from_dtm)
|
||||
This criteria allows sites to include only medications that are active after the
|
||||
specified date. This will return all those medications that are active before this
|
||||
date and resolved after this date, and active after this date which may/may not
|
||||
be completed. Any medications that are completed on or before the specified
|
||||
date will be excluded.
|
||||
When the condition is specified, if a medication has either the start date or an
|
||||
end date, then the date is used to determine if the medication is active on the
|
||||
specified date. A medication is always included if neither start date nor end date
|
||||
is valued.
|
||||
(a) Set value to NULL to indicate no filtering is required, and all items are
|
||||
eligible.
|
||||
(d) Site specified date or time-offset: allows set to override the default behavior
|
||||
so that all data that are active after a specific date will be provided.
|
||||
- Set value to a date string formatted as "mmm dd yyyy"
|
||||
e.g. effective_start_from_dtm := "Jan 01 2014";
|
||||
- Set value to arden date keyword
|
||||
e.g. effective_start_from_dtm := now;
|
||||
- Set value to time offset in seconds/days/weeks/months/years ago
|
||||
e.g. effective_start_from_dtm := 2 years ago;
|
||||
- Set value as a calculated value using units in
|
||||
seconds/days/weeks/months/years, if applicable.
|
||||
e.g. effective_start_from_dtm := db_last_modified_from_dtm -
|
||||
6 months
|
||||
(3) Site defined Identifiers to exclude (criteria: rejected_id_list)
|
||||
This criteria allows sites to specify a list of identifiers to exclude. These identifiers
|
||||
can specify those records that have been processed by a Sunrise user and so no
|
||||
updates would be presented, or to exclude all those
|
||||
identifiers that are sent from a source facility that is a non-trusted source.
|
||||
Defined as a combined list of rejected identifiers from hard coded identifier list
|
||||
and database identifier list.
|
||||
|
||||
Specify hard coded identifier list and/or database identifier list as conditions for
|
||||
this criteria:
|
||||
(a) Hard coded identifier list: specify identifiers formatted as <system OID>.<id>
|
||||
- Specific all identifiers to be excluded, which can be a list of specific
|
||||
identifiers, or as wildcard in the form of "<system OID>.%".
|
||||
e.g. hardcoded_id_list := (
|
||||
"1.3.6.1.4.1.22812.11.0.0.4.10.2.41700060",
|
||||
"1.3.6.1.4.1.22812.11.0.0.4.10.2.39248233",
|
||||
"1.3.6.1.4.1.22812.11.2014.1001.%",
|
||||
"1.3.6.1.4.1.22812.11.2014.9876.%"
|
||||
);
|
||||
(b) Database identifier list: Retrieve community identifiers from database that
|
||||
are already accepted by users, and so updates will not be allowed.
|
||||
e.g.
|
||||
database_id_list := read = { "SELECT DISTINCT Dtl.CommunityMedID " ||
|
||||
" FROM SXAAMBeRxDispensedDetail Dtl " ||
|
||||
" INNER JOIN SXAAMBeRxDispensedHeader Hdr " ||
|
||||
" ON Hdr.DispensedHeaderID = Dtl.DispensedHeaderID " ||
|
||||
" WHERE " ||
|
||||
" Hdr.ClientGUID = " || SQL(client_guid) ||
|
||||
" AND Dtl.StatusType in (1, 2) "
|
||||
};
|
||||
(4) Field name and value list to include or exclude
|
||||
This criteria allows sites to specify a field name, and indicate an option to include
|
||||
or exclude, along with a list of eligible values. Filtering by the field is only
|
||||
performed if all required elements are specified.
|
||||
All data values matching the specified value list will be included or excluded as
|
||||
defined.
|
||||
Only 1 field is supported for Medications: Status Code.
|
||||
(a) Status Code (criteria: status_code_include_values, status_code_list)
|
||||
- Set status_code_include_values to true to include records with the listed
|
||||
values in the returned result, and false to exclude them.
|
||||
e.g. status_code_include_values := false;
|
||||
- Specify status_code_list formatted as <system OID>.<code> to include
|
||||
or exclude.
|
||||
e.g. status_code_list := (
|
||||
"2.16.840.1.113883.5.14.cancelled",
|
||||
"2.16.840.1.113883.5.14.completed"
|
||||
);
|
||||
This example is configured to exclude all those statuses that are
|
||||
identified as cancelled or completed.
|
||||
(5) Semantic Group filter (criteria: ExcludeMyEHRData, ExcludeSemanticGroup)
|
||||
Sites will be able to indicate that only data records that are semantically different to be returned.
|
||||
There are 2 fields to indicate what the filter should be.
|
||||
(a) Exclude data that already exist in current EHR (criteria: ExcludeMyEHRData)
|
||||
- Set ExcludeMyEHRData to true to filter out data that already exists in current EHR, and
|
||||
false to include them.
|
||||
Default: set value to True.
|
||||
e.g. ExcludeMyEHRData := True;
|
||||
(b) Exclude semantic equivalent data (criteria: ExcludeSemanticGroup)
|
||||
- Set ExcludeSemanticGroup to true to filter out data that exists in current EHR based on
|
||||
semantic similarity, and false to include them. For Medications, data having same
|
||||
generic or branded code using baseline code or local code are filtered out if set to true.
|
||||
Default: set value to False.
|
||||
e.g. ExcludeSemanticGroup := False;
|
||||
;;
|
||||
keywords: Fusion; Filter; Community Medications
|
||||
;;
|
||||
citations:
|
||||
;;
|
||||
knowledge:
|
||||
type: data-driven;;
|
||||
data:
|
||||
// Specify which .NET assemblies need to be loaded
|
||||
using "mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089";
|
||||
using namespace "System";
|
||||
using namespace "System.Exception";
|
||||
using namespace "System.Windows.Forms";
|
||||
|
||||
// Arguments are passed in from the calling C++ program or MLM */
|
||||
(client_guid,
|
||||
visit_guid,
|
||||
last_modified_from_db_str
|
||||
) := argument;
|
||||
|
||||
// ------------------------------------------------------------------
|
||||
// Do not touch this section
|
||||
// ------------------------------------------------------------------
|
||||
error_message := "";
|
||||
fatal_error := false;
|
||||
|
||||
// Declare the MLMs that can be called
|
||||
func_gen_dictionary := MLM {{{SINGLE-QUOTE}}}STD_FUNC_FILTER_VPO_GEN_DICTIONARY{{{SINGLE-QUOTE}}};
|
||||
func_gen_property_dictionary := MLM {{{SINGLE-QUOTE}}}STD_FUNC_FILTER_VPO_GEN_PROPERTY_DICTIONARY{{{SINGLE-QUOTE}}};
|
||||
|
||||
// Set the input from string to time
|
||||
db_last_modified_from_dtm := last_modified_from_db_str as time;
|
||||
|
||||
// Set the default last modified value
|
||||
last_modified_from_dtm := db_last_modified_from_dtm;
|
||||
|
||||
// Define the name value object
|
||||
NameValueObject := OBJECT [ field_name, include_flag, value_list ];
|
||||
|
||||
// Define the name value object for properties
|
||||
PropertyValueObject := OBJECT [ field_name, value ];
|
||||
|
||||
// Initialize the id list
|
||||
rejected_id_list := ();
|
||||
hardcoded_id_list := ();
|
||||
database_id_list := ();
|
||||
|
||||
//***************Make Changes To Spelling And Flags In This Section************
|
||||
// Set to true if logging is needed.
|
||||
log_execution_info := false;
|
||||
show_Debug_statements := false;
|
||||
|
||||
// Semantic group filter
|
||||
// Specify the flag to indicate whether to include or exclude the data that already exists in
|
||||
// current EHR in criteria ExcludeMyEHRData.
|
||||
// By default, if the entry is missing or value is set to false, no filtering will be performed and
|
||||
// data from current EHR will also be returned.
|
||||
// If entry is set to true, all data that already exists in current EHR are filtered.
|
||||
//
|
||||
ExcludeMyEHRData := true;
|
||||
|
||||
// Specify the flag to indicate whether to include or exclude the data that exists in current EHR
|
||||
// based on semantic similarity in criteria ExcludeSemanticGroup.
|
||||
// By default, if the entry is missing or value is set to false, no filtering will be performed and
|
||||
// data that is semantically similar will also be returned.
|
||||
// If entry is set to true, only the semantic delta list of data is returned.
|
||||
ExcludeSemanticGroup := false;
|
||||
|
||||
// ------------------------------------------------------------------
|
||||
// Please update this section to customize the community data filter
|
||||
// ------------------------------------------------------------------
|
||||
// Last Modified from dtm
|
||||
//1.By Default, value is set to NULL so that no filtering will be
|
||||
//done based on last modified and all the data will come back.
|
||||
//2. User specified
|
||||
// - set to db_last_modified_from_dtm to use the last successful
|
||||
//retrieval timestamp
|
||||
// - string date time "Jan 25 2014"
|
||||
//e.g. last_modified_from_dtm := "Jan 25 2014" ;
|
||||
// - arden date keyword : now
|
||||
//e.g.last_modified_from_dtm := now;
|
||||
// - time offset:3[seconds|days|weeks|months|years]ago
|
||||
//e.g.last_modified_from_dtm:= 3 months ago;
|
||||
// - calculated time:db_last_modified_from_dtm-3 hours
|
||||
//e.g. last_modified_from_dtm:=db_last_modified_from_dtm -2 weeks;
|
||||
last_modified_from_dtm := NULL;
|
||||
|
||||
// By setting up this filter value, we retrieve medications that
|
||||
// are active at this date. The medication that are completed on or before
|
||||
// the effective_start_from_dtm value will be eliminated.
|
||||
// 1. By default, this value is set to 18 months ago
|
||||
// 2. User specified
|
||||
// - null to do no filtering by episode time from
|
||||
// - string effective_start_from_dtm "Jan 25 2014"
|
||||
// e.g. effective_start_from_dtm := "Jan 25 2014";
|
||||
// - arden date keyword: now
|
||||
// e.g. effective_start_from_dtm := now;
|
||||
// - time offset: 3 [seconds|days|weeks|months|years] ago
|
||||
// e.g. effective_start_from_dtm := 3 months ago;
|
||||
// - calculated time: db_last_modified_from_dtm - 3 hours
|
||||
// e.g. effective_start_from_dtm := db_last_modified_from_dtm - 2 weeks;
|
||||
// 3. Note if the medication does not have an episode time, and the episode time
|
||||
// filter is specified, it brings all the medication without episode time
|
||||
// 4. Both last modified time and episode time filter will be applied
|
||||
effective_start_from_dtm := 18 months ago;
|
||||
|
||||
// Specify the list of Ids to exclude in rejected_id_list
|
||||
// The ids can be hard coded, or fetched from the database
|
||||
// or combination of both
|
||||
// By default, the rejected id list is empty
|
||||
|
||||
/*
|
||||
// comment this in to use hard coded list of ids
|
||||
// specify the ids
|
||||
hardcoded_id_list := ();
|
||||
|
||||
rejected_id_list := rejected_id_list, hardcoded_id_list;
|
||||
*/
|
||||
/*
|
||||
// comment this in to use the ids from the database
|
||||
// update the SQL to get the ids you want to exclude
|
||||
database_id_list := read { "SELECT DISTINCT Dtl.CommunityMedID " ||
|
||||
" FROM SXAAMBeRxDispensedDetail Dtl " ||
|
||||
" INNER JOIN SXAAMBeRxDispensedHeader Hdr " ||
|
||||
" ON Hdr.DispensedHeaderID = Dtl.DispensedHeaderID " ||
|
||||
" WHERE " ||
|
||||
" Hdr.ClientGUID = " || SQL(client_guid) ||
|
||||
" AND Dtl.StatusType in (1, 2) "
|
||||
};
|
||||
rejected_id_list := rejected_id_list, database_id_list;
|
||||
*/
|
||||
|
||||
// Field Name value filter
|
||||
// Specify the field name, flag to indicate whether to include or exclude the values, and list of values.
|
||||
// By default, if the entry is missing for the field, or the value list is empty, no filtering
|
||||
// will be performed for the field
|
||||
// If the values are specified, the data matching the specified data will be filtered as specified
|
||||
status_code_include_values := false; // true include listed values in result, false exclude
|
||||
status_code_list := (
|
||||
"2.16.840.1.113883.5.14.cancelled", // cancelled
|
||||
"2.16.840.1.113883.6.96.185981001" // entered-in-error
|
||||
);
|
||||
|
||||
// ------------------------------------------------------------------
|
||||
// End of user customization section
|
||||
// ------------------------------------------------------------------
|
||||
//*****************************************************************************
|
||||
;;
|
||||
priority: 50
|
||||
;;
|
||||
evoke:
|
||||
;;
|
||||
logic:
|
||||
/************************* DO NOT UPDATE ****************************************/
|
||||
|
||||
// This section formats the data in a format that is understood by
|
||||
// the caller
|
||||
|
||||
|
||||
// Format the return value as time, so it can be read by the caller
|
||||
if exists last_modified_from_dtm
|
||||
then
|
||||
last_modified_from_dtm := last_modified_from_dtm as time;
|
||||
LastModifiedStartDateTime := last_modified_from_dtm as {{{SINGLE-QUOTE}}}DateTime{{{SINGLE-QUOTE}}};
|
||||
endif;
|
||||
|
||||
if exists effective_start_from_dtm
|
||||
then
|
||||
effective_start_from_dtm := effective_start_from_dtm as time;
|
||||
EffectiveStartFromDateTime := effective_start_from_dtm as {{{SINGLE-QUOTE}}}DateTime{{{SINGLE-QUOTE}}};
|
||||
endif;
|
||||
|
||||
//
|
||||
field_value_list := (
|
||||
(new NameValueObject with "statusCode", status_code_include_values, status_code_list)
|
||||
);
|
||||
|
||||
// Format the name value pairs into a .Net Dictionary with field name, and a list of values
|
||||
(FieldCriteriaDictionary, FieldValuesListDictionary) := call func_gen_dictionary with field_value_list;
|
||||
|
||||
// Ids to exclude
|
||||
if (count rejected_id_list > 0)
|
||||
then
|
||||
IdsToExcludeList := new net_object {{{SINGLE-QUOTE}}}Collections.Generic.List<String>{{{SINGLE-QUOTE}}};
|
||||
for id in rejected_id_list
|
||||
do
|
||||
id_val := id as {{{SINGLE-QUOTE}}}String{{{SINGLE-QUOTE}}};
|
||||
void := call IdsToExcludeList.Add with id_val;
|
||||
enddo;
|
||||
else
|
||||
IdsToExcludeList := null;
|
||||
endif;
|
||||
|
||||
property_value_list := (
|
||||
(new PropertyValueObject with "ExcludeMyEHRData", ExcludeMyEHRData),
|
||||
(new PropertyValueObject with "ExcludeSemanticGroup", ExcludeSemanticGroup)
|
||||
);
|
||||
|
||||
// Format the name value pairs into a .Net Dictionary
|
||||
PropertyNameDictionary := call func_gen_property_dictionary with property_value_list;
|
||||
|
||||
conclude true;
|
||||
;;
|
||||
action:
|
||||
if fatal_error
|
||||
then
|
||||
return fatal_error, error_message;
|
||||
else
|
||||
return
|
||||
LastModifiedStartDateTime,
|
||||
EffectiveStartFromDateTime,
|
||||
FieldCriteriaDictionary,
|
||||
FieldValuesListDictionary,
|
||||
IdsToExcludeList,
|
||||
PropertyNameDictionary
|
||||
;
|
||||
endif;
|
||||
;;
|
||||
Urgency: 50;;
|
||||
end:
|
||||
272
MLMStripper/bin/Debug/STD/STD_FILTER_VPO_RESULTS.mlm
Normal file
272
MLMStripper/bin/Debug/STD/STD_FILTER_VPO_RESULTS.mlm
Normal file
@@ -0,0 +1,272 @@
|
||||
maintenance:
|
||||
|
||||
title: Fused Agent filter for importing community Results data;;
|
||||
mlmname: STD_FILTER_VPO_RESULTS;;
|
||||
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) 2017 - 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: This standard MLM defines the filtering criteria for community results when the
|
||||
respective data is requested from dbMotion.
|
||||
|
||||
This MLM allows specification of either inclusion or exclusion of data to ensure only the
|
||||
minimal volume of data that is necessary for processing to be returned.
|
||||
;;
|
||||
explanation:
|
||||
The use case and respective filtering criteria supported by this MLM may be customized for the limited list of filtering criteria only:
|
||||
(1) Last updated date/time to include (criteria: effective_start_from_dtm)
|
||||
This criteria allows sites to include only data that has been changed since a
|
||||
specified date/time to filter out any redundant data. Specify any one of the
|
||||
following conditions:
|
||||
(a) Last updated timestamp stored in SXACommunityDataStatus for
|
||||
results data for the patient in context is used to ensure only data that
|
||||
has been changed since the last successful request will be returned.
|
||||
- Set value to db_last_modified_from_dtm.
|
||||
e.g. effective_start_from_dtm := db_last_modified_from_dtm;
|
||||
(b) Site specified date or time-offset: allows the site to override the default
|
||||
behavior so that all data that have been modified since a specific date will be
|
||||
provided.
|
||||
- Set value to a date string formatted as "mmm dd yyyy"
|
||||
e.g. effective_start_from_dtm := "Jan 25 2014";
|
||||
- Set value to arden date keyword
|
||||
e.g. effective_start_from_dtm := now;
|
||||
- Set value to time offset in seconds/days/weeks/months/years ago
|
||||
e.g. effective_start_from_dtm := 2 years ago;
|
||||
- Set value as a calculated value using units in
|
||||
seconds/days/weeks/months/years, if applicable.
|
||||
e.g. effective_start_from_dtm := db_last_modified_from_dtm -
|
||||
6 months
|
||||
(c) No filter - Always return all data: allows sites to override the default behavior so that all
|
||||
data is provided for reprocessing. This can be useful when processing of
|
||||
previously filtered data is required. Using this option can result in an impact
|
||||
to performance. (Recommended to ensure all data after Patient Merge are returned in VPO)
|
||||
- Set value to NULL.
|
||||
(2) Source Object Identifiers to exclude (criteria: hardcoded_id_list)
|
||||
This criteria allows sites to specify a list of object identifiers to exclude. These object
|
||||
identifiers specifies source facilities that are non-trusted sources.
|
||||
|
||||
Hard coded identifier list: specify identifiers formatted as <system OID>! to exclude.
|
||||
- Specify all object identifiers to be excluded with an exclaimation mark at the end
|
||||
to indicate a source OID value.
|
||||
e.g. hardcoded_id_list := (
|
||||
"1.3.6.1.4.1.22812.11.0.0.4.10.2.41700060!",
|
||||
"1.3.6.1.4.1.22812.11.0.0.4.10.2.39248233!",
|
||||
"1.3.6.1.4.1.22812.11.2014.1001!",
|
||||
"1.3.6.1.4.1.22812.11.2014.9876!"
|
||||
);
|
||||
(3) Field name and value list to include or exclude
|
||||
This criteria allows sites to specify a field name, and indicate an option to include
|
||||
or exclude, along with a list of eligible values. Filtering by the field is only
|
||||
performed if all required elements are specified.
|
||||
All data values matching the specified value list will be included or excluded as
|
||||
defined.
|
||||
Only 1 field is supported for Results: Status Code.
|
||||
(a) Status Code (criteria: status_code_include_values, status_code_list)
|
||||
- Set status_code_include_values to true to include records with the listed
|
||||
values in the returned result, and false to exclude them.
|
||||
e.g. status_code_include_values := true;
|
||||
- Specify status_code_list formatted as <system OID>.<code> to include
|
||||
or exclude.
|
||||
e.g. status_code_list := (
|
||||
"2.16.840.1.113883.5.4.PRLMN", // preliminary
|
||||
"2.16.840.1.113883.5.4.C", // corrected
|
||||
"2.16.840.1.113883.5.4.F" // final
|
||||
);
|
||||
This example is configured to include all those statuses that are
|
||||
identified as preliminary, corrected or final.
|
||||
(4) Top N records filter
|
||||
This criteria allows sites to include only last N records.
|
||||
The top items to choose from are based on sorting by the effective dates in descending order.
|
||||
Set TopItemCount to the maximum number of lab events you wish to receive from dbMotion.
|
||||
This filter only limits the maximum lab events returned by dbMotion, the actual number of lab events
|
||||
may become less due to additional filtering such as Source Object Identifiers, which occurs after
|
||||
the lab events are returned by dbMotion.
|
||||
e.g. TopItemCount := 200;
|
||||
|
||||
;;
|
||||
keywords: Fusion; Filter; Community Results
|
||||
;;
|
||||
citations:
|
||||
;;
|
||||
knowledge:
|
||||
type: data-driven;;
|
||||
data:
|
||||
// Specify which .NET assemblies need to be loaded
|
||||
using "mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089";
|
||||
using namespace "System";
|
||||
using namespace "System.Exception";
|
||||
using namespace "System.Windows.Forms";
|
||||
|
||||
// Arguments are passed in from the calling C++ program or MLM */
|
||||
(client_guid,
|
||||
visit_guid,
|
||||
last_modified_from_db_str
|
||||
) := argument;
|
||||
|
||||
// ------------------------------------------------------------------
|
||||
// Do not touch this section
|
||||
// ------------------------------------------------------------------
|
||||
error_message := "";
|
||||
fatal_error := false;
|
||||
|
||||
// Declare the MLMs that can be called
|
||||
func_gen_dictionary := MLM {{{SINGLE-QUOTE}}}STD_FUNC_FILTER_VPO_GEN_DICTIONARY{{{SINGLE-QUOTE}}};
|
||||
func_gen_property_dictionary := MLM {{{SINGLE-QUOTE}}}STD_FUNC_FILTER_VPO_GEN_PROPERTY_DICTIONARY{{{SINGLE-QUOTE}}};
|
||||
|
||||
// Set the input from string to time
|
||||
db_last_modified_from_dtm := last_modified_from_db_str as time;
|
||||
|
||||
// Define the name value object
|
||||
NameValueObject := OBJECT [ field_name, include_flag, value_list ];
|
||||
|
||||
// Define the name value object for properties
|
||||
PropertyValueObject := OBJECT [ field_name, value ];
|
||||
|
||||
// Initialize the id list
|
||||
rejected_id_list := ();
|
||||
hardcoded_id_list := ();
|
||||
database_id_list := ();
|
||||
|
||||
// Initialize the Top filter
|
||||
TopItemCount := 0;
|
||||
|
||||
//***************Make Changes To Spelling And Flags In This Section************
|
||||
// Set to true if logging is needed.
|
||||
log_execution_info := false;
|
||||
show_Debug_statements := false;
|
||||
|
||||
// ------------------------------------------------------------------
|
||||
// Please update this section to customize the community data filter
|
||||
// ------------------------------------------------------------------
|
||||
|
||||
// By setting up this filter value, we retrieve results that
|
||||
// are active at this date.
|
||||
// 1. By default, this value is set to 5 years ago
|
||||
// 2. User specified
|
||||
// - null to do no filtering by episode time from
|
||||
// - string effective_start_from_dtm "Jan 25 2014"
|
||||
// e.g. effective_start_from_dtm := "Jan 25 2014";
|
||||
// - arden date keyword: now
|
||||
// e.g. effective_start_from_dtm := now;
|
||||
// - time offset: 3 [seconds|days|weeks|months|years] ago
|
||||
// e.g. effective_start_from_dtm := 3 months ago;
|
||||
// - calculated time: db_last_modified_from_dtm - 3 hours
|
||||
// e.g. effective_start_from_dtm := db_last_modified_from_dtm - 2 weeks;
|
||||
effective_start_from_dtm := 5 years ago;
|
||||
|
||||
// Hard coded identifier list: specify identifiers formatted as <system OID>.<ID>
|
||||
// if the <system OID> ends with an ! then any result from that OID will be filtered out.
|
||||
//
|
||||
// This list should contain at minimum the myEHR OID. Use the format "<myEHR OID>!".
|
||||
//
|
||||
// By default, if the entry is missing for the field, or the value list is empty, no filtering
|
||||
// will be performed for the field
|
||||
// If the values are specified, the data matching the specified data will be filtered as specified
|
||||
//
|
||||
|
||||
hardcoded_id_list := (
|
||||
//"1.3.6.1.4.1.22812.4.545.6.1!" // An exact match against system OID.
|
||||
);
|
||||
rejected_id_list := rejected_id_list, hardcoded_id_list;
|
||||
|
||||
// Field Name value filter
|
||||
// Specify the field name, flag to indicate whether to include or exclude the values, and list of values.
|
||||
// By default, if the entry is missing for the field, or the value list is empty, no filtering
|
||||
// will be performed for the field
|
||||
// If the values are specified, the data matching the specified data will be filtered as specified
|
||||
status_code_include_values := true; // true include listed values in result, false exclude
|
||||
status_code_list := (
|
||||
//"2.16.840.1.113883.5.4.PRLMN", // preliminary
|
||||
//"2.16.840.1.113883.5.4.C", // corrected
|
||||
//"2.16.840.1.113883.5.4.F" // final
|
||||
);
|
||||
|
||||
// Top N records filter
|
||||
// Specify the maximum number of lab events to receive from dbMotion.
|
||||
// If specified, only the last N lab events will be included.
|
||||
// Default value: 200
|
||||
TopItemCount := 200; // Set to top 200 records
|
||||
|
||||
|
||||
// ------------------------------------------------------------------
|
||||
// End of user customization section
|
||||
// ------------------------------------------------------------------
|
||||
//*****************************************************************************
|
||||
;;
|
||||
priority: 50
|
||||
;;
|
||||
evoke:
|
||||
;;
|
||||
logic:
|
||||
/************************* DO NOT UPDATE ****************************************/
|
||||
|
||||
// This section formats the data in a format that is understood by
|
||||
// the caller
|
||||
|
||||
if exists effective_start_from_dtm
|
||||
then
|
||||
effective_start_from_dtm := effective_start_from_dtm as time;
|
||||
EffectiveStartFromDateTime := effective_start_from_dtm as {{{SINGLE-QUOTE}}}DateTime{{{SINGLE-QUOTE}}};
|
||||
endif;
|
||||
|
||||
//
|
||||
field_value_list := (
|
||||
(new NameValueObject with "statusCode", status_code_include_values, status_code_list)
|
||||
);
|
||||
|
||||
// Format the name value pairs into a .Net Dictionary with field name, and a list of values
|
||||
(FieldCriteriaDictionary, FieldValuesListDictionary) := call func_gen_dictionary with field_value_list;
|
||||
|
||||
// Ids to exclude
|
||||
if (count rejected_id_list > 0)
|
||||
then
|
||||
IdsToExcludeList := new net_object {{{SINGLE-QUOTE}}}Collections.Generic.List<String>{{{SINGLE-QUOTE}}};
|
||||
for id in rejected_id_list
|
||||
do
|
||||
id_val := id as {{{SINGLE-QUOTE}}}String{{{SINGLE-QUOTE}}};
|
||||
void := call IdsToExcludeList.Add with id_val;
|
||||
enddo;
|
||||
else
|
||||
IdsToExcludeList := null;
|
||||
endif;
|
||||
|
||||
conclude true;
|
||||
;;
|
||||
action:
|
||||
if fatal_error
|
||||
then
|
||||
return fatal_error, error_message;
|
||||
else
|
||||
return
|
||||
null,
|
||||
EffectiveStartFromDateTime,
|
||||
FieldCriteriaDictionary,
|
||||
FieldValuesListDictionary,
|
||||
IdsToExcludeList,
|
||||
PropertyNameDictionary,
|
||||
TopItemCount
|
||||
;
|
||||
endif;
|
||||
;;
|
||||
Urgency: 50;;
|
||||
end:
|
||||
177
MLMStripper/bin/Debug/STD/STD_FUNC_ALERT_ON_DEMAND_FILTER.mlm
Normal file
177
MLMStripper/bin/Debug/STD/STD_FUNC_ALERT_ON_DEMAND_FILTER.mlm
Normal file
@@ -0,0 +1,177 @@
|
||||
maintenance:
|
||||
|
||||
title: Get Filter Query And Bit Flags Based on Alert On Demand flag ;;
|
||||
mlmname: STD_Func_Alert_On_Demand_Filter;;
|
||||
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: This sub MLM generates the order session type filter and
|
||||
prescription type filter list based on the AlertCheckAgainstSelection flag
|
||||
;;
|
||||
explanation:
|
||||
The AlertCheckAgainstSelection flag is a combination of following values:
|
||||
|
||||
0 - No items selected
|
||||
1 - Order or Client Prescription selected from the catalog
|
||||
2 - Current database orders selected
|
||||
3 - (1+2)
|
||||
4 - Current database Client Prescriptions selected
|
||||
5 - (1+4)
|
||||
6 - (2+4)
|
||||
7 - (1+2+4)
|
||||
;;
|
||||
keywords:
|
||||
Session Type
|
||||
;;
|
||||
knowledge:
|
||||
type: data-driven;;
|
||||
data:
|
||||
/***************Make Changes To Spelling And Flags In This Section***************/
|
||||
/* Set to true if logging is needed.*/
|
||||
log_execution_info := false;
|
||||
|
||||
/********************************************************************************/
|
||||
|
||||
(AlertCheckAgainstSelection,
|
||||
use_community_medication) /* this flag specifies whether to check
|
||||
against community medication or not */
|
||||
:= ARGUMENT;
|
||||
|
||||
//--------- Unpack the bit packed values -------//
|
||||
// The AlertCheckAgainstSelection is a value
|
||||
// that ranges between 0~7 inclusively.
|
||||
//
|
||||
// This is a bit packed value. It is created by adding
|
||||
// at most one instance of 1, 2, or 4.
|
||||
//
|
||||
// Unpack by subtracting the largest value first
|
||||
user_selection_const_val := 1;
|
||||
order_const_val := 2;
|
||||
rx_const_val := 4;
|
||||
|
||||
combined_value := AlertCheckAgainstSelection;
|
||||
|
||||
if (combined_value >= rx_const_val)
|
||||
then
|
||||
// The combined value contains 4.
|
||||
// Possible values are 4,5,6 or 7
|
||||
combined_value := combined_value - rx_const_val;
|
||||
gen_rx_filters := true;
|
||||
else
|
||||
gen_rx_filters := false;
|
||||
endif;
|
||||
|
||||
if (combined_value >= order_const_val)
|
||||
then
|
||||
// The combined value contains 2.
|
||||
// Possible values are 2 or 3
|
||||
combined_value := combined_value - order_const_val;
|
||||
gen_order_filters := true;
|
||||
else
|
||||
gen_order_filters := false;
|
||||
endif;
|
||||
|
||||
// Initialize the values for the include community medication flag
|
||||
if (use_community_medication = true)
|
||||
then
|
||||
include_community_medication := true;
|
||||
else
|
||||
include_community_medication := false;
|
||||
endif;
|
||||
|
||||
// The combined value is either 0 or 1
|
||||
user_selection_exists := (combined_value = user_selection_const_val);
|
||||
|
||||
//------- Generate filters ---------------------//
|
||||
// Enum values for Rx, Hx, Community Medication defined
|
||||
enum_rx_type_Rx := 1;
|
||||
enum_rx_type_Hx := 3;
|
||||
enum_rx_type_Community_Med := 5;
|
||||
|
||||
// Generate alert-on-demand filters for
|
||||
// database prescriptions
|
||||
if (include_community_medication)
|
||||
then
|
||||
unsubmitted_rx_type_list := (enum_rx_type_Rx, enum_rx_type_Hx, enum_rx_type_Community_Med);
|
||||
else
|
||||
unsubmitted_rx_type_list := (enum_rx_type_Rx, enum_rx_type_Hx);
|
||||
endif;
|
||||
|
||||
if (gen_rx_filters)
|
||||
then
|
||||
db_rx_type_str := enum_rx_type_Rx || ", " || enum_rx_type_Hx;
|
||||
db_rx_types_list := (enum_rx_type_Rx, enum_rx_type_Hx);
|
||||
|
||||
if (include_community_medication)
|
||||
then
|
||||
db_rx_type_str := db_rx_type_str || ", "|| enum_rx_type_Community_Med;
|
||||
db_rx_types_list := db_rx_types_list, enum_rx_type_Community_Med;
|
||||
endif;
|
||||
|
||||
else
|
||||
db_rx_type_str := "";
|
||||
db_rx_types_list := ();
|
||||
endif;
|
||||
|
||||
order_table_name := "";
|
||||
include_in_house_session_type_orders := false;
|
||||
include_historical_session_type_orders := false;
|
||||
include_discharge_session_type_orders := false;
|
||||
include_outpatient_rx_session_type_orders := false;
|
||||
include_outpatient_hx_session_type_orders := false;
|
||||
|
||||
// Generate alert-on-demand filters for
|
||||
// database prescriptions
|
||||
unsubmitted_session_type_bit_flags := 1;
|
||||
if (gen_order_filters)
|
||||
then
|
||||
order_table_name := "CV3AllOrdersVw";
|
||||
include_in_house_session_type_orders := true;
|
||||
include_discharge_session_type_orders := true;
|
||||
include_outpatient_rx_session_type_orders := true;
|
||||
endif;
|
||||
|
||||
;;
|
||||
priority: 50
|
||||
;;
|
||||
evoke:
|
||||
;;
|
||||
logic:
|
||||
conclude true;
|
||||
;;
|
||||
action:
|
||||
return( order_table_name,
|
||||
include_in_house_session_type_orders,
|
||||
include_historical_session_type_orders,
|
||||
include_discharge_session_type_orders,
|
||||
include_outpatient_rx_session_type_orders,
|
||||
include_outpatient_hx_session_type_orders,
|
||||
unsubmitted_session_type_bit_flags,
|
||||
unsubmitted_rx_type_list,
|
||||
db_rx_type_str,
|
||||
db_rx_types_list,
|
||||
include_community_medication );
|
||||
;;
|
||||
Urgency: 50;;
|
||||
end:
|
||||
360
MLMStripper/bin/Debug/STD/STD_FUNC_ALLERGY_CAT.mlm
Normal file
360
MLMStripper/bin/Debug/STD/STD_FUNC_ALLERGY_CAT.mlm
Normal file
@@ -0,0 +1,360 @@
|
||||
maintenance:
|
||||
|
||||
title: Allergy Checking Using the Item-Catalog;;
|
||||
mlmname: STD_FUNC_ALLERGY_CAT;;
|
||||
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: Checks for Drug Allergies via Item-Catalog.
|
||||
;;
|
||||
explanation: See STD_ALLERGY MLM for an explanation.
|
||||
;;
|
||||
keywords: allergy; IV additives; Item-Catalog;;
|
||||
|
||||
knowledge:
|
||||
type: data-driven;;
|
||||
data:
|
||||
(
|
||||
order_name,
|
||||
order_is_additive,
|
||||
patient_allergy_names,
|
||||
OrderCatalogMasterItemGUID,
|
||||
Generic_name_id,
|
||||
patient_allergy_category_types,
|
||||
patient_allergy_adverse_event_date_year,
|
||||
patient_allergy_adverse_event_date_month,
|
||||
patient_allergy_adverse_event_date_day,
|
||||
input_parameter_xml,
|
||||
allergen_guid,
|
||||
client_guid,
|
||||
allergy_category_type,
|
||||
rx_other_allergen_check,
|
||||
is_reverse_check,
|
||||
reverse_check_order,
|
||||
reverse_check_rx,
|
||||
reverse_check_med_orders,
|
||||
reverse_check_outpatient_orders_flag):= ARGUMENT;
|
||||
|
||||
/*******************Make Changes To Spelling And Flags In This Section*******************/
|
||||
|
||||
/* Set to true if logging is needed.*/
|
||||
log_execution_info := false;
|
||||
|
||||
/***************************************************************************************/
|
||||
//Declare the Med_Data_Object
|
||||
Med_Data_Object := OBJECT [
|
||||
rx_hx_typecode,
|
||||
sort_field,
|
||||
OrderName,
|
||||
OrderOrAdditiveName,
|
||||
PrescriptionName,
|
||||
ComponentName,
|
||||
ComboDrugName,
|
||||
OrderGUID,
|
||||
AdditiveGUID,
|
||||
PrescriptionID,
|
||||
StartDate,
|
||||
StatusType,
|
||||
TypeCode,
|
||||
IsUnmapped,
|
||||
allergen_msg,
|
||||
msg_type,
|
||||
IsComboDrug
|
||||
];
|
||||
|
||||
|
||||
// list that holds all of the objects that will be returned
|
||||
mdo_list := ();
|
||||
|
||||
if is_reverse_check
|
||||
then
|
||||
|
||||
( rx_hx_typecode_list,
|
||||
allergen_msg_list,
|
||||
order_guid_list,
|
||||
additive_guid_list,
|
||||
prescription_id_list,
|
||||
order_name_list,
|
||||
order_or_additive_name_list,
|
||||
prescription_name_list,
|
||||
start_date_list,
|
||||
status_type_list,
|
||||
type_code_list,
|
||||
IsDnumLevel_list,
|
||||
FormularyBrandKey_list
|
||||
) := read { "EXEC SXACatalogAllergyAlertSelPr "
|
||||
|| SQL(input_parameter_xml)|| ", "
|
||||
|| SQL(allergen_guid) || ", "
|
||||
|| SQL(client_guid) || ", "
|
||||
|| SQL(allergy_category_type) || ", "
|
||||
|| SQL(rx_other_allergen_check) || ", "
|
||||
|| SQL(reverse_check_order) || ", "
|
||||
|| SQL(reverse_check_rx) || ", "
|
||||
|| SQL(reverse_check_med_orders) || ", "
|
||||
|| SQL(reverse_check_outpatient_orders_flag) };
|
||||
|
||||
if exist allergen_msg_list
|
||||
then
|
||||
|
||||
num_msgs := count (allergen_msg_list);
|
||||
//num_msgs := num_msgs + 1;
|
||||
for JJ in (1 seqto num_msgs ) do
|
||||
instance := new Med_Data_Object;
|
||||
|
||||
instance.rx_hx_typecode := rx_hx_typecode_list[JJ];
|
||||
instance.OrderName := order_name_list[JJ];
|
||||
instance.OrderOrAdditiveName := order_or_additive_name_list[JJ];
|
||||
instance.PrescriptionName := prescription_name_list[JJ];
|
||||
instance.ComponentName := "";
|
||||
instance.ComboDrugName := "";
|
||||
instance.OrderGUID := order_guid_list[JJ];
|
||||
instance.AdditiveGUID := additive_guid_list[JJ];
|
||||
instance.PrescriptionID := prescription_id_list[JJ];
|
||||
instance.StartDate := start_date_list[JJ];
|
||||
instance.StatusType := status_type_list[JJ];
|
||||
instance.TypeCode := type_code_list[JJ];
|
||||
instance.msg_type := "Catalog";
|
||||
instance.IsComboDrug := false;
|
||||
instance.IsUnmapped := false;
|
||||
|
||||
if (instance.PrescriptionID is not null and instance.PrescriptionID <> -1)
|
||||
then
|
||||
instance.sort_field :=
|
||||
instance.PrescriptionName || "|" || instance.PrescriptionID
|
||||
|| "|{2}";
|
||||
|
||||
//[MU2][SNOMEDCT]
|
||||
current_FormularyBrandKey := FormularyBrandKey_list[JJ];
|
||||
|
||||
IsDnumLevel := IsDnumLevel_list[JJ];
|
||||
if IsDnumLevel = false
|
||||
then
|
||||
IsDnumLevel:=0;
|
||||
else
|
||||
IsDnumLevel:=1;
|
||||
endif;
|
||||
tempallergen_msg := allergen_msg_list[JJ];
|
||||
(one_allergen_msg) := read last { "EXEC SXACatalogAllergenMessageTextSelPr "
|
||||
|| SQL(IsDnumLevel)|| ", "
|
||||
|| SQL(instance.PrescriptionName) || ", "
|
||||
|| SQL(current_FormularyBrandKey) || ", "
|
||||
|| SQL(allergen_guid) || ", "
|
||||
|| SQL(1) || ", "
|
||||
|| SQL(NULL) };
|
||||
|
||||
|
||||
if one_allergen_msg <> ""
|
||||
then
|
||||
instance.allergen_msg := allergen_msg_list[JJ] || one_allergen_msg;
|
||||
mdo_list := mdo_list, instance;
|
||||
endif;
|
||||
|
||||
elseif (instance.AdditiveGUID is not null)
|
||||
then
|
||||
instance.sort_field :=
|
||||
instance.OrderOrAdditiveName || "|" || instance.AdditiveGUID
|
||||
|| "|{2}";
|
||||
instance.allergen_msg := allergen_msg_list[JJ];
|
||||
mdo_list := mdo_list, instance;
|
||||
|
||||
else
|
||||
instance.sort_field :=
|
||||
instance.OrderName || "|" || instance.OrderGUID
|
||||
|| "|{2}";
|
||||
instance.allergen_msg := allergen_msg_list[JJ];
|
||||
mdo_list := mdo_list, instance;
|
||||
endif;
|
||||
enddo;
|
||||
endif;
|
||||
/* Only retrieves data if the patient has allergies */
|
||||
elseIf exist patient_allergy_names
|
||||
then
|
||||
|
||||
if OrderCatalogMasterItemGUID is not null
|
||||
then
|
||||
/* Gets the allergen codes and other relevant data associated with the order{{{SINGLE-QUOTE}}}s
|
||||
catalog item allergens */
|
||||
(allergen_codes,
|
||||
allergen_msg_texts) := read
|
||||
{ "SELECT Code, MessageText,CV3OrderCatalogMasterItem.Name "
|
||||
|| " FROM CV3Allergen JOIN CV3CatalogItemAllergen"
|
||||
|| " ON CV3Allergen.GUID = CV3CatalogItemAllergen.AllergenGUID"
|
||||
|| " INNER JOIN CV3OrderCatalogMasterItem ON"
|
||||
|| " CV3CatalogItemAllergen.ItemGUID = CV3OrderCatalogMasterItem.GUID"
|
||||
|| " WHERE CV3CatalogItemAllergen.ItemGUID = "
|
||||
|| SQL(OrderCatalogMasterItemGUID)};
|
||||
|
||||
if (order_is_additive)
|
||||
then
|
||||
order_or_prescription_string := " additive.";
|
||||
else
|
||||
order_or_prescription_string := " order.";
|
||||
endif;
|
||||
|
||||
else
|
||||
/* Gets the allergen codes and other relevant data associated with the
|
||||
prescription{{{SINGLE-QUOTE}}}s catalog item allergens */
|
||||
num_allergies := count (patient_allergy_names);
|
||||
for J in (1 seqto num_allergies ) do
|
||||
if J=1
|
||||
then
|
||||
one_patient_allergy_name:= patient_allergy_names[J];
|
||||
else
|
||||
one_patient_allergy_name:= one_patient_allergy_name || "," || patient_allergy_names[J];
|
||||
endif;
|
||||
enddo;
|
||||
(allergen_codes,
|
||||
allergen_msg_texts) := read { "EXEC SXACatalogAllergenMessageTextSelPr "
|
||||
|| SQL(NULL)|| ", "
|
||||
|| SQL(order_name) || ", "
|
||||
|| SQL(EVOKINGOBJECT.FormularyBrandKey) || ", "
|
||||
|| SQL(allergen_guid) || ", "
|
||||
|| SQL(0) || ", "
|
||||
|| SQL(one_patient_allergy_name) };
|
||||
order_or_prescription_string := " prescription.";
|
||||
endif;
|
||||
|
||||
endif; /* If exist patient_allergy_names */
|
||||
;;
|
||||
evoke: ;;
|
||||
|
||||
logic:
|
||||
if (is_reverse_check)
|
||||
then
|
||||
conclude true;
|
||||
endif;
|
||||
|
||||
/* Stops processing when the patient does not have any allergies */
|
||||
if not (exist order_name or exist patient_allergy_names)
|
||||
then
|
||||
xxx_debug_check:= "patient does not have allergies";
|
||||
conclude false;
|
||||
endif;
|
||||
|
||||
/* Initializes variables */
|
||||
alert_msg_list:= ();
|
||||
alert_allergen_list:= ();
|
||||
alert_category_type_list := ();
|
||||
alert_adverse_event_year_list := ();
|
||||
alert_adverse_event_month_list := ();
|
||||
alert_adverse_event_day_list := ();
|
||||
|
||||
allergies_found := patient_allergy_names is in allergen_codes ;
|
||||
|
||||
if any allergies_found
|
||||
then
|
||||
|
||||
num_allergies := count (patient_allergy_names);
|
||||
for J in (1 seqto num_allergies ) do
|
||||
one_patient_allergy_name:= patient_allergy_names[J];
|
||||
if (one_patient_allergy_name is in allergen_codes)
|
||||
then
|
||||
category_type := patient_allergy_category_types[J];
|
||||
adverse_event_date_year := patient_allergy_adverse_event_date_year[J];
|
||||
adverse_event_date_month := patient_allergy_adverse_event_date_month[J];
|
||||
adverse_event_date_day := patient_allergy_adverse_event_date_day[J];
|
||||
allergen_code := one_patient_allergy_name;
|
||||
|
||||
if (category_type = "Adverse Event" and
|
||||
category_type = prev_category_type and
|
||||
allergen_code = prev_allergen_code)
|
||||
then
|
||||
alert_allergen_list := alert_allergen_list, null;
|
||||
alert_msg_list:= alert_msg_list, null;
|
||||
alert_category_type_list := alert_category_type_list, null;
|
||||
alert_adverse_event_year_list := alert_adverse_event_year_list, null;
|
||||
alert_adverse_event_month_list := alert_adverse_event_month_list, null;
|
||||
alert_adverse_event_day_list := alert_adverse_event_day_list, null;
|
||||
else
|
||||
/* Creates the list of matching allergens
|
||||
to return to the calling MLM */
|
||||
alert_allergen_list:= alert_allergen_list, allergen_code;
|
||||
|
||||
/* Creates a portion of the alert message */
|
||||
if (category_type = "Allergy" or category_type is null)
|
||||
then
|
||||
temp_alert_msg:=
|
||||
"The patient is allergic to " || allergen_code
|
||||
|| ". A reaction may occur with the "
|
||||
|| order_name || order_or_prescription_string;
|
||||
elseif (category_type = "Adverse Event")
|
||||
then
|
||||
temp_alert_msg:=
|
||||
"The patient had an adverse event with " || allergen_code
|
||||
|| ". A reaction may occur with the "
|
||||
|| order_name || order_or_prescription_string ;
|
||||
elseif (category_type = "Intolerance")
|
||||
then
|
||||
temp_alert_msg:=
|
||||
"The patient has an intolerance to " || allergen_code
|
||||
|| ". A reaction may occur with the "
|
||||
|| order_name || order_or_prescription_string ;
|
||||
endif;
|
||||
/* Extracts the freetext message in the item-catalog that is */
|
||||
/* assocated with the allergen code */
|
||||
|
||||
allergy_freetext_msg:= first(allergen_msg_texts
|
||||
where allergen_code = allergen_codes);
|
||||
|
||||
|
||||
/* Adds the item-catalog{{{SINGLE-QUOTE}}}s freetext message to the alert */
|
||||
if exist allergy_freetext_msg
|
||||
then
|
||||
temp_alert_msg:= temp_alert_msg || " " || allergy_freetext_msg;
|
||||
endif;
|
||||
|
||||
/* Creates the alert message that is returned to the calling MLM */
|
||||
alert_msg_list:= alert_msg_list, temp_alert_msg;
|
||||
alert_category_type_list := alert_category_type_list, category_type;
|
||||
alert_adverse_event_year_list := alert_adverse_event_year_list,
|
||||
adverse_event_date_year;
|
||||
alert_adverse_event_month_list := alert_adverse_event_month_list,
|
||||
adverse_event_date_month;
|
||||
alert_adverse_event_day_list := alert_adverse_event_day_list,
|
||||
adverse_event_date_day;
|
||||
endif;
|
||||
prev_category_type := category_type;
|
||||
prev_allergen_code := allergen_code;
|
||||
endif;
|
||||
enddo;
|
||||
endif; /* if any allergies_found */
|
||||
|
||||
|
||||
/* Always conclude true to return information to the calling MLM */
|
||||
conclude true;
|
||||
;;
|
||||
action:
|
||||
if is_reverse_check
|
||||
then
|
||||
return mdo_list;
|
||||
else
|
||||
return (alert_allergen_list,
|
||||
alert_msg_list,
|
||||
alert_category_type_list,
|
||||
alert_adverse_event_year_list,
|
||||
alert_adverse_event_month_list,
|
||||
alert_adverse_event_day_list);
|
||||
endif;
|
||||
;;
|
||||
end:
|
||||
678
MLMStripper/bin/Debug/STD/STD_FUNC_ALLERGY_DRUG_VENDOR_DATA.mlm
Normal file
678
MLMStripper/bin/Debug/STD/STD_FUNC_ALLERGY_DRUG_VENDOR_DATA.mlm
Normal file
@@ -0,0 +1,678 @@
|
||||
maintenance:
|
||||
|
||||
title: Medication Allergy Checking using Drug Vendor Data Drug Database;;
|
||||
mlmname: STD_FUNC_ALLERGY_DRUG_VENDOR_DATA;;
|
||||
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: Checks for Drug Allergies via Drug Vendor Data.
|
||||
;;
|
||||
explanation: See STD_ALLERGY MLM for an explanation.
|
||||
;;
|
||||
keywords: allergy; IV additives; Drug Vendor Data ;;
|
||||
|
||||
knowledge:
|
||||
type: data-driven;;
|
||||
data:
|
||||
|
||||
/* List Arguments passed by the calling MLM */
|
||||
(unmapped_allergen_type_list,
|
||||
pending_community_allergy_alert_text,
|
||||
enable_community_data_allergy_alerts,
|
||||
retrieve_pending_imported_allergies,
|
||||
cat_item_guid,
|
||||
client_guid,
|
||||
allergy_names,
|
||||
allergy_external_drug_code_list,
|
||||
allergy_external_drug_category_list,
|
||||
allergy_external_categorytype_list,
|
||||
generic_nameID,
|
||||
Allergen_Classification_Check,
|
||||
evoked_from_prescriptions,
|
||||
display_alert_types,
|
||||
alert_if_error,
|
||||
alert_if_unmapped,
|
||||
input_parameter_xml,
|
||||
allergy_decl_xml,
|
||||
DRUG_VENDOR_DATA_ALLERGY_CHECK,
|
||||
reverse_check_order,
|
||||
reverse_check_rx,
|
||||
reverse_check_outpatient_orders_flag):= ARGUMENT;
|
||||
|
||||
|
||||
|
||||
/***************Make Changes To Spelling And Flags In This Section**************/
|
||||
|
||||
/* Set to true if logging is needed.*/
|
||||
log_execution_info := false;
|
||||
|
||||
/*******************************************************************************/
|
||||
|
||||
alert_allergen_list:= ();
|
||||
temp_alert_msg_list:= ();
|
||||
alert_msg_list:= ();
|
||||
temp_drug_vendor_allergen_IDs := ();
|
||||
drug_vendor_allergen_IDs := ();
|
||||
temp_drug_vendor_allergen_reaction_level := ();
|
||||
temp_drug_vendor_category_names := ();
|
||||
temp_drug_vendor_class_names := ();
|
||||
temp_allergen_categorytype_description := ();
|
||||
temp_allergen_categorytype := ();
|
||||
temp_allergen_onset_day_list := ();
|
||||
temp_allergen_onset_month_list:= ();
|
||||
temp_allergen_onset_year_list := ();
|
||||
temp_drug_vendor_allergen_name_list := ();
|
||||
temp_drug_vendor_allergen_component_name_list := ();
|
||||
temp_drug_vendor_component_allergen_id_list := ();
|
||||
temp_drug_vendor_text_id_list := ();
|
||||
temp_drug_vendor_drug_category_id_list := ();
|
||||
temp_drug_vendor_drug_class_id_list := ();
|
||||
temp_drug_vendor_catalog_guid_list := ();
|
||||
temp_drug_vendor_prescription_id_list := ();
|
||||
|
||||
temp_order_name_list := ();
|
||||
temp_OrderOrAdditive_name_list := ();
|
||||
temp_prescription_name_list := ();
|
||||
temp_start_date_list := ();
|
||||
temp_status_type_list := ();
|
||||
|
||||
alert_category_list := ();
|
||||
alert_adverse_event_year:= ();
|
||||
alert_adverse_event_month:= ();
|
||||
alert_adverse_event_day:= ();
|
||||
alert_allergen_generic_name_list:= ();
|
||||
alert_allergen_component_list:= ();
|
||||
|
||||
alert_allergen_id_list := ();
|
||||
alert_reaction_level_list := ();
|
||||
alert_medication_category_name_list := ();
|
||||
alert_medication_class_name_list :=();
|
||||
alert_allergen_category_type_list := ();
|
||||
alert_allergen_component_id_list := ();
|
||||
alert_drug_vendor_text_id_list := ();
|
||||
alert_medication_category_id_list := ();
|
||||
alert_medication_class_id_list := ();
|
||||
alert_drug_is_combo_drug_list := ();
|
||||
|
||||
|
||||
unmapped_allergen_error_code := "-1";
|
||||
unmapped_drug_error_code := "-2";
|
||||
invalid_cat_item_guid_and_generic_name_id_error := "-3";
|
||||
classification_reaction_level := 3;
|
||||
|
||||
is_reverse_check := (exist input_parameter_xml AND exist allergy_decl_xml);
|
||||
|
||||
//convert unmapped_allergen_type_list into comma separated string so that we can pass it to SXADrugVendorAllergyAlertSelPr stored proc
|
||||
unmapped_allergen_type_string := "";
|
||||
if ((exists unmapped_allergen_type_list) and (count unmapped_allergen_type_list > 0))
|
||||
then
|
||||
string_length := count unmapped_allergen_type_list;
|
||||
//unmapped_allergen_type_string := "{{{SINGLE-QUOTE}}}" || unmapped_allergen_type_list || "{{{SINGLE-QUOTE}}}";
|
||||
FOR i in 1 seqto count unmapped_allergen_type_list DO
|
||||
unmapped_allergen_type_item := TRIM(unmapped_allergen_type_list[i]);
|
||||
unmapped_allergen_type_string := unmapped_allergen_type_string || unmapped_allergen_type_item;
|
||||
if string_length <> i
|
||||
then
|
||||
unmapped_allergen_type_string := unmapped_allergen_type_string || ",";
|
||||
endif;
|
||||
ENDDO;
|
||||
endif;
|
||||
//---------------------
|
||||
// Declare the Objects
|
||||
//---------------------
|
||||
|
||||
//Declare the Med_Data_Object
|
||||
Med_Data_Object := OBJECT [
|
||||
rx_hx_typecode,
|
||||
sort_field,
|
||||
OrderName,
|
||||
OrderOrAdditiveName,
|
||||
PrescriptionName,
|
||||
ComponentName,
|
||||
ComboDrugName,
|
||||
OrderGUID,
|
||||
AdditiveGUID,
|
||||
PrescriptionID,
|
||||
StartDate,
|
||||
StatusType,
|
||||
TypeCode,
|
||||
IsUnmapped,
|
||||
allergen_msg,
|
||||
msg_type,
|
||||
IsComboDrug,
|
||||
ExternalDrugCode,
|
||||
DrugClassName,
|
||||
DrugClassID,
|
||||
IsIntentionallyNotMapped,
|
||||
AlternateOrderType,
|
||||
IsScript,
|
||||
EnteredDate
|
||||
];
|
||||
|
||||
|
||||
// list that holds all of the objects that will be returned
|
||||
mdo_list := ();
|
||||
|
||||
if is_reverse_check
|
||||
then
|
||||
(
|
||||
temp_drug_vendor_allergen_IDs,
|
||||
temp_alert_msg_list,
|
||||
temp_drug_vendor_allergen_component_name_list,
|
||||
temp_drug_vendor_combo_drug_name_list,
|
||||
temp_drug_vendor_order_guid_list,
|
||||
temp_drug_vendor_additive_guid_list,
|
||||
temp_drug_vendor_prescription_id_list,
|
||||
temp_order_name_list,
|
||||
temp_OrderOrAdditive_name_list,
|
||||
temp_prescription_name_list,
|
||||
temp_start_date_list,
|
||||
temp_status_type_list,
|
||||
temp_type_code_list,
|
||||
temp_is_combo_drug_list,
|
||||
temp_drug_class_name_list,
|
||||
temp_drug_vendor_drug_class_id_list,
|
||||
temp_is_intentionally_not_mapped_list,
|
||||
temp_alternate_order_type_list,
|
||||
temp_is_script_list,
|
||||
temp_entered_date_list,
|
||||
temp_rx_hx_typecode_list
|
||||
) := read { "EXEC SXADrugVendorAllergyAlertSelPr "
|
||||
|| SQL(unmapped_allergen_type_string) || ", "
|
||||
|| SQL(pending_community_allergy_alert_text) || ", "
|
||||
|| SQL(retrieve_pending_imported_allergies) || ", "
|
||||
|| SQL(enable_community_data_allergy_alerts) || ", "
|
||||
|| SQL(cat_item_guid) || ", "
|
||||
|| SQL(client_guid) || ", "
|
||||
|| SQL(generic_nameID) || ", "
|
||||
|| SQL(allergy_decl_xml) || ", "
|
||||
|| SQL(input_parameter_xml) || ", "
|
||||
|| SQL(Allergen_Classification_Check) || ", "
|
||||
|| SQL(alert_if_unmapped) || ", "
|
||||
|| SQL(DRUG_VENDOR_DATA_ALLERGY_CHECK) || ", "
|
||||
|| SQL(is_reverse_check) || ", "
|
||||
|| SQL(reverse_check_order) || ", "
|
||||
|| SQL(reverse_check_rx) || ", "
|
||||
|| SQL(reverse_check_outpatient_orders_flag)};
|
||||
|
||||
// populate mdo_list using data returned from the stored procedure
|
||||
index_list := 1 seqto count (temp_drug_vendor_allergen_IDs);
|
||||
for JJ in index_list do
|
||||
|
||||
instance := new Med_Data_Object;
|
||||
|
||||
instance.rx_hx_typecode := temp_rx_hx_typecode_list[JJ];
|
||||
instance.OrderName := temp_order_name_list[JJ];
|
||||
instance.OrderOrAdditiveName := temp_OrderOrAdditive_name_list[JJ];
|
||||
instance.PrescriptionName := temp_prescription_name_list[JJ];
|
||||
instance.ComponentName := temp_drug_vendor_allergen_component_name_list[JJ];
|
||||
instance.ComboDrugName := temp_drug_vendor_combo_drug_name_list[JJ];
|
||||
instance.OrderGUID := temp_drug_vendor_order_guid_list[JJ];
|
||||
instance.AdditiveGUID := temp_drug_vendor_additive_guid_list[JJ];
|
||||
instance.PrescriptionID := temp_drug_vendor_prescription_id_list[JJ];
|
||||
instance.StartDate := temp_start_date_list[JJ];
|
||||
instance.StatusType := temp_status_type_list[JJ];
|
||||
instance.TypeCode := temp_type_code_list[JJ];
|
||||
instance.allergen_msg := temp_alert_msg_list[JJ];
|
||||
instance.msg_type := "DrugVendor";
|
||||
instance.IsComboDrug := temp_is_combo_drug_list[JJ];
|
||||
instance.ExternalDrugCode := temp_drug_vendor_allergen_IDs[JJ];//AlertRef
|
||||
instance.DrugClassName := temp_drug_class_name_list[JJ];//AlertRef
|
||||
instance.DrugClassID := temp_drug_vendor_drug_class_id_list[JJ];//AlertRef
|
||||
instance.AlternateOrderType := temp_alternate_order_type_list[jj];
|
||||
instance.IsScript := temp_is_script_list[jj];
|
||||
instance.EnteredDate := temp_entered_date_list[jj];
|
||||
|
||||
if (temp_drug_vendor_allergen_IDs[JJ] = "-2") // unmapped drug
|
||||
then
|
||||
instance.IsUnmapped := true;
|
||||
else
|
||||
instance.IsUnmapped := false;
|
||||
endif;
|
||||
|
||||
if (instance.IsComboDrug)
|
||||
then
|
||||
instance.sort_field :=
|
||||
instance.ComponentName || " in " || instance.ComboDrugName || "|";
|
||||
|
||||
if (instance.PrescriptionID is not null AND instance.PrescriptionID <> -1)
|
||||
then
|
||||
instance.sort_field := instance.sort_field || instance.PrescriptionID;
|
||||
elseif instance.AdditiveGUID is not null
|
||||
then
|
||||
instance.sort_field := instance.sort_field || instance.AdditiveGUID;
|
||||
else
|
||||
instance.sort_field := instance.sort_field || instance.OrderGUID;
|
||||
endif;
|
||||
|
||||
instance.sort_field := instance.sort_field || "|{1}";
|
||||
|
||||
elseif (instance.AdditiveGUID is not null)
|
||||
then
|
||||
instance.sort_field :=
|
||||
instance.OrderOrAdditiveName || "|" || instance.AdditiveGUID || "|{1}";
|
||||
|
||||
elseif (instance.PrescriptionID is not null AND instance.PrescriptionID <> -1)
|
||||
then
|
||||
instance.sort_field :=
|
||||
instance.PrescriptionName || "|" || instance.PrescriptionID || "|{1}";
|
||||
else
|
||||
instance.sort_field :=
|
||||
instance.OrderName || "|" || instance.OrderGUID || "|{1}";
|
||||
endif;
|
||||
if alert_if_unmapped = true
|
||||
then
|
||||
if instance.PrescriptionID = -1
|
||||
then
|
||||
if temp_is_intentionally_not_mapped_list[JJ] = true
|
||||
OR temp_is_intentionally_not_mapped_list[JJ] is null// unmapped drug
|
||||
then
|
||||
mdo_list := mdo_list, instance;
|
||||
endif;
|
||||
else
|
||||
mdo_list := mdo_list, instance;
|
||||
endif;
|
||||
else
|
||||
mdo_list := mdo_list, instance;
|
||||
endif;
|
||||
enddo;
|
||||
else
|
||||
|
||||
(
|
||||
temp_drug_vendor_allergen_IDs,
|
||||
temp_alert_msg_list,
|
||||
temp_drug_vendor_allergen_reaction_level,
|
||||
temp_drug_vendor_category_names,
|
||||
temp_drug_vendor_class_names,
|
||||
temp_allergen_categorytype_description,
|
||||
temp_allergen_categorytype,
|
||||
temp_allergen_onset_day_list,
|
||||
temp_allergen_onset_month_list,
|
||||
temp_allergen_onset_year_list,
|
||||
temp_drug_vendor_allergen_component_name_list,
|
||||
temp_drug_vendor_allergen_name_list,
|
||||
temp_drug_vendor_component_allergen_id_list,
|
||||
temp_drug_vendor_text_id_list,
|
||||
temp_drug_vendor_drug_category_id_list,
|
||||
temp_drug_vendor_drug_class_id_list,
|
||||
temp_is_combo_drug_list
|
||||
) := read { "EXEC SXADrugVendorAllergyAlertSelPr "
|
||||
|| SQL(unmapped_allergen_type_string) || ", "
|
||||
|| SQL(pending_community_allergy_alert_text) || ", "
|
||||
|| SQL(retrieve_pending_imported_allergies) || ", "
|
||||
|| SQL(enable_community_data_allergy_alerts) || ", "
|
||||
|| SQL(cat_item_guid) || " , " || SQL(client_guid) || " ,"
|
||||
|| SQL(generic_nameID) || ", " || SQL(allergy_decl_xml) || ", "
|
||||
|| SQL(input_parameter_xml) || ", " || SQL(Allergen_Classification_Check) || ", "
|
||||
|| SQL(alert_if_unmapped)};
|
||||
|
||||
endif;
|
||||
|
||||
|
||||
;;
|
||||
evoke: ;;
|
||||
|
||||
logic:
|
||||
|
||||
if (is_reverse_check)
|
||||
then
|
||||
conclude true;
|
||||
elseif (not exist cat_item_guid AND not exist generic_nameID)
|
||||
OR (not exist allergy_names)
|
||||
then
|
||||
conclude false;
|
||||
endif;
|
||||
|
||||
num_allergies := count (temp_drug_vendor_allergen_IDs);
|
||||
|
||||
// Always conclude true to return information to the calling MLM
|
||||
// Create the list of allergens that map to the Drug Vendor IDs.
|
||||
for J in (1 seqto num_allergies ) do
|
||||
one_drug_vendor_allergen_ID:= temp_drug_vendor_allergen_IDs[J];
|
||||
one_drug_vendor_alert_msg := temp_alert_msg_list[J];
|
||||
one_drug_vendor_reaction_level :=
|
||||
temp_drug_vendor_allergen_reaction_level[J];
|
||||
one_drug_vendor_category_name := temp_drug_vendor_category_names[J];
|
||||
one_drug_vendor_class_name := temp_drug_vendor_class_names[J];
|
||||
one_allergen_categorytype_description :=
|
||||
temp_allergen_categorytype_description[J];
|
||||
one_allergen_categorytype := temp_allergen_categorytype[J];
|
||||
one_allergen_onset_day := temp_allergen_onset_day_list[J];
|
||||
one_allergen_onset_month := temp_allergen_onset_month_list[J];
|
||||
one_allergen_onset_year := temp_allergen_onset_year_list[J];
|
||||
one_allergen_component_generic_name :=
|
||||
temp_drug_vendor_allergen_component_name_list[j];
|
||||
one_allergen_parent_generic_name := temp_drug_vendor_allergen_name_list[j];
|
||||
one_drug_vendor_component_allergen_id :=
|
||||
temp_drug_vendor_component_allergen_id_list[j];
|
||||
one_drug_vendor_text_id := temp_drug_vendor_text_id_list[j];
|
||||
one_drug_vendor_category_id := temp_drug_vendor_drug_category_id_list[j];
|
||||
one_drug_vendor_class_id := temp_drug_vendor_drug_class_id_list[j];
|
||||
one_drug_is_combo_drug := temp_is_combo_drug_list[j];
|
||||
|
||||
prev_temp_category := temp_allergen_categorytype_description[j-1];
|
||||
prev_vendor_allergen_id := temp_drug_vendor_allergen_IDs[j-1];
|
||||
prev_vendor_component_allergen_id := temp_drug_vendor_component_allergen_id_list[j-1];
|
||||
|
||||
// if not reverse checking, then proceed as normal.
|
||||
//If the drug is not mapped the Drug_vendor_allergen_ID will be -2
|
||||
if string(one_drug_vendor_allergen_ID) = unmapped_drug_error_code
|
||||
then
|
||||
if alert_if_unmapped and (not evoked_from_prescriptions)
|
||||
then
|
||||
alert_allergen_list:= alert_allergen_list, NULL;
|
||||
alert_msg_list:= alert_msg_list,
|
||||
"The order listed below could not be checked against the"
|
||||
|| " patient{{{SINGLE-QUOTE}}}s allergies."
|
||||
|| " Please use an alternate plan to do the check. "
|
||||
|| " Notify your system administrator for Sunrise Clinical Manager"
|
||||
|| " that the Multum Allergy Checking could not be done because below order(s) is an Unmapped drug";
|
||||
alert_category_list := alert_category_list, NULL;
|
||||
alert_adverse_event_year := alert_adverse_event_year, NULL;
|
||||
alert_adverse_event_month := alert_adverse_event_month, NULL;
|
||||
alert_adverse_event_day := alert_adverse_event_day, NULL;
|
||||
alert_allergen_generic_name_list := one_allergen_parent_generic_name;
|
||||
alert_allergen_component_list := alert_allergen_component_list, NULL;
|
||||
if exist one_drug_vendor_allergen_ID
|
||||
then
|
||||
alert_allergen_id_list := one_drug_vendor_allergen_ID;
|
||||
endif;
|
||||
alert_reaction_level_list := alert_reaction_level_list, NULL;
|
||||
alert_medication_category_name_list := alert_medication_category_name_list, NULL;
|
||||
alert_medication_class_name_list :=alert_medication_class_name_list, NULL;
|
||||
alert_allergen_category_type_list := alert_allergen_category_type_list, NULL;
|
||||
alert_allergen_component_id_list := alert_allergen_component_id_list, NULL;
|
||||
alert_drug_vendor_text_id_list := alert_drug_vendor_text_id_list, NULL;
|
||||
alert_medication_category_id_list := alert_medication_category_id_list, NULL;
|
||||
alert_medication_class_id_list := alert_medication_class_id_list, NULL;
|
||||
alert_drug_is_combo_drug_list := alert_drug_is_combo_drug_list, NULL;
|
||||
else
|
||||
alert_allergen_list:= alert_allergen_list, NULL;
|
||||
alert_msg_list := alert_msg_list, NULL;
|
||||
alert_category_list := alert_category_list, NULL;
|
||||
alert_adverse_event_year := alert_adverse_event_year, NULL;
|
||||
alert_adverse_event_month := alert_adverse_event_month, NULL;
|
||||
alert_adverse_event_day := alert_adverse_event_day, NULL;
|
||||
alert_allergen_generic_name_list := alert_allergen_generic_name_list, NULL;
|
||||
alert_allergen_component_list := alert_allergen_component_list, NULL;
|
||||
alert_allergen_id_list := alert_allergen_id_list, NULL;
|
||||
alert_reaction_level_list := alert_reaction_level_list, NULL;
|
||||
alert_medication_category_name_list := alert_medication_category_name_list, NULL;
|
||||
alert_medication_class_name_list :=alert_medication_class_name_list, NULL;
|
||||
alert_allergen_category_type_list := alert_allergen_category_type_list, NULL;
|
||||
alert_allergen_component_id_list := alert_allergen_component_id_list, NULL;
|
||||
alert_drug_vendor_text_id_list := alert_drug_vendor_text_id_list, NULL;
|
||||
alert_medication_category_id_list := alert_medication_category_id_list, NULL;
|
||||
alert_medication_class_id_list := alert_medication_class_id_list, NULL;
|
||||
alert_drug_is_combo_drug_list := alert_drug_is_combo_drug_list, NULL;
|
||||
|
||||
endif;
|
||||
//If the allergen is not mapped or the external code is invalid,
|
||||
//the Drug_vendor_allergen_ID will be -1
|
||||
elseif string(one_drug_vendor_allergen_ID) = unmapped_allergen_error_code
|
||||
then
|
||||
if alert_if_unmapped
|
||||
then
|
||||
alert_allergen_list:= alert_allergen_list, NULL;
|
||||
alert_msg_list:= alert_msg_list,
|
||||
"The order listed below could not be checked against the"
|
||||
|| " patient{{{SINGLE-QUOTE}}}s allergies."
|
||||
|| " Please use an alternate plan to do the check. "
|
||||
|| " Notify your system administrator for Sunrise Clinical Manager"
|
||||
|| " that the following error occurred with the Drug Data: "
|
||||
|| one_drug_vendor_alert_msg;
|
||||
alert_category_list := alert_category_list, NULL;
|
||||
alert_adverse_event_year := alert_adverse_event_year, NULL;
|
||||
alert_adverse_event_month := alert_adverse_event_month, NULL;
|
||||
alert_adverse_event_day := alert_adverse_event_day, NULL;
|
||||
alert_allergen_generic_name_list := alert_allergen_generic_name_list, NULL;
|
||||
alert_allergen_component_list := alert_allergen_component_list, NULL;
|
||||
alert_allergen_id_list := alert_allergen_id_list, NULL;
|
||||
alert_reaction_level_list := alert_reaction_level_list, NULL;
|
||||
alert_medication_category_name_list := alert_medication_category_name_list, NULL;
|
||||
alert_medication_class_name_list :=alert_medication_class_name_list, NULL;
|
||||
alert_allergen_category_type_list := alert_allergen_category_type_list, NULL;
|
||||
alert_allergen_component_id_list := alert_allergen_component_id_list, NULL;
|
||||
alert_drug_vendor_text_id_list := alert_drug_vendor_text_id_list, NULL;
|
||||
alert_medication_category_id_list := alert_medication_category_id_list, NULL;
|
||||
alert_medication_class_id_list := alert_medication_class_id_list, NULL;
|
||||
alert_drug_is_combo_drug_list := alert_drug_is_combo_drug_list, NULL;
|
||||
|
||||
else
|
||||
alert_allergen_list:= alert_allergen_list, NULL;
|
||||
alert_msg_list := alert_msg_list, NULL;
|
||||
alert_category_list := alert_category_list, NULL;
|
||||
alert_adverse_event_year := alert_adverse_event_year, NULL;
|
||||
alert_adverse_event_month := alert_adverse_event_month, NULL;
|
||||
alert_adverse_event_day := alert_adverse_event_day, NULL;
|
||||
alert_allergen_generic_name_list := alert_allergen_generic_name_list, NULL;
|
||||
alert_allergen_component_list := alert_allergen_component_list, NULL;
|
||||
alert_allergen_id_list := alert_allergen_id_list, NULL;
|
||||
alert_reaction_level_list := alert_reaction_level_list, NULL;
|
||||
alert_medication_category_name_list := alert_medication_category_name_list, NULL;
|
||||
alert_medication_class_name_list :=alert_medication_class_name_list, NULL;
|
||||
alert_allergen_category_type_list := alert_allergen_category_type_list, NULL;
|
||||
alert_allergen_component_id_list := alert_allergen_component_id_list, NULL;
|
||||
alert_drug_vendor_text_id_list := alert_drug_vendor_text_id_list, NULL;
|
||||
alert_medication_category_id_list := alert_medication_category_id_list, NULL;
|
||||
alert_medication_class_id_list := alert_medication_class_id_list, NULL;
|
||||
alert_drug_is_combo_drug_list := alert_drug_is_combo_drug_list, NULL;
|
||||
|
||||
endif;
|
||||
//@CatItemGUID and @DrugGenericNameID parameters for the stored procedure
|
||||
//are both null, the Drug_vendor_allergen_ID will be -3
|
||||
|
||||
elseif (string(one_drug_vendor_allergen_ID) =
|
||||
invalid_cat_item_guid_and_generic_name_id_error)
|
||||
then
|
||||
alert_allergen_list:= alert_allergen_list, NULL;
|
||||
alert_msg_list:= alert_msg_list,
|
||||
"The order listed below could not be checked against the"
|
||||
|| " patient{{{SINGLE-QUOTE}}}s allergies."
|
||||
|| " Please use an alternate plan to do the check. "
|
||||
|| " Notify your system administrator for Sunrise Clinical Manager"
|
||||
|| " that the following error occurred with the Drug Data: "
|
||||
|| one_drug_vendor_alert_msg;
|
||||
alert_category_list := alert_category_list, NULL;
|
||||
alert_adverse_event_year := alert_adverse_event_year, NULL;
|
||||
alert_adverse_event_month := alert_adverse_event_month, NULL;
|
||||
alert_adverse_event_day := alert_adverse_event_day, NULL;
|
||||
alert_allergen_generic_name_list := alert_allergen_generic_name_list, NULL;
|
||||
alert_allergen_component_list := alert_allergen_component_list, NULL;
|
||||
alert_allergen_id_list := alert_allergen_id_list, NULL;
|
||||
alert_reaction_level_list := alert_reaction_level_list, NULL;
|
||||
alert_medication_category_name_list := alert_medication_category_name_list, NULL;
|
||||
alert_medication_class_name_list :=alert_medication_class_name_list, NULL;
|
||||
alert_allergen_category_type_list := alert_allergen_category_type_list, NULL;
|
||||
alert_allergen_component_id_list := alert_allergen_component_id_list, NULL;
|
||||
alert_drug_vendor_text_id_list := alert_drug_vendor_text_id_list, NULL;
|
||||
alert_medication_category_id_list := alert_medication_category_id_list, NULL;
|
||||
alert_medication_class_id_list := alert_medication_class_id_list, NULL;
|
||||
alert_drug_is_combo_drug_list := alert_drug_is_combo_drug_list, NULL;
|
||||
|
||||
// external drug code = external drug code field in CV3Allergen (see config tools)
|
||||
// return drug allergy messages that match the allergy{{{SINGLE-QUOTE}}}s drug id or drug category id
|
||||
// also, will only return messages if allergy is in specified category type
|
||||
// list (adverse event, intolerance)
|
||||
|
||||
elseif one_drug_vendor_allergen_ID is in allergy_external_drug_code_list
|
||||
and one_allergen_categorytype_description is in display_alert_types
|
||||
then
|
||||
|
||||
temp_allergy_list := allergy_names where one_drug_vendor_allergen_ID = allergy_external_drug_code_list
|
||||
and one_allergen_categorytype = allergy_external_categorytype_list;
|
||||
|
||||
for temp_name in temp_allergy_list do
|
||||
if (Allergen_Classification_Check = true
|
||||
or (Allergen_Classification_Check = false
|
||||
and one_drug_vendor_reaction_level <> classification_reaction_level))
|
||||
then
|
||||
|
||||
if (one_allergen_categorytype_description = "Adverse Event" and
|
||||
one_allergen_categorytype_description = prev_temp_category and
|
||||
one_drug_vendor_allergen_ID = prev_vendor_allergen_id and
|
||||
one_drug_vendor_component_allergen_id = prev_vendor_component_allergen_id)
|
||||
then
|
||||
alert_allergen_list:= alert_allergen_list, null;
|
||||
alert_msg_list := alert_msg_list, null;
|
||||
alert_category_list := alert_category_list, null;
|
||||
alert_adverse_event_year := alert_adverse_event_year, NULL;
|
||||
alert_adverse_event_month := alert_adverse_event_month, NULL;
|
||||
alert_adverse_event_day := alert_adverse_event_day, NULL;
|
||||
alert_allergen_generic_name_list := alert_allergen_generic_name_list, NULL;
|
||||
alert_allergen_component_list := alert_allergen_component_list, NULL;
|
||||
alert_allergen_id_list := alert_allergen_id_list, NULL;
|
||||
alert_reaction_level_list := alert_reaction_level_list, NULL;
|
||||
alert_medication_category_name_list := alert_medication_category_name_list, NULL;
|
||||
alert_medication_class_name_list :=alert_medication_class_name_list, NULL;
|
||||
alert_allergen_category_type_list := alert_allergen_category_type_list, NULL;
|
||||
alert_allergen_component_id_list := alert_allergen_component_id_list, NULL;
|
||||
alert_drug_vendor_text_id_list := alert_drug_vendor_text_id_list, NULL;
|
||||
alert_medication_category_id_list := alert_medication_category_id_list, NULL;
|
||||
alert_medication_class_id_list := alert_medication_class_id_list, NULL;
|
||||
alert_drug_is_combo_drug_list := alert_drug_is_combo_drug_list, NULL;
|
||||
|
||||
|
||||
else
|
||||
|
||||
alert_allergen_list:= alert_allergen_list, temp_name;
|
||||
alert_msg_list := alert_msg_list, one_drug_vendor_alert_msg;
|
||||
alert_category_list :=
|
||||
alert_category_list, one_allergen_categorytype_description;
|
||||
alert_adverse_event_year :=
|
||||
alert_adverse_event_year, one_allergen_onset_year;
|
||||
alert_adverse_event_month :=
|
||||
alert_adverse_event_month, one_allergen_onset_month;
|
||||
alert_adverse_event_day :=
|
||||
alert_adverse_event_day, one_allergen_onset_day;
|
||||
alert_allergen_generic_name_list := alert_allergen_generic_name_list,
|
||||
one_allergen_parent_generic_name;
|
||||
alert_allergen_component_list := alert_allergen_component_list,
|
||||
one_allergen_component_generic_name;
|
||||
|
||||
alert_allergen_id_list := alert_allergen_id_list, one_drug_vendor_allergen_ID;
|
||||
alert_reaction_level_list := alert_reaction_level_list, one_drug_vendor_reaction_level;
|
||||
alert_medication_category_name_list := alert_medication_category_name_list, one_drug_vendor_category_name;
|
||||
alert_medication_class_name_list :=alert_medication_class_name_list, one_drug_vendor_class_name;
|
||||
alert_allergen_category_type_list := alert_allergen_category_type_list, one_allergen_categorytype;
|
||||
alert_allergen_component_id_list := alert_allergen_component_id_list, one_drug_vendor_component_allergen_id;
|
||||
alert_drug_vendor_text_id_list := alert_drug_vendor_text_id_list, one_drug_vendor_text_id;
|
||||
alert_medication_category_id_list := alert_medication_category_id_list, one_drug_vendor_category_id;
|
||||
alert_medication_class_id_list := alert_medication_class_id_list, one_drug_vendor_class_id;
|
||||
alert_drug_is_combo_drug_list := alert_drug_is_combo_drug_list, one_drug_is_combo_drug;
|
||||
|
||||
|
||||
|
||||
endif;
|
||||
endif;
|
||||
enddo;
|
||||
|
||||
elseif one_drug_vendor_allergen_ID
|
||||
is in allergy_external_drug_category_list
|
||||
and one_allergen_categorytype_description
|
||||
is in display_alert_types
|
||||
then
|
||||
temp_allergy_list := allergy_names where
|
||||
(one_drug_vendor_allergen_ID = allergy_external_drug_category_list
|
||||
and one_allergen_categorytype = allergy_external_categorytype_list);
|
||||
|
||||
for temp_name in temp_allergy_list do
|
||||
alert_allergen_list:= alert_allergen_list, temp_name;
|
||||
alert_msg_list := alert_msg_list, one_drug_vendor_alert_msg;
|
||||
alert_category_list := alert_category_list,
|
||||
one_allergen_categorytype_description;
|
||||
alert_adverse_event_year := alert_adverse_event_year,
|
||||
one_allergen_onset_year;
|
||||
alert_adverse_event_month := alert_adverse_event_month,
|
||||
one_allergen_onset_month;
|
||||
alert_adverse_event_day := alert_adverse_event_day,
|
||||
one_allergen_onset_day;
|
||||
alert_allergen_generic_name_list := alert_allergen_generic_name_list,
|
||||
one_allergen_parent_generic_name;
|
||||
alert_allergen_component_list := alert_allergen_component_list,
|
||||
one_allergen_component_generic_name;
|
||||
alert_allergen_id_list := alert_allergen_id_list, one_drug_vendor_allergen_ID;
|
||||
alert_reaction_level_list := alert_reaction_level_list, one_drug_vendor_reaction_level;
|
||||
alert_medication_category_name_list := alert_medication_category_name_list, one_drug_vendor_category_name;
|
||||
alert_medication_class_name_list :=alert_medication_class_name_list, one_drug_vendor_class_name;
|
||||
alert_allergen_category_type_list := alert_allergen_category_type_list, one_allergen_categorytype;
|
||||
alert_allergen_component_id_list := alert_allergen_component_id_list, one_drug_vendor_component_allergen_id;
|
||||
alert_drug_vendor_text_id_list := alert_drug_vendor_text_id_list, one_drug_vendor_text_id;
|
||||
alert_medication_category_id_list := alert_medication_category_id_list, one_drug_vendor_category_id;
|
||||
alert_medication_class_id_list := alert_medication_class_id_list, one_drug_vendor_class_id;
|
||||
alert_drug_is_combo_drug_list := alert_drug_is_combo_drug_list, one_drug_is_combo_drug;
|
||||
|
||||
enddo;
|
||||
else
|
||||
alert_allergen_list:= alert_allergen_list, NULL;
|
||||
alert_msg_list := alert_msg_list, NULL;
|
||||
alert_category_list := alert_category_list, NULL;
|
||||
alert_adverse_event_year := alert_adverse_event_year, NULL;
|
||||
alert_adverse_event_month := alert_adverse_event_month, NULL;
|
||||
alert_adverse_event_day := alert_adverse_event_day, NULL;
|
||||
alert_allergen_generic_name_list := alert_allergen_generic_name_list, NULL;
|
||||
alert_allergen_component_list := alert_allergen_component_list, NULL;
|
||||
alert_allergen_id_list := alert_allergen_id_list, NULL;
|
||||
alert_reaction_level_list := alert_reaction_level_list, NULL;
|
||||
alert_medication_category_name_list := alert_medication_category_name_list, NULL;
|
||||
alert_medication_class_name_list :=alert_medication_class_name_list, NULL;
|
||||
alert_allergen_category_type_list := alert_allergen_category_type_list, NULL;
|
||||
alert_allergen_component_id_list := alert_allergen_component_id_list, NULL;
|
||||
alert_drug_vendor_text_id_list := alert_drug_vendor_text_id_list, NULL;
|
||||
alert_medication_category_id_list := alert_medication_category_id_list, NULL;
|
||||
alert_medication_class_id_list := alert_medication_class_id_list, NULL;
|
||||
alert_drug_is_combo_drug_list := alert_drug_is_combo_drug_list, NULL;
|
||||
endif; // if one_drug_vendor_allergen_ID
|
||||
|
||||
prev_vendor_allergen_id := one_drug_vendor_allergen_ID;
|
||||
prev_temp_category := one_allergen_categorytype_description;
|
||||
enddo; // for J
|
||||
conclude true;
|
||||
|
||||
;;
|
||||
action:
|
||||
if (is_reverse_check) then
|
||||
return ( mdo_list );
|
||||
else
|
||||
return (alert_allergen_list,
|
||||
alert_msg_list,
|
||||
alert_category_list,
|
||||
alert_adverse_event_year,
|
||||
alert_adverse_event_month,
|
||||
alert_adverse_event_day,
|
||||
alert_allergen_generic_name_list, // prescription name
|
||||
alert_allergen_component_list, // component of prescription
|
||||
alert_allergen_id_list,
|
||||
alert_reaction_level_list,
|
||||
alert_medication_category_name_list,
|
||||
alert_medication_class_name_list,
|
||||
alert_allergen_category_type_list,
|
||||
alert_allergen_component_id_list,
|
||||
alert_drug_vendor_text_id_list,
|
||||
alert_medication_category_id_list,
|
||||
alert_medication_class_id_list,
|
||||
alert_drug_is_combo_drug_list);
|
||||
endif;
|
||||
;;
|
||||
end:
|
||||
120
MLMStripper/bin/Debug/STD/STD_FUNC_BUILD_RESULT_OBJECT.mlm
Normal file
120
MLMStripper/bin/Debug/STD/STD_FUNC_BUILD_RESULT_OBJECT.mlm
Normal file
@@ -0,0 +1,120 @@
|
||||
maintenance:
|
||||
|
||||
title: Build a result object;;
|
||||
mlmname: STD_FUNC_BUILD_RESULT_OBJECT;;
|
||||
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: This MLM will create one or more Result data objects based
|
||||
on parameter data and any parent/child relationships found in the
|
||||
database.
|
||||
|
||||
This MLM should be called by any MLM that calls the STD_FUNC_INSERT_REPORTABLE_SURVEILLANCE
|
||||
MLM with result data.
|
||||
;;
|
||||
explanation:
|
||||
;;
|
||||
keywords:
|
||||
;;
|
||||
citations:
|
||||
;;
|
||||
knowledge:
|
||||
type: data-driven;;
|
||||
data:
|
||||
|
||||
(parentOrderKey,
|
||||
childResultGUIDs,
|
||||
reasonCode) := ARGUMENT;
|
||||
|
||||
log_execution_info := false;
|
||||
|
||||
// Common code to all Bio-Surveillance MLMs
|
||||
ReportableType := OBJECT
|
||||
[
|
||||
ParentKey,
|
||||
ChildKeys,
|
||||
ObjectType,
|
||||
Reason
|
||||
];
|
||||
|
||||
resultsType := OBJECT [ resultGUID, orderGUID ];
|
||||
|
||||
// Call SQL function to find all parent/child orders and results for the
|
||||
// parent order key passed in
|
||||
if (childResultGUIDs is not null AND not childResultGUIDs is list) then
|
||||
childResultGUIDs := ,childResultGUIDs;
|
||||
endif;
|
||||
|
||||
// Build the XML field used to send in the list of results used to filter
|
||||
childResultGUIDsXML := null;
|
||||
if childResultGUIDs is list
|
||||
then
|
||||
childResultGUIDsXML := "<results>";
|
||||
for guid in childResultGUIDs do
|
||||
childResultGUIDsXML := childResultGUIDsXML || "<guid>" || guid || "</guid>";
|
||||
enddo;
|
||||
|
||||
childResultGUIDsXML := childResultGUIDsXML || "</results>";
|
||||
endif;
|
||||
|
||||
// Execute the SQL function to retrieve all parent and child orders
|
||||
resultsObjects := read as resultsType { "select ord.* from dbo.SXAFindAllResultsFromParentOrderFn(" || SQL(parentOrderKey) || "," ||
|
||||
SQL(parentOrderKey) || "," ||
|
||||
SQL(childResultGUIDsXML) || ", 0) ord " };
|
||||
resultObjectList := ();
|
||||
orderGUIDs := ();
|
||||
|
||||
// Use the list of objects returned from the SQL function and build up ReportType objects containing all orders and their
|
||||
// matching results.
|
||||
for obj in resultsObjects do
|
||||
if obj.OrderGUID is not in orderGUIDs then
|
||||
orderGUIDs := orderGUIDs,obj.OrderGUID;
|
||||
|
||||
resultObject := new ReportableType;
|
||||
resultObject.ParentKey := obj.OrderGUID;
|
||||
resultObject.ChildKeys := resultsObjects.resultGUID where resultsObjects.OrderGUID = obj.OrderGUID;
|
||||
resultObject.ObjectType := "result";
|
||||
resultObject.reason := reasonCode;
|
||||
|
||||
resultObjectList := resultObjectList, resultObject;
|
||||
|
||||
endif;
|
||||
enddo;
|
||||
|
||||
;;
|
||||
priority: 50
|
||||
;;
|
||||
evoke:
|
||||
;;
|
||||
logic:
|
||||
conclude true;
|
||||
;;
|
||||
action:
|
||||
|
||||
// return the list of result objects
|
||||
return resultObjectList;
|
||||
|
||||
;;
|
||||
Urgency: 50;;
|
||||
end:
|
||||
86
MLMStripper/bin/Debug/STD/STD_FUNC_CHECK_PAST_ALERTS.mlm
Normal file
86
MLMStripper/bin/Debug/STD/STD_FUNC_CHECK_PAST_ALERTS.mlm
Normal file
@@ -0,0 +1,86 @@
|
||||
maintenance:
|
||||
|
||||
title: Check for Past Alerts;;
|
||||
mlmname: STD_FUNC_CHECK_PAST_ALERTS;;
|
||||
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: This MLM will check for matching alert rule groups and rule numbers that were
|
||||
stored in the database within the past interval of time.
|
||||
;;
|
||||
explanation: Locates alert matches on RuleGroup, RuleNumber and CreatedWhen that occur within
|
||||
the alert interval. The MLM is passed the rule group, rule number, client,
|
||||
and interval by the calling MLM and returns TRUE if a matching alert is found
|
||||
within the interval.
|
||||
;;
|
||||
keywords: alert, interval, rule
|
||||
;;
|
||||
knowledge:
|
||||
type: data-driven;;
|
||||
data:
|
||||
|
||||
(client_guid, // Client indicator
|
||||
chart_guid, // Chart indicator
|
||||
rule_group, // The rule group for the alert to be matched
|
||||
rule_number, // The rule number for the alert to be matched
|
||||
alert_interval_start, // Start date &time to check for past alerts
|
||||
alert_interval_stop // Stop date &time to check for past alerts
|
||||
) := ARGUMENT;
|
||||
|
||||
// Get all matching alerts for the given interval
|
||||
(AD_CreatedWhen,
|
||||
AD_Status,
|
||||
AD_ClientVisitGUID,
|
||||
AD_ClientGUID,
|
||||
AD_ChartGUID,
|
||||
AD_Description,
|
||||
AD_TypeCode,
|
||||
AD_EventType,
|
||||
AD_RuleGroup,
|
||||
AD_RuleNumber) := read{ "SELECT CreatedWhen, Status, ClientVisitGUID, ClientGUID, "
|
||||
|| " ChartGUID, Description, TypeCode, EventType, RuleGroup, RuleNumber"
|
||||
|| " FROM CV3AlertDeclaration "
|
||||
|| " WHERE ClientGUID = " || SQL(client_guid)
|
||||
|| " AND ChartGUID = " || SQL(chart_guid)
|
||||
|| " AND RuleGroup = " || SQL(rule_group)
|
||||
|| " AND RuleNumber = " || SQL(rule_number)
|
||||
|| " AND CreatedWhen >= " || SQL(alert_interval_start)
|
||||
// || " AND CreatedWhen <= " || SQL(alert_interval_stop)||")"
|
||||
,PrimaryTime = CreatedWhen};
|
||||
;;
|
||||
evoke:
|
||||
;;
|
||||
logic:
|
||||
if exists AD_RuleGroup then
|
||||
CheckForAlertInInterval := TRUE;
|
||||
else
|
||||
CheckForAlertInInterval := FALSE;
|
||||
endif; // check to see if alert occurred within the time interval
|
||||
|
||||
conclude TRUE;
|
||||
;;
|
||||
action:
|
||||
return CheckForAlertInInterval;
|
||||
;;
|
||||
end:
|
||||
166
MLMStripper/bin/Debug/STD/STD_FUNC_CLINSUM_TRANSLATE.mlm
Normal file
166
MLMStripper/bin/Debug/STD/STD_FUNC_CLINSUM_TRANSLATE.mlm
Normal file
@@ -0,0 +1,166 @@
|
||||
maintenance:
|
||||
|
||||
title: Translation MLM required by the ClinSum Tile MLMs;;
|
||||
mlmname: STD_FUNC_CLINSUM_TRANSLATE;;
|
||||
arden: version 2.5;;
|
||||
version: 18.4;;
|
||||
institution: Allscripts, Standard ClinSum MLMs;;
|
||||
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:
|
||||
This MLM is called by all Clinical Summary MLMs that are used by the Tiles
|
||||
functionality to convert row definitions and values that were created by the
|
||||
parent CLINSUM_ mlm into data structures which can be process by the calling code.
|
||||
|
||||
;;
|
||||
explanation:
|
||||
You are required to load this MLM first before attempting to run
|
||||
any sample or custom CLINSUM tile MLMs.
|
||||
|
||||
Do not make any changes to this MLM unless authorized by Allscripts.
|
||||
|
||||
;;
|
||||
keywords: Clinical Summary Tiles
|
||||
;;
|
||||
|
||||
knowledge:
|
||||
type: data-driven;;
|
||||
data:
|
||||
|
||||
(rowDefinition_obj, rows_obj) := argument;
|
||||
|
||||
log_execution_info := false;
|
||||
|
||||
standard_libs := MLM {{{SINGLE-QUOTE}}}std_include_libs{{{SINGLE-QUOTE}}};
|
||||
include standard_libs;
|
||||
|
||||
using "SCM.CDS.Core";
|
||||
using namespace "CDS";
|
||||
using namespace "CDSData";
|
||||
|
||||
;;
|
||||
priority: 50
|
||||
;;
|
||||
evoke:
|
||||
;;
|
||||
logic:
|
||||
|
||||
// For the MLM Editor
|
||||
if rowDefinition_obj is NULL OR
|
||||
rows_obj is NULL
|
||||
then
|
||||
conclude false;
|
||||
endif;
|
||||
|
||||
// Define the schema of CDSDataObject that will contain the row definition.
|
||||
// NOTE: This schema must match the fields defined in the parent MLM.
|
||||
colDefinition := new net_object {{{SINGLE-QUOTE}}}DataObjectDefinition{{{SINGLE-QUOTE}}};
|
||||
x := call colDefinition.AddColumn with "FieldName", "CDSString" as {{{SINGLE-QUOTE}}}CDSType{{{SINGLE-QUOTE}}};
|
||||
x := call colDefinition.AddColumn with "ColumnHeader", "CDSString" as {{{SINGLE-QUOTE}}}CDSType{{{SINGLE-QUOTE}}};
|
||||
x := call colDefinition.AddColumn with "DisplaySeqNum", "CDSInteger" as {{{SINGLE-QUOTE}}}CDSType{{{SINGLE-QUOTE}}};
|
||||
x := call colDefinition.AddColumn with "DataType", "CDSString" as {{{SINGLE-QUOTE}}}CDSType{{{SINGLE-QUOTE}}};
|
||||
x := call colDefinition.AddColumn with "DisplayFormat", "CDSString" as {{{SINGLE-QUOTE}}}CDSType{{{SINGLE-QUOTE}}};
|
||||
x := call colDefinition.AddColumn with "WidthDefaultPixel", "CDSInteger" as {{{SINGLE-QUOTE}}}CDSType{{{SINGLE-QUOTE}}};
|
||||
x := call colDefinition.AddColumn with "WidthMinPixel", "CDSInteger" as {{{SINGLE-QUOTE}}}CDSType{{{SINGLE-QUOTE}}};
|
||||
x := call colDefinition.AddColumn with "WidthMaxPixel", "CDSInteger" as {{{SINGLE-QUOTE}}}CDSType{{{SINGLE-QUOTE}}};
|
||||
x := call colDefinition.AddColumn with "IsVisible", "CDSInteger" as {{{SINGLE-QUOTE}}}CDSType{{{SINGLE-QUOTE}}};
|
||||
x := call colDefinition.AddColumn with "IsSortable", "CDSInteger" as {{{SINGLE-QUOTE}}}CDSType{{{SINGLE-QUOTE}}};
|
||||
x := call {{{SINGLE-QUOTE}}}CDSDataObject{{{SINGLE-QUOTE}}}.DeclareObjectSchema with "ColDefinitionType", colDefinition;
|
||||
|
||||
rowdefinition_dataobj := call {{{SINGLE-QUOTE}}}CDSDataObject{{{SINGLE-QUOTE}}}.CreateObject with "ColDefinitionType";
|
||||
|
||||
// Populate the row definition data object from the Arden object
|
||||
colCounter := 1 seqto (count rowDefinition_obj);
|
||||
for CC in colCounter do
|
||||
|
||||
x := call rowdefinition_dataobj.AppendEmptyRow;
|
||||
x := call rowdefinition_dataobj.SetString with
|
||||
"FieldName", rowDefinition_obj[cc].FieldName as {{{SINGLE-QUOTE}}}String{{{SINGLE-QUOTE}}};
|
||||
x := call rowdefinition_dataobj.SetString with
|
||||
"ColumnHeader", rowDefinition_obj[cc].ColumnHeader as {{{SINGLE-QUOTE}}}String{{{SINGLE-QUOTE}}};
|
||||
x := call rowdefinition_dataobj.SetDouble with
|
||||
"DisplaySeqNum", rowDefinition_obj[cc].DisplaySeqNum as {{{SINGLE-QUOTE}}}Int32{{{SINGLE-QUOTE}}};
|
||||
x := call rowdefinition_dataobj.SetString with
|
||||
"DataType", rowDefinition_obj[cc].DataType as {{{SINGLE-QUOTE}}}String{{{SINGLE-QUOTE}}};
|
||||
x := call rowdefinition_dataobj.SetString with
|
||||
"DisplayFormat", rowDefinition_obj[cc].DisplayFormat as {{{SINGLE-QUOTE}}}String{{{SINGLE-QUOTE}}};
|
||||
x := call rowdefinition_dataobj.SetDouble with
|
||||
"WidthDefaultPixel", rowDefinition_obj[cc].WidthDefaultPixel as {{{SINGLE-QUOTE}}}Int32{{{SINGLE-QUOTE}}};
|
||||
x := call rowdefinition_dataobj.SetDouble with
|
||||
"WidthMinPixel", rowDefinition_obj[cc].WidthMinPixel as {{{SINGLE-QUOTE}}}Double{{{SINGLE-QUOTE}}};
|
||||
x := call rowdefinition_dataobj.SetDouble with
|
||||
"WidthMaxPixel", rowDefinition_obj[cc].WidthMaxPixel as {{{SINGLE-QUOTE}}}Double{{{SINGLE-QUOTE}}};
|
||||
x := call rowdefinition_dataobj.SetBoolean with
|
||||
"IsVisible", rowDefinition_obj[cc].IsVisible as {{{SINGLE-QUOTE}}}Boolean{{{SINGLE-QUOTE}}};
|
||||
x := call rowdefinition_dataobj.SetBoolean with
|
||||
"IsSortable", rowDefinition_obj[cc].IsSortable as {{{SINGLE-QUOTE}}}Boolean{{{SINGLE-QUOTE}}};
|
||||
enddo;
|
||||
|
||||
// Create a row definition schema based on the parent definition
|
||||
rowDefinition := new net_object {{{SINGLE-QUOTE}}}DataObjectDefinition{{{SINGLE-QUOTE}}};
|
||||
for CC in colCounter do
|
||||
|
||||
x := call rowDefinition.AddColumn with
|
||||
rowDefinition_obj[cc].FieldName as {{{SINGLE-QUOTE}}}String{{{SINGLE-QUOTE}}}, "CDSString" as {{{SINGLE-QUOTE}}}CDSType{{{SINGLE-QUOTE}}};
|
||||
|
||||
enddo;
|
||||
x := call {{{SINGLE-QUOTE}}}CDSDataObject{{{SINGLE-QUOTE}}}.DeclareObjectSchema with
|
||||
"RowDefinitionType", rowDefinition;
|
||||
|
||||
rows_dataobj := call {{{SINGLE-QUOTE}}}CDSDataObject{{{SINGLE-QUOTE}}}.CreateObject with "RowDefinitionType";
|
||||
|
||||
// Take the data in the arden Object and populate the CDSDataObject
|
||||
rowCounter := 1 seqto (count rows_obj);
|
||||
for rr in rowCounter do
|
||||
x := call rows_dataobj.AppendEmptyRow;
|
||||
for cc in colCounter do
|
||||
columnName := rowDefinition_obj[cc].FieldName as {{{SINGLE-QUOTE}}}String{{{SINGLE-QUOTE}}};
|
||||
|
||||
if rowDefinition_obj[cc].DataType = "DateTime" then
|
||||
columnValue := (attribute rowDefinition_obj[cc].FieldName from
|
||||
rows_obj[rr]) as {{{SINGLE-QUOTE}}}DateTime{{{SINGLE-QUOTE}}};
|
||||
x := call rows_dataobj.SetDate with ColumnName, ColumnValue;
|
||||
else
|
||||
// Can default string for all other types since it can be cast easily
|
||||
columnValue := (attribute rowDefinition_obj[cc].FieldName from
|
||||
rows_obj[rr]) as {{{SINGLE-QUOTE}}}String{{{SINGLE-QUOTE}}};
|
||||
x := call rows_dataobj.SetString with ColumnName, ColumnValue;
|
||||
endif;
|
||||
|
||||
enddo;
|
||||
enddo;
|
||||
|
||||
// Reset to the start of the collection
|
||||
rowdefinition_dataobj.ActiveRowPosition := 1;
|
||||
rows_dataobj.ActiveRowPosition := 1;
|
||||
|
||||
conclude true;
|
||||
|
||||
;;
|
||||
action:
|
||||
|
||||
return rowdefinition_dataobj, rows_dataobj;
|
||||
|
||||
|
||||
;;
|
||||
Urgency: 50;;
|
||||
end:
|
||||
@@ -0,0 +1,247 @@
|
||||
maintenance:
|
||||
|
||||
title: Community Data Retrieval Rules;;
|
||||
mlmname: STD_FUNC_COMMUNITY_DATA_RETRIEVAL_RULES;;
|
||||
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: This MLM centralizes the business rules to prevent over-alerting about
|
||||
certain community data by using trigger names and rights to determine
|
||||
if the calling MLM should continue to check for potential issues and
|
||||
if the MLM should skip the database retrieval of certain community data.
|
||||
|
||||
This functional MLM is called by other MLMs that generate alerts,
|
||||
and it returns data indicating whether the calling MLM should:
|
||||
(1) continue performing the alert checking
|
||||
(2) retrieve the specified community data
|
||||
;;
|
||||
explanation:
|
||||
The arguments passed into the MLM are:
|
||||
* evoking_object - the EvokingObject
|
||||
* trigger_name - the trigger name
|
||||
* mlm_name - the name of the MLM that was triggered
|
||||
* community_data_excluded_triggers_list - the list of trigger names to exclude
|
||||
from community data retrieval. Trigger names should be listed as strings.
|
||||
|
||||
The data returned by the MLM are:
|
||||
* can_perform - Boolean.
|
||||
Indicates if calling MLM should continue the alert checking.
|
||||
* can_retrieve_data_obj - an object with the following:
|
||||
.PendingImportedAllergies - Boolean.
|
||||
Indicates if PENDING Imported Allergies should be retrieved
|
||||
from the database.
|
||||
.PendingImportedMedications - Boolean.
|
||||
Indicates if PENDING Imported Medications should be
|
||||
retrieved from the database.
|
||||
.UnreconciledImportedHealthIssues - Boolean.
|
||||
Indicates if UNRECONCILED Imported Health Issues should be
|
||||
retrieved from the database.
|
||||
.ImportedResults - Boolean.
|
||||
Indicates if Imported Results should be retrieved from
|
||||
the database.
|
||||
|
||||
|
||||
In order to avoid over-alerting enterprise-wide, if the MLM is evoked at a trigger
|
||||
which is listed the community_data_excluded_triggers_list
|
||||
then the data in the can_retrieve_data_obj will be set to false so that
|
||||
pending or unreconciled community data are not retrieved by the calling MLM.
|
||||
|
||||
In order to avoid over-alerting for specific users, if the user has an override right
|
||||
for a specific MLM, that MLM will not alert about potential problems with
|
||||
pending or unreconciled community data. These rights are:
|
||||
* NoAlert-Allergy MLM for ImportedAllergies
|
||||
* NoAlert-Allergy MLM for ImportedMeds
|
||||
* NoAlert-DrugDiag MLM for ImportedMeds
|
||||
* NoAlert-DrugDiag MLM for ImportedProblems
|
||||
* NoAlert-DrugIntx MLM for ImportedMeds
|
||||
* NoAlert-DupMedTh MLM for ImportedMeds
|
||||
* NoAlert-PregLact MLM for ImportedMeds
|
||||
* NoAlert-LabDrug MLM for CommunityResults
|
||||
* NoAlert-DupLab MLM for CommunityResults
|
||||
|
||||
|
||||
Specific rules for User Rights:
|
||||
- When the Evoking Object is for a Pending Community Allergy or Unreconciled Community
|
||||
Health Issue:
|
||||
. The can_perform_check flag is FALSE, when the user has the
|
||||
override right that corresponds to the MLM and Trigger
|
||||
Example1: "NoAlert-Allergy MLM for ImportedAllergies" right is PRESENT
|
||||
for the STD_Allergy MLM with an AllergyDeclaration Evoking Object
|
||||
and a Pending status at the AllergyImport Trigger
|
||||
Example2: "NoAlert-DrugDiag MLM for ImportedProblems" right is PRESENT
|
||||
for the STD_Drug-Diagnosis_Conflict MLM with a Health Issue Evoking Object
|
||||
and an Unreconciled status at the HealthIssueImport trigger.
|
||||
|
||||
. The can_perform_check flag is TRUE, when the user does NOT have the
|
||||
override right that corresponds to the MLM and Trigger:
|
||||
Example1: "NoAlert-Allergy MLM for ImportedAllergies" right is ABSENT
|
||||
for the STD_Allergy MLM with an AllergyDeclaration Evoking Object
|
||||
and a Pending status at the AllergyImport trigger.
|
||||
Example2: "NoAlert-DrugDiag MLM for ImportedProblems" right is ABSENT
|
||||
for the STD_Drug-Diagnosis_Conflict MLM with an Health Issue Evoking Object
|
||||
and an Unreconciled status at the HealthIssueImport trigger.
|
||||
|
||||
. The MLM will not check pending or unreconciled community data against one another.
|
||||
So the can_retrieve_data object will be FALSE for all the community data flags
|
||||
that at the Import Triggers.
|
||||
|
||||
- When the Evoking Object is NOT for a Pending Community Allergy or Unreconciled Community
|
||||
Health Issue:
|
||||
. The can_perform_check flag will always be TRUE, so alert checking
|
||||
will always occur.
|
||||
|
||||
. The flags settings within the can_retrieve_data object depend on whether
|
||||
the user has the override right for the MLM that is calling this funtional MLM.
|
||||
Example1: PendingImportedAllergies is TRUE
|
||||
when the "NoAlert-Allergy MLM for ImportedAllergies" right
|
||||
is ABSENT for the Allergy MLM.
|
||||
Example2: PendingImportedAllergies is FALSE
|
||||
when the "NoAlert-Allergy MLM for ImportedAllergies" right
|
||||
is PRESENT for the Allergy MLM
|
||||
Example3: PendingImportedMedications is TRUE
|
||||
when the "NoAlert-DrugIntx MLM for ImportedMeds" right
|
||||
is ABSENT for the Drug Interaction MLM.
|
||||
Example4: PendingImportedMedications is FALSE
|
||||
when the "NoAlert-DrugIntx MLM for ImportedMeds" right
|
||||
is PRESENT for the Drug Interaction MLM.
|
||||
Example5: UnreconciledImportedHealthIssues is TRUE
|
||||
when the "NoAlert-DrugDiag MLM for ImportedProblems" right
|
||||
is ABSENT for the Drug Diagnosis MLM.
|
||||
Example6: UnreconciledImportedHealthIssues is FALSE
|
||||
when the "NoAlert-DrugDiag MLM for ImportedProblems" right
|
||||
is PRESENT for the Drug Diagnosis MLM
|
||||
|
||||
;;
|
||||
keywords:
|
||||
Fused Agent;
|
||||
Community Data;
|
||||
Pending Allergy Data;
|
||||
Pending Medication Data;
|
||||
Unreconciled Health Issue Data;
|
||||
dbMotion Data;
|
||||
;;
|
||||
citations:
|
||||
;;
|
||||
knowledge:
|
||||
type: data-driven;;
|
||||
data:
|
||||
|
||||
// Set to true if logging is needed.
|
||||
log_execution_info := false;
|
||||
|
||||
(
|
||||
evoking_object,
|
||||
trigger_name,
|
||||
mlm_name,
|
||||
community_data_excluded_triggers_list
|
||||
) := argument;
|
||||
|
||||
|
||||
//get user rights
|
||||
using "Sunrise.Clinicals.CommunityData.Helper";
|
||||
using namespace "Sunrise.Clinicals.CommunityData.Helper";
|
||||
HasNoAlertAllergyImportedAllergiesRight := {{{SINGLE-QUOTE}}}UserRights{{{SINGLE-QUOTE}}}.HasNoAlertAllergyImportedAllergiesRight;
|
||||
HasNoAlertAllergyImportedMedsRight := {{{SINGLE-QUOTE}}}UserRights{{{SINGLE-QUOTE}}}.HasNoAlertAllergyImportedMedsRight;
|
||||
HasNoAlertDrugDiagImportedMedsRight := {{{SINGLE-QUOTE}}}UserRights{{{SINGLE-QUOTE}}}.HasNoAlertDrugDiagImportedMedsRight;
|
||||
HasNoAlertDrugDiagImportedProblemsRight := {{{SINGLE-QUOTE}}}UserRights{{{SINGLE-QUOTE}}}.HasNoAlertDrugDiagImportedProblemsRight;
|
||||
HasNoAlertDrugIntxImportedMedsRight := {{{SINGLE-QUOTE}}}UserRights{{{SINGLE-QUOTE}}}.HasNoAlertDrugIntxImportedMedsRight;
|
||||
HasNoAlertDupMedThImportedMedsRight := {{{SINGLE-QUOTE}}}UserRights{{{SINGLE-QUOTE}}}.HasNoAlertDupMedThImportedMedsRight;
|
||||
HasNoAlertPregLactImportedMedsRight := {{{SINGLE-QUOTE}}}UserRights{{{SINGLE-QUOTE}}}.HasNoAlertPregLactImportedMedsRight;
|
||||
HasNoAlertLabDrugForCommunityResultsRight := {{{SINGLE-QUOTE}}}UserRights{{{SINGLE-QUOTE}}}.HasNoAlertLabDrugCommunityResultsRight;
|
||||
HasNoAlertDupLabCommunityResultsRight := {{{SINGLE-QUOTE}}}UserRights{{{SINGLE-QUOTE}}}.HasNoAlertDupLabCommunityResultsRight;
|
||||
|
||||
CommunityDataStruct := object [ CallingMlmName, ObjectType, UserOverrideRight];
|
||||
rule_list := (
|
||||
// mlm, type, right for the mlm and type
|
||||
(new CommunityDataStruct with "STD_Allergy", "AllergyDeclaration", HasNoAlertAllergyImportedAllergiesRight),
|
||||
(new CommunityDataStruct with "STD_Allergy", "Medication", HasNoAlertAllergyImportedMedsRight),
|
||||
(new CommunityDataStruct with "STD_DRUG_DIAGNOSIS_CONFLICT", "Medication", HasNoAlertDrugDiagImportedMedsRight),
|
||||
(new CommunityDataStruct with "STD_DRUG_DIAGNOSIS_CONFLICT", "HealthIssueDeclaration", HasNoAlertDrugDiagImportedProblemsRight),
|
||||
(new CommunityDataStruct with "STD_DRUG_INTERACTION", "Medication", HasNoAlertDrugIntxImportedMedsRight),
|
||||
(new CommunityDataStruct with "STD_DUPLICATE_MEDICATION_THERAPY", "Medication", HasNoAlertDupMedThImportedMedsRight),
|
||||
(new CommunityDataStruct with "STD_PREGNANCY_AND_LACTATION", "Medication", HasNoAlertPregLactImportedMedsRight),
|
||||
(new CommunityDataStruct with "STD_MAIN_LAB_DRUG_INTERACTIONS", "Medication", HasNoAlertLabDrugForCommunityResultsRight),
|
||||
(new CommunityDataStruct with "STD_DUPLICATE", "Medication", HasNoAlertDupLabCommunityResultsRight)
|
||||
);
|
||||
|
||||
can_perform := false;
|
||||
is_community_data := false;
|
||||
|
||||
if evoking_object is AllergyDeclaration then evoking_object_type := "AllergyDeclaration";
|
||||
elseif evoking_object is HealthIssueDeclaration then evoking_object_type := "HealthIssueDeclaration";
|
||||
elseif evoking_object is ClientPrescription then evoking_object_type := "Medication";
|
||||
elseif evoking_object is Order then evoking_object_type := "Medication";
|
||||
else evoking_object_type := "Other";
|
||||
endif;
|
||||
|
||||
if ( ( evoking_object is AllergyDeclaration AND evoking_object.status = "Pending" )
|
||||
or ( evoking_object is HealthIssueDeclaration AND evoking_object.InternalStateType = 1 ) // internalStateType = 1 for unreconciled
|
||||
)
|
||||
then
|
||||
is_community_data := true;
|
||||
endif;
|
||||
|
||||
RightTypes := object [PendingImportedAllergies, PendingImportedMedications, UnreconciledImportedHealthIssues, ImportedResults];
|
||||
can_retrieve_data_obj := new RightTypes;
|
||||
is_trigger_excluded := trigger_name in community_data_excluded_triggers_list;
|
||||
mlm_rule_list := rule_list where rule_list.CallingMlmName = mlm_name;
|
||||
|
||||
if is_community_data
|
||||
then
|
||||
// If evoking object is community data, the calling mlm can perform community data checking if the override right does not exist
|
||||
override_right_exists := last (mlm_rule_list.UserOverrideRight where mlm_rule_list.ObjectType = evoking_object_type);
|
||||
can_perform := not (override_right_exists or is_trigger_excluded);
|
||||
|
||||
// If evoking object is community data, the business rule says never perform checking community data against community data.
|
||||
// Can retrieve is always false.
|
||||
can_retrieve_data_obj := new RightTypes with (false, false, false);
|
||||
else
|
||||
// if not community data
|
||||
can_perform := true;
|
||||
|
||||
if is_trigger_excluded
|
||||
then
|
||||
can_retrieve_data_obj := new RightTypes with (false, false, false);
|
||||
else
|
||||
can_retrieve_data_obj.PendingImportedAllergies := last(not mlm_rule_list.UserOverrideRight where mlm_rule_list.ObjectType = "AllergyDeclaration");
|
||||
can_retrieve_data_obj.PendingImportedMedications := last(not mlm_rule_list.UserOverrideRight where mlm_rule_list.ObjectType = "Medication") ;
|
||||
can_retrieve_data_obj.UnreconciledImportedHealthIssues := last(not mlm_rule_list.UserOverrideRight where mlm_rule_list.ObjectType = "HealthIssueDeclaration") ;
|
||||
can_retrieve_data_obj.ImportedResults := last(not mlm_rule_list.UserOverrideRight where mlm_rule_list.ObjectType = "Medication") ;
|
||||
endif;
|
||||
endif;
|
||||
|
||||
;;
|
||||
priority: 50
|
||||
;;
|
||||
evoke:
|
||||
;;
|
||||
logic:
|
||||
|
||||
conclude true;
|
||||
;;
|
||||
action:
|
||||
return (can_perform, can_retrieve_data_obj );
|
||||
;;
|
||||
Urgency: 50;;
|
||||
end:
|
||||
@@ -0,0 +1,125 @@
|
||||
maintenance:
|
||||
|
||||
title: Create An Action Object;;
|
||||
mlmname: STD_FUNC_CREATE_ALERT_ACTION_OBJECT;;
|
||||
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: This MLM declares the AlertAction Object, creates a single instance
|
||||
of the object, and partially populates it with data.
|
||||
;;
|
||||
explanation: This MLM is called by any MLM that wants an AlertAction Object created.
|
||||
1. It sets the values for the fields that repeat in every object.
|
||||
2. The two arguments are used to determine if the AlertAction object
|
||||
is for an Order. If it is, certain data are defaulted.
|
||||
3. It sets the remaining fields to NULL.
|
||||
;;
|
||||
keywords:
|
||||
;;
|
||||
knowledge:
|
||||
type: data-driven;;
|
||||
data:
|
||||
|
||||
/***************Make Changes To Spelling And Flags In This Section***************/
|
||||
/* Set to true if logging is needed.*/
|
||||
log_execution_info := false;
|
||||
|
||||
/********************************************************************************/
|
||||
|
||||
|
||||
// Arguments
|
||||
(evoking_object_table, //STRING--Name of Evoking Object{{{SINGLE-QUOTE}}}s table
|
||||
action_item_table ) //STRING--Name of Action Item{{{SINGLE-QUOTE}}}s table
|
||||
:= ARGUMENT;
|
||||
|
||||
|
||||
//Declare the AlertAction Object
|
||||
AlertAction := OBJECT [
|
||||
EvokingEnterpriseItemTable,
|
||||
EvokingEnterpriseItemID,
|
||||
EvokingObjectTable,
|
||||
EvokingObjectID,
|
||||
EvokingObjectName,
|
||||
HighLevelDecision,
|
||||
ActionItemStatus,
|
||||
ActionEvent,
|
||||
ActionItemTable,
|
||||
ActionItemID,
|
||||
ActionItemName,
|
||||
ActionEnterpriseItemTable,
|
||||
ActionEnterpriseItemID,
|
||||
MLMName,
|
||||
ShortMessage ];
|
||||
|
||||
|
||||
// Create on instance of the AlertAction object.
|
||||
instance := new AlertAction;
|
||||
|
||||
|
||||
// Set the value of the HighLevelDecision field.
|
||||
// This field is always "Keep".
|
||||
instance.HighLevelDecision := "Keep";
|
||||
|
||||
|
||||
// Partiallly populate one instance of the AlertAction Object
|
||||
// in the Evoking and HighLevelDecision fields of the object.
|
||||
// Also, instantiate the unpopulated fields to NULL.
|
||||
if evoking_object_table = "CV3Order"
|
||||
then
|
||||
instance.EvokingEnterpriseItemTable := "CV3OrderCatalogMasterItem";
|
||||
instance.EvokingEnterpriseItemID := null;
|
||||
instance.EvokingObjectTable := evoking_object_table;
|
||||
instance.EvokingObjectID := null;
|
||||
instance.EvokingObjectName := null;
|
||||
endif; //if evoking_object_table
|
||||
|
||||
|
||||
// Partiallly populate one instance of the AlertAction Object
|
||||
// in the ActionItem fields of the object.
|
||||
// Also instantiate the unpopulated fields to NULL.
|
||||
if action_item_table = "CV3Order"
|
||||
OR action_item_table = "CV3OrderCatalogItem"
|
||||
then
|
||||
instance.ActionItemStatus := null;
|
||||
instance.ActionEvent := null;
|
||||
instance.ActionItemTable := action_item_table;
|
||||
instance.ActionItemID := null;
|
||||
instance.ActionItemName := null;
|
||||
instance.ActionEnterpriseItemTable := "CV3OrderCatalogMasterItem";
|
||||
instance.ActionEnterpriseItemID := null;
|
||||
instance.MLMName := null;
|
||||
instance.ShortMessage := null;
|
||||
|
||||
endif; //if action_item_table
|
||||
|
||||
;;
|
||||
evoke: //MLM is called, not evoked
|
||||
;;
|
||||
logic:
|
||||
conclude true;
|
||||
;;
|
||||
action:
|
||||
return instance;
|
||||
;;
|
||||
end:
|
||||
90
MLMStripper/bin/Debug/STD/STD_FUNC_DOC_REPLACE_CHAR.mlm
Normal file
90
MLMStripper/bin/Debug/STD/STD_FUNC_DOC_REPLACE_CHAR.mlm
Normal file
@@ -0,0 +1,90 @@
|
||||
maintenance:
|
||||
|
||||
title: STD_FUNC_DOC_REPLACE_CHAR;;
|
||||
mlmname: STD_FUNC_DOC_REPLACE_CHAR;;
|
||||
arden: version 2.5;;
|
||||
version: 18.4;;
|
||||
institution: Allscripts,Standard Document called 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: this function takes 3 parameters, it searches all occurences of the str
|
||||
in second parameter, and replaces them with str in third parameter
|
||||
;;
|
||||
explanation: Called by DOC_STD_HOME_MED_SUMMARY.MLM.
|
||||
|
||||
;;
|
||||
keywords:
|
||||
;;
|
||||
knowledge:
|
||||
type: data-driven;;
|
||||
data:
|
||||
(Str, ToBeRepld, insertStr) := argument;
|
||||
|
||||
/* Set to true if a decision.log is needed */
|
||||
log_execution_info := false;
|
||||
|
||||
// default to " ", if not passed
|
||||
if (not exists insertStr) then
|
||||
insertStr := " ";
|
||||
endif;
|
||||
|
||||
if (called_by_editor) then
|
||||
Str:= "This is a\ntest string to be\npassed";
|
||||
ToBeRepld:="\n";
|
||||
insertStr:=" ";
|
||||
endif;
|
||||
|
||||
tmpStr:="";
|
||||
strLen:=LENGTH OF Str;
|
||||
if (exists Str and strLen > 0) then
|
||||
// do some replacement
|
||||
prepos:=1;
|
||||
pos:= FIND ToBeRepld IN STRING Str STARTING AT prepos;
|
||||
|
||||
|
||||
while pos > 0 and prepos < strLen do
|
||||
tmp:=SUBSTRING pos-prepos CHARACTERS STARTING AT prepos FROM Str;
|
||||
tmpStr:=tmpStr || tmp || insertStr;
|
||||
prepos:=pos +1;
|
||||
|
||||
// find
|
||||
pos:= FIND ToBeRepld IN STRING Str STARTING AT prepos;
|
||||
enddo;
|
||||
tmp:=SUBSTRING strLen-prepos+1 CHARACTERS STARTING AT prepos FROM Str;
|
||||
tmpStr:=tmpStr || tmp;
|
||||
endif;
|
||||
/* Set to true if a decision.log is needed.*/
|
||||
log_execution_info := false;
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
;;
|
||||
evoke:
|
||||
;;
|
||||
logic:
|
||||
conclude true;
|
||||
;;
|
||||
action:
|
||||
return tmpStr;
|
||||
;;
|
||||
Urgency: 50;;
|
||||
end:
|
||||
179
MLMStripper/bin/Debug/STD/STD_FUNC_DOC_WRITE_TO_DOCUMENT.mlm
Normal file
179
MLMStripper/bin/Debug/STD/STD_FUNC_DOC_WRITE_TO_DOCUMENT.mlm
Normal file
@@ -0,0 +1,179 @@
|
||||
maintenance:
|
||||
|
||||
title: Starter MLM to Create Documents;;
|
||||
mlmname: STD_FUNC_DOC_WRITE_TO_DOCUMENT;;
|
||||
arden: version 2.5;;
|
||||
version: 18.4;;
|
||||
institution: Allscripts,Standard Document Called 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: This MLM identifies the current observation in a Structured Document
|
||||
instantiates the parameter.
|
||||
;;
|
||||
explanation: This is a basic starter MLM for all document MLMs.
|
||||
|
||||
;;
|
||||
keywords: RTF; Document Called MLM; list; multi-select
|
||||
;;
|
||||
knowledge:
|
||||
type: data-driven;;
|
||||
data:
|
||||
(this_documentCommunication,parameter_name,newValue,sugg_txt_value,UpdateType) :=
|
||||
argument;
|
||||
/***************Make Changes To Spelling And Flags In This Section************/
|
||||
|
||||
/* Set to true if a decision.log is needed.*/
|
||||
log_execution_info := false;
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
//*** Variable and Constant Declaration ***//
|
||||
|
||||
(this_structuredNoteDoc) := this_documentCommunication.DocumentConfigurationObj;
|
||||
(this_parameters) := this_structuredNoteDoc.ParametersList;
|
||||
(this_chartedObservationsList) := this_structuredNoteDoc.ChartedObservationsList;
|
||||
|
||||
// if the parameter type is a text and the observation already exist the new data may
|
||||
// be a Replace of Append to current valueObj.Value
|
||||
if not exists UpdateType OR UpdateType NOT IN("Append","Replace") then
|
||||
UpdateType := "Replace";
|
||||
endif;
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////
|
||||
//*** Data Structures ***//
|
||||
// The following data structures can be used to create new objects within the MLM
|
||||
// itself. Not all data structures are represented here, only ones that can be
|
||||
// created in the MLM. Parameter Types
|
||||
NUMERICVALUE := "NumericValue";
|
||||
FREETEXTVALUE := "FreeTextValue";
|
||||
LISTVALUE := "ListValue";
|
||||
LISTSETVALUE := "ListSetValue";
|
||||
DATEVALUE := "DateValue";
|
||||
IOVALUE := "IOValue" ;
|
||||
GENERICDRIPVALUE := "GenericDripValue" ;
|
||||
DRIPVALUE := "DripValue" ;
|
||||
|
||||
ObservationType := OBJECT
|
||||
[ObservationGUID, ClientDocumentGUID, ParameterGUID, DataType, ValueObj];
|
||||
ListValueType := OBJECT [ListGUID,ListItemsList, SuggestedTextValue];
|
||||
ListValueListItemType := OBJECT [ListItemGUID, Value, IsSelected];
|
||||
DateValueType := OBJECT [Value];
|
||||
FreeTextValueType := OBJECT [Value];
|
||||
NumericValueType := OBJECT [Value];
|
||||
//
|
||||
// This section of code will demonstrate how to write to FreeTextValue, DateValue,
|
||||
// NumericValue and ListValue
|
||||
parameter := FIRST OF (this_Parameters WHERE this_Parameters.Name = parameter_name );
|
||||
|
||||
IF EXISTS parameter THEN
|
||||
//****************************************************************************
|
||||
// Check for existing object
|
||||
//****************************************************************************
|
||||
obs := first of(this_ChartedObservationsList WHERE
|
||||
this_ChartedObservationsList.parameterGUID = parameter.parameterGUID) ;
|
||||
if not exist obs then
|
||||
//Create a new Observation for the list
|
||||
obs := NEW ObservationType;
|
||||
obs.ClientDocumentGUID :=
|
||||
this_documentCommunication.DocumentConfigurationObj.ClientDocumentGUID;
|
||||
obs.ParameterGUID := parameter.ParameterGUID;
|
||||
obs.DataType := parameter.DataType;
|
||||
// Based on the parameter.DataType create the ValueObj Type and set
|
||||
// the valueObj.value for
|
||||
// (FREETEXTVALUETYPE,DATEVALUETYPE,NUMERICVALUETYPE)
|
||||
// If the DataType is LISTVALUE then creat the valueObj
|
||||
// of LISTVALUETYPE ABD ASSIGN
|
||||
// THE paramter.configurationObj.ListGUID
|
||||
if parameter.DataType = FREETEXTVALUE then
|
||||
obs.ValueObj := NEW FreeTextValueType ;
|
||||
elseif parameter.DataType = DATEVALUE then
|
||||
obs.ValueObj := NEW DateValueType ;
|
||||
elseif parameter.DataType = NUMERICVALUE then
|
||||
obs.ValueObj := NEW NumericValueType ;
|
||||
elseif parameter.DataType = LISTVALUE then
|
||||
obs.ValueObj := NEW ListValueType;
|
||||
obs.ValueObj.ListGUID := parameter.ConfigurationObj.ListGUID;
|
||||
endif; // if parameter.DataType = FREETEXTVALUE then
|
||||
// APPEND obs to the ChartedObservationsList
|
||||
this_documentCommunication.DocumentConfigurationObj.ChartedObservationsList := (
|
||||
this_documentCommunication.DocumentConfigurationObj.ChartedObservationsList,
|
||||
obs);
|
||||
endif;
|
||||
|
||||
if parameter.DataType = FREETEXTVALUE then
|
||||
if UpdateType = "Append" then
|
||||
if length of obs.ValueObj.Value > 0 then
|
||||
obs.ValueObj.Value := obs.ValueObj.Value || "\n" || newValue ;
|
||||
else
|
||||
obs.ValueObj.Value := newValue;
|
||||
endif;
|
||||
else // UpdateType = "Replace"
|
||||
obs.ValueObj.Value := newValue;
|
||||
endif;
|
||||
elseif parameter.DataType IN(DATEVALUE,NUMERICVALUE) then
|
||||
if exists newValue then
|
||||
obs.ValueObj.Value := newValue ;
|
||||
else
|
||||
obs.ValueObj := null;
|
||||
endif;
|
||||
elseif parameter.DataType = LISTVALUE then
|
||||
|
||||
// Populate the ListItemsList in the new observation object (obs)
|
||||
// loop through each item in the parameter.ConfugurationObj.ListItemsList using
|
||||
// "item"and append the item to the newly created object ListValueListItemType
|
||||
// assign the item.listItemGUID to the selectedItem.ListItemGUID,
|
||||
// the Item.value to the
|
||||
// selectedItem.Value and set the SelectedItem.IsSelected := true
|
||||
listItems := ();
|
||||
FOR item IN parameter.ConfigurationObj.ListItemsList DO
|
||||
IF item.Value IN newValue THEN
|
||||
//Create a list item object for the selected list item
|
||||
selectedItem := NEW ListValueListItemType;
|
||||
selectedItem.ListItemGUID := item.ListItemGUID;
|
||||
selectedItem.Value := item.Value;
|
||||
selectedItem.IsSelected := true;
|
||||
// Arden list append statement appending the new object to the listItems object
|
||||
// of the ListValueListItemType Object
|
||||
listItems := (listItems, selectedItem);
|
||||
ENDIF;
|
||||
// set the obs.valueObj.ListItemsList := listItems list object
|
||||
Obs.ValueObj.ListItemsList := listItems;
|
||||
if exists sugg_txt_value then
|
||||
obs.ValueObj.SuggestedTextValue := sugg_txt_value ;
|
||||
endif ;
|
||||
ENDDO;
|
||||
endif; //if parameter.DataType = LISTVALUE then
|
||||
ENDIF; //IF EXISTS parameter THEN
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
;;
|
||||
evoke:
|
||||
;;
|
||||
logic:
|
||||
conclude true;
|
||||
;;
|
||||
action:
|
||||
return this_documentCommunication;
|
||||
;;
|
||||
Urgency: 50;;
|
||||
end:
|
||||
550
MLMStripper/bin/Debug/STD/STD_FUNC_DOSAGE_ADMIN_TIMES.mlm
Normal file
550
MLMStripper/bin/Debug/STD/STD_FUNC_DOSAGE_ADMIN_TIMES.mlm
Normal file
@@ -0,0 +1,550 @@
|
||||
maintenance:
|
||||
|
||||
title: : Creates the Estimated Dose Administrations;;
|
||||
mlmname: STD_FUNC_DOSAGE_ADMIN_TIMES;;
|
||||
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: The purpose of this MLM is to create the estimated Dose Administration Date-Times
|
||||
for Frequencies such as BID, Q18H, <Variable Interval>, <User Schedule>, etc.
|
||||
;;
|
||||
explanation: Using the data that is passed into the MLM, plus the Frequency dictionary and
|
||||
the Units of Measure dictionary, the ESTIMATED Dose Administrations date-times are
|
||||
created, put into a list, and then returned to the calling MLM.
|
||||
;;
|
||||
keywords: single dose; average daily dose; total daily dose; dosage range
|
||||
;;
|
||||
knowledge:
|
||||
type: data-driven;;
|
||||
data:
|
||||
|
||||
(order_med_frequency,
|
||||
start_dtm,
|
||||
stop_dtm,
|
||||
stop_after_value,
|
||||
stop_after_option_type,
|
||||
freq_from_time,
|
||||
from_uom,
|
||||
order_TaskScheduleDefinition_obj ):= ARGUMENT;
|
||||
|
||||
|
||||
// Set to true if logging is needed.
|
||||
log_execution_info := false;
|
||||
|
||||
|
||||
// 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";
|
||||
ounce_string := "oz";
|
||||
second_string := "s";
|
||||
week_string := "week";
|
||||
year_string := "year";
|
||||
shift_string := "shift";
|
||||
|
||||
// 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*)};
|
||||
|
||||
|
||||
// Declare Task_Schedule_Definition_Object
|
||||
Task_Schedule_Definition_Object := OBJECT
|
||||
[ scheduled_dtm, scheduled_time, day_of_week, parent_GUID, scheduled_duration ];
|
||||
|
||||
|
||||
//================================================================
|
||||
// <User Schedule> FREQUENCY
|
||||
//================================================================
|
||||
if order_med_frequency = "<User Schedule>"
|
||||
then
|
||||
//Task_Schedule_Definition_Object := OBJECT
|
||||
//[ scheduled_dtm, scheduled_time, day_of_week, parent_GUID, scheduled_duration ];
|
||||
|
||||
task_schedule_definition_list := read AS Task_Schedule_Definition_Object
|
||||
{ TaskScheduleDefinition: ScheduledDtm, ScheduledTime, DayOfWeek, ParentGUID
|
||||
REFERENCING order_TaskScheduleDefinition_obj };
|
||||
|
||||
|
||||
//================================================================
|
||||
// <Variable Interval> FREQUENCY
|
||||
//================================================================
|
||||
elseif order_med_frequency = "<Variable Interval>"
|
||||
then
|
||||
frequency_type := 3;
|
||||
time_from_value := freq_from_time as number;
|
||||
|
||||
time_core_uom := read last
|
||||
{"SELECT CoreUOM "
|
||||
|| " FROM CV3UnitOfMeasure"
|
||||
|| " WHERE Code = " || SQL (from_uom)
|
||||
|| " AND Active = 1 " };
|
||||
|
||||
|
||||
//================================================================
|
||||
// REGULAR FREQUENCY
|
||||
//================================================================
|
||||
else
|
||||
// Gets the Frequency information from the Enterprise data
|
||||
// Only gets the Active Frequencies and Active Units of Measures
|
||||
(
|
||||
frequency_type,
|
||||
time_from_value,
|
||||
time_core_uom):= read last
|
||||
{"SELECT f.DefinitionType, f.TimeFromValue, 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 (order_med_frequency)
|
||||
|| " AND f.Active = 1 " };
|
||||
endif; // if order_med_frequency
|
||||
;;
|
||||
evoke:
|
||||
;;
|
||||
logic:
|
||||
|
||||
// If the frequency is shift based then do not
|
||||
// do any calculations. Return an empty list
|
||||
// of admin times.
|
||||
if time_core_uom = shift_string
|
||||
then
|
||||
isShiftFrequency := true;
|
||||
next_startDtm := start_dtm + 24 hours;
|
||||
conclude true;
|
||||
endif;
|
||||
isShiftFrequency := false;
|
||||
|
||||
//==================================================================================
|
||||
// <User Schedule> Frequency
|
||||
//==================================================================================
|
||||
if order_med_frequency = "<User Schedule>"
|
||||
then
|
||||
//---------------------------------
|
||||
// Set Begin_DTM
|
||||
//---------------------------------
|
||||
//Calculate Begin_DTM
|
||||
begin_dtm := start_dtm;
|
||||
|
||||
|
||||
//---------------------------------
|
||||
// Calculate End_DTM
|
||||
//---------------------------------
|
||||
if stop_after_option_type = 1 //days
|
||||
then
|
||||
end_dtm := begin_dtm + stop_after_value DAYS;
|
||||
elseif stop_after_option_type = 2 //hours
|
||||
then
|
||||
end_dtm := begin_dtm + stop_after_value HOURS;
|
||||
elseif stop_after_option_type = 3 //minutes
|
||||
then
|
||||
end_dtm := begin_dtm + stop_after_value MINUTES;
|
||||
elseif stop_after_option_type = 4 //times
|
||||
then
|
||||
//end_dtm is unknown until the DTMs are generated.
|
||||
//the end_dtm will be set after the DTMs are generated.
|
||||
end_dtm := null;
|
||||
elseif exist stop_dtm
|
||||
then
|
||||
end_dtm := stop_dtm ;
|
||||
endif; //if stop_after_option_type
|
||||
|
||||
|
||||
//=============================================
|
||||
// <User Schedule> -- DAILY or WEEKLY
|
||||
//=============================================
|
||||
if from_uom is in ( "day", "week")
|
||||
then
|
||||
//----------------------------------------------
|
||||
// Convert Scheduled_Time to Scheduled_Duration
|
||||
//----------------------------------------------
|
||||
|
||||
duration_list := ();
|
||||
for task_schedule_definition in task_schedule_definition_list do
|
||||
//Convert the Number to a String
|
||||
//Extract the Characters from the String
|
||||
temp_string := (""|| task_schedule_definition.scheduled_time);
|
||||
temp_characters := extract characters temp_string;
|
||||
|
||||
//Convert the front characters to the number of hours
|
||||
//Convert the back character to the number of minutes
|
||||
if count (temp_characters) = 4
|
||||
then
|
||||
num_hours := (temp_characters[1] || temp_characters[2]) AS NUMBER ;
|
||||
num_minutes := (temp_characters[3] || temp_characters[4]) AS NUMBER ;
|
||||
elseif count (temp_characters) = 3
|
||||
then
|
||||
num_hours := (temp_characters[1]) AS NUMBER ;
|
||||
num_minutes := (temp_characters[2] || temp_characters[3]) AS NUMBER ;
|
||||
elseif count (temp_characters) = 2
|
||||
then
|
||||
num_hours := 0;
|
||||
num_minutes := (temp_characters[1] || temp_characters[2]) AS NUMBER ;
|
||||
elseif count (temp_characters) = 1
|
||||
then
|
||||
num_hours := 0 ;
|
||||
num_minutes := ("" || temp_characters[1]) AS NUMBER ;
|
||||
endif;
|
||||
|
||||
//Add the Hours and Minutes and put them in a list
|
||||
duration_list := duration_list, ( num_hours HOUR) + (num_minutes MINUTE) ;
|
||||
enddo; //for task_schedule_definition
|
||||
|
||||
//Set the Scheduled_Duration in the Task_Schedule_Definition_Object
|
||||
task_schedule_definition_list.scheduled_duration := duration_list;
|
||||
|
||||
//--------------------------------------------------------------
|
||||
// Determine how to increment "Every X Days" or "Every Y Weeks"
|
||||
//--------------------------------------------------------------
|
||||
if from_uom = "day"
|
||||
then
|
||||
increment_duration := freq_from_time DAY;
|
||||
elseif from_uom = "week"
|
||||
then
|
||||
increment_duration := freq_from_time WEEK;
|
||||
endif; //if from_uom = "day"
|
||||
|
||||
//-----------------------------------------------------
|
||||
// Generate the first set of DTMs based on the schedule
|
||||
//-----------------------------------------------------
|
||||
//task_schedule_definition_list.day_of_week values
|
||||
// 0=Sun, 1=Mon, 2=Tue, 3=Wed, 4=Thur, 5=Fri, 6=Sat
|
||||
// 7=DayOnly
|
||||
|
||||
//Initialize Variables
|
||||
midnight_begin_dtm := day floor of begin_dtm;
|
||||
original_schedule_dtm_list := ();
|
||||
|
||||
for task_schedule_definition in task_schedule_definition_list do
|
||||
|
||||
if task_schedule_definition.day_of_week < 7
|
||||
then //Figure Out Which Day of the Week to Create
|
||||
from_day_of_week := (day floor of begin_dtm - week floor of begin_dtm ) / 1 day;
|
||||
|
||||
to_day_of_week := task_schedule_definition.day_of_week;
|
||||
|
||||
if to_day_of_week >= from_day_of_week
|
||||
then //it is this week
|
||||
number_of_days := to_day_of_week - from_day_of_week ;
|
||||
else //it is next week
|
||||
number_of_days := (7 - from_day_of_week) + to_day_of_week;
|
||||
endif; //if to_day_of_week
|
||||
|
||||
temp_dtm1 := midnight_begin_dtm + (number_of_days day)
|
||||
+ task_schedule_definition.scheduled_duration ;
|
||||
else //It is not a day of the week. It is the initial day.
|
||||
temp_dtm1 := midnight_begin_dtm
|
||||
+ task_schedule_definition.scheduled_duration ;
|
||||
endif; //if task_schedule_definition.day_of_week < 7
|
||||
|
||||
//Append DTM to List
|
||||
original_schedule_dtm_list := original_schedule_dtm_list, temp_dtm1;
|
||||
enddo; //for task_schedule_definition
|
||||
|
||||
//--------------------------------------------
|
||||
// Create a Valid Set of Sorted Scheduled DTMs
|
||||
//--------------------------------------------
|
||||
original_schedule_dtm_list := Sort DATA original_schedule_dtm_list;
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
// For DAYS, move any DTMs forward when they are less than the Begin_DTM
|
||||
//-----------------------------------------------------------------------
|
||||
if from_uom = "day"
|
||||
then
|
||||
temp_past_dtm_list := original_schedule_dtm_list where it < begin_dtm;
|
||||
temp_current_dtm_list := original_schedule_dtm_list where it >= begin_dtm ;
|
||||
updated_schedule_dtm_list := temp_current_dtm_list;
|
||||
|
||||
for past_dtm in temp_past_dtm_list do
|
||||
temp_future_dtm := past_dtm + 1 day;
|
||||
updated_schedule_dtm_list := updated_schedule_dtm_list, temp_future_dtm;
|
||||
enddo;
|
||||
|
||||
//-------------------------------------------------------------------------------
|
||||
// For WEEKS, do not move any DTMs forward when they are less than the Begin_DTM
|
||||
//-------------------------------------------------------------------------------
|
||||
elseif from_uom = "week"
|
||||
then
|
||||
updated_schedule_dtm_list := original_schedule_dtm_list;
|
||||
endif; //if from_uom
|
||||
|
||||
//-----------------------------------------
|
||||
// Finish Creating all the rest of the DTM
|
||||
//-----------------------------------------
|
||||
|
||||
//Get the last DTM in the list
|
||||
new_dtm := last updated_schedule_dtm_list;
|
||||
|
||||
//Initialize Variables
|
||||
admin_dtm_list := updated_schedule_dtm_list;
|
||||
multiplier := 0;
|
||||
|
||||
if stop_after_option_type = 4 //4 = TIMES
|
||||
then //Use the TIMES to stop generating DTMs
|
||||
|
||||
admin_dtm_list := updated_schedule_dtm_list where it >= begin_dtm;
|
||||
count_of_dtm := count admin_dtm_list;
|
||||
|
||||
//If there aren{{{SINGLE-QUOTE}}}t enough DTM{{{SINGLE-QUOTE}}}s then generate more
|
||||
if stop_after_value > count_of_dtm
|
||||
then
|
||||
num_of_dtm := count_of_dtm;
|
||||
|
||||
While num_of_dtm <= stop_after_value do
|
||||
//Increment num_of_dtm
|
||||
num_of_dtm := num_of_dtm + (count of updated_schedule_dtm_list);
|
||||
|
||||
//Increment the multiplier
|
||||
multiplier := multiplier + 1;
|
||||
|
||||
//Generate new DTM by looping through the list DTMS and
|
||||
//increasing the duration of each one
|
||||
for temp_dtm2 in (updated_schedule_dtm_list) do
|
||||
new_dtm := temp_dtm2 + (increment_duration * multiplier) ;
|
||||
admin_dtm_list := admin_dtm_list, new_dtm;
|
||||
enddo; //for temp_dtm2
|
||||
enddo; //While num_of_dtm
|
||||
endif; //if stop_after_value
|
||||
|
||||
//only keep the number of DTM{{{SINGLE-QUOTE}}}s needed
|
||||
admin_dtm_list := first stop_after_value FROM admin_dtm_list;
|
||||
|
||||
//set the end_dtm
|
||||
end_dtm := last admin_dtm_list;
|
||||
|
||||
else //Use the End_Dtm to stop generating DTMs
|
||||
While new_dtm <= end_dtm do
|
||||
|
||||
//Increment the multiplier
|
||||
multiplier := multiplier + 1;
|
||||
|
||||
//Generate new DTM by looping through the list DTMS and
|
||||
//increasing the duration of each one
|
||||
for temp_dtm2 in (updated_schedule_dtm_list) do
|
||||
new_dtm := temp_dtm2 + (increment_duration * multiplier) ;
|
||||
if new_dtm <= end_dtm
|
||||
then
|
||||
admin_dtm_list := admin_dtm_list, new_dtm;
|
||||
endif; //if new_dtm
|
||||
enddo; //for temp_dtm2
|
||||
enddo; //While new_dtm
|
||||
|
||||
endif; //if stop_after_option_type = 4
|
||||
|
||||
|
||||
//=============================================
|
||||
// <User Schedule> -- IRREGULAR
|
||||
//=============================================
|
||||
else //Use the ScheduledDtm to set the Admin DTMS
|
||||
|
||||
if exist task_schedule_definition_list.scheduled_dtm
|
||||
then
|
||||
admin_dtm_list := Sort DATA task_schedule_definition_list.scheduled_dtm;
|
||||
else
|
||||
admin_dtm_list := null;
|
||||
endif; //if exist task_schedule_definition_list.scheduled_dtm;
|
||||
endif; //if from_uom
|
||||
|
||||
//---------------------------------------------------
|
||||
// Remove any dates outside of Begin_DTM and End_DTM
|
||||
//---------------------------------------------------
|
||||
admin_dtm_list := admin_dtm_list where (it >= begin_dtm and it <= end_dtm);
|
||||
|
||||
//==================================================================================
|
||||
// REGULAR OR <Variable Interval> FREQUENCY
|
||||
//==================================================================================
|
||||
else
|
||||
//------------------------------------
|
||||
// Frequency <QxH> and <QxM> Template
|
||||
//------------------------------------
|
||||
// Handle frequency templates <qxh> and <qxm> by parsing the frequency string
|
||||
// If changes are made to this code, also change them in SYS_CALC_FREQMULT_AVERAGE
|
||||
// This is a temporary workaround for frequency templates
|
||||
If NOT Exist frequency_type
|
||||
then
|
||||
|
||||
// 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 (order_med_frequency, h_delim);
|
||||
get_M:= call func_get_str with (order_med_frequency, m_delim);
|
||||
|
||||
// Remove the front Q, so xH or xM is left
|
||||
trim_Q:= call func_get_token with (order_med_frequency, 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
|
||||
time_from_value := freq_num_str as number;
|
||||
endif; // If NOT Exist frequency_type
|
||||
|
||||
|
||||
//--------------------------------
|
||||
// Convert Frequency to Durations
|
||||
//--------------------------------
|
||||
if time_core_uom = day_string then
|
||||
if frequency_type = 1 // y times per day
|
||||
then time_interval:= 1 DAY /time_from_value;
|
||||
else time_interval:= time_from_value DAY ;
|
||||
endif;
|
||||
elseif time_core_uom = hour_string then
|
||||
if frequency_type = 1 // y times per hour
|
||||
then time_interval:= 1 HOUR /time_from_value;
|
||||
else time_interval:= time_from_value HOUR ;
|
||||
endif;
|
||||
elseif time_core_uom = minute_string then
|
||||
if frequency_type = 1 // y times per minute
|
||||
then time_interval:= 1 MINUTE /time_from_value;
|
||||
else time_interval:= time_from_value MINUTE ;
|
||||
endif;
|
||||
elseif time_core_uom = second_string then
|
||||
if frequency_type = 1 // y times per second
|
||||
then time_interval:= 1 SECOND /time_from_value;
|
||||
else time_interval:= time_from_value SECOND ;
|
||||
endif;
|
||||
elseif time_core_uom = week_string then
|
||||
if frequency_type = 1 // y times per week
|
||||
then time_interval:= 1 WEEK /time_from_value;
|
||||
else time_interval:= time_from_value WEEK ;
|
||||
endif;
|
||||
elseif time_core_uom = month_string then
|
||||
if frequency_type = 1 // y times per month
|
||||
then time_interval:= 1 MONTH /time_from_value;
|
||||
else time_interval:= time_from_value MONTH ;
|
||||
endif;
|
||||
elseif time_core_uom = year_string then
|
||||
if frequency_type = 1 // y times per year
|
||||
then time_interval:= 1 YEAR /time_from_value;
|
||||
else time_interval:= time_from_value YEAR ;
|
||||
endif;
|
||||
endif; // if time_core_uom
|
||||
|
||||
|
||||
// Calculate the Number of Administrations
|
||||
// Calculation uses CEILING to round the calculation up to
|
||||
// the next whole number.
|
||||
if NOT exist order_med_frequency OR frequency_type = 0
|
||||
then
|
||||
// Assume that one dose is administered if the frequency is NULL
|
||||
// or NONE regardless of the values for StopDtm or a StopAfter.
|
||||
number_of_admins := 1;
|
||||
elseif stop_after_option_type = 1 //days
|
||||
then
|
||||
total_time := 1 day * stop_after_value;
|
||||
number_of_admins := ceiling (total_time/time_interval);
|
||||
elseif stop_after_option_type = 2 //hours
|
||||
then
|
||||
total_time := 1 hour * stop_after_value;
|
||||
number_of_admins := ceiling (total_time/time_interval);
|
||||
elseif stop_after_option_type = 3 //minutes
|
||||
then
|
||||
total_time := 1 minute * stop_after_value;
|
||||
number_of_admins := ceiling (total_time/time_interval);
|
||||
elseif stop_after_option_type = 4 //times
|
||||
then
|
||||
number_of_admins := truncate (stop_after_value);
|
||||
elseif exist stop_dtm
|
||||
and exist order_med_frequency
|
||||
then
|
||||
//Calculate the amount of time between the start_dtm and stop_dtm.
|
||||
//Adjust by adding 1 minute because the orders application calculates the
|
||||
//stop_dtm by multiplying the number of days by 24 hours and subtracting 1 minute.
|
||||
//We have to restore the 1 minute because this algorithm truncates, rather than rounds up.
|
||||
//Example: 1 day is 2005-11-05T00:00:00 to 2005-11-05T23:59:00,
|
||||
//rather than 2005-11-06T00:00:00
|
||||
|
||||
total_time := stop_dtm - start_dtm + 1 minute;
|
||||
number_of_admins := ceiling (total_time/time_interval); // rounds up
|
||||
else
|
||||
//If the time_interval greater than 24 hours
|
||||
If (time_interval / 24 hours) > 1
|
||||
then //There is only 1 administration during the time_interval
|
||||
number_of_admins := 1;
|
||||
else //Calculate the number of administrations in 24 hours
|
||||
// by Rounding Up to the full day if there is a decimal
|
||||
number_of_admins := ceiling (24 HOURS/ time_interval);
|
||||
endif; //If (time_interval / 24 hours)
|
||||
endif; //if NOT exist order_med_frequency
|
||||
|
||||
|
||||
//----------------------------------------------
|
||||
// Generate the Administration Date-Times (DTM)
|
||||
//----------------------------------------------
|
||||
//Initialize the list to append date-times
|
||||
admin_dtm_list := ();
|
||||
|
||||
//Generate the date-times
|
||||
for JJ in (1 seqto number_of_admins) do
|
||||
if JJ = 1
|
||||
then
|
||||
temp_date := start_dtm;
|
||||
else
|
||||
temp_date := temp_date + time_interval;
|
||||
endif;
|
||||
admin_dtm_list := admin_dtm_list, temp_date;
|
||||
enddo;
|
||||
|
||||
// Generate an end_dtm that can be used as
|
||||
// the start date of the next component if needed.
|
||||
next_startDtm := temp_date + time_interval;
|
||||
|
||||
endif; //if order_med_frequency = "<User Schedule>"
|
||||
|
||||
//-----------------
|
||||
// Debug Variables
|
||||
//-----------------
|
||||
DEBUG_Number_Of_Days_In_Time_Interval := time_interval/ 1 DAY;
|
||||
DEBUG_Number_Of_Hours_In_Time_Interval := time_interval/ 1 HOUR;
|
||||
DEBUG_Number_Of_Minutes_In_Time_Interval := time_interval/ 1 MINUTE;
|
||||
DEBUG_Number_Of_Seconds_In_Time_Interval := time_interval/ 1 SECOND;
|
||||
DEBUG_admin_dtm_list := admin_dtm_list;
|
||||
|
||||
// If no next_startDtm at this point, take the last administration time
|
||||
// and add 24 hours. This can be used as the start of next component
|
||||
// for a complex order.
|
||||
if next_startDtm is null then
|
||||
next_startDtm := last admin_dtm_list + 24 hours;
|
||||
endif;
|
||||
|
||||
// Always Conclude True
|
||||
Conclude true;
|
||||
;;
|
||||
action:
|
||||
return admin_dtm_list, next_startDtm, isShiftFrequency;
|
||||
;;
|
||||
end:
|
||||
@@ -0,0 +1,240 @@
|
||||
maintenance:
|
||||
|
||||
title: Creates the Generated Administration Date-Times;;
|
||||
mlmname: STD_FUNC_DOSAGE_ADMIN_TIMES_GENERATED;;
|
||||
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: The purpose of this MLM is to calculate the Dose Administration Date-Times
|
||||
for any order passed in.
|
||||
;;
|
||||
explanation: This MLM will call the methods that generate the administration times
|
||||
based on business rules found on library SCMLib.CDS.
|
||||
1. DetermineAdministrationSchedule is used to generate
|
||||
Dose Administration Date-Times for Regular Orders and IV-Additives.
|
||||
2. DetermineAdministrationScheduleForVarComponents is used to
|
||||
generate Dose Administration Date-Times for
|
||||
Complex Orders (Dosing Options).
|
||||
There are two version of each method. If the Start Date-Time is null OR the
|
||||
Stop Date-Time is null, the method is called without the date-times. The
|
||||
missing date-times are set by the method and the Administration Date-Times
|
||||
will be generated accordingly. If the Start Date-Time and the Stop Date-Time
|
||||
are available, then the date-times are passed to the method and the method
|
||||
will use them to generate the Administration Date-Times.
|
||||
;;
|
||||
keywords: single dose; average daily dose; total daily dose; dosage range
|
||||
;;
|
||||
knowledge:
|
||||
type: data-driven;;
|
||||
data:
|
||||
|
||||
(order_GUID,
|
||||
component_GUID,
|
||||
start_dtm,
|
||||
stop_dtm,
|
||||
isFirstComponent,
|
||||
isLastComponent ):= ARGUMENT;
|
||||
|
||||
// Set to true if logging is needed.
|
||||
log_execution_info := false;
|
||||
|
||||
// Set to true if task/occurences already generated should be considered
|
||||
IncludePerformed := TRUE;
|
||||
IncludeProvisionalAdminTimes := FALSE;
|
||||
|
||||
// Load the correct version of .NET 2.0
|
||||
using "mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089";
|
||||
using "SCMLib.CDS";
|
||||
|
||||
// List of admin times to be returned
|
||||
admin_dtm_list := ();
|
||||
|
||||
// If the list of admin times was able to be calculated correctly. The list maybe empty
|
||||
// which is a valid condition.
|
||||
schedule_calculated := true;
|
||||
|
||||
|
||||
// Get the order type from the EvokingObject
|
||||
(complex_order_type) := read last
|
||||
{ Order: ComplexOrderType
|
||||
REFERENCING EvokingObject};
|
||||
;;
|
||||
evoke:
|
||||
;;
|
||||
logic:
|
||||
|
||||
isShiftAdmin := false;
|
||||
|
||||
if order_GUID is NULL then
|
||||
conclude TRUE;
|
||||
endif;
|
||||
|
||||
try
|
||||
// Class defined in SCMLib OrderPObj.h
|
||||
CalcObjType := "[SCMLib.CDS]SCMLib.CDS.OrderCalculations" as "System.Type";
|
||||
|
||||
// Create an order object and populate it with the current order
|
||||
CalcObj := new net_object CalcObjType;
|
||||
loadStatus := call CalcObj.Populate with order_GUID;
|
||||
calculate_administrations := true;
|
||||
|
||||
while calculate_administrations do
|
||||
|
||||
// Loop only runs once unless logic later on specifies
|
||||
// that it needs to be run a second time.
|
||||
calculate_administrations := false;
|
||||
|
||||
// Process as a Regular order or IV-Additive
|
||||
if component_GUID is null
|
||||
then
|
||||
|
||||
if start_dtm is null OR stop_dtm is null
|
||||
then
|
||||
adminScheduleObj := call CalcObj.DetermineAdministrationSchedule
|
||||
with IncludePerformed as "System.Boolean";
|
||||
else
|
||||
adminScheduleObj := call CalcObj.DetermineAdministrationSchedule
|
||||
with start_dtm as "System.DateTime",
|
||||
stop_dtm as "System.DateTime",
|
||||
IncludePerformed as "System.Boolean";
|
||||
endif;
|
||||
|
||||
else // Process as a Complex Order
|
||||
|
||||
if start_dtm is null OR stop_dtm is null
|
||||
then
|
||||
adminScheduleObj := call CalcObj.DetermineAdministrationScheduleForVarComponents
|
||||
with component_GUID as "System.String",
|
||||
IncludePerformed as "System.Boolean";
|
||||
|
||||
else
|
||||
adminScheduleObj := call CalcObj.DetermineAdministrationScheduleForVarComponents
|
||||
with component_GUID as "System.String",
|
||||
start_dtm as "System.DateTime",
|
||||
stop_dtm as "System.DateTime",
|
||||
IncludePerformed as "System.Boolean";
|
||||
endif;
|
||||
|
||||
endif; // If component_GUID is null
|
||||
|
||||
// Take the information returned by the .NET call to get the list of admin times
|
||||
|
||||
if adminScheduleObj is not null
|
||||
then
|
||||
foundAdminTimes := first adminScheduleObj.AdministrationOccur is not NULL;
|
||||
AdminTimes := count of (adminScheduleObj.AdministrationOccur);
|
||||
|
||||
// If the frequence is shift based then ignore any admin times generated and
|
||||
// return false to the calling MLM
|
||||
isShiftAdmin := adminScheduleObj.FrequencySchedule is not NULL AND
|
||||
adminScheduleObj.FrequencySchedule.FreqUOM = "Shift";
|
||||
|
||||
if foundAdminTimes AND not isShiftAdmin
|
||||
then
|
||||
|
||||
for occ in adminScheduleObj.AdministrationOccur do
|
||||
|
||||
fromDtm := occ.AdminFromDtm;
|
||||
|
||||
// Only reset the admin time for a unscheduled recurring if it a regular
|
||||
// or concurrent order or if it is the first component of a sequential.
|
||||
if complex_order_type is in (0,3) OR // Regular or Concurrent
|
||||
( complex_order_type is in (1,5) AND isFirstComponent ) // Sequential or Multiple and first
|
||||
then
|
||||
|
||||
// If the frequency is unscheduled recurring it can throw the 24 hour range off
|
||||
// Therefore for the first {{{SINGLE-QUOTE}}}day{{{SINGLE-QUOTE}}} of administrations set the from time of the
|
||||
// occurrence for calcuations purposes to be 00:00 or the start of shift
|
||||
if adminScheduleObj.AdminScheduleType = "Unscheduled" AND
|
||||
adminScheduleObj.AdminProcessType = "Recurring" AND
|
||||
adminScheduleObj.StartDtm = occ.AdminFromDtm
|
||||
then
|
||||
|
||||
fromDtm := day floor of fromDtm;
|
||||
|
||||
endif;
|
||||
|
||||
endif;
|
||||
|
||||
// Provisional Admin times are generated when the order date/time is
|
||||
// outside a time range specified when creating the frequency translation
|
||||
// The hospital can configure if they want to include this provisional admin
|
||||
// in the calculations.
|
||||
isProvisionalAdmin := occ.AdminToDtm is NOT NULL AND
|
||||
adminScheduleObj.AdminScheduleType = "Scheduled" AND
|
||||
adminScheduleObj.AdminProcessType = "Recurring";
|
||||
|
||||
// Add the calculated admin time to the list of times. The Provisional admin
|
||||
// time can be skipped
|
||||
if (isProvisionalAdmin = true AND IncludeProvisionalAdminTimes = true) OR
|
||||
isProvisionalAdmin = false
|
||||
then
|
||||
admin_dtm_list := admin_dtm_list, fromDtm;
|
||||
endif;
|
||||
|
||||
enddo; // for occ
|
||||
|
||||
else // if No admin times
|
||||
|
||||
// For complex sequential order, if the last component didn{{{SINGLE-QUOTE}}}t have a
|
||||
// a stop date and the order object was unable to determine any administration
|
||||
// times, set a stop date of 3 days from the start of the component and try
|
||||
// the calculations again.
|
||||
if stop_dtm is NULL AND
|
||||
adminScheduleObj.StartDtm is not NULL AND
|
||||
complex_order_type is in (1,5) AND
|
||||
isLastComponent AND
|
||||
not isShiftAdmin
|
||||
then
|
||||
|
||||
start_dtm := adminScheduleObj.StartDtm;
|
||||
stop_dtm := adminScheduleObj.StartDtm + (3 Day - 1 minute);
|
||||
calculate_administrations := true; // try again.
|
||||
|
||||
else
|
||||
// Report no admin times as an error in all cases
|
||||
schedule_calculated := false;
|
||||
endif;
|
||||
endif;
|
||||
else
|
||||
schedule_calculated := false;
|
||||
endif;
|
||||
|
||||
enddo; // while calculate_administrations
|
||||
|
||||
endtry;
|
||||
catch exception ex
|
||||
// error trying to access the object, return an empty list
|
||||
admin_dtm_list := ();
|
||||
schedule_calculated := false;
|
||||
endcatch;
|
||||
|
||||
Conclude true;
|
||||
|
||||
;;
|
||||
action:
|
||||
return admin_dtm_list, schedule_calculated, isShiftAdmin;
|
||||
;;
|
||||
Urgency: 50;;
|
||||
end:
|
||||
205
MLMStripper/bin/Debug/STD/STD_FUNC_DOSAGE_BASIS.mlm
Normal file
205
MLMStripper/bin/Debug/STD/STD_FUNC_DOSAGE_BASIS.mlm
Normal file
@@ -0,0 +1,205 @@
|
||||
maintenance:
|
||||
|
||||
title: Create Lists of the Weights for the Dose Basis;;
|
||||
mlmname: STD_FUNC_DOSAGE_BASIS;;
|
||||
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: The MLM determines which Weight should be used for dosage-range checking.
|
||||
;;
|
||||
explanation: In the Dosage Calculation UI, the user can specify which type of weight
|
||||
or BSA should be used to calculate the dose. Examples of the types are:
|
||||
actual KG, KG (ADJUSTED), KG (IDEAL), actual M2, M2 (ADJUSTED), M2 (IDEAL)
|
||||
|
||||
The correct weight is determined by calling a system MLM that calcuates the
|
||||
differnt types of weight. The information is then passed back to the calling program.
|
||||
|
||||
NOTE: When a facility adds codes to the CALCULATION OPTION Dictionary,
|
||||
this MLM will NOT automatically adjust for any codes that use IDEAL or
|
||||
ADJUSTED weights in them. You must manually added the codes to the following
|
||||
variables: ADJUSTED_COMPARE_STRING and/or IDEAL_COMPARE_STRING
|
||||
;;
|
||||
keywords: single dose; average daily dose; total daily dose; dosage range
|
||||
;;
|
||||
knowledge:
|
||||
type: data-driven;;
|
||||
data:
|
||||
|
||||
(ht_cm, //A number. Patient{{{SINGLE-QUOTE}}}s height in centimeter
|
||||
wt_kg, //A number. Patient{{{SINGLE-QUOTE}}}s weight in kilograms
|
||||
calc_med_per_uom_list //A list that is the DOSE BASIS such as "kg (ideal)", "m2 (adjusted)"
|
||||
) := ARGUMENT;
|
||||
|
||||
|
||||
/* Set to true if logging is needed.*/
|
||||
log_execution_info := false;
|
||||
|
||||
/* Lists to determine which weight dose basis uses: ideal, adjusted, actual, or unspecified */
|
||||
/* DO NOT CHANGE the values in the kg_compare_string and the m2_compare_string */
|
||||
|
||||
kg_compare_string := ("kg", "kg (ideal)", "kg (adjusted)");
|
||||
m2_compare_string := ("m2", "m2 (ideal)", "m2 (adjusted)");
|
||||
actual_compare_string := ("kg", "m2");
|
||||
adjusted_compare_string := ("kg (adjusted)", "m2 (adjusted)",
|
||||
"AUC (Cockcroft-Gault adjusted)", "AUC (Jelliffe adjusted)");
|
||||
ideal_compare_string := ("kg (ideal)", "m2 (ideal)",
|
||||
"AUC (Cockcroft-Gault ideal)", "AUC (Jelliffe ideal)" );
|
||||
|
||||
/* Declare the MLMs that can be called */
|
||||
calculate_weight := MLM {{{SINGLE-QUOTE}}}sys_calc_WT{{{SINGLE-QUOTE}}};
|
||||
|
||||
/* Get ClientInfo Object */
|
||||
client_info_obj := read last {ClientInfo: This };
|
||||
;;
|
||||
evoke:
|
||||
;;
|
||||
logic:
|
||||
|
||||
/*-----------------------------------------*/
|
||||
/* Modify Lists For Ideal & Adjust Weights */
|
||||
/*-----------------------------------------*/
|
||||
|
||||
/* Initalize Variables */
|
||||
calc_text_list := ();
|
||||
dose_basis := "";
|
||||
dose_basis_list := ();
|
||||
wt_kg_list := ();
|
||||
updated_calc_med_per_uom_list := ();
|
||||
|
||||
|
||||
index_list:= 1 seqto(count calc_med_per_uom_list);
|
||||
|
||||
for M in index_list do
|
||||
user_value_item := first (calc_med_per_uom_list where index_list = M);
|
||||
|
||||
if user_value_item is in kg_compare_string
|
||||
then
|
||||
if user_value_item is in ideal_compare_string
|
||||
then
|
||||
temp_user_value_item := "kg";
|
||||
dose_basis := "Ideal";
|
||||
calc_text_list := calc_text_list, " (using ideal weight).";
|
||||
elseif user_value_item is in adjusted_compare_string
|
||||
then
|
||||
temp_user_value_item := "kg";
|
||||
dose_basis := "Adjusted";
|
||||
calc_text_list := calc_text_list, " (using adjusted weight).";
|
||||
elseif user_value_item is in actual_compare_string
|
||||
then
|
||||
temp_user_value_item := "kg";
|
||||
dose_basis := "Actual";
|
||||
calc_text_list := calc_text_list, ".";
|
||||
else
|
||||
temp_user_value_item := NULL;
|
||||
dose_basis := "Unspecified";
|
||||
calc_text_list := calc_text_list, ".";
|
||||
endif; // if user_value_item is in ideal_compare_string
|
||||
elseif user_value_item is in m2_compare_string
|
||||
then
|
||||
if user_value_item is in ideal_compare_string
|
||||
then
|
||||
temp_user_value_item := "m2";
|
||||
dose_basis:= "Ideal";
|
||||
calc_text_list := calc_text_list, " (using ideal BSA).";
|
||||
elseif user_value_item is in adjusted_compare_string
|
||||
then
|
||||
temp_user_value_item := "m2";
|
||||
dose_basis := "Adjusted";
|
||||
calc_text_list := calc_text_list, " (using adjusted BSA).";
|
||||
elseif user_value_item is in actual_compare_string
|
||||
then
|
||||
temp_user_value_item := "m2";
|
||||
dose_basis := "Actual";
|
||||
calc_text_list := calc_text_list, ".";
|
||||
else
|
||||
temp_user_value_item := NULL;
|
||||
dose_basis := "Unspecified";
|
||||
calc_text_list := calc_text_list, ".";
|
||||
endif; //user_value_item is in ideal_compare_string
|
||||
else
|
||||
//This is a customer supplied entry in the CV3CalculationOption table
|
||||
//Or a dose basis from the AUC group
|
||||
if user_value_item is in ideal_compare_string
|
||||
then
|
||||
temp_user_value_item := NULL;
|
||||
dose_basis := "Ideal";
|
||||
calc_text_list := calc_text_list, " (using ideal weight).";
|
||||
elseif user_value_item is in adjusted_compare_string
|
||||
then
|
||||
temp_user_value_item := NULL;
|
||||
dose_basis := "Adjusted";
|
||||
calc_text_list := calc_text_list, " (using adjusted weight).";
|
||||
else
|
||||
temp_user_value_item := NULL;
|
||||
dose_basis := "Unspecified";
|
||||
calc_text_list := calc_text_list, ".";
|
||||
endif; // if user_value_item is in ideal_compare_string
|
||||
endif; //if user_value_item is in kg_compare_string
|
||||
|
||||
|
||||
/*--------------------------------------------------------*/
|
||||
/* Append the DOSE BASIS and the Updated PER UOM to Lists */
|
||||
/*--------------------------------------------------------*/
|
||||
dose_basis_list := dose_basis_list, dose_basis;
|
||||
|
||||
/* Changes calc_med_per_uom_list to KG or M2 where values include (ideal) or (adjusted) */
|
||||
/* Note: temp_user_value_item should be NULL, except for the values listed */
|
||||
/* in the kg_compare_string and the m2_compare_string */
|
||||
/* The purpose of this statement is to replace the IDEAL and ADJUSTED values */
|
||||
/* in the strings such as "KG (ideal)" so that dosage-range checking will continue to */
|
||||
/* match the KG or M2 in the "PER WT OR M2" field dosage-range configuration */
|
||||
updated_calc_med_per_uom_list := updated_calc_med_per_uom_list, temp_user_value_item;
|
||||
|
||||
|
||||
/*---------------------------------------------------------*/
|
||||
/* Get the WEIGHT-- null, actual, ideal or adjusted weight */
|
||||
/*---------------------------------------------------------*/
|
||||
if dose_basis is in ( "Ideal", "Adjusted" )
|
||||
then
|
||||
(wt_kg_str, Tooltip_formula, display_message) := call calculate_weight
|
||||
with (dose_basis, ht_cm, wt_kg, client_info_obj);
|
||||
|
||||
wt_kg_list := wt_kg_list, (wt_kg_str AS NUMBER);
|
||||
elseif dose_basis = "Actual"
|
||||
then
|
||||
wt_kg_list := wt_kg_list, (wt_kg AS NUMBER);
|
||||
else
|
||||
wt_kg_list := wt_kg_list, (wt_kg AS NUMBER);
|
||||
endif; //if dose_basis
|
||||
|
||||
enddo; //for M in index_list do
|
||||
|
||||
/*-------------------------------------------*/
|
||||
/* Always conclude true to return the values */
|
||||
/*-------------------------------------------*/
|
||||
conclude true;
|
||||
;;
|
||||
action:
|
||||
return
|
||||
(calc_text_list,
|
||||
dose_basis_list,
|
||||
wt_kg_list,
|
||||
updated_calc_med_per_uom_list );
|
||||
;;
|
||||
end:
|
||||
121
MLMStripper/bin/Debug/STD/STD_FUNC_DOSAGE_CALC_METHOD.mlm
Normal file
121
MLMStripper/bin/Debug/STD/STD_FUNC_DOSAGE_CALC_METHOD.mlm
Normal file
@@ -0,0 +1,121 @@
|
||||
maintenance:
|
||||
|
||||
title: Summed Dose Versus Conversion Factor Methods;;
|
||||
mlmname: STD_FUNC_DOSAGE_CALC_METHOD;;
|
||||
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: Returns a string indicating the type of dosage range calculation to use:
|
||||
SUMMED OR CONVERSION
|
||||
;;
|
||||
explanation: This MLM determines if the Dosage Range check should be done
|
||||
using the SUMMED DOSE or the CONVERSION FACTOR approach.
|
||||
|
||||
If the following conditions are met, the calculation type used will be SUMMED.
|
||||
if the order type is "Complex Order"
|
||||
if the order type is "IV-Additive" AND the first component is "Complex Order"
|
||||
If the order duration is less than 24 hours
|
||||
If the order frequency is <User Scheduled> or <Multiple>
|
||||
If the stop after option for the order is TIMES (4)
|
||||
|
||||
;;
|
||||
keywords: Dosage Range
|
||||
;;
|
||||
knowledge:
|
||||
type: data-driven;;
|
||||
data:
|
||||
|
||||
( med_data_list ) := ARGUMENT;
|
||||
|
||||
/* Set to true if logging is needed.*/
|
||||
log_execution_info := false;
|
||||
|
||||
return_value := "SUMMED";
|
||||
|
||||
from_uom := med_data_list[1].freq_uom;
|
||||
order_med_frequency := med_data_list[1].order_med_frequency;
|
||||
|
||||
if order_med_frequency <> "<User Schedule>"
|
||||
then
|
||||
(time_core_uom) := read last
|
||||
{"SELECT u.Code, u.CoreUOM"
|
||||
|| " FROM CV3UnitOfMeasure u"
|
||||
|| " INNER JOIN CV3Frequency f"
|
||||
|| " ON (f.Code like {{{SINGLE-QUOTE}}}Variable Interval{{{SINGLE-QUOTE}}} AND u.Code = " || SQL(from_uom) || ")"
|
||||
|| " OR (f.Code = " || SQL(order_med_frequency) || " AND f.TimeUom = u.Code ) "
|
||||
|| " WHERE u.Active = 1"
|
||||
};
|
||||
endif;
|
||||
|
||||
;;
|
||||
evoke:
|
||||
;;
|
||||
logic:
|
||||
|
||||
//------------------------------------
|
||||
//Calculate the Duration of the Order
|
||||
//------------------------------------
|
||||
|
||||
if med_data_list[1].stop_after_option_type = 1
|
||||
then order_duration := med_data_list[1].stop_after_value DAY;
|
||||
elseif med_data_list[1].stop_after_option_type = 2
|
||||
then order_duration := med_data_list[1].stop_after_value HOUR;
|
||||
elseif med_data_list[1].stop_after_option_type = 3
|
||||
then order_duration := med_data_list[1].stop_after_value MINUTE;
|
||||
elseif exist med_data_list[1].stop_dtm
|
||||
then order_duration := med_data_list[1].stop_dtm
|
||||
- med_data_list[1].order_med_significant_date;
|
||||
else
|
||||
order_duration := NULL;
|
||||
endif;
|
||||
|
||||
|
||||
//***************
|
||||
// CLINICAL RULE
|
||||
//***************
|
||||
|
||||
if med_data_list[1].is_order
|
||||
AND
|
||||
(med_data_list[1].med_order_type = "Complex Order"
|
||||
OR (med_data_list[1].med_order_type = "IV-Additive"
|
||||
AND med_data_list[2].med_order_type = "Complex Order")
|
||||
OR order_duration < 24 hours
|
||||
OR med_data_list[1].order_med_frequency is in ("<User Schedule>","<Multiple>")
|
||||
OR med_data_list[1].stop_after_option_type = 4 // Stop after X times(
|
||||
OR time_core_uom = "shift" // Shift based frequency
|
||||
)
|
||||
then
|
||||
return_value := "SUMMED"; // Summed dose
|
||||
else
|
||||
return_value := "CONVERSION"; // Conversion factor
|
||||
endif;
|
||||
|
||||
conclude true;
|
||||
;;
|
||||
action:
|
||||
return return_value;
|
||||
|
||||
;;
|
||||
Urgency: 50;;
|
||||
end:
|
||||
286
MLMStripper/bin/Debug/STD/STD_FUNC_DOSAGE_CALC_STOPDTM.mlm
Normal file
286
MLMStripper/bin/Debug/STD/STD_FUNC_DOSAGE_CALC_STOPDTM.mlm
Normal file
@@ -0,0 +1,286 @@
|
||||
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:
|
||||
321
MLMStripper/bin/Debug/STD/STD_FUNC_DOSAGE_CAT.mlm
Normal file
321
MLMStripper/bin/Debug/STD/STD_FUNC_DOSAGE_CAT.mlm
Normal file
@@ -0,0 +1,321 @@
|
||||
maintenance:
|
||||
|
||||
title: Extraction of Dosage Range Criteria;;
|
||||
mlmname: STD_FUNC_DOSAGE_CAT;;
|
||||
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: Finds the appropriate dose-range criteria from the order{{{SINGLE-QUOTE}}}s item-catalog and
|
||||
returns the information to the calling MLM.
|
||||
;;
|
||||
explanation: This MLM assists the STD_Dosage MLM with dose-range checking.
|
||||
A large list of arguments is passed to this MLM, and they are used to find
|
||||
all the appropriate dose-range criteria (AGE, BSA, or WEIGHT)
|
||||
for the patient.
|
||||
|
||||
If the ORDERED-DOSE is being checking and the "PER WT OR M2" field has a
|
||||
valid uom (kg,lb,oz,g,m2), then the upper and lower dose-ranges will be
|
||||
(1) multiplied by the patient{{{SINGLE-QUOTE}}}s weight or BSA and
|
||||
(2) rounded using the rules found in the SYS_round_dosage MLM,
|
||||
if there is a valid route.
|
||||
|
||||
If the DOSE-PER is being checking and the "PER WT OR M2" field has a
|
||||
valid uom (kg,lb,oz,g,m2), then the upper and lower dose-ranges will NOT be
|
||||
multiplied or rounded.
|
||||
|
||||
The dose-ranges and other pertinent information are returned to the calling MLM.
|
||||
See the STD_Dosage MLM for further information.
|
||||
;;
|
||||
keywords: single dose; average daily dose; total daily dose; dosage range
|
||||
;;
|
||||
knowledge:
|
||||
type: data-driven;;
|
||||
data:
|
||||
// include common data structures
|
||||
std_dosage_includes := MLM {{{SINGLE-QUOTE}}}std_func_dosage_includes{{{SINGLE-QUOTE}}};
|
||||
include std_dosage_includes;
|
||||
|
||||
(
|
||||
drug_name,
|
||||
is_order,
|
||||
catalog_item_obj,
|
||||
drc_grouper_id,
|
||||
multum_dnum,
|
||||
multum_mmdc,
|
||||
order_med_route,
|
||||
order_med_route_id,
|
||||
is_generic_route,
|
||||
order_med_significant_date,
|
||||
order_med_units,
|
||||
order_med_uom_id,
|
||||
single_order_calc_per_uom,
|
||||
average_order_calc_per_uom,
|
||||
total_order_calc_per_uom,
|
||||
patient_birthday_info_on_order,
|
||||
has_valid_birthdate,
|
||||
wt_kg,
|
||||
BSA_number_rounded,
|
||||
intl_patient_gender,
|
||||
core_uom_const,
|
||||
alert_if_missing_flags,
|
||||
patient_info
|
||||
):= ARGUMENT;
|
||||
|
||||
// Set to true if logging is needed.
|
||||
log_execution_info := false;
|
||||
|
||||
/* Declare the MLMs that can be called */
|
||||
xml_params := MLM {{{SINGLE-QUOTE}}}STD_Func_Dosage_XML_Params{{{SINGLE-QUOTE}}};
|
||||
|
||||
// XML parameter
|
||||
( input_param_xml,
|
||||
missing_route,
|
||||
unmapped_route,
|
||||
missing_uom,
|
||||
unmapped_uom
|
||||
) := call xml_params with
|
||||
(
|
||||
// Common medication data
|
||||
drc_grouper_id,
|
||||
multum_dnum,
|
||||
multum_mmdc,
|
||||
order_med_route,
|
||||
order_med_route_id,
|
||||
is_generic_route,
|
||||
order_med_significant_date,
|
||||
order_med_units,
|
||||
order_med_uom_id,
|
||||
null, // multum_freq_id not needed
|
||||
null, // med_order_type not needed
|
||||
is_order,
|
||||
// Patient data
|
||||
patient_birthday_info_on_order,
|
||||
has_valid_birthdate,
|
||||
wt_kg,
|
||||
BSA_number_rounded,
|
||||
intl_patient_gender,
|
||||
// Item Catalog only
|
||||
true, //for_item_catalog
|
||||
catalog_item_obj,
|
||||
// Multum only
|
||||
null, //has_liver_disease_bit,
|
||||
null, //dialysis_type_str,
|
||||
null, //serum_creatinine,
|
||||
// Flags and constants
|
||||
alert_if_missing_flags,
|
||||
patient_info,
|
||||
core_uom_const
|
||||
);
|
||||
|
||||
debug_sql_str := "SCMGetItemCatDosageRangePr "
|
||||
|| SQL(input_param_xml);
|
||||
|
||||
if exists drug_name
|
||||
then
|
||||
(match_found_list,
|
||||
dose_type_list,
|
||||
gender_codes,
|
||||
facility_gender_codes,
|
||||
criteria_type_names,
|
||||
criteria_type_codes,
|
||||
criteria_type_low_codes,
|
||||
criteria_type_high_codes,
|
||||
criteria_type_facility_uoms,
|
||||
routes,
|
||||
route_ids,
|
||||
range_low_codes,
|
||||
range_high_codes,
|
||||
range_uoms,
|
||||
range_uom_ids,
|
||||
is_PER_WT_list,
|
||||
is_PER_M2_list,
|
||||
range_per_facility_uoms,
|
||||
range_per_core_uoms,
|
||||
uom_conversion_factor_list,
|
||||
uom_conversion_issue_list,
|
||||
route_conversion_issue_list,
|
||||
cat_item_match_list,
|
||||
estimated_age_used_list
|
||||
) := read {"SCMGetItemCatDosageRangePr "
|
||||
|| SQL(input_param_xml)
|
||||
};
|
||||
endif;
|
||||
|
||||
;;
|
||||
evoke:
|
||||
;;
|
||||
logic:
|
||||
/* Intializes variables */
|
||||
dose_per_string:= "Dose Per";
|
||||
dose_reg_string:= "Dose Reg";
|
||||
found_criteria:= false;
|
||||
|
||||
item_cat_dosage_range_list := ();
|
||||
if exists match_found_list
|
||||
then
|
||||
row_count := count match_found_list;
|
||||
list_indices := 1 seqto row_count;
|
||||
|
||||
for ind in list_indices
|
||||
do
|
||||
// Put the dosage range values into the dosage range object
|
||||
dosage_range_item := new Dosage_Range_Object;
|
||||
item_cat_dosage_range_list := item_cat_dosage_range_list, dosage_range_item;
|
||||
|
||||
dosage_range_item.med_name := drug_name;
|
||||
dosage_range_item.match_found := (match_found_list[ind] = true) or (match_found_list[ind]=1);
|
||||
|
||||
dosage_range_item.dosage_type := dose_type_list[ind];
|
||||
dosage_range_item.is_range := true; // ItemCatalog is always a range value
|
||||
dosage_range_item.lower_dose := range_low_codes[ind];
|
||||
dosage_range_item.upper_dose := range_high_codes[ind];
|
||||
dosage_range_item.is_PER_WT := is_PER_WT_list[ind];
|
||||
dosage_range_item.is_PER_M2 := is_PER_M2_list[ind];
|
||||
|
||||
uom_conversion_factor := uom_conversion_factor_list[ind];
|
||||
conversion_factor := uom_conversion_factor;
|
||||
|
||||
if (dosage_range_item.dosage_type = "single") then order_med_per_uom := single_order_calc_per_uom;
|
||||
elseif (dosage_range_item.dosage_type = "average") then order_med_per_uom := average_order_calc_per_uom;
|
||||
else order_med_per_uom := total_order_calc_per_uom;
|
||||
endif;
|
||||
|
||||
per_units := range_per_core_uoms[ind];
|
||||
|
||||
if (order_med_per_uom = per_units) // dose per
|
||||
then
|
||||
dosage_range_item.dose_calc_method := dose_per_string;
|
||||
|
||||
corrected_uom := range_uoms[ind] || "/" || per_units;
|
||||
else // dose reg
|
||||
dosage_range_item.dose_calc_method := dose_reg_string;
|
||||
|
||||
if per_units is null
|
||||
then
|
||||
corrected_uom := range_uoms[ind];
|
||||
dosage_range_item.unit_of_measure := range_uoms[ind];
|
||||
else
|
||||
corrected_uom := range_uoms[ind] || "/" || per_units;
|
||||
dosage_range_item.unit_of_measure := range_uoms[ind] || "/" || per_units;
|
||||
|
||||
per_weight_list := (core_uom_const.kg_string, core_uom_const.gm_string, core_uom_const.lb_string, core_uom_const.ounce_string);
|
||||
per_weight_conversion := (1000, 1, 453.6, 28.35);
|
||||
|
||||
if (per_units in per_weight_list)
|
||||
then
|
||||
dosage_range_item.is_PER_WT := true;
|
||||
dosage_range_item.unit_of_measure := range_uoms[ind] || "/" || per_units;
|
||||
|
||||
if wt_kg is number and wt_kg > 0
|
||||
then
|
||||
wt_gm := wt_kg * 1000;
|
||||
weight_conv_factor := (last (per_weight_conversion where per_units = per_weight_list));
|
||||
per_weight := wt_gm / weight_conv_factor;
|
||||
conversion_factor := conversion_factor / per_weight;
|
||||
else
|
||||
conversion_factor := -1 * abs(conversion_factor);
|
||||
dosage_range_item.match_found := false;
|
||||
endif;
|
||||
elseif per_units = core_uom_const.M2_string
|
||||
then
|
||||
dosage_range_item.is_PER_M2 := true;
|
||||
dosage_range_item.unit_of_measure := range_uoms[ind] || "/" || per_units;
|
||||
|
||||
if BSA_number_rounded is number
|
||||
and BSA_number_rounded > 0
|
||||
then
|
||||
conversion_factor := conversion_factor / BSA_number_rounded;
|
||||
else
|
||||
conversion_factor := -1 * abs(conversion_factor);
|
||||
dosage_range_item.match_found := false;
|
||||
endif;
|
||||
endif;
|
||||
endif;
|
||||
endif;
|
||||
|
||||
dosage_range_item.corrected_uom := corrected_uom;
|
||||
dosage_range_item.calc_per_core_uom := per_units;
|
||||
dosage_range_item.is_multum := false;
|
||||
dosage_range_item.route := routes[ind];
|
||||
dosage_range_item.route_id := route_ids[ind];
|
||||
dosage_range_item.med_route := order_med_route;
|
||||
dosage_range_item.med_route_id := order_med_route_id;
|
||||
dosage_range_item.dnum_ic_match_found := cat_item_match_list[ind] not in (1, true);
|
||||
dosage_range_item.estimated_age_used := estimated_age_used_list[ind];
|
||||
|
||||
route_conversion_issue := route_conversion_issue_list[ind] in (1, true);
|
||||
if is_generic_route
|
||||
then
|
||||
dosage_range_item.unrecognized_route_conversion_issue := route_conversion_issue;
|
||||
else
|
||||
dosage_range_item.inapplicable_route_conversion_issue := route_conversion_issue;
|
||||
endif;
|
||||
|
||||
dosage_range_item.uom_conversion_factor := uom_conversion_factor;
|
||||
dosage_range_item.conversion_factor := conversion_factor;
|
||||
dosage_range_item.uom_conversion_issue := uom_conversion_issue_list[ind] in (1, true);
|
||||
|
||||
criteria_type := criteria_type_codes[ind];
|
||||
dosage_range_item.is_default := criteria_type = "age" and
|
||||
(gender_codes[ind] in (null, "", "U"));
|
||||
|
||||
criteria_low_str := criteria_type_low_codes[ind];
|
||||
criteria_high_str := criteria_type_high_codes[ind];
|
||||
criteria_uom_str := criteria_type_facility_uoms[ind];
|
||||
criteria_str := ">=" || criteria_low_str || " " || criteria_uom_str || " and " ||
|
||||
"<" || criteria_high_str || " " || criteria_uom_str;
|
||||
|
||||
if criteria_type = "age"
|
||||
then
|
||||
dosage_range_item.age_criteria:= criteria_str;
|
||||
elseif criteria_type = "bsa"
|
||||
then
|
||||
dosage_range_item.BSA_criteria:= criteria_str;
|
||||
elseif criteria_type = "weight"
|
||||
then
|
||||
dosage_range_item.weight_criteria:= criteria_str;
|
||||
endif;
|
||||
|
||||
case_id := criteria_str;
|
||||
gender_criteria := facility_gender_codes[ind];
|
||||
|
||||
if facility_gender_codes[ind] not in (null, "", "U")
|
||||
then
|
||||
dosage_range_item.gender_criteria := gender_criteria;
|
||||
case_id := case_id || gender_criteria;
|
||||
endif;
|
||||
|
||||
dosage_range_item.case_id := case_id;
|
||||
enddo;
|
||||
uom_conversion_issue := any item_cat_dosage_range_list.uom_conversion_issue;
|
||||
endif;
|
||||
|
||||
/* Always conclude true to return variables to calling MLM */
|
||||
CONCLUDE TRUE;
|
||||
|
||||
;;
|
||||
action:
|
||||
return (item_cat_dosage_range_list, missing_route, unmapped_route, missing_uom, unmapped_uom, uom_conversion_issue);
|
||||
;;
|
||||
end:
|
||||
376
MLMStripper/bin/Debug/STD/STD_FUNC_DOSAGE_COMPARE.mlm
Normal file
376
MLMStripper/bin/Debug/STD/STD_FUNC_DOSAGE_COMPARE.mlm
Normal file
@@ -0,0 +1,376 @@
|
||||
maintenance:
|
||||
|
||||
title: Order Modification Comparison for the Dosage-Range Checking MLM;;
|
||||
mlmname: STD_FUNC_DOSAGE_COMPARE;;
|
||||
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: When an order is modified, this MLM compares information in the
|
||||
current Order, Order Component, and Order Variable Component Objects and the
|
||||
backup Order, its Order Components, and its Order Variable Component Objects
|
||||
to determine if the dosage information have been modified.
|
||||
|
||||
Order Component Objects are used for IV-Additives.
|
||||
Order Variable Component Objects are used for Complex Orders.
|
||||
;;
|
||||
explanation: The comparison is as follows for the current order and its backup order:
|
||||
Order Object: DosageLow, DosageHigh, UOM, Frequency, Route
|
||||
Order Component Object: IV Additive{{{SINGLE-QUOTE}}}s DosageLow, UOM
|
||||
Order Variable Component Object:
|
||||
Complex Order{{{SINGLE-QUOTE}}}s DosageLow, DosageHigh, UOM, Route, and Frequency data.
|
||||
In addition, if the Order is a Concurrent Order,
|
||||
the data affecting the Start and Stop Dates will also be compared.
|
||||
|
||||
If the information has changed, set the flag to return
|
||||
to calling MLM to indicate that dosage has changed.
|
||||
|
||||
If the Order Variable Component Objects were created, return the current list
|
||||
of these objects to the calling MLM.
|
||||
;;
|
||||
keywords: single dose; average daily dose; total daily dose; dosage range
|
||||
;;
|
||||
knowledge:
|
||||
type: data-driven;;
|
||||
data:
|
||||
|
||||
time_offset_limit //An Arden Duration that is used with Complex Orders.
|
||||
:= ARGUMENT;
|
||||
|
||||
// Set to true if logging is needed.
|
||||
log_execution_info := false;
|
||||
|
||||
|
||||
// Executes only when this MLM is called by the editor
|
||||
if called_by_editor then
|
||||
EvokingObject := read last
|
||||
{ Order: This
|
||||
};
|
||||
endif;
|
||||
|
||||
// Declare the MLM that will be called by this MLM
|
||||
func_dosage_retrieve_components := MLM {{{SINGLE-QUOTE}}}std_func_dosage_retrieve_components{{{SINGLE-QUOTE}}};
|
||||
|
||||
|
||||
// Initialize flag used to indicate of dose was modified
|
||||
medication_dose_modified := false;
|
||||
|
||||
// Get the current order{{{SINGLE-QUOTE}}}s Dosage information
|
||||
(order_name,
|
||||
order_med_uom,
|
||||
order_med_dose_low_str,
|
||||
order_med_dose_high_str,
|
||||
order_med_route,
|
||||
order_med_frequency,
|
||||
order_med_significant_date,
|
||||
client_guid,
|
||||
chart_guid,
|
||||
order_complex_order_type,
|
||||
order_catalog_item_obj,
|
||||
order_component_obj,
|
||||
order_user_data_obj,
|
||||
order_variable_component_obj,
|
||||
order_backup_obj ) := read last
|
||||
{ Order: Name, UOM, DosageLow, DosageHigh, OrderRouteCode, FrequencyCode,
|
||||
SignificantDtm, ClientGUID, ChartGUID, ComplexOrderType,
|
||||
OrderCatalogMasterItem, OrderComponent,
|
||||
OrderUserData, OrderVariableComponent, Backup
|
||||
REFERENCING EvokingObject};
|
||||
|
||||
|
||||
// Get the backup order{{{SINGLE-QUOTE}}}s Dosage information
|
||||
(backup_order_name,
|
||||
backup_order_med_uom,
|
||||
backup_order_med_dose_low_str,
|
||||
backup_order_med_dose_high_str,
|
||||
backup_order_med_route,
|
||||
backup_order_med_frequency,
|
||||
backup_order_component_obj,
|
||||
backup_order_user_data_obj,
|
||||
backup_order_variable_component_obj ) := read last
|
||||
{ Order: Name, UOM, DosageLow, DosageHigh, OrderRouteCode, FrequencyCode
|
||||
OrderComponent,OrderUserData, OrderVariableComponent
|
||||
REFERENCING order_backup_obj};
|
||||
|
||||
|
||||
// Get the current order{{{SINGLE-QUOTE}}}s Component information
|
||||
(comp_name_list,
|
||||
comp_type_list,
|
||||
comp_low_dose_list,
|
||||
comp_hi_dose_list,
|
||||
comp_uom_list,
|
||||
comp_calc_actual_dose_list,
|
||||
comp_calc_uom_per_list,
|
||||
comp_catalog_item_obj_list ):= read
|
||||
{OrderComponent: Name, Type, Dosage, DosageTo, UOM,
|
||||
CalcActualDose, CalcUOMPer, OrderCatalogMasterItem
|
||||
REFERENCING order_component_obj
|
||||
where (Dosage AS number) > 0};
|
||||
|
||||
|
||||
// Get the backup order{{{SINGLE-QUOTE}}}s Component information
|
||||
(oc_backup_name_list,
|
||||
oc_backup_type_list,
|
||||
oc_backup_low_dose_list,
|
||||
oc_backup_hi_dose_list,
|
||||
oc_backup_uom_list,
|
||||
oc_backup_calc_actual_dose_list,
|
||||
oc_backup_calc_uom_per_list,
|
||||
oc_backup_catalog_item_obj_list ):= read
|
||||
{OrderComponent: Name, Type, Dosage, DosageTo, UOM,
|
||||
CalcActualDose, CalcUOMPer, OrderCatalogMasterItem
|
||||
REFERENCING backup_order_component_obj
|
||||
where (Dosage AS number) > 0 };
|
||||
|
||||
|
||||
user_data_weight_string:= "Weight";
|
||||
user_data_height_string:= "Height";
|
||||
|
||||
// Get the current OrderUserData information for weight and height
|
||||
(weight_user_data_code,
|
||||
weight_user_value) := read
|
||||
{OrderUserData: UserDataCode, Value
|
||||
REFERENCING order_user_data_obj
|
||||
WHERE user_data_code = user_data_weight_string };
|
||||
|
||||
(height_user_data_code,
|
||||
height_user_value) := read
|
||||
{OrderUserData: UserDataCode, Value
|
||||
REFERENCING order_user_data_obj
|
||||
WHERE user_data_code = user_data_height_string };
|
||||
|
||||
// Get the back up OrderUserData information for weight and height
|
||||
(backup_weight_user_data_code,
|
||||
backup_weight_user_value) := read
|
||||
{OrderUserData: UserDataCode, Value
|
||||
REFERENCING backup_order_user_data_obj
|
||||
WHERE user_data_code = user_data_weight_string
|
||||
};
|
||||
|
||||
(backup_height_user_data_code,
|
||||
backup_height_user_value) := read
|
||||
{OrderUserData: UserDataCode, Value
|
||||
REFERENCING backup_order_user_data_obj
|
||||
WHERE user_data_code = user_data_height_string
|
||||
};
|
||||
;;
|
||||
evoke:
|
||||
;;
|
||||
logic:
|
||||
|
||||
// Convert back up and current med order doses to numbers
|
||||
original_low_dose := backup_order_med_dose_low_str as number;
|
||||
current_low_dose := order_med_dose_low_str as number;
|
||||
original_high_dose := backup_order_med_dose_high_str as number;
|
||||
current_high_dose := order_med_dose_high_str as number;
|
||||
|
||||
// If the current order dosage has changed from previous dosage set modification flag.
|
||||
// Existance tests were added to the condition so that if the change was
|
||||
// from NULL to a non-NULL value, the MLM would recheck the dosage range.
|
||||
If (original_low_dose <> current_low_dose)
|
||||
OR (exist original_low_dose <> exist current_low_dose)
|
||||
OR (original_high_dose <> current_high_dose)
|
||||
OR (exist original_high_dose <> exist current_high_dose)
|
||||
OR (backup_order_med_uom <> order_med_uom)
|
||||
OR (exist backup_order_med_uom <> exist order_med_uom)
|
||||
OR (backup_order_med_route <> order_med_route)
|
||||
OR (exist backup_order_med_route <> exist order_med_route)
|
||||
OR (backup_order_med_frequency <> order_med_frequency)
|
||||
OR (exist backup_order_med_frequency <> exist order_med_frequency)
|
||||
then
|
||||
medication_dose_modified := TRUE;
|
||||
endif;
|
||||
|
||||
//------------------------------
|
||||
// Check order user data
|
||||
//------------------------------
|
||||
// If the weight or height data has changed, then
|
||||
// medication dosage information can change
|
||||
if ( (exists weight_user_value and not exists backup_weight_user_value)
|
||||
or (not exists weight_user_value and exists backup_weight_user_value)
|
||||
or (weight_user_value <> backup_weight_user_value)
|
||||
or (exists height_user_value and not exists backup_height_user_value)
|
||||
or (not exists height_user_value and exists backup_height_user_value)
|
||||
or (height_user_value <> backup_height_user_value)
|
||||
)
|
||||
then
|
||||
medication_dose_modified := TRUE;
|
||||
endif;
|
||||
|
||||
//------------------------------
|
||||
// Check OrderComponent Objects
|
||||
//------------------------------
|
||||
// If the order has OrderComponent Objects then
|
||||
// Continue checking if the main item has not had its dose modifed
|
||||
If exist order_component_obj
|
||||
and exist comp_name_list
|
||||
and NOT medication_dose_modified then
|
||||
|
||||
// If count or dosage has changed from previous set modification flag.
|
||||
// Check component item count and then step through list of components.
|
||||
If (count comp_name_list) = (count oc_backup_name_list) then
|
||||
current_additive_index := 1 seqto (count comp_name_list);
|
||||
|
||||
// Step through list of IV-Additive components and compare
|
||||
for JJ in current_additive_index do
|
||||
comp_name := first(comp_name_list where current_additive_index = JJ);
|
||||
backup_name := first(oc_backup_name_list where current_additive_index = JJ);
|
||||
|
||||
// Make certain they are the same item.
|
||||
if comp_name = backup_name then
|
||||
|
||||
// Get the values
|
||||
comp_low_dose := comp_low_dose_list[JJ] as number;
|
||||
backup_low_dose := oc_backup_low_dose_list[JJ] as number;
|
||||
comp_uom := comp_uom_list[JJ];
|
||||
backup_uom := oc_backup_uom_list[JJ];
|
||||
|
||||
// Compare the values, set flag if different
|
||||
if (comp_low_dose <> backup_low_dose)
|
||||
OR (comp_uom <> backup_uom) then
|
||||
medication_dose_modified := TRUE;
|
||||
endif;
|
||||
|
||||
else // Not the same name so set flag indicating change
|
||||
medication_dose_modified := TRUE;
|
||||
endif; //if comp_name = backup_name
|
||||
enddo; // for JJ
|
||||
|
||||
else // Number of items different so set flag indicating change
|
||||
medication_dose_modified := TRUE;
|
||||
endif; //If (count comp_name_list) =
|
||||
endif; //If exist order_component_obj
|
||||
|
||||
|
||||
|
||||
//---------------------------------
|
||||
// Check Order Variable Components
|
||||
//---------------------------------
|
||||
// If the order has OrderVariable Component Objects then
|
||||
// Continue checking if the main item has not had its dose modifed
|
||||
|
||||
If exist order_variable_component_obj
|
||||
and NOT medication_dose_modified then
|
||||
|
||||
// Retrieve the Order_Variable_Component Objects
|
||||
(current_ovc_list,
|
||||
backup_ovc_list ) := call func_dosage_retrieve_components;
|
||||
|
||||
|
||||
// Check the details of the Order Components
|
||||
// when there are the same number of components
|
||||
If count current_ovc_list = count backup_ovc_list then
|
||||
|
||||
// Step through list of Complex Order components and compare
|
||||
for KK in (1 seqto count current_ovc_list) do
|
||||
|
||||
// Make certain they are the same components by checking GUIDs
|
||||
if current_ovc_list[KK].GUID = backup_ovc_list[KK].GUID then
|
||||
|
||||
// Compare the values, set flag if different
|
||||
// Compensate for the possibility that one or both values can be NULL.
|
||||
// For Example:
|
||||
// var1 := NULL <> 1 returns NULL
|
||||
// var2 := Exist 1 <> Exist NULL returns TRUE
|
||||
// var3 := var1 or var2 returns TRUE
|
||||
|
||||
if current_ovc_list[KK].dosage_low <> backup_ovc_list[KK].dosage_low
|
||||
OR (exist current_ovc_list[KK].dosage_low
|
||||
<> exist backup_ovc_list[KK].dosage_low)
|
||||
|
||||
OR current_ovc_list[KK].dosage_high <> backup_ovc_list[KK].dosage_high
|
||||
OR (exist current_ovc_list[KK].dosage_high
|
||||
<> exist backup_ovc_list[KK].dosage_high)
|
||||
|
||||
OR current_ovc_list[KK].uom <> backup_ovc_list[KK].uom
|
||||
OR (exist current_ovc_list[KK].uom
|
||||
<> exist backup_ovc_list[KK].uom)
|
||||
|
||||
OR current_ovc_list[KK].order_route_code <> backup_ovc_list[KK].order_route_code
|
||||
OR (exist current_ovc_list[KK].order_route_code
|
||||
<> exist backup_ovc_list[KK].order_route_code)
|
||||
|
||||
OR current_ovc_list[KK].frequency_code <> backup_ovc_list[KK].frequency_code
|
||||
OR (exist current_ovc_list[KK].frequency_code
|
||||
<> exist backup_ovc_list[KK].frequency_code)
|
||||
|
||||
OR current_ovc_list[KK].freq_from_time <> backup_ovc_list[KK].freq_from_time
|
||||
OR (exist current_ovc_list[KK].freq_from_time
|
||||
<> exist backup_ovc_list[KK].freq_from_time)
|
||||
|
||||
OR current_ovc_list[KK].freq_uom <> backup_ovc_list[KK].freq_uom
|
||||
OR (exist current_ovc_list[KK].freq_uom
|
||||
<> exist backup_ovc_list[KK].freq_uom)
|
||||
then
|
||||
medication_dose_modified := TRUE;
|
||||
endif;
|
||||
|
||||
else // Not the same GUIDs so set flag indicating change
|
||||
medication_dose_modified := TRUE;
|
||||
endif; //if comp_name = backup_name
|
||||
|
||||
|
||||
// If the order is a complex order, a change to the
|
||||
// CalculatedStartDtm, the StopDtm, or the StopAfter can affect
|
||||
// the Total Daily Dose by shifting the DTMs and affecting the totals.
|
||||
|
||||
// Calculate the difference between the current and backup DTMs
|
||||
// can convert the duration to an absolute number by dividing by 1 minute.
|
||||
diff_calculated_start_dtm := ABS ((current_ovc_list[KK].calculated_start_dtm -
|
||||
backup_ovc_list[KK].calculated_start_dtm)/ 1 minute);
|
||||
diff_estimated_stop_dtm := ABS ((current_ovc_list[KK].estimated_stop_dtm -
|
||||
backup_ovc_list[KK].estimated_stop_dtm)/ 1 minute) ;
|
||||
|
||||
// Convert the time_offset_limit to an absolute number by dividing 1 minute;
|
||||
time_offset_limit_num := ABS (time_offset_limit/ 1 minute) ;
|
||||
|
||||
// If the calucated values are off by more than the time_offset_limit_num
|
||||
// or the Stop After Value or Stop After Option Type have changed
|
||||
// then this is a modification that will affect the Total Daily Dose.
|
||||
if diff_calculated_start_dtm > time_offset_limit_num
|
||||
OR diff_estimated_stop_dtm > time_offset_limit_num
|
||||
OR current_ovc_list[KK].stop_after_value
|
||||
<> backup_ovc_list[KK].stop_after_value
|
||||
OR (exist current_ovc_list[KK].stop_after_value
|
||||
<> exist backup_ovc_list[KK].stop_after_value)
|
||||
OR current_ovc_list[KK].stop_after_option_type
|
||||
<> backup_ovc_list[KK].stop_after_option_type
|
||||
OR (exist current_ovc_list[KK].stop_after_option_type
|
||||
<> exist backup_ovc_list[KK].stop_after_option_type) then
|
||||
medication_dose_modified := TRUE;
|
||||
endif; //if diff_calculated_start_dtm
|
||||
enddo; // for KK
|
||||
|
||||
else // Number of complex order components different so set flag indicating change
|
||||
medication_dose_modified := TRUE;
|
||||
endif; //If count current_ovc_list
|
||||
endif; //If exist order_variable_component_obj
|
||||
|
||||
|
||||
// Always Conclude True to Return Answer
|
||||
conclude TRUE;
|
||||
;;
|
||||
action:
|
||||
return medication_dose_modified, current_ovc_list ;
|
||||
;;
|
||||
end:
|
||||
132
MLMStripper/bin/Debug/STD/STD_FUNC_DOSAGE_CSS.mlm
Normal file
132
MLMStripper/bin/Debug/STD/STD_FUNC_DOSAGE_CSS.mlm
Normal file
@@ -0,0 +1,132 @@
|
||||
maintenance:
|
||||
|
||||
title: CSS style sheet for STD_FUNC_DOSAGE_MESSAGES;;
|
||||
mlmname: STD_FUNC_DOSAGE_CSS;;
|
||||
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: This MLM contains the CSS style sheet for STD_FUNC_DOSAGE_MESSAGES.
|
||||
;;
|
||||
explanation: Dose range alert messages are in HTML format. This MLM contains
|
||||
the CSS styles used to format the message.
|
||||
;;
|
||||
keywords: single dose; average daily dose; total daily dose; dosage range; HTML
|
||||
;;
|
||||
knowledge:
|
||||
type: data-driven;;
|
||||
data:
|
||||
// Define the CSS to be used for the HTML dose range check alerts
|
||||
Standard_CSS :=
|
||||
"<style type={{{SINGLE-QUOTE}}}text/css{{{SINGLE-QUOTE}}}> " ||
|
||||
|
||||
// general style applied to entire alert message
|
||||
" body " ||
|
||||
" { color:black; " ||
|
||||
" font-size:12pt; " ||
|
||||
" font-family:Segoe UI,sans-serif; " ||
|
||||
" margin-top: 0px; }" ||
|
||||
|
||||
// generic styles
|
||||
" #PaddingLeft" ||
|
||||
" { padding-left:50px; } " ||
|
||||
" #NormalText" ||
|
||||
" { font-weight:Normal; " ||
|
||||
" color:black; } " ||
|
||||
|
||||
// header styles
|
||||
" #Title" ||
|
||||
" { color:Red; " ||
|
||||
" font-size:14pt; " ||
|
||||
" font-weight:bold; } " ||
|
||||
" #MedicationHeader" ||
|
||||
" { color:Blue; } " ||
|
||||
|
||||
// specific message styles
|
||||
" #BasedOnMsg" ||
|
||||
" { font-size:12pt; } " ||
|
||||
" #BasedOnAdditionalInfoMsg" ||
|
||||
" { font-size:12pt; } " ||
|
||||
|
||||
// table styles
|
||||
" #ContraindicationTable" ||
|
||||
" { font-size:12pt; } " ||
|
||||
" #OutsideDoseRangeTable" ||
|
||||
" { font-size:12pt; } " ||
|
||||
" #AdditionalInfoTable" ||
|
||||
" { font-size:12pt; } " ||
|
||||
|
||||
// table column style
|
||||
" #TableColumnHeader" ||
|
||||
" { text-align:left;" ||
|
||||
" padding-right:50px; } " ||
|
||||
" #AdditionalInfoColumnHeader" ||
|
||||
" { text-align:left; " ||
|
||||
" font-weight:normal} " ||
|
||||
|
||||
// table cell styles
|
||||
" #TableCellPaddingRight" ||
|
||||
" { padding-right:50px; } " ||
|
||||
|
||||
// highlighted data styles
|
||||
" #MedicationName" ||
|
||||
" { color:Blue; } " ||
|
||||
" #OutsideDoseRangeValue" ||
|
||||
" { color:Red; } " ||
|
||||
" #WithinDoseRangeValue" ||
|
||||
" { color:Black; } " ||
|
||||
" #ContraindicationPatientInfo" ||
|
||||
" { color:Red; } " ||
|
||||
" #CreatinineClearanceNote" ||
|
||||
" { color:rgb(31,73,125); } " ||
|
||||
" #FrequencyIssue" ||
|
||||
" { color:Red; } " ||
|
||||
|
||||
// debug section style
|
||||
" #DebugSection" ||
|
||||
" { font-size:10pt; " ||
|
||||
" font-family:Segoe UI,sans-serif; }" ||
|
||||
|
||||
// list margin
|
||||
" ul" ||
|
||||
" {margin-top:0px; " ||
|
||||
" margin-bottom:0px; } " ||
|
||||
|
||||
// breakpoint height
|
||||
" br" ||
|
||||
" {line-height:85%; }" ||
|
||||
"</style> ";
|
||||
;;
|
||||
priority: 50
|
||||
;;
|
||||
evoke:
|
||||
;;
|
||||
logic:
|
||||
conclude true;
|
||||
;;
|
||||
action:
|
||||
|
||||
return Standard_CSS;
|
||||
;;
|
||||
Urgency: 50;;
|
||||
end:
|
||||
305
MLMStripper/bin/Debug/STD/STD_FUNC_DOSAGE_INCLUDES.mlm
Normal file
305
MLMStripper/bin/Debug/STD/STD_FUNC_DOSAGE_INCLUDES.mlm
Normal file
@@ -0,0 +1,305 @@
|
||||
maintenance:
|
||||
|
||||
title: Regression test include definitions;;
|
||||
mlmname: STD_FUNC_DOSAGE_INCLUDES;;
|
||||
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: The purpose of this MLM is to include the common data structures needed by dosage range MLMs
|
||||
;;
|
||||
explanation: Include this MLM at the start of any MLM that will
|
||||
be making using the objects in the MLM
|
||||
;;
|
||||
keywords: single dose; average daily dose; total daily dose; dosage range
|
||||
;;
|
||||
knowledge:
|
||||
type: data-driven;;
|
||||
data:
|
||||
// Core UOM Constant Object
|
||||
Core_UOM_OBJECT := OBJECT [
|
||||
lb_string,
|
||||
gm_string,
|
||||
kg_string,
|
||||
M2_string,
|
||||
ounce_string,
|
||||
day_string,
|
||||
hour_string,
|
||||
minute_string,
|
||||
month_string,
|
||||
second_string,
|
||||
week_string,
|
||||
year_string
|
||||
];
|
||||
|
||||
// Item catalog criteria type string object
|
||||
Catalog_DRC_Criteria_Type_String_Object := OBJECT [
|
||||
age_average_daily_dose_string,
|
||||
age_string,
|
||||
age_total_daily_dose_string,
|
||||
BSA_average_daily_dose_string,
|
||||
Body_Surface_Area_string,
|
||||
BSA_total_daily_dose_string,
|
||||
weight_average_daily_dose_string,
|
||||
weight_string,
|
||||
weight_total_daily_dose_string
|
||||
];
|
||||
|
||||
//Declare the Med_Data_Object
|
||||
//Note: Med_Data_GUID is the
|
||||
//CV3Order.GUID, CV3OrderComponent.GUID or CV3OrderVariableComponent.GUID
|
||||
//Depending on whether this is a Regular Order, IV-Additive Order, or Complex Order
|
||||
Med_Data_Object := OBJECT [
|
||||
sort_number,
|
||||
med_order_type,
|
||||
med_data_guid,
|
||||
grouper_id,
|
||||
multum_dnum,
|
||||
multum_mmdc,
|
||||
order_med_significant_date, // CalculatedStartDtm when component
|
||||
order_med_name,
|
||||
order_med_route,
|
||||
order_med_route_id, // multum drug key for the order_med_route
|
||||
order_med_dose_low,
|
||||
order_med_dose_high,
|
||||
order_med_units,
|
||||
order_med_uom_id, // multum drug key for the order_med_units
|
||||
order_med_frequency,
|
||||
multum_freq_id, // multum drug key for frequency
|
||||
order_interval,
|
||||
calc_dose_method,
|
||||
calc_med_dose_low,
|
||||
calc_med_dose_high,
|
||||
calc_med_per_uom,
|
||||
updated_calc_med_per_uom, //Populated by DoseBasis MLM
|
||||
wt_kg, //Populated by DoseBasis MLM
|
||||
calc_text, //Populated by DoseBasis MLM
|
||||
dose_basis, //Populated by DoseBasis MLM
|
||||
stop_dtm,
|
||||
calcStop_dtm, //Debug info
|
||||
calcStart_dtm, //Debug info
|
||||
calculation_method, //Debug info
|
||||
stop_after_value,
|
||||
stop_after_option_type,
|
||||
freq_from_time,
|
||||
freq_to_time,
|
||||
freq_uom,
|
||||
freq_multiplier, // only used by Prescription
|
||||
isShiftFrequency,
|
||||
admin_dtm_list,
|
||||
admin_dtm_list_calc_method, // ORDER or MLM - Debug Info
|
||||
order_catalog_item_obj,
|
||||
retrieved_dose_range_data,
|
||||
missing_route,
|
||||
unmapped_route,
|
||||
generic_route,
|
||||
missing_uom,
|
||||
unmapped_uom,
|
||||
uom_conversion_issue,
|
||||
unmapped_drug,
|
||||
unmapped_grouper,
|
||||
processed_missing_data_msg,
|
||||
processed_for_printing,
|
||||
outside_single_dosage_range,
|
||||
contraindication_found,
|
||||
alert_msg_for_single,
|
||||
is_order,
|
||||
is_outpatient_order, //indicate whether this order is outpatient order or not
|
||||
is_script, //used for outpatient order
|
||||
is_iv_additive,
|
||||
rx_instructions
|
||||
];
|
||||
|
||||
// Declare dosage range object
|
||||
Dosage_Range_Object := OBJECT [
|
||||
sort_number,
|
||||
match_found, // true if matching dose range found. false if missing age/weight/gender/route
|
||||
dosage_type, // single, average, total, or contraindication
|
||||
med_name,
|
||||
age_criteria,
|
||||
BSA_criteria,
|
||||
weight_criteria,
|
||||
gender_criteria,
|
||||
renal_criteria,
|
||||
creatinine_criteria,
|
||||
liver_criteria,
|
||||
contraindication_msg, // for dosage_type = contraindication
|
||||
recommendation_msg, // for dosage type = single/average/total
|
||||
is_range,
|
||||
lower_dose, // for dosage_type = single/average/total
|
||||
upper_dose, // for dosage_type = single/average/total
|
||||
unit_of_measure,
|
||||
conversion_factor,
|
||||
uom_conversion_factor, // Keep the pure UOM conversion factor based on the SXAUnitOfMeasureConversion table
|
||||
// This is used only used for Catalog DRC checking in STD_FUNC_DOSAGE_CAT, because
|
||||
// STD_FUNC_DOSAGE_CAT has logic to override conversion_factor value for "per weight" scenario.
|
||||
// uom_conversion_factor is currently not used in STD_FUNC_DOSAGE_MULTUM.
|
||||
uom_conversion_issue,
|
||||
Is_PER_WT,
|
||||
Is_PER_M2,
|
||||
dose_calc_method,
|
||||
corrected_uom,
|
||||
calc_per_core_uom,
|
||||
is_multum,
|
||||
grouper_id,
|
||||
case_id,
|
||||
route,
|
||||
route_id,
|
||||
// Populated in STD_FUNC_DOSAGE_MULTUM.mlm and STD_FUNC_DOSAGE_CAT.mlm
|
||||
// Contains the medication route and route ID used to retrieve this
|
||||
// dosage range by the two MLMs mentioned above
|
||||
med_route,
|
||||
med_route_id,
|
||||
|
||||
display_route, // the route to display to the user. Populated by
|
||||
// STD_FUNC_DOSAGE_MESSAGES.MLM.
|
||||
|
||||
//cannot_match_to_generic_route,
|
||||
unrecognized_route_conversion_issue,
|
||||
inapplicable_route_conversion_issue,
|
||||
is_default,
|
||||
hard_stop_high,
|
||||
hard_stop_low,
|
||||
crcl_within_range,
|
||||
patient_age_at_order,
|
||||
dnum_ic_match_found,
|
||||
dose_frequency, // e.g. "once a day"
|
||||
frequency_issue, // "too frequent", "unmapped", or null
|
||||
//[New born birth-time missing]
|
||||
// 0: alert not using estimated ages; 1: using estimated min age; 2: using estimated max age max; 3: using both estimated age min/max.
|
||||
estimated_age_used
|
||||
];
|
||||
|
||||
// medication dosage range map object
|
||||
Medication_Dosage_Range_Map := OBJECT [
|
||||
sort_number,
|
||||
med_sort_number,
|
||||
dosage_range_sort_number,
|
||||
dosage_type,
|
||||
match_found,
|
||||
above_range,
|
||||
below_range,
|
||||
med_name,
|
||||
med_dose_low,
|
||||
med_dose_high,
|
||||
med_dose_uom,
|
||||
adjusted_dose_high,
|
||||
adjusted_dose_low,
|
||||
adjusted_dose_uom,
|
||||
hard_stop_low,
|
||||
hard_stop_high,
|
||||
dose_frequency, // e.g. "once a day"
|
||||
frequency_issue // "too frequent", "unmapped", or null
|
||||
];
|
||||
|
||||
Alert_If_Missing_Obj := OBJECT [
|
||||
patient_age,
|
||||
patient_gender,
|
||||
patient_height,
|
||||
patient_weight,
|
||||
uom,
|
||||
route,
|
||||
uom_conversion,
|
||||
unmapped_drug,
|
||||
unmapped_grouper,
|
||||
unmapped_gender,
|
||||
unmapped_route,
|
||||
unmapped_uom,
|
||||
unmapped_frequency,
|
||||
cannot_check_DNUM_Rx_to_Multum,
|
||||
cannot_check_Rx_to_IC,
|
||||
cannot_check_generic_route,
|
||||
inapplicable_route
|
||||
];
|
||||
|
||||
//[New born birth-time missing]Holding info of birthday and max estimated_birthday
|
||||
//the age values are patient_age_at_order calcualted by birthday and order order_med_significant_date
|
||||
Patient_Birthday_Info_Obj := OBJECT [
|
||||
birthday,
|
||||
age_year_value,
|
||||
age_month_value,
|
||||
age_week_value,
|
||||
age_day_value,
|
||||
age_hour_value,
|
||||
age_str,
|
||||
// from here only used when is_estimated_birthday is true
|
||||
is_estimated_birthday,
|
||||
age_max_inhour_str,
|
||||
estimated_birthday_to,
|
||||
age_year_min_value,
|
||||
age_month_min_value,
|
||||
age_week_min_value,
|
||||
age_day_min_value,
|
||||
age_hour_min_value,
|
||||
age_min_inhour_str
|
||||
];
|
||||
|
||||
// weight, 68 kg, entered on 2011-nov-22, false, false
|
||||
// height,
|
||||
Patient_Property_Obj := OBJECT [
|
||||
type,
|
||||
value,
|
||||
date,
|
||||
is_missing,
|
||||
is_unmapped,
|
||||
not_current,
|
||||
unknown_other
|
||||
];
|
||||
|
||||
// Holds patient property objects
|
||||
Patient_Info_Obj := Object [
|
||||
Age,
|
||||
Weight,
|
||||
Height,
|
||||
BSA,
|
||||
Gender,
|
||||
Liver,
|
||||
Renal,
|
||||
Creatinine,
|
||||
DNum_Grouper,
|
||||
ICD9_List
|
||||
];
|
||||
|
||||
// Holds the currentness duration
|
||||
Validity_Duration := OBJECT [
|
||||
duration,
|
||||
toAge,
|
||||
fromAge ]; // Note fromAge is set by the system
|
||||
|
||||
|
||||
Grouper_Info_Object := OBJECT [
|
||||
grouper_id,
|
||||
grouper_name,
|
||||
dosage_range_found
|
||||
];
|
||||
;;
|
||||
priority: 50
|
||||
;;
|
||||
evoke:
|
||||
;;
|
||||
logic:
|
||||
;;
|
||||
action:
|
||||
;;
|
||||
Urgency: 50;;
|
||||
end:
|
||||
914
MLMStripper/bin/Debug/STD/STD_FUNC_DOSAGE_LISTS.mlm
Normal file
914
MLMStripper/bin/Debug/STD/STD_FUNC_DOSAGE_LISTS.mlm
Normal file
@@ -0,0 +1,914 @@
|
||||
maintenance:
|
||||
|
||||
title: Creates a List of Objects with Medication Data;;
|
||||
mlmname: STD_FUNC_DOSAGE_LISTS;;
|
||||
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: Gathers the dosing data for the medication order.
|
||||
;;
|
||||
explanation: The dosing data for a medication are stored in several tables/objects.
|
||||
Regular medications, IV-Additive, and Complex Orders have some tables they jointly use
|
||||
and other tables that are specific to the type of order. This MLM gathers all the data
|
||||
from the various sources and consolidates them into an object called Med_Data_Object.
|
||||
There can be one or more Med_Data_Objects for an order. A regular medication order
|
||||
only has one object for its data. IV-Additives and Complex Orders can have
|
||||
two or more objects for their data.
|
||||
;;
|
||||
keywords: single dose; average daily dose; total daily dose; dosage range
|
||||
;;
|
||||
knowledge:
|
||||
type: data-driven;;
|
||||
data:
|
||||
// include common data structures
|
||||
std_dosage_includes := MLM {{{SINGLE-QUOTE}}}std_func_dosage_includes{{{SINGLE-QUOTE}}};
|
||||
include std_dosage_includes;
|
||||
|
||||
(ht_cm,
|
||||
wt_kg,
|
||||
current_ovc_list,
|
||||
order_TaskScheduleDefinition_obj ) := ARGUMENT;
|
||||
|
||||
// Set to true if logging is needed.
|
||||
log_execution_info := false;
|
||||
|
||||
//--------------
|
||||
// Declare MLMs
|
||||
//--------------
|
||||
func_dosage_basis := MLM {{{SINGLE-QUOTE}}}std_func_dosage_basis{{{SINGLE-QUOTE}}};
|
||||
func_dosage_admin_times := MLM {{{SINGLE-QUOTE}}}STD_func_dosage_admin_times{{{SINGLE-QUOTE}}};
|
||||
func_dosage_admin_times_generated := MLM {{{SINGLE-QUOTE}}}STD_FUNC_DOSAGE_ADMIN_TIMES_GENERATED{{{SINGLE-QUOTE}}};
|
||||
calc_freqmult_daily := MLM {{{SINGLE-QUOTE}}}sys_calc_freqmult_daily{{{SINGLE-QUOTE}}};
|
||||
// Declare the MLM that will be called by this MLM
|
||||
func_dosage_retrieve_components := MLM {{{SINGLE-QUOTE}}}std_func_dosage_retrieve_components{{{SINGLE-QUOTE}}};
|
||||
func_calc_method := MLM {{{SINGLE-QUOTE}}}STD_FUNC_DOSAGE_CALC_METHOD{{{SINGLE-QUOTE}}};
|
||||
func_dosage_calc_stopdtm := MLM {{{SINGLE-QUOTE}}}STD_FUNC_DOSAGE_CALC_STOPDTM{{{SINGLE-QUOTE}}};
|
||||
|
||||
//---------------------
|
||||
// Declare the Objects
|
||||
//---------------------
|
||||
//The Med_Data_Object declaration moved to STD_FUNC_DOSAGE_INCLUDES
|
||||
//Note: Med_Data_GUID is the
|
||||
//CV3Order.GUID, CV3OrderComponent.GUID or CV3OrderVariableComponent.GUID
|
||||
//Depending on whether this is a Regular Order, IV-Additive Order, or Complex Order
|
||||
|
||||
//--------------------------------------------
|
||||
// Get the current order{{{SINGLE-QUOTE}}}s Dosage information
|
||||
//--------------------------------------------
|
||||
(client_guid,
|
||||
order_name,
|
||||
order_med_uom,
|
||||
order_med_dose_low_str,
|
||||
order_med_dose_high_str,
|
||||
order_med_route,
|
||||
order_med_frequency,
|
||||
order_med_significant_date,
|
||||
order_StopDtm,
|
||||
order_guid,
|
||||
order_is_held,
|
||||
order_complex_order_type,
|
||||
order_catalog_item_obj,
|
||||
order_component_obj,
|
||||
order_user_data_obj,
|
||||
order_Interval,
|
||||
order_AdditionalInfo_obj,
|
||||
order_variable_component_obj,
|
||||
order_backup_obj ) := read last
|
||||
{ Order: ClientGUID, Name, UOM, DosageLow, DosageHigh, OrderRouteCode,
|
||||
FrequencyCode, SignificantDtm, StopDtm, GUID, IsHeld, ComplexOrderType
|
||||
OrderCatalogMasterItem, OrderComponent, OrderUserData,
|
||||
Interval, OrderAdditionalInfo,
|
||||
OrderVariableComponent, Backup
|
||||
REFERENCING EvokingObject};
|
||||
|
||||
|
||||
// Get information for frequency for "<Variable Interaval>" and StopAfter Data
|
||||
(OrderInfo_order_stop_after_value,
|
||||
OrderInfo_order_stop_after_option,
|
||||
OrderInfo_FreqFromTime,
|
||||
OrderInfo_FreqToTime,
|
||||
OrderInfo_FreqUOM,
|
||||
OrderInfo_Dosing_Option_GUID ) := read last
|
||||
{OrderAdditionalInfo: StopAfterValue, StopAfterOption
|
||||
FreqFromTime, FreqToTime, FreqUOM,
|
||||
DosingOptionGUID
|
||||
REFERENCING order_AdditionalInfo_obj };
|
||||
|
||||
|
||||
// Get the current order{{{SINGLE-QUOTE}}}s IV-Additive Component information
|
||||
(comp_guid_list,
|
||||
comp_name_list,
|
||||
comp_type_list,
|
||||
comp_low_dose_list,
|
||||
comp_hi_dose_list,
|
||||
comp_uom_list,
|
||||
comp_calc_actual_dose_list,
|
||||
comp_calc_uom_per_list,
|
||||
comp_catalog_item_obj_list ):= read
|
||||
{OrderComponent: GUID, Name, Type, Dosage, DosageTo, UOM,
|
||||
CalcActualDose, CalcUOMPer, OrderCatalogMasterItem
|
||||
REFERENCING order_component_obj
|
||||
where (Dosage AS number) > 0 };
|
||||
|
||||
// For Irregular intervals get the total number of doses given
|
||||
ScheduleDTM_list := read
|
||||
{TaskScheduleDefinition: SCHEDULEDDTM
|
||||
REFERENCING order_TaskScheduleDefinition_obj };
|
||||
|
||||
|
||||
// Get the current OrderUserData information
|
||||
(user_data_code,
|
||||
user_value) := read
|
||||
{OrderUserData: UserDataCode, Value
|
||||
REFERENCING order_user_data_obj };
|
||||
|
||||
|
||||
// If the Order is a Concurrent Complex Order and its is on HOLD
|
||||
// then retrieve the Template for the Dates
|
||||
if order_is_held
|
||||
and order_complex_order_type = 3 //Concurrent
|
||||
and exist OrderInfo_Dosing_Option_GUID
|
||||
then
|
||||
// Retrieve the Template for the Dates
|
||||
requested_date_template_list := read
|
||||
{"Select RequestedDate "
|
||||
||" FROM CV3DosingOptionGridRow "
|
||||
||" WHERE DosingOptionGUID = " || SQLEX(OrderInfo_Dosing_Option_GUID) };
|
||||
endif; //if order_is_held
|
||||
|
||||
|
||||
// Retrieve and populate the data for the Complex Order{{{SINGLE-QUOTE}}}s Order_Variable_Component Objects
|
||||
if exist current_ovc_list
|
||||
then
|
||||
// The data was already constructed when the modifed order was compared to the backup data
|
||||
complex_order_list := current_ovc_list;
|
||||
else
|
||||
// Retrieve the data, since the data was not created previously.
|
||||
complex_order_list := call func_dosage_retrieve_components;
|
||||
endif;
|
||||
|
||||
/* Get the Units of Measure info */
|
||||
(uom_facility_code,
|
||||
uom_sys_code,
|
||||
uom_drug_catalog_key):= read
|
||||
{"SELECT Code, CoreUOM, DrugCatalogKey "
|
||||
|| " FROM CV3UnitOfMeasure"
|
||||
|| " WHERE Active = 1" };
|
||||
|
||||
/* Get Route Dictionary ID info */
|
||||
(route_code,
|
||||
route_drug_catalog_key):= read
|
||||
{"SELECT Code, DrugCatalogKey "
|
||||
|| " FROM CV3OrderRoute"
|
||||
|| " WHERE Active = 1" };
|
||||
|
||||
|
||||
/* Get Frequency Dictionary ID info */
|
||||
(frequency_code,
|
||||
frequency_drug_catalog_key):= read
|
||||
{"SELECT f.Code, f.DrugCatalogKey "
|
||||
|| " FROM CV3Frequency f"
|
||||
|| " INNER JOIN SXAMTmultum_frequencySYN mf on mf.frequency_code = f.DrugCatalogKey "
|
||||
|| " WHERE Active = 1" };
|
||||
|
||||
;;
|
||||
evoke:
|
||||
;;
|
||||
logic:
|
||||
|
||||
//--------------------------------
|
||||
// Update HELD Complex Order DTMs
|
||||
//---------------------------------
|
||||
// If the Order is a Complex Order and its is on HOLD
|
||||
// then correct the CalculatedStartDtm and the EstimatedStopDtm
|
||||
if order_is_held
|
||||
and order_complex_order_type > 0
|
||||
then
|
||||
HH := 0;
|
||||
prior_estimated_stop_dtm := null;
|
||||
complex_order_stop_after_duration := null;
|
||||
|
||||
|
||||
If exist requested_date_template_list
|
||||
then
|
||||
alternating_day_start_dtm_list := ();
|
||||
//Try to Match it to a "T" or "T+n" Pattern
|
||||
for date_template in requested_date_template_list do
|
||||
|
||||
character_list := extract characters date_template;
|
||||
if count character_list = 1
|
||||
and character_list[1] = "T"
|
||||
then
|
||||
temp_start_dtm := order_med_significant_date;
|
||||
alternating_day_start_dtm_list :=
|
||||
alternating_day_start_dtm_list, temp_start_dtm;
|
||||
elseif count character_list > 2
|
||||
and character_list[1] = "T"
|
||||
and character_list[2] = "+"
|
||||
then
|
||||
new_num := (STRING (character_list where it is not in ("T", "+"))) AS NUMBER;
|
||||
temp_start_dtm := order_med_significant_date + new_num DAY;
|
||||
alternating_day_start_dtm_list :=
|
||||
alternating_day_start_dtm_list, temp_start_dtm;
|
||||
endif; //if count character_list = 1
|
||||
enddo; //for date_template
|
||||
endif; //If exist requested_date_template_list
|
||||
|
||||
|
||||
for complex_order in complex_order_list do
|
||||
// Increment Counter
|
||||
HH := HH + 1;
|
||||
|
||||
// Calculate the Duration of the StopAfter
|
||||
if complex_order.stop_after_option_type = 1 // Days
|
||||
then complex_order_stop_after_duration := complex_order.stop_after_value DAYS;
|
||||
elseif complex_order.stop_after_option_type = 2 // Hours
|
||||
then complex_order_stop_after_duration := complex_order.stop_after_value HOURS;
|
||||
elseif complex_order.stop_after_option_type = 3 // Minutes
|
||||
then complex_order_stop_after_duration := complex_order.stop_after_value MINUTES;
|
||||
elseif complex_order.stop_after_option_type = 4 // Times
|
||||
then
|
||||
// Create a list of dose admin times based on x-times. Use the estimation
|
||||
// method instead of the order as hold orders do not calculate
|
||||
(temp_admin_time_list,
|
||||
temp_next_start_dtm) := call func_dosage_admin_times with
|
||||
complex_order.frequency_code,
|
||||
complex_order.calculated_start_dtm,
|
||||
complex_order.estimated_stop_dtm,
|
||||
complex_order.stop_after_value,
|
||||
complex_order.stop_after_option_type,
|
||||
complex_order.freq_from_time,
|
||||
complex_order.freq_uom,
|
||||
null;
|
||||
|
||||
// Calculate the duration from the first admin-time to the last admin-time.
|
||||
temp_duration1 := (last temp_admin_time_list)
|
||||
- (first temp_admin_time_list);
|
||||
|
||||
//Calculate the duration from the last admin-time to when the
|
||||
// child order should stop
|
||||
temp_duration2 := (last temp_admin_time_list)
|
||||
- first (last 2 from temp_admin_time_list);
|
||||
|
||||
// Add the two durations
|
||||
complex_order_stop_after_duration := temp_duration1 + temp_duration2;
|
||||
|
||||
endif; //if complex_order.stop_after_option_type
|
||||
|
||||
if order_complex_order_type is in ( 1, 5) //Sequential or <Multiple> Frequency
|
||||
and exist complex_order_stop_after_duration
|
||||
then
|
||||
// Calculate and Set the DTMs
|
||||
if HH = 1
|
||||
then
|
||||
complex_order.calculated_start_dtm := order_med_significant_date;
|
||||
complex_order.estimated_stop_dtm := order_med_significant_date
|
||||
+ complex_order_stop_after_duration - 1 minute;
|
||||
else
|
||||
// Add 1 minute back to the prior stop dtm to calculate the new start dtm
|
||||
complex_order.calculated_start_dtm := prior_estimated_stop_dtm
|
||||
+ 1 minute;
|
||||
complex_order.estimated_stop_dtm := prior_estimated_stop_dtm
|
||||
+ complex_order_stop_after_duration;
|
||||
endif; // if HH
|
||||
|
||||
// Reset the Prior DTM
|
||||
prior_estimated_stop_dtm := complex_order.estimated_stop_dtm;
|
||||
|
||||
elseif order_complex_order_type = 3 //Concurrent
|
||||
then
|
||||
if exist alternating_day_start_dtm_list[HH]
|
||||
then
|
||||
complex_order.calculated_start_dtm := alternating_day_start_dtm_list[HH];
|
||||
endif;
|
||||
if exist complex_order_stop_after_duration
|
||||
then
|
||||
complex_order.estimated_stop_dtm := complex_order.calculated_start_dtm
|
||||
+ complex_order_stop_after_duration - 1 minute;
|
||||
endif; //if exist complex_order_stop_after_duration
|
||||
endif; //if order_complex_order_type
|
||||
enddo; //for complex_order
|
||||
endif; //if order_is_held
|
||||
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
// Remove Discontinued/Canceled Order Variable Components, if needed
|
||||
//-------------------------------------------------------------------
|
||||
// If any of the child orders have been discontinued/canceled
|
||||
// the dosage range should ignored the discontinued/ canceled doses.
|
||||
// This is handled by removing the discontinued/canceled object(s)
|
||||
// from the list of Order Variable Components.
|
||||
// A discontinued/canceled order has an OrderStatusLevelNum of 69.
|
||||
|
||||
if exist complex_order_list
|
||||
and any (complex_order_list.child_order_status_level_num = 69)
|
||||
then
|
||||
// Find the Order Variable Component Objects that are NOT Discontinued
|
||||
complex_order_list := complex_order_list where
|
||||
(complex_order_list.child_order_status_level_num <> 69
|
||||
or complex_order_list.child_order_status_level_num is NULL);
|
||||
endif; //if exist complex_order_list
|
||||
|
||||
|
||||
|
||||
//------------------------------------------------------------------
|
||||
// Create and Populate Med_Data_Object for the Main Order (CV3Order)
|
||||
//------------------------------------------------------------------
|
||||
|
||||
// This is the MAIN Order. It can be a Regular, IV-Additive or Complex Order
|
||||
//Create One Med_Data_Object
|
||||
mdo_main_order_list := ();
|
||||
instance := new Med_Data_Object;
|
||||
mdo_main_order_list := mdo_main_order_list, instance;
|
||||
|
||||
// Support for outpatient order: populate outpatient order properties
|
||||
if EvokingObject.AlternateOrderType = 2
|
||||
then
|
||||
mdo_main_order_list.is_outpatient_order := TRUE;
|
||||
mdo_main_order_list.is_script := order_AdditionalInfo_obj.IsScript;
|
||||
else
|
||||
mdo_main_order_list.is_outpatient_order := FALSE;
|
||||
endif;
|
||||
|
||||
// If the Main Order is a Complex Order with a frequency of <Multiple>
|
||||
// Do not populate the dose information on this instance of the object.
|
||||
// Instead, transfer the data to the other instances of the object for the Complex Order.
|
||||
// This transfer is done in the STD_Func_Dosage_Retrieve_Components MLM.
|
||||
if order_med_frequency = "<Multiple>"
|
||||
and exist complex_order_list
|
||||
then
|
||||
transfer_dose_to_complex_order_child_component := TRUE;
|
||||
else
|
||||
transfer_dose_to_complex_order_child_component := FALSE;
|
||||
|
||||
// Populate Med_Data_Object with Main Order Data
|
||||
mdo_main_order_list.order_med_dose_low := (order_med_dose_low_str AS NUMBER);
|
||||
mdo_main_order_list.order_med_units := order_med_uom;
|
||||
mdo_main_order_list.calc_med_per_uom := last (user_value
|
||||
where (user_data_code = "CalcUOMPer"));
|
||||
|
||||
// Select the Calc Dose Method and set it in the Med_Data_Object
|
||||
temp_calc_dose_method := (last (user_value
|
||||
where (user_data_code = "CalcDoseMethod"))) AS NUMBER;
|
||||
mdo_main_order_list.calc_dose_method := temp_calc_dose_method;
|
||||
|
||||
// Find the CalcDoseMethod and
|
||||
// Set the calculated-doses based on the CalcDoseMethod
|
||||
// 0 means the dose is stored as a single-dose-per-xx
|
||||
// 1 means the dose is stored as a total-daily-dose-per-xx
|
||||
// Convert to single-dose-per-xx by dividing the total-daily-dose-per-xx
|
||||
// by the conversion_factor_total
|
||||
|
||||
if temp_calc_dose_method = 0
|
||||
then
|
||||
mdo_main_order_list.calc_med_dose_high := (last (user_value
|
||||
where (user_data_code = "CalcActualDose")))AS NUMBER;
|
||||
mdo_main_order_list.calc_med_dose_low := (last (user_value
|
||||
where (user_data_code = "CalcActualDose")))AS NUMBER;
|
||||
elseif temp_calc_dose_method = 1
|
||||
then
|
||||
conversion_factor_total := call calc_freqmult_daily with
|
||||
order_med_frequency, OrderInfo_FreqFromTime, OrderInfo_FreqUOM;
|
||||
temp_calc_med_dose := ((last (user_value
|
||||
where (user_data_code = "CalcActualDose")))AS NUMBER) / conversion_factor_total;
|
||||
mdo_main_order_list.calc_med_dose_high := temp_calc_med_dose;
|
||||
mdo_main_order_list.calc_med_dose_low := temp_calc_med_dose;
|
||||
endif; //if temp_calc_dose_method = 0
|
||||
|
||||
|
||||
//When the high dose is NULL, substitute the low dose.
|
||||
if exist order_med_dose_high_str
|
||||
then mdo_main_order_list.order_med_dose_high := (order_med_dose_high_str AS NUMBER);
|
||||
else mdo_main_order_list.order_med_dose_high := (order_med_dose_low_str AS NUMBER);
|
||||
endif; //if exist order_med_dose_high_str
|
||||
endif; //if order_med_frequency = "<Multiple>"
|
||||
|
||||
|
||||
// Populate the object with the remaining data
|
||||
mdo_main_order_list.med_data_guid := order_guid;
|
||||
mdo_main_order_list.order_med_frequency := order_med_frequency;
|
||||
mdo_main_order_list.order_interval := order_interval;
|
||||
mdo_main_order_list.order_med_name := order_name;
|
||||
mdo_main_order_list.order_med_route := order_med_route;
|
||||
mdo_main_order_list.order_med_significant_date := order_med_significant_date;
|
||||
mdo_main_order_list.stop_dtm := order_stopdtm;
|
||||
mdo_main_order_list.stop_after_value := (OrderInfo_order_stop_after_value AS NUMBER) ;
|
||||
mdo_main_order_list.stop_after_option_type := (OrderInfo_order_stop_after_option AS NUMBER);
|
||||
mdo_main_order_list.freq_from_time := orderinfo_freqfromtime AS NUMBER;
|
||||
mdo_main_order_list.freq_to_time := orderinfo_freqtotime AS NUMBER;
|
||||
mdo_main_order_list.freq_uom := orderinfo_frequom;
|
||||
mdo_main_order_list.order_catalog_item_obj := order_catalog_item_obj;
|
||||
|
||||
//Determine the Med_Order_Type
|
||||
if exist comp_name_list
|
||||
then mdo_main_order_list.med_order_type := "IV-Additive";
|
||||
elseif exist complex_order_list
|
||||
then mdo_main_order_list.med_order_type := "Complex Order";
|
||||
else
|
||||
mdo_main_order_list.med_order_type := "Regular";
|
||||
endif; // if exist complex_order_list
|
||||
|
||||
|
||||
//----------------------------------------------------------
|
||||
// Create and Populate Med_Data_Objects with IV-Additives
|
||||
//----------------------------------------------------------
|
||||
mdo_iv_additive_list := ();
|
||||
|
||||
//Only execute this code if there are IV-Additives that
|
||||
//are not part of a complex order.
|
||||
if exist comp_name_list AND not exist complex_order_list
|
||||
then
|
||||
|
||||
for AA in (1 seqto count (comp_name_list)) do
|
||||
instance := new Med_Data_Object;
|
||||
mdo_iv_additive_list := mdo_iv_additive_list, instance;
|
||||
|
||||
//If the dose is calculated for the IV-Additive,
|
||||
//then a calc_dose_method of zero is the only one allowed.
|
||||
if exist comp_calc_actual_dose_list[AA]
|
||||
then instance.calc_dose_method := 0;
|
||||
endif; //if exist comp_calc_actual_dose_list[AA]
|
||||
|
||||
//When the high dose is NULL, substitute the low dose.
|
||||
if exist comp_hi_dose_list[AA]
|
||||
then instance.order_med_dose_high := comp_hi_dose_list[AA] AS NUMBER;
|
||||
else instance.order_med_dose_high := comp_low_dose_list[AA] AS NUMBER;
|
||||
endif; //if exist comp_hi_dose_list[AA]
|
||||
|
||||
enddo; // for AA
|
||||
|
||||
mdo_iv_additive_list.med_order_type := "IV-Additive";
|
||||
mdo_iv_additive_list.med_data_guid := comp_guid_list;
|
||||
mdo_iv_additive_list.calc_med_dose_high := (comp_calc_actual_dose_list AS NUMBER);
|
||||
mdo_iv_additive_list.calc_med_dose_low := (comp_calc_actual_dose_list AS NUMBER);
|
||||
mdo_iv_additive_list.calc_med_per_uom := comp_calc_uom_per_list;
|
||||
mdo_iv_additive_list.order_med_dose_low := (comp_low_dose_list AS NUMBER);
|
||||
mdo_iv_additive_list.order_med_frequency := order_med_frequency;
|
||||
mdo_iv_additive_list.order_interval := order_interval;
|
||||
mdo_iv_additive_list.order_med_name := comp_name_list;
|
||||
mdo_iv_additive_list.order_med_route := order_med_route;
|
||||
mdo_iv_additive_list.order_med_units := comp_uom_list;
|
||||
mdo_iv_additive_list.order_med_significant_date := order_med_significant_date;
|
||||
mdo_iv_additive_list.stop_dtm := order_stopdtm;
|
||||
mdo_iv_additive_list.stop_after_value := (OrderInfo_order_stop_after_value AS NUMBER) ;
|
||||
mdo_iv_additive_list.stop_after_option_type :=
|
||||
(OrderInfo_order_stop_after_option AS NUMBER);
|
||||
mdo_iv_additive_list.freq_from_time := orderinfo_freqfromtime AS NUMBER;
|
||||
mdo_iv_additive_list.freq_to_time := orderinfo_freqtotime AS NUMBER;
|
||||
mdo_iv_additive_list.freq_uom := orderinfo_frequom;
|
||||
mdo_iv_additive_list.order_catalog_item_obj := comp_catalog_item_obj_list;
|
||||
mdo_iv_additive_list.is_iv_additive := true;
|
||||
endif; //if exist comp_name_list
|
||||
|
||||
//----------------------------------------------------------
|
||||
// Create and Populate Med_Data_Objects with Complex Orders
|
||||
//----------------------------------------------------------
|
||||
//Create Med_Data_Objects
|
||||
mdo_complex_order_list := ();
|
||||
numComplexItems := 0;
|
||||
|
||||
//Only execute this code if there are Complex Order Components
|
||||
if exist complex_order_list
|
||||
then
|
||||
complexIVOrder := exists comp_name_list;
|
||||
numIVItems := 0;
|
||||
numComplexItems := count complex_order_list;
|
||||
if ( complexIVOrder )
|
||||
then
|
||||
numIVItems := count comp_name_list;
|
||||
endif;
|
||||
|
||||
for BB in ( 1 seqto numComplexItems ) do
|
||||
|
||||
instance := new Med_Data_Object;
|
||||
mdo_complex_order_list := mdo_complex_order_list, instance;
|
||||
|
||||
// Populate the High and Low Doses
|
||||
// Use the Doses from the Complex Order Component (OrderVariableComponent)
|
||||
dosageLow := complex_order_list[BB].dosage_low AS NUMBER;
|
||||
dosageHigh := complex_order_list[BB].dosage_high AS NUMBER;
|
||||
|
||||
instance.order_med_dose_low := dosageLow;
|
||||
|
||||
//When the HIGH DOSE is NULL, substitute the low dose from the Component
|
||||
if exist dosageHigh
|
||||
then instance.order_med_dose_high := dosageHigh;
|
||||
else instance.order_med_dose_high := dosageLow;
|
||||
endif; //if exist complex_order_list[BB].calc_actual_dose
|
||||
|
||||
// Select the Calc Dose Method and set it in the Med_Data_Object
|
||||
temp_calc_dose_method := complex_order_list[BB].calc_dose_method AS NUMBER;
|
||||
instance.calc_dose_method := temp_calc_dose_method;
|
||||
|
||||
// Find the CalcDoseMethod and
|
||||
// Set the calculated-doses based on the CalcDoseMethod
|
||||
// 0 means the dose is stored as a single-dose-per-xx
|
||||
// 1 means the dose is stored as a total-daily-dose-per-xx
|
||||
// Convert to single-dose-per-xx by dividing the total-daily-dose-per-xx
|
||||
// by the conversion_factor_total
|
||||
|
||||
if temp_calc_dose_method = 0
|
||||
then
|
||||
instance.calc_med_dose_high := complex_order_list[BB].calc_actual_dose AS NUMBER;
|
||||
instance.calc_med_dose_low := complex_order_list[BB].calc_actual_dose AS NUMBER;
|
||||
elseif temp_calc_dose_method = 1
|
||||
then
|
||||
conversion_factor_total := call calc_freqmult_daily with
|
||||
complex_order_list[BB].frequency_code,
|
||||
(complex_order_list[BB].freq_from_time AS NUMBER),
|
||||
complex_order_list[BB].freq_uom;
|
||||
temp_calc_med_dose :=
|
||||
(complex_order_list[BB].calc_actual_dose AS NUMBER) / conversion_factor_total;
|
||||
instance.calc_med_dose_high := temp_calc_med_dose;
|
||||
instance.calc_med_dose_low := temp_calc_med_dose;
|
||||
endif; //if temp_calc_dose_method = 0
|
||||
|
||||
//Populate Med_Data_Object Instances with Complex_Order data
|
||||
instance.order_med_units := complex_order_list[BB].uom;
|
||||
instance.calc_med_per_uom := complex_order_list[BB].calc_uom_per;
|
||||
instance.order_med_route := complex_order_list[BB].order_route_code;
|
||||
instance.order_med_frequency := complex_order_list[BB].frequency_code;
|
||||
instance.order_med_significant_date := complex_order_list[BB].calculated_start_dtm;
|
||||
instance.stop_dtm := complex_order_list[BB].Estimated_Stop_Dtm;
|
||||
instance.stop_after_value := complex_order_list[BB].stop_after_value AS NUMBER;
|
||||
instance.stop_after_option_type :=
|
||||
complex_order_list[BB].stop_after_option_type AS NUMBER;
|
||||
instance.freq_from_time := complex_order_list[BB].freq_from_time AS NUMBER;
|
||||
instance.freq_to_time := complex_order_list[BB].freq_to_time AS NUMBER;
|
||||
instance.freq_uom := complex_order_list[BB].freq_uom;
|
||||
instance.med_data_guid := complex_order_list[BB].guid;
|
||||
instance.order_med_name := order_name;
|
||||
instance.order_catalog_item_obj := order_catalog_item_obj;
|
||||
|
||||
//Populate Med_Data from OTHER Sources
|
||||
instance.med_order_type := "Complex Order";
|
||||
instance.order_interval := NULL;
|
||||
|
||||
for IV in ( 1 seqto numIVItems ) do
|
||||
|
||||
// Create an IV Order instance
|
||||
if numIVItems >= 1
|
||||
then
|
||||
IV_instance := new Med_Data_Object;
|
||||
dosageLow := comp_low_dose_list[IV] AS NUMBER;
|
||||
dosageHigh := comp_hi_dose_list[IV] AS NUMBER;
|
||||
//When the HIGH DOSE is NULL, substitute the low dose from the Component
|
||||
if exist dosageHigh
|
||||
then IV_instance.order_med_dose_high := dosageHigh;
|
||||
else IV_instance.order_med_dose_high := dosageLow;
|
||||
endif;
|
||||
IV_instance.order_med_dose_low := dosageLow;
|
||||
IV_instance.order_med_units := comp_uom_list[IV];
|
||||
IV_instance.calc_med_per_uom := comp_calc_uom_per_list[IV];
|
||||
IV_instance.order_med_name := comp_name_list[IV];
|
||||
IV_instance.order_catalog_item_obj := comp_catalog_item_obj_list[IV];
|
||||
|
||||
// Get rest of information from the current component
|
||||
IV_instance.order_med_route := complex_order_list[BB].order_route_code;
|
||||
IV_instance.order_med_frequency := complex_order_list[BB].frequency_code;
|
||||
IV_instance.order_med_significant_date := complex_order_list[BB].calculated_start_dtm;
|
||||
IV_instance.stop_dtm := complex_order_list[BB].Estimated_Stop_Dtm;
|
||||
IV_instance.stop_after_value := complex_order_list[BB].stop_after_value AS NUMBER;
|
||||
IV_instance.stop_after_option_type :=
|
||||
complex_order_list[BB].stop_after_option_type AS NUMBER;
|
||||
IV_instance.freq_from_time := complex_order_list[BB].freq_from_time AS NUMBER;
|
||||
IV_instance.freq_to_time := complex_order_list[BB].freq_to_time AS NUMBER;
|
||||
IV_instance.freq_uom := complex_order_list[BB].freq_uom;
|
||||
IV_instance.med_data_guid := complex_order_list[BB].guid;
|
||||
IV_instance.med_order_type := "Complex Order";
|
||||
IV_instance.is_iv_additive := true;
|
||||
|
||||
mdo_complex_order_list := mdo_complex_order_list, IV_instance;
|
||||
|
||||
endif;
|
||||
|
||||
enddo; // for IV
|
||||
|
||||
|
||||
enddo; // for BB
|
||||
|
||||
endif; //if exist complex_order_list
|
||||
|
||||
|
||||
//-----------------------------------
|
||||
//Create One List of Med_Data_Objects
|
||||
//-----------------------------------
|
||||
med_data_list := mdo_main_order_list, mdo_iv_additive_list, mdo_complex_order_list;
|
||||
|
||||
|
||||
//-----------------------
|
||||
//Create the Sort Numbers
|
||||
//-----------------------
|
||||
med_data_list.sort_number := 1 seqto count med_data_list;
|
||||
|
||||
//-----------------------
|
||||
//Get values used for multum support
|
||||
//-----------------------
|
||||
med_data_list.is_order := true;
|
||||
// Look up the multum drug catalog key for unit and route
|
||||
for med_data in med_data_list
|
||||
do
|
||||
med_data.order_med_uom_id := last(uom_drug_catalog_key where (uom_facility_code = med_data.order_med_units)) as NUMBER;
|
||||
med_data.order_med_route_id := last(route_drug_catalog_key where (route_code = med_data.order_med_route)) as NUMBER;
|
||||
enddo;
|
||||
|
||||
med_data_list.grouper_id := med_data_list.order_catalog_item_obj.DrcGrouperID;
|
||||
|
||||
//-------------------------------------------
|
||||
// Determine DOSE BASIS and Calculate WEIGHT
|
||||
//-------------------------------------------
|
||||
(calc_text_list,
|
||||
dose_basis_list,
|
||||
wt_kg_list,
|
||||
updated_calc_med_per_uom_list) :=
|
||||
call func_dosage_basis with (ht_cm, wt_kg, med_data_list.calc_med_per_uom);
|
||||
|
||||
//Set DoseBasis data in the Med Data object
|
||||
med_data_list.calc_text := calc_text_list;
|
||||
med_data_list.updated_calc_med_per_uom := updated_calc_med_per_uom_list;
|
||||
med_data_list.dose_basis := dose_basis_list;
|
||||
med_data_list.wt_kg := wt_kg_list;
|
||||
|
||||
// If the MLM is going to use the conversion factor logic then
|
||||
// the admin_times are not needed.
|
||||
Calculation_Method := call func_calc_method with med_data_list;
|
||||
med_data_list.calculation_method := Calculation_Method;
|
||||
|
||||
if Calculation_Method = "SUMMED"
|
||||
then
|
||||
|
||||
//---------------------------------------------------------
|
||||
//Populate the Administration Times in the Med_Data_Object
|
||||
//---------------------------------------------------------
|
||||
|
||||
orderCalculationFailed := true;
|
||||
performOrderCalculation := true;
|
||||
performMLMCalculation := false;
|
||||
next_StartTime := "";
|
||||
FirstComponentPosition := 2;
|
||||
CalculateAdministration := true;
|
||||
numMedItems := count med_data_list;
|
||||
|
||||
// Get the latest estimated Start and Stop dates from the complex order.
|
||||
// Make sure any NULL dates are removed
|
||||
if order_complex_order_type = 3 then
|
||||
latest_startDtm := max (med_data_list.order_med_significant_date where it is not NULL);
|
||||
latest_stopDtm := (max (med_data_list.stop_dtm where it is not NULL)) + 1 minute;
|
||||
latest_calcDtm := max ((latest_startDtm, latest_stopDtm) where it is not NULL);
|
||||
endif;
|
||||
|
||||
// First attempt to calculate the admin times using the order calculation object.
|
||||
// If any one of the calculations, throw all away and then calculate using
|
||||
// the MLM estimation method.
|
||||
while orderCalculationFailed do
|
||||
|
||||
for CC in med_data_list do
|
||||
|
||||
// If a Complex order or a complex IV Additive order skip the first
|
||||
// object as it is the master and contains no dosage information.
|
||||
if ( CC.med_order_type = "Complex order" OR complexIVOrder ) AND
|
||||
CC.sort_number = 1
|
||||
then
|
||||
CC.admin_dtm_list_calc_method := "Master";
|
||||
CalculateAdministration := false;
|
||||
else
|
||||
CalculateAdministration := true;
|
||||
|
||||
// Optimization: For IV and Complex IV orders only need to calculate the
|
||||
// the administration times once per administration.
|
||||
if med_data_list[1].med_order_type = "IV-Additive"
|
||||
then
|
||||
// If the current IV component has the same name as the master item
|
||||
// then it is the start of a new component block
|
||||
if med_data_list[1].Order_med_name = CC.Order_med_name
|
||||
then
|
||||
FirstComponentPosition := CC.sort_number;
|
||||
CalculateAdministration := true;
|
||||
else
|
||||
// If a reqular IV-Additive, just always copy the first additive.
|
||||
if CC.med_order_type = "IV-Additive"
|
||||
then
|
||||
if exists med_data_list[1].admin_dtm_list
|
||||
then
|
||||
//copy first object{{{SINGLE-QUOTE}}}s DTMs to the current object since they are both the same
|
||||
CC.admin_dtm_list := med_data_list[1].admin_dtm_list;
|
||||
CC.admin_dtm_list_calc_method := med_data_list[1].admin_dtm_list_calc_method;
|
||||
CalculateAdministration := false;
|
||||
endif;
|
||||
// If a Complex IV-Additive, copy the first additive of the current component
|
||||
elseif CC.med_order_type = "Complex order" AND complexIVOrder = true
|
||||
then
|
||||
// Copy the previously calculated DTMs
|
||||
CC.admin_dtm_list := med_data_list[FirstComponentPosition].admin_dtm_list;
|
||||
CC.admin_dtm_list_calc_method := med_data_list[FirstComponentPosition].admin_dtm_list_calc_method;
|
||||
CalculateAdministration := false;
|
||||
endif;
|
||||
endif;
|
||||
endif;
|
||||
endif;
|
||||
|
||||
if CalculateAdministration
|
||||
then
|
||||
isShiftFrequency := false;
|
||||
|
||||
// Set the calcStart_dtm to the calculated start date.
|
||||
// If this is a sequential order then only set it if not null,
|
||||
// otherwise for concurrent orders always set; it might be NULL.
|
||||
if CC.order_med_significant_date is not null OR
|
||||
order_complex_order_type = 3
|
||||
then
|
||||
calcStart_dtm := CC.order_med_significant_date;
|
||||
endif;
|
||||
|
||||
// Initialize the calculated stop date. For sequential orders
|
||||
// this value will be reset to null. For concurrent orders the
|
||||
// date will be calculated based on the latest start or stop information.
|
||||
calcStop_dtm := CC.stop_dtm;
|
||||
|
||||
if order_guid = CC.med_data_guid then
|
||||
componentGUID := null;
|
||||
else
|
||||
componentGUID := CC.med_data_guid;
|
||||
endif;
|
||||
|
||||
// First try to calculate all adminstrations using the order object
|
||||
if performOrderCalculation
|
||||
then
|
||||
|
||||
// If a complex order and the type is sequential or <Multiple> then
|
||||
// do not trust the EstimatedStopDtm calcuated by the order object.
|
||||
// It can sometimes be wrong. Instead pass a NULL to the DetermineAdministrationTimes
|
||||
// function and let the order figure it out.
|
||||
if order_complex_order_type is in (1,5) AND // Sequential or <Multiple>
|
||||
CC.med_order_type = "Complex order"
|
||||
then
|
||||
calcStop_dtm := null;
|
||||
else
|
||||
// If the Stop date is null and stop after type is not times (4)
|
||||
// then the code needs to calculate a stop date or the order calculations will fail.
|
||||
if CC.stop_after_option_type <> 4 // Times
|
||||
then
|
||||
if CC.stop_dtm is NULL
|
||||
then
|
||||
// For concurrent orders that do not have a defined stop date
|
||||
// the MLM will estimate a stop date based on 24 hours after
|
||||
// the last stop or start date, which ever is greater.
|
||||
if order_complex_order_type = 3 then
|
||||
calcStop_dtm := latest_calcDtm + (1 day - 1 minute);
|
||||
else
|
||||
// For sequential orders calculate a new stop date
|
||||
// based on the frequency and stop information.
|
||||
calcStop_dtm := call func_dosage_calc_stopdtm with
|
||||
CC.order_med_frequency,
|
||||
calcStart_dtm, //CC.order_med_significant_date,
|
||||
CC.freq_uom,
|
||||
CC.freq_from_time,
|
||||
CC.freq_to_time,
|
||||
CC.stop_after_value,
|
||||
CC.stop_after_option_type,
|
||||
order_TaskScheduleDefinition_obj;
|
||||
endif;
|
||||
else
|
||||
calcStop_dtm := CC.stop_dtm;
|
||||
endif;
|
||||
else
|
||||
// If stop after option is times, then ignore any calculated
|
||||
// stop date from the order.
|
||||
calcStop_dtm := null;
|
||||
endif;
|
||||
endif;
|
||||
|
||||
// Need a flag to indicate when we are on the first and last
|
||||
// complex item component.
|
||||
isFirstComponent := (CC.sort_number = 2);
|
||||
isLastComponent := (CC.sort_number = numMedItems - numIVItems);
|
||||
|
||||
// Calculate the admin times using the cached order object. These times
|
||||
// are more accurate.
|
||||
(admin_answer,
|
||||
calc_success,
|
||||
isShiftFrequency) := call func_dosage_admin_times_generated with
|
||||
order_guid,
|
||||
componentGUID,
|
||||
calcStart_dtm, // CC.order_med_significant_date,
|
||||
calcStop_dtm,
|
||||
isFirstComponent,
|
||||
isLastComponent;
|
||||
|
||||
// If the calculation succeeds then continue processing. if it fails
|
||||
// Then discard previous calculations and revert to MLM estimation
|
||||
// method.
|
||||
if NOT calc_success OR first admin_answer is NULL
|
||||
then
|
||||
// If a concurrent order then switch for this component to
|
||||
// MLM calculation logic, then switch back to try the order calculation
|
||||
// for the next component.
|
||||
if order_complex_order_type = 3 then
|
||||
performMLMCalculation := true;
|
||||
else
|
||||
orderCalculationFailed := true;
|
||||
performOrderCalculation := false;
|
||||
next_StartTime := "";
|
||||
endif;
|
||||
|
||||
else // Success
|
||||
CC.admin_dtm_list_calc_method := "Order";
|
||||
CC.calcStop_dtm := calcStop_dtm;
|
||||
|
||||
orderCalculationFailed := false;
|
||||
performMLMCalculation := false;
|
||||
endif;
|
||||
|
||||
endif; // PerformOrderCalculation
|
||||
|
||||
// If the order object calculation fails then
|
||||
// calculate using the MLM estimation method.
|
||||
if performMLMCalculation
|
||||
then
|
||||
// reset the admin times
|
||||
CC.admin_dtm_list := null;
|
||||
|
||||
(admin_answer,
|
||||
next_StartTime,
|
||||
isShiftFrequency) := call func_dosage_admin_times with
|
||||
CC.order_med_frequency,
|
||||
calcStart_dtm, // CC.order_med_significant_date,
|
||||
calcStop_dtm, // CC.stop_dtm,
|
||||
CC.stop_after_value,
|
||||
CC.stop_after_option_type,
|
||||
CC.freq_from_time,
|
||||
CC.freq_uom,
|
||||
order_TaskScheduleDefinition_obj ;
|
||||
|
||||
CC.admin_dtm_list_calc_method := "MLM";
|
||||
|
||||
orderCalculationFailed := false; // always success
|
||||
|
||||
// Capture for debug, the calculated Start and stop times.
|
||||
CC.calcStart_dtm := calcStart_dtm;
|
||||
if calcStop_dtm is NULL
|
||||
then
|
||||
CC.calcStop_dtm := next_StartTime - 1 minute;
|
||||
else
|
||||
CC.calcStop_dtm := calcStop_dtm;
|
||||
endif;
|
||||
|
||||
// Set the start Dtm for the next sequential component
|
||||
// value can be overridden by the component{{{SINGLE-QUOTE}}}s CalculatedStartDtm.
|
||||
calcStart_dtm := next_StartTime;
|
||||
|
||||
endif;
|
||||
|
||||
// Only populate admin_dtm_list when DTMs exist
|
||||
if exist admin_answer
|
||||
then CC.admin_dtm_list := admin_answer;
|
||||
endif;
|
||||
|
||||
CC.isShiftFrequency := isShiftFrequency;
|
||||
|
||||
endif; // CalculateAdministration
|
||||
|
||||
enddo; //for CC
|
||||
|
||||
performMLMCalculation := true;
|
||||
performOrderCalculation := false;
|
||||
|
||||
enddo; // orderCalculationFailed
|
||||
|
||||
endif; // Use_conversion_factor
|
||||
|
||||
// Set the multum frequency id
|
||||
for med_data_item in med_data_list
|
||||
do
|
||||
med_data_item.multum_freq_id := last (frequency_drug_catalog_key where (frequency_code = med_data_item.order_med_frequency));
|
||||
enddo;
|
||||
|
||||
//Always Conclude True
|
||||
Conclude True;
|
||||
;;
|
||||
action:
|
||||
return med_data_list;
|
||||
;;
|
||||
Urgency: 50;;
|
||||
end:
|
||||
323
MLMStripper/bin/Debug/STD/STD_FUNC_DOSAGE_LISTS_RX.mlm
Normal file
323
MLMStripper/bin/Debug/STD/STD_FUNC_DOSAGE_LISTS_RX.mlm
Normal file
@@ -0,0 +1,323 @@
|
||||
maintenance:
|
||||
|
||||
title: Creates a List of Objects with Medication Data;;
|
||||
mlmname: STD_FUNC_DOSAGE_LISTS_RX;;
|
||||
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: Gathers the dosing data for the prescription.
|
||||
;;
|
||||
explanation: The dosing data for a prescription are stored in several tables/objects.
|
||||
This MLM gathers all the data from the various sources and consolidates them into
|
||||
an object called Med_Data_Object.
|
||||
There can be one Med_Data_Objects for a prescription.
|
||||
;;
|
||||
keywords: single dose; average daily dose; total daily dose; dosage range
|
||||
;;
|
||||
knowledge:
|
||||
type: data-driven;;
|
||||
data:
|
||||
// include common data structures
|
||||
std_dosage_includes := MLM {{{SINGLE-QUOTE}}}std_func_dosage_includes{{{SINGLE-QUOTE}}};
|
||||
include std_dosage_includes;
|
||||
|
||||
(
|
||||
ht_cm,
|
||||
wt_kg
|
||||
) := ARGUMENT;
|
||||
|
||||
// Set to true if logging is needed.
|
||||
log_execution_info := false;
|
||||
|
||||
//--------------
|
||||
// Declare MLMs
|
||||
//--------------
|
||||
func_dosage_basis := MLM {{{SINGLE-QUOTE}}}std_func_dosage_basis{{{SINGLE-QUOTE}}};
|
||||
calc_freqmult_daily := MLM {{{SINGLE-QUOTE}}}sys_calc_freqmult_daily{{{SINGLE-QUOTE}}};
|
||||
func_calc_method := MLM {{{SINGLE-QUOTE}}}STD_FUNC_DOSAGE_CALC_METHOD{{{SINGLE-QUOTE}}};
|
||||
|
||||
//---------------------
|
||||
// Declare the Objects
|
||||
//---------------------
|
||||
//The Med_Data_Object declaration moved to STD_FUNC_DOSAGE_INCLUDES
|
||||
//Note: Med_Data_GUID is the SXAAMBClientPrescription.CDSUniqueIDGUID
|
||||
|
||||
//--------------------------------------------
|
||||
// Get the current order{{{SINGLE-QUOTE}}}s Dosage information
|
||||
//--------------------------------------------
|
||||
(rx_name,
|
||||
rx_dose_str,
|
||||
rx_dose_uom,
|
||||
rx_dose_uom_id,
|
||||
rx_frequency,
|
||||
rx_frequency_multiplier,
|
||||
rx_frequency_id,
|
||||
rx_route,
|
||||
rx_route_id,
|
||||
rx_start_date,
|
||||
rx_stop_date,
|
||||
rx_renewal_date,
|
||||
rx_cds_unique_guid,
|
||||
rx_status_type,
|
||||
rx_prescription_type,
|
||||
rx_formulary_drug_key,
|
||||
rx_formulary_brand_key,
|
||||
rx_generic_item_id,
|
||||
rx_generic_name_id,
|
||||
rx_instructions,
|
||||
backup) := read last {ClientPrescription:
|
||||
DrugName,
|
||||
DoseAmount,
|
||||
DoseUOM,
|
||||
DoseUOMID,
|
||||
Frequency,
|
||||
FrequencyMultiplier,
|
||||
ScriptFrequencyID,
|
||||
Route,
|
||||
RouteID,
|
||||
StartDate,
|
||||
EndDate,
|
||||
RenewalDate,
|
||||
CDSUniqueIDGUID,
|
||||
StatusType,
|
||||
PrescriptionType,
|
||||
FormularyDrugKey,
|
||||
FormularyBrandKey,
|
||||
GenericItemID,
|
||||
GenericNameID,
|
||||
Instructions,
|
||||
BackUp
|
||||
REFERENCING EvokingObject
|
||||
WHERE PrescriptionTypeDescription in ("Rx", "Hx", "E") };
|
||||
|
||||
// Dnum value can be found in SXAAMBClientPrescription table
|
||||
// when the formulary brand key does not exist and
|
||||
// the formulary drug key exists
|
||||
if ((rx_formulary_brand_key is null or rx_formulary_brand_key = "")
|
||||
and (exists rx_formulary_drug_key and rx_formulary_drug_key <> "")
|
||||
)
|
||||
then
|
||||
multum_dnum := rx_formulary_drug_key;
|
||||
else
|
||||
(multum_dnum) := read last {
|
||||
"SELECT name.DrugCatalogKey "
|
||||
|| "FROM SXARxGenericName name "
|
||||
|| "WHERE name.GenericNameID = " || SQLEX(rx_generic_name_id)
|
||||
};
|
||||
endif;
|
||||
|
||||
// MMDC value is not always filled in the SXAAMBClientPrescription table
|
||||
// The value can be found when the formulary brand key exists
|
||||
if (exists rx_formulary_brand_key
|
||||
and rx_formulary_brand_key <> "")
|
||||
then
|
||||
multum_mmdc := rx_formulary_drug_key;
|
||||
else
|
||||
(multum_mmdc) := read last {
|
||||
"SELECT item.DrugCatalogKey "
|
||||
|| "FROM SXARxGenericItem item "
|
||||
|| "WHERE item.GenericItemID = " || SQLEX(rx_generic_item_id)
|
||||
};
|
||||
endif;
|
||||
|
||||
(multum_route_desc, multum_route_id) := read last {
|
||||
"SELECT rxRoute.RouteDescription, rxRoute.DrugCatalogKey "
|
||||
|| "FROM SXARxRoute rxRoute "
|
||||
|| "WHERE rxRoute.RxRouteID = " || SQLEX(rx_route_id)
|
||||
};
|
||||
|
||||
if (multum_route_id is NULL)
|
||||
then
|
||||
(multum_route_desc, multum_route_id) := read last {
|
||||
"SELECT route_description, route_code "
|
||||
|| "FROM SXAMTmultum_clinical_routeSYN "
|
||||
|| "WHERE route_description = " || SQLEX(rx_route) || "\n"
|
||||
|| "UNION "
|
||||
|| "SELECT route_description, route_code "
|
||||
|| "FROM SXAMTmultum_product_routeSYN "
|
||||
|| "WHERE route_description =" || SQLEX(rx_route) || "\n"
|
||||
|| "UNION "
|
||||
|| "SELECT ne.nomenclature_description, ne.nomenclature_id "
|
||||
|| "FROM SXAMTdrc_nomenclatureSYN ne "
|
||||
|| "WHERE ne.nomenclature_description = " || SQLEX(rx_route)
|
||||
};
|
||||
endif;
|
||||
|
||||
multum_route_id := multum_route_id as NUMBER;
|
||||
|
||||
(multum_unit, multum_uom_id) := read last {
|
||||
"SELECT unit.Name, unit.DrugCatalogKey "
|
||||
|| "FROM SXARxUnitOfMeasure unit "
|
||||
|| "WHERE (unit.RxUOMID = " || SQLEX(rx_dose_uom_id) || ") "
|
||||
|| "or (unit.Name = " || SQLEX(rx_dose_uom) || ")"
|
||||
};
|
||||
|
||||
if (multum_uom_id is null)
|
||||
then
|
||||
(multum_unit, multum_uom_id) := read last {
|
||||
"SELECT ne.nomenclature_description, ne.nomenclature_id "
|
||||
||"FROM SXAMTdrc_nomenclatureSYN ne "
|
||||
||"WHERE ne.nomenclature_description = " || SQLEX(rx_dose_uom)
|
||||
};
|
||||
endif;
|
||||
|
||||
// Extract multum frequency id
|
||||
(multum_frequency, multum_frequency_id) := read last {
|
||||
"SELECT f.Description, f.DrugCatalogKey "
|
||||
||"FROM SXAAMBScriptFrequency f "
|
||||
||"INNER JOIN SXAMTmultum_frequencySYN mf on mf.frequency_code = f.DrugCatalogKey "
|
||||
||"WHERE f.ScriptFrequencyID = " || SQLEX(rx_frequency_id)
|
||||
};
|
||||
|
||||
if multum_mmdc is not NULL
|
||||
then
|
||||
// SXAABMClientPrescription.FormularyDrugKey stores both mmdc and dnum
|
||||
(multum_grouper_id) := read last {
|
||||
"SELECT drc.grouper_id "
|
||||
|| "FROM SXAMTdrc_grouper_route_mmdcSYN drc "
|
||||
|| "WHERE drc.main_multum_drug_code = " || SQLEX(multum_mmdc)
|
||||
};
|
||||
else
|
||||
(grouper_id_list, grouper_name_list) := read {
|
||||
"SELECT grp.grouper_id, grp.grouper_name "
|
||||
|| "FROM SXAMTdrc_grouperSYN grp "
|
||||
|| "WHERE grp.drug_id = " || SQLEX(multum_dnum)
|
||||
};
|
||||
|
||||
grouper_count := count grouper_id_list;
|
||||
|
||||
if grouper_count = 1
|
||||
then
|
||||
multum_grouper_id := grouper_id_list[1];
|
||||
else
|
||||
multum_grouper_id := last (grouper_id_list WHERE grouper_name_list = rx_name);
|
||||
|
||||
if (multum_grouper_id is NULL)
|
||||
then
|
||||
grouper_info_list := ();
|
||||
for ind in (1 seqto grouper_count)
|
||||
do
|
||||
grouper_info_instance := new Grouper_Info_Object;
|
||||
grouper_info_instance.grouper_id := grouper_id_list[ind];
|
||||
grouper_info_instance.grouper_name := grouper_name_list[ind];
|
||||
grouper_info_list := grouper_info_list, grouper_info_instance;
|
||||
enddo;
|
||||
|
||||
dnum_grouper_info := new Patient_Property_Obj;
|
||||
dnum_grouper_info.type := "Dnum-Grouper";
|
||||
dnum_grouper_info.value := grouper_info_list;
|
||||
dnum_grouper_info.is_unmapped := true;
|
||||
endif;
|
||||
endif;
|
||||
endif;
|
||||
|
||||
// Get the evoking object{{{SINGLE-QUOTE}}}s visit TimeZone
|
||||
(visit_time_zone) := read last { ClientVisit: TimeZone };
|
||||
|
||||
;;
|
||||
evoke:
|
||||
;;
|
||||
logic:
|
||||
//------------------------------------------------------------------
|
||||
// Create and Populate Med_Data_Object for the Prescription (SXAAMBClientPrescription)
|
||||
//------------------------------------------------------------------
|
||||
|
||||
//Create One Med_Data_Object
|
||||
med_data_list := ();
|
||||
instance := new Med_Data_Object;
|
||||
med_data_list := med_data_list, instance;
|
||||
|
||||
if (rx_renewal_date is not null)
|
||||
then
|
||||
rx_significant_dtm := rx_renewal_date;
|
||||
else
|
||||
rx_significant_dtm := rx_start_date;
|
||||
endif;
|
||||
|
||||
if rx_significant_dtm is null
|
||||
then
|
||||
rx_significant_dtm := (day floor of (now AS TIME visit_time_zone));
|
||||
endif;
|
||||
|
||||
// Populate the object with the remaining data
|
||||
med_data_list.med_data_guid := rx_cds_unique_guid;
|
||||
med_data_list.order_med_frequency := rx_frequency;
|
||||
med_data_list.multum_freq_id := multum_frequency_id;
|
||||
med_data_list.order_med_name := rx_name;
|
||||
med_data_list.order_med_route := rx_route;
|
||||
med_data_list.order_med_significant_date := rx_significant_dtm;
|
||||
med_data_list.stop_dtm := rx_stop_date;
|
||||
|
||||
med_data_list.rx_instructions := rx_instructions;
|
||||
med_data_list.freq_multiplier := (rx_frequency_multiplier AS NUMBER);
|
||||
|
||||
med_data_list.order_med_dose_high := (rx_dose_str AS NUMBER);
|
||||
med_data_list.order_med_dose_low := (rx_dose_str AS NUMBER);
|
||||
med_data_list.order_med_units := rx_dose_uom;
|
||||
|
||||
med_data_list.order_med_route := rx_route;
|
||||
|
||||
// Map multum values
|
||||
med_data_list.order_med_route_id := multum_route_id AS NUMBER;
|
||||
med_data_list.order_med_uom_id := multum_uom_id AS NUMBER;
|
||||
med_data_list.grouper_id := multum_grouper_id;
|
||||
med_data_list.multum_mmdc := multum_mmdc AS NUMBER;
|
||||
med_data_list.multum_dnum := multum_dnum;
|
||||
|
||||
//-------------------------------------------
|
||||
// Determine DOSE BASIS and Calculate WEIGHT
|
||||
//-------------------------------------------
|
||||
(calc_text_list,
|
||||
dose_basis_list,
|
||||
wt_kg_list,
|
||||
updated_calc_med_per_uom_list) :=
|
||||
call func_dosage_basis with (ht_cm, wt_kg, "");
|
||||
|
||||
//Set DoseBasis data in the Med Data object
|
||||
med_data_list.calc_text := calc_text_list;
|
||||
med_data_list.updated_calc_med_per_uom := updated_calc_med_per_uom_list;
|
||||
med_data_list.dose_basis := dose_basis_list;
|
||||
med_data_list.wt_kg := wt_kg_list;
|
||||
|
||||
// If the MLM is going to use the conversion factor logic then
|
||||
// the admin_times are not needed.
|
||||
Calculation_Method := call func_calc_method with med_data_list;
|
||||
med_data_list.calculation_method := Calculation_Method;
|
||||
|
||||
//-----------------------
|
||||
//Create the Sort Numbers
|
||||
//-----------------------
|
||||
med_data_list.sort_number := 1 seqto count med_data_list;
|
||||
|
||||
med_data_list.med_order_type := "Prescription";
|
||||
med_data_list.is_order := false;
|
||||
|
||||
//Always Conclude True
|
||||
Conclude True;
|
||||
;;
|
||||
action:
|
||||
return med_data_list, dnum_grouper_info;
|
||||
;;
|
||||
Urgency: 50;;
|
||||
end:
|
||||
3711
MLMStripper/bin/Debug/STD/STD_FUNC_DOSAGE_MESSAGES.mlm
Normal file
3711
MLMStripper/bin/Debug/STD/STD_FUNC_DOSAGE_MESSAGES.mlm
Normal file
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,73 @@
|
||||
maintenance:
|
||||
|
||||
title: ;;
|
||||
mlmname: STD_FUNC_DOSAGE_MSG_FORMAT_DOSE_RANGE;;
|
||||
arden: version 2.5;;
|
||||
version: 18.4;;
|
||||
institution: Allscripts, Standard MLM;;
|
||||
author: Allscripts Healthcare Solutions, Inc.;;
|
||||
specialist: ;;
|
||||
date: 2018-10-26;;
|
||||
validation: testing;;
|
||||
|
||||
/* P r o p r i e t a r y N o t i c e */
|
||||
/* Unpublished (c) 2013 - 2018 Allscripts Healthcare, LLC. and/or its affiliates. All Rights Reserved.
|
||||
|
||||
P r o p r i e t a r y N o t i c e: This software has been provided pursuant to a License Agreement, with
|
||||
Allscripts Healthcare, LLC. and/or its affiliates, containing restrictions on its use. This software contains
|
||||
valuable trade secrets and proprietary information of Allscripts Healthcare, LLC. and/or its affiliates and is
|
||||
protected by trade secret and copyright law. This software may not be copied or distributed in any form or medium,
|
||||
disclosed to any third parties, or used in any manner not provided for in said License Agreement except with prior
|
||||
written authorization from Allscripts Healthcare, LLC. and/or its affiliates. Notice to U.S. Government Users:
|
||||
This software is {{{SINGLE-QUOTE}}}Commercial Computer Software{{{SINGLE-QUOTE}}}.
|
||||
|
||||
All product names are the trademarks or registered trademarks of Allscripts Healthcare, LLC. and/or its affiliates.
|
||||
*/
|
||||
/* P r o p r i e t a r y N o t i c e */
|
||||
|
||||
library:
|
||||
purpose: Creates the dose detail string for the Dosage-Range checking MLM.
|
||||
;;
|
||||
explanation: This MLM creates the dose string:
|
||||
- Formats the dose value for display
|
||||
- When lower and upper doses are different, it shows as "lower dose" - "upper dose"
|
||||
- When the doses are the same, it shows the single dose
|
||||
;;
|
||||
keywords: single dose; average daily dose; total daily dose; dosage range
|
||||
;;
|
||||
knowledge:
|
||||
type: data-driven;;
|
||||
data:
|
||||
add_commas := MLM {{{SINGLE-QUOTE}}}SYS_FORMAT_NUMBER{{{SINGLE-QUOTE}}};
|
||||
|
||||
(lower_dose, upper_dose) := ARGUMENT;
|
||||
|
||||
;;
|
||||
priority: 50
|
||||
;;
|
||||
evoke:
|
||||
;;
|
||||
logic:
|
||||
|
||||
if lower_dose = upper_dose
|
||||
then
|
||||
formatted_lower_dose:= call add_commas with (,lower_dose);
|
||||
printable_dose_range:= formatted_lower_dose ;
|
||||
else
|
||||
formatted_lower_dose := call add_commas with (,lower_dose);
|
||||
formatted_upper_dose := call add_commas with (,upper_dose);
|
||||
printable_dose_range := formatted_lower_dose || "-"
|
||||
|| formatted_upper_dose ;
|
||||
endif; //if lower_dose = upper_dose
|
||||
|
||||
|
||||
|
||||
// Always Conclude True
|
||||
conclude true;
|
||||
|
||||
;;
|
||||
action:
|
||||
return printable_dose_range;
|
||||
;;
|
||||
Urgency: 50;;
|
||||
end:
|
||||
298
MLMStripper/bin/Debug/STD/STD_FUNC_DOSAGE_MULTUM.mlm
Normal file
298
MLMStripper/bin/Debug/STD/STD_FUNC_DOSAGE_MULTUM.mlm
Normal file
@@ -0,0 +1,298 @@
|
||||
maintenance:
|
||||
|
||||
title: Executes the stored procedure that retrieves Multum dosage ranges from the database;;
|
||||
mlmname: STD_FUNC_DOSAGE_MULTUM;;
|
||||
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: Finds the appropriate dose-range from the multum grouper dose ranges and
|
||||
returns the information to the calling MLM.
|
||||
;;
|
||||
explanation: The MLM assists the STD_Func_Dosage_Rules MLM to retrieve Multum dosage ranges
|
||||
from the database that may be out of range
|
||||
;;
|
||||
keywords: single dose; average daily dose; total daily dose; dosage range
|
||||
;;
|
||||
knowledge:
|
||||
type: data-driven;;
|
||||
data:
|
||||
// include common data structures
|
||||
std_dosage_includes := MLM {{{SINGLE-QUOTE}}}std_func_dosage_includes{{{SINGLE-QUOTE}}};
|
||||
include std_dosage_includes;
|
||||
|
||||
(
|
||||
drc_grouper_id,
|
||||
drug_name,
|
||||
multum_dnum,
|
||||
multum_mmdc,
|
||||
order_med_route,
|
||||
order_med_route_id,
|
||||
is_generic_route,
|
||||
order_med_significant_date,
|
||||
order_med_units,
|
||||
order_med_uom_id,
|
||||
order_med_frequency,
|
||||
multum_freq_id,
|
||||
med_order_type,
|
||||
patient_birthday_info_on_order,
|
||||
wt_kg,
|
||||
BSA_value,
|
||||
intl_patient_gender,
|
||||
has_liver_disease_bit,
|
||||
dialysis_type_str,
|
||||
serum_creatinine,
|
||||
intentionally_unmapped_frequency_list,
|
||||
alert_if_missing_flags,
|
||||
is_order,
|
||||
patient_info,
|
||||
core_uom_const
|
||||
) := ARGUMENT;
|
||||
|
||||
// Set to true if logging is needed.
|
||||
log_execution_info := false;
|
||||
|
||||
// Declare the MLMs that can be called
|
||||
xml_params := MLM {{{SINGLE-QUOTE}}}STD_Func_Dosage_XML_Params{{{SINGLE-QUOTE}}};
|
||||
|
||||
// Change the internal patient gender to XML
|
||||
if (intl_patient_gender = "O")
|
||||
then
|
||||
patient_gender := "U";
|
||||
else
|
||||
patient_gender := intl_patient_gender;
|
||||
endif;
|
||||
|
||||
// Need User GUID for security purposes
|
||||
//user_GUID := read last { UserInfo: GUID }; // fails under specflow
|
||||
user_GUID := read last { StateInfo: UserGUID };
|
||||
|
||||
// XML parameter
|
||||
( input_param_xml,
|
||||
missing_route,
|
||||
unmapped_route,
|
||||
missing_uom,
|
||||
unmapped_uom
|
||||
) := call xml_params with
|
||||
(
|
||||
// Common medication data
|
||||
drc_grouper_id,
|
||||
multum_dnum,
|
||||
multum_mmdc,
|
||||
order_med_route,
|
||||
order_med_route_id,
|
||||
is_generic_route,
|
||||
order_med_significant_date,
|
||||
order_med_units,
|
||||
order_med_uom_id,
|
||||
multum_freq_id,
|
||||
med_order_type,
|
||||
is_order,
|
||||
// Patient data
|
||||
patient_birthday_info_on_order,
|
||||
true, //has_valid_birthdate,
|
||||
wt_kg,
|
||||
BSA_value,
|
||||
patient_gender,
|
||||
// Item Catalog only
|
||||
false, //for_item_catalog
|
||||
null, //catalog_item_obj,
|
||||
// Multum only
|
||||
has_liver_disease_bit,
|
||||
dialysis_type_str,
|
||||
serum_creatinine,
|
||||
// Flags and constants
|
||||
alert_if_missing_flags,
|
||||
patient_info,
|
||||
core_uom_const
|
||||
);
|
||||
|
||||
debug_db_str:="EXEC SCMMultumGrouperDosageRangePR "
|
||||
|| SQL(input_param_xml) || ", "
|
||||
|| SQL(user_GUID);
|
||||
|
||||
if (exists drc_grouper_id
|
||||
or alert_if_missing_flags.cannot_check_DNUM_Rx_to_Multum)
|
||||
then
|
||||
// Call the stored procedure
|
||||
(
|
||||
found_matching_case_list,
|
||||
dosage_type_list,
|
||||
case_id_list,
|
||||
grouper_id_list,
|
||||
route_id_list,
|
||||
route_list,
|
||||
contraindication_list,
|
||||
recommendation_list,
|
||||
actual_lower_dose_list,
|
||||
actual_upper_dose_list,
|
||||
actual_uom_id_list,
|
||||
actual_dose_uom_list,
|
||||
conversion_factor_list,
|
||||
actual_dose_freq_list,
|
||||
is_PER_WT_list,
|
||||
is_PER_M2_list,
|
||||
age_criteria_list,
|
||||
weight_criteria_list,
|
||||
gender_criteria_list,
|
||||
renal_criteria_list,
|
||||
creatinine_criteria_list,
|
||||
liver_criteria_list,
|
||||
condition_criteria_list,
|
||||
uom_conversion_issue_list,
|
||||
route_conversion_issue_list,
|
||||
frequency_issue_list,
|
||||
is_default_list,
|
||||
hard_stop_high_list,
|
||||
hard_stop_low_list,
|
||||
crcl_within_range_list,
|
||||
estimated_age_used_list
|
||||
) := read { "EXEC SCMMultumGrouperDosageRangePR "
|
||||
|| SQL(input_param_xml) || ", "
|
||||
|| SQL(user_GUID)
|
||||
};
|
||||
|
||||
endif;
|
||||
;;
|
||||
evoke:
|
||||
;;
|
||||
logic:
|
||||
|
||||
multum_dosage_range_list := ();
|
||||
|
||||
if exists found_matching_case_list
|
||||
then
|
||||
row_count := count found_matching_case_list;
|
||||
list_indices := 1 seqto row_count;
|
||||
|
||||
// Step through the multum results and create the dosage range list
|
||||
for ind in list_indices
|
||||
do
|
||||
dosage_range_item := new Dosage_Range_Object;
|
||||
multum_dosage_range_list := multum_dosage_range_list, dosage_range_item;
|
||||
|
||||
dosage_range_item.med_name := drug_name;
|
||||
if found_matching_case_list[ind] = 1 or found_matching_case_list[ind] = true
|
||||
then
|
||||
dosage_range_item.match_found := true;
|
||||
else
|
||||
dosage_range_item.match_found := false;
|
||||
endif;
|
||||
|
||||
if ((dosage_type_list[ind] = "daily dose range checking (metric)" ) or
|
||||
(dosage_type_list[ind] = "daily dose range checking (formulation)" ))
|
||||
then
|
||||
dosage_range_item.dosage_type := "total";
|
||||
dosage_range_item.is_range := true;
|
||||
elseif ((dosage_type_list[ind] = "single dose range checking (metric)" ) or
|
||||
(dosage_type_list[ind] = "single dose range checking (formulation)" ))
|
||||
then
|
||||
dosage_range_item.dosage_type := "single";
|
||||
dosage_range_item.is_range := true;
|
||||
else
|
||||
dosage_range_item.dosage_type := "contraindication";
|
||||
dosage_range_item.is_range := false;
|
||||
endif;
|
||||
|
||||
dosage_range_item.contraindication_msg := contraindication_list[ind];
|
||||
dosage_range_item.recommendation_msg := recommendation_list[ind];
|
||||
|
||||
dosage_range_item.lower_dose := actual_lower_dose_list[ind];
|
||||
dosage_range_item.upper_dose := actual_upper_dose_list[ind];
|
||||
dosage_range_item.unit_of_measure := actual_dose_uom_list[ind];
|
||||
dosage_range_item.age_criteria := age_criteria_list[ind];
|
||||
dosage_range_item.weight_criteria := weight_criteria_list[ind];
|
||||
dosage_range_item.gender_criteria := gender_criteria_list[ind];
|
||||
dosage_range_item.renal_criteria := renal_criteria_list[ind];
|
||||
dosage_range_item.creatinine_criteria := creatinine_criteria_list[ind];
|
||||
dosage_range_item.liver_criteria := liver_criteria_list[ind];
|
||||
dosage_range_item.condition_criteria := condition_criteria_list[ind];
|
||||
dosage_range_item.is_PER_WT := is_PER_WT_list[ind];
|
||||
dosage_range_item.is_PER_M2 := is_PER_M2_list[ind];
|
||||
dosage_range_item.conversion_factor := conversion_factor_list[ind];
|
||||
dosage_range_item.uom_conversion_issue := uom_conversion_issue_list[ind] in (1, true);
|
||||
dosage_range_item.crcl_within_range := crcl_within_range_list[ind] in (1, true);
|
||||
|
||||
route_conversion_issue := route_conversion_issue_list[ind] in (1, true);
|
||||
|
||||
if is_generic_route
|
||||
then
|
||||
dosage_range_item.unrecognized_route_conversion_issue := route_conversion_issue;
|
||||
else
|
||||
dosage_range_item.inapplicable_route_conversion_issue := route_conversion_issue;
|
||||
endif;
|
||||
|
||||
// Dose range frequency
|
||||
dosage_range_item.dose_frequency := actual_dose_freq_list[ind];
|
||||
if multum_freq_id is null
|
||||
then
|
||||
if ( order_med_frequency not in (intentionally_unmapped_frequency_list, null)
|
||||
and alert_if_missing_flags.unmapped_frequency )
|
||||
then
|
||||
dosage_range_item.frequency_issue := "unmapped";
|
||||
endif;
|
||||
else
|
||||
if frequency_issue_list[ind] in (1, true)
|
||||
then
|
||||
dosage_range_item.frequency_issue := "too frequent";
|
||||
endif;
|
||||
endif;
|
||||
|
||||
// multum data will always be "Dose Reg", as the denominator will be multiplied
|
||||
dosage_range_item.dose_calc_method := "Dose Reg";
|
||||
dosage_range_item.corrected_uom := actual_dose_uom_list[ind];
|
||||
|
||||
dosage_range_item.is_multum := true;
|
||||
dosage_range_item.grouper_id := grouper_id_list[ind];
|
||||
dosage_range_item.case_id := case_id_list[ind];
|
||||
dosage_range_item.route := route_list[ind];
|
||||
dosage_range_item.route_id := route_id_list[ind];
|
||||
dosage_range_item.med_route := order_med_route;
|
||||
dosage_range_item.med_route_id := order_med_route_id;
|
||||
|
||||
is_default := false;
|
||||
if (is_default_list[ind] = 1)
|
||||
then
|
||||
is_default := true;
|
||||
endif;
|
||||
|
||||
dosage_range_item.is_default := is_default;
|
||||
|
||||
dosage_range_item.hard_stop_high := hard_stop_high_list[ind];
|
||||
dosage_range_item.hard_stop_low := hard_stop_low_list[ind];
|
||||
dosage_range_item.estimated_age_used := estimated_age_used_list[ind];
|
||||
enddo;
|
||||
|
||||
uom_conversion_issue := any (uom_conversion_issue_list = 1);
|
||||
endif;
|
||||
|
||||
/* Always conclude true to return variables to calling MLM */
|
||||
CONCLUDE TRUE;
|
||||
|
||||
;;
|
||||
action:
|
||||
|
||||
|
||||
return (multum_dosage_range_list, missing_route, unmapped_route, missing_uom, unmapped_uom, uom_conversion_issue);
|
||||
;;
|
||||
end:
|
||||
@@ -0,0 +1,694 @@
|
||||
maintenance:
|
||||
|
||||
title: Retrieve Dosage Data for Complex Order Components ;;
|
||||
mlmname: STD_FUNC_DOSAGE_RETRIEVE_COMPONENTS;;
|
||||
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: Retrieves dosage data for Complex Order components.
|
||||
;;
|
||||
explanation: The data for complex orders are located in several objects and tables.
|
||||
This MLM retrieves data from the Evoking Object, Backup Object, Unsubmitted Orders, and the
|
||||
database from the following tables: CV3Order, CV3OrderAddnIlnfo, CV3OrderUserData, and
|
||||
CV3OrderVariableComponent. The data are consolidated into the Order_Variable_Component
|
||||
object.
|
||||
|
||||
When the Master Order is first created, all the data in the CV3OrderVariableComponent
|
||||
table are up to date. However, as the Child Orders are generated and later modified,
|
||||
the data in the CV3OrderVariableComponent table can become out of date. This MLM uses
|
||||
data from the Evoking Object, Backup Object, Unsubmitted Orders, and the Database
|
||||
to create Order_Variable_Component objects that have the most current dosing information.
|
||||
|
||||
Two lists of Order_Variable_Component objects are created--one for the current order
|
||||
and the other for the backup order. These lists are passed back to the calling MLM.
|
||||
;;
|
||||
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;
|
||||
|
||||
|
||||
// Get the current order
|
||||
(client_guid,
|
||||
order_guid,
|
||||
order_name,
|
||||
order_dosage_low,
|
||||
order_dosage_high,
|
||||
order_uom,
|
||||
order_route_code,
|
||||
order_frequency_code,
|
||||
order_significant_dtm,
|
||||
order_stop_dtm,
|
||||
order_additional_info_obj,
|
||||
order_user_data_obj,
|
||||
order_variable_component_obj,
|
||||
order_backup_obj ) := read last
|
||||
{ Order: ClientGUID, GUID, Name,
|
||||
DosageLow, DosageHigh, UOM, OrderRouteCode, FrequencyCode,
|
||||
SignificantDtm, StopDtm,
|
||||
OrderAdditionalInfo, OrderUserData,
|
||||
OrderVariableComponent, Backup
|
||||
REFERENCING EvokingObject};
|
||||
|
||||
|
||||
// Get the backup order
|
||||
(backup_order_name,
|
||||
backup_order_dosage_low,
|
||||
backup_order_dosage_high,
|
||||
backup_order_uom,
|
||||
backup_order_route_code,
|
||||
backup_order_frequency_code,
|
||||
backup_order_significant_dtm,
|
||||
backup_order_stop_dtm,
|
||||
backup_order_additional_info_obj,
|
||||
backup_order_user_data_obj,
|
||||
backup_order_variable_component_obj ) := read last
|
||||
{ Order: Name,
|
||||
DosageLow, DosageHigh, UOM, OrderRouteCode, FrequencyCode,
|
||||
SignificantDtm, StopDtm,
|
||||
OrderAdditionalInfo, OrderUserData,
|
||||
OrderVariableComponent
|
||||
REFERENCING order_backup_obj};
|
||||
|
||||
|
||||
// Get the current order{{{SINGLE-QUOTE}}}s data from OrderAdditionalInfo object
|
||||
(order_freq_from_time,
|
||||
order_freq_to_time,
|
||||
order_freq_uom,
|
||||
order_stop_after_option,
|
||||
order_stop_after_value,
|
||||
order_dosing_option_guid ) := read last
|
||||
{ OrderAdditionalInfo:
|
||||
FreqFromTime, FreqToTime, FreqUom,
|
||||
StopAfterOption, StopAfterValue, DosingOptionGuid
|
||||
REFERENCING order_additional_info_obj };
|
||||
|
||||
|
||||
// Get the backup order{{{SINGLE-QUOTE}}}s data from OrderAdditionalInfo object
|
||||
(backup_order_freq_from_time,
|
||||
backup_order_freq_to_time,
|
||||
backup_order_freq_uom,
|
||||
backup_order_stop_after_option,
|
||||
backup_order_stop_after_value ) := read last
|
||||
{ OrderAdditionalInfo:
|
||||
FreqFromTime, FreqToTime, FreqUom,
|
||||
StopAfterOption, StopAfterValue
|
||||
REFERENCING backup_order_additional_info_obj };
|
||||
|
||||
// Get the current order{{{SINGLE-QUOTE}}}s data from OrderUserData object
|
||||
(order_user_data_code_list,
|
||||
order_user_data_value_list ) := read
|
||||
{ OrderUserData: UserDataCode, Value
|
||||
REFERENCING order_user_data_obj
|
||||
Where UserDataCode is in ("CalcDoseMethod" , "CalcActualDose", "CalcUOMPer" ) };
|
||||
|
||||
|
||||
// Get the backup order{{{SINGLE-QUOTE}}}s data from OrderUserData object
|
||||
(backup_order_user_data_code_list,
|
||||
backup_order_user_data_value_list ) := read
|
||||
{ OrderUserData: UserDataCode, Value
|
||||
REFERENCING backup_order_user_data_obj
|
||||
Where UserDataCode is in ("CalcDoseMethod" , "CalcActualDose", "CalcUOMPer" ) };
|
||||
|
||||
|
||||
// Get DosingOptionGridColumn Info
|
||||
dosing_option_data_item_code_list := read
|
||||
{"Select DataItemCode "
|
||||
||" From CV3DosingOptionGridColumn "
|
||||
||" Where DosingOptionGUID = " || SQLEX(order_dosing_option_guid) };
|
||||
|
||||
|
||||
// Declare Order_Variable_Component Object
|
||||
Order_Variable_Component := OBJECT
|
||||
[Sequence_Number, Complex_Order_Type, GUID, Order_GUID, Child_Order_GUID,
|
||||
Dosage_Low, Dosage_High, UOM, Order_Route_Code,
|
||||
Frequency_Code, Freq_From_Time, Freq_To_Time, Freq_Uom,
|
||||
Calculated_Start_Dtm, Estimated_Stop_Dtm,
|
||||
Stop_After_Value, Stop_After_Option_Type,
|
||||
Calc_Dose_Method, Calc_Actual_Dose, Calc_UOM_Per,
|
||||
// The following object fields are place holders.
|
||||
// The data are populated after the READ statement.
|
||||
Child_Order_Status_Level_Num ];
|
||||
|
||||
|
||||
// Populate Order_Variable_Component
|
||||
current_ovc_list := read as Order_Variable_Component
|
||||
{OrderVariableComponent:
|
||||
SequenceNumber, ComplexOrderType, GUID, OrderGUID, ChildOrderGUID,
|
||||
DosageLow, DosageHigh, UOM, OrderRouteCode,
|
||||
FrequencyCode, FreqFromTime, FreqToTime, FreqUom,
|
||||
CalculatedStartDtm, EstimatedStopDtm,
|
||||
StopAfterValue, StopAfterOptionType,
|
||||
CalcDoseMethod, CalcActualDose, CalcUOMPer
|
||||
REFERENCING order_variable_component_obj};
|
||||
|
||||
|
||||
// Populate Order_Variable_Component object with BACK Data
|
||||
backup_ovc_list := read as Order_Variable_Component
|
||||
{OrderVariableComponent:
|
||||
SequenceNumber, ComplexOrderType, GUID, OrderGUID, ChildOrderGUID,
|
||||
DosageLow, DosageHigh, UOM, OrderRouteCode,
|
||||
FrequencyCode, FreqFromTime, FreqToTime, FreqUom,
|
||||
CalculatedStartDtm, EstimatedStopDtm,
|
||||
StopAfterValue, StopAfterOptionType,
|
||||
CalcDoseMethod, CalcActualDose, CalcUOMPer
|
||||
REFERENCING backup_order_variable_component_obj };
|
||||
|
||||
|
||||
// Get the OrderVariableComponent Objects in the Correct Sequence before using the data.
|
||||
// The identical CalculatedStartDtm could cause them to be out of order.
|
||||
current_ovc_list := SORT sequence_number DATA current_ovc_list;
|
||||
backup_ovc_list := SORT Sequence_Number DATA backup_ovc_list;
|
||||
|
||||
|
||||
// Make a copy of the OrderVariableComponent Objects before they are changed.
|
||||
// This will assist in Debugging problems
|
||||
debug_current_ovc_list := CLONE current_ovc_list;
|
||||
debug_backup_ovc_list := CLONE backup_ovc_list;
|
||||
|
||||
|
||||
// Check if the Complex Order{{{SINGLE-QUOTE}}}s Master Order has any Child Orders
|
||||
complex_order_child_order_guid_list := current_ovc_list.Child_Order_GUID where it is present;
|
||||
|
||||
// If the Complex Order Child Orders generated
|
||||
// then look up DTM information on the Child Orders.
|
||||
if exist complex_order_child_order_guid_list
|
||||
then
|
||||
|
||||
// Set Flag to update OrderVariableComponent data before making comparisons
|
||||
update_order_variable_component_data := TRUE;
|
||||
|
||||
// If there is only 1 Child Order GUID,
|
||||
// Make it a singleton so that the SQL query works correctly
|
||||
if count complex_order_child_order_guid_list = 1 then
|
||||
complex_order_child_order_guid_list := first complex_order_child_order_guid_list;
|
||||
endif;
|
||||
|
||||
// Retrieve Data for the Child Orders from the Database
|
||||
(db_complex_child_order_guid_list,
|
||||
db_complex_child_order_name_list,
|
||||
db_complex_child_order_dosage_low_list,
|
||||
db_complex_child_order_dosage_high_list,
|
||||
db_complex_child_order_uom_list,
|
||||
db_complex_child_order_route_code_list,
|
||||
db_complex_child_order_frequency_code_list,
|
||||
db_complex_child_order_freq_from_time_list,
|
||||
db_complex_child_order_freq_to_time_list,
|
||||
db_complex_child_order_freq_uom_list,
|
||||
db_complex_child_order_stop_after_option_list,
|
||||
db_complex_child_order_stop_after_value_list,
|
||||
db_complex_child_order_significant_dtm_list,
|
||||
db_complex_child_order_stop_dtm_list,
|
||||
db_complex_child_order_status_level_num_list ) := read
|
||||
{ "Select O.GUID, O.Name, "
|
||||
||" M.DosageLow, M.DosageHigh, M.UOM, M.OrderRouteCode, O.FrequencyCode, "
|
||||
||" OA.FreqFromTime, OA.FreqToTime, OA.FreqUom, OA.StopAfterOption, OA.StopAfterValue, "
|
||||
||" ConvSignificantDtm.TimeValue as SignificantDtm, "
|
||||
||" ConvStopDtm.TimeValue as StopDtm, "
|
||||
||" O.OrderStatusLevelNum "
|
||||
||" From CV3Order AS O "
|
||||
||" JOIN CV3MedicationExtension AS M "
|
||||
||" ON O.ClientGUID = M.ClientGUID AND O.GUID = M.GUID "
|
||||
||" JOIN CV3OrderAddnlInfo as OA "
|
||||
||" ON O.ClientGUID = OA.ClientGUID AND O.GUID = OA.GUID "
|
||||
||" INNER JOIN CV3ClientVisit AS CV "
|
||||
||" ON O.ClientVisitGUID = CV.GUID "
|
||||
||" CROSS APPLY dbo.SXADBConvertLocalToOffsetTblFn(CV.TimeZone, O.SignificantDtm) AS ConvSignificantDtm "
|
||||
||" CROSS APPLY dbo.SXADBConvertLocalToOffsetTblFn(CV.TimeZone, O.StopDtm) AS ConvStopDtm "
|
||||
||" WHERE O.ClientGUID = "|| SQLEX(client_guid)
|
||||
||" AND O.GUID in ( " || complex_order_child_order_guid_list || ")" };
|
||||
|
||||
|
||||
// Retrieve The Child Orders{{{SINGLE-QUOTE}}} OrderUserData Information from Database
|
||||
(db_complex_child_order_user_data_code_guid_list,
|
||||
db_complex_child_order_user_data_code_list,
|
||||
db_complex_child_order_user_data_value_list ) := read
|
||||
{ "Select OrderGUID, UserDataCode, Value "
|
||||
||" From CV3OrderUserData "
|
||||
||" Where ClientGUID = " || SQLEX(client_guid)
|
||||
||" AND OrderGUID IN ( " || complex_order_child_order_guid_list || " )"
|
||||
||" AND UserDataCode IN ({{{SINGLE-QUOTE}}}CalcDoseMethod{{{SINGLE-QUOTE}}} , {{{SINGLE-QUOTE}}}CalcActualDose{{{SINGLE-QUOTE}}}, {{{SINGLE-QUOTE}}}CalcUOMPer{{{SINGLE-QUOTE}}} ) " };
|
||||
|
||||
|
||||
// Retrieve Child Orders{{{SINGLE-QUOTE}}} OrderAdditionalInfo data from Unsubmitted Orders
|
||||
(unsub_complex_child_order_guid_list,
|
||||
unsub_complex_child_order_name_list,
|
||||
unsub_complex_child_order_dosage_low_list,
|
||||
unsub_complex_child_order_dosage_high_list,
|
||||
unsub_complex_child_order_uom_list,
|
||||
unsub_complex_child_order_route_code_list,
|
||||
unsub_complex_child_order_frequency_code_list,
|
||||
unsub_complex_child_order_significant_dtm_list,
|
||||
unsub_complex_child_order_stop_dtm_list,
|
||||
unsub_complex_child_order_additional_info_obj_list,
|
||||
unsub_complex_child_order_user_data_obj_list ) := read
|
||||
{ Unsubmitted Order:
|
||||
GUID, Name,
|
||||
DosageLow, DosageHigh, UOM, OrderRouteCode, FrequencyCode
|
||||
SignificantDtm, StopDtm, OrderAdditionalInfo, OrderUserData
|
||||
Where GUID is in (complex_order_child_order_guid_list) };
|
||||
|
||||
|
||||
unsub_complex_child_order_additional_guid_list := ();
|
||||
unsub_complex_child_order_freq_from_time_list := ();
|
||||
unsub_complex_child_order_freq_to_time_list := ();
|
||||
unsub_complex_child_order_freq_uom_list := ();
|
||||
unsub_complex_child_order_stop_after_option_list := ();
|
||||
unsub_complex_child_order_stop_after_value_list := ();
|
||||
|
||||
for temp_unsub_order_additional_info_obj in
|
||||
unsub_complex_child_order_additional_info_obj_list do
|
||||
|
||||
(temp_unsub_complex_child_order_additional_guid,
|
||||
temp_unsub_complex_child_order_freq_from_time,
|
||||
temp_unsub_complex_child_order_freq_to_time ,
|
||||
temp_unsub_complex_child_order_freq_uom,
|
||||
temp_unsub_complex_child_order_stop_after_option,
|
||||
temp_unsub_complex_child_order_stop_after_value ) := read last
|
||||
{ OrderAdditionalInfo:
|
||||
GUID, FreqFromTime, FreqToTime, FreqUom,
|
||||
StopAfterOption, StopAfterValue
|
||||
REFERENCING temp_unsub_order_additional_info_obj };
|
||||
|
||||
unsub_complex_child_order_additional_guid_list :=
|
||||
unsub_complex_child_order_additional_guid_list,
|
||||
temp_unsub_complex_child_order_additional_guid;
|
||||
unsub_complex_child_order_freq_from_time_list :=
|
||||
unsub_complex_child_order_freq_from_time_list,
|
||||
temp_unsub_complex_child_order_freq_from_time;
|
||||
unsub_complex_child_order_freq_to_time_list :=
|
||||
unsub_complex_child_order_freq_to_time_list,
|
||||
temp_unsub_complex_child_order_freq_to_time;
|
||||
unsub_complex_child_order_freq_uom_list :=
|
||||
unsub_complex_child_order_freq_uom_list,
|
||||
temp_unsub_complex_child_order_freq_uom;
|
||||
unsub_complex_child_order_stop_after_option_list :=
|
||||
unsub_complex_child_order_stop_after_option_list,
|
||||
temp_unsub_complex_child_order_stop_after_option;
|
||||
unsub_complex_child_order_stop_after_value_list :=
|
||||
unsub_complex_child_order_stop_after_value_list,
|
||||
temp_unsub_complex_child_order_stop_after_value;
|
||||
enddo; //for temp_unsub_order_additional_info_obj
|
||||
|
||||
|
||||
unsub_complex_child_order_user_data_code_guid_list := ();
|
||||
unsub_complex_child_order_user_data_code_list := ();
|
||||
unsub_complex_child_order_user_data_value_list := ();
|
||||
|
||||
|
||||
for temp_unsub_order_user_data_obj in unsub_complex_child_order_user_data_obj_list do
|
||||
// Get the unsumbitted order{{{SINGLE-QUOTE}}}s data from OrderUserData object
|
||||
(temp_unsub_complex_child_order_user_data_code_guid_list,
|
||||
temp_unsub_complex_child_order_user_data_code_list,
|
||||
temp_unsub_complex_child_order_user_data_value_list ) := read
|
||||
{ OrderUserData: OrderGUID, UserDataCode, Value
|
||||
REFERENCING temp_unsub_order_user_data_obj
|
||||
Where UserDataCode is in ("CalcDoseMethod" , "CalcActualDose", "CalcUOMPer" ) };
|
||||
|
||||
unsub_complex_child_order_user_data_code_guid_list :=
|
||||
unsub_complex_child_order_user_data_code_guid_list,
|
||||
temp_unsub_complex_child_order_user_data_code_guid_list;
|
||||
unsub_complex_child_order_user_data_code_list :=
|
||||
unsub_complex_child_order_user_data_code_list,
|
||||
temp_unsub_complex_child_order_user_data_code_list ;
|
||||
unsub_complex_child_order_user_data_value_list :=
|
||||
unsub_complex_child_order_user_data_value_list,
|
||||
temp_unsub_complex_child_order_user_data_value_list ;
|
||||
enddo; //for temp_unsub_order_user_data_obj
|
||||
|
||||
endif; //if exist complex_order_child_order_guid_list
|
||||
;;
|
||||
evoke:
|
||||
;;
|
||||
logic:
|
||||
//----------------------------------------------------------------------------
|
||||
// Update the CURRENT Order Variable Components with the Main Order Form Data
|
||||
//----------------------------------------------------------------------------
|
||||
// The facility can choose which dosing data will appear on the Order Option Grid
|
||||
// and which will appear on the Main Order Form. This algorithm consolidates
|
||||
// all the dosing data for the CURRENT Complex Order onto the OrderVariableComponent Object,
|
||||
// thus eliminating the need to look in more than one place for the data.
|
||||
|
||||
// Loop through the Current Order Variable Components and Consolidate Data
|
||||
for current_ovc in current_ovc_list do
|
||||
|
||||
if not exist current_ovc.dosage_low
|
||||
then current_ovc.dosage_low := order_dosage_low;
|
||||
endif;
|
||||
if not exist current_ovc.dosage_high
|
||||
then current_ovc.dosage_high := order_dosage_high;
|
||||
endif;
|
||||
if not exist current_ovc.uom
|
||||
then current_ovc.uom := order_uom;
|
||||
endif;
|
||||
if not exist current_ovc.order_route_code
|
||||
then current_ovc.order_route_code := order_route_code;
|
||||
endif;
|
||||
if not exist current_ovc.frequency_code
|
||||
then current_ovc.frequency_code := order_frequency_code;
|
||||
endif;
|
||||
if not exist current_ovc.freq_from_time
|
||||
or (current_ovc.freq_from_time AS NUMBER) = 0
|
||||
then current_ovc.freq_from_time := order_freq_from_time;
|
||||
endif;
|
||||
if not exist current_ovc.freq_to_time
|
||||
or (current_ovc.freq_to_time AS NUMBER) = 0
|
||||
then current_ovc.freq_to_time := order_freq_to_time;
|
||||
endif;
|
||||
if not exist current_ovc.freq_uom
|
||||
then current_ovc.freq_uom := order_freq_uom;
|
||||
endif;
|
||||
|
||||
|
||||
// If StopAfter or StopDate are NOT in the Dosing Option Grid
|
||||
// then get the data from the Main Order Form.
|
||||
if NOT ANY (("StopAfter", "StopDate") IS IN dosing_option_data_item_code_list)
|
||||
then
|
||||
if (current_ovc.stop_after_value AS NUMBER) = 0
|
||||
then current_ovc.stop_after_value := order_stop_after_value;
|
||||
endif;
|
||||
if (current_ovc.stop_after_option_type AS NUMBER) = 0
|
||||
then current_ovc.stop_after_option_type := order_stop_after_option;
|
||||
endif;
|
||||
if not exist current_ovc.estimated_stop_dtm
|
||||
then current_ovc.estimated_stop_dtm := order_stop_dtm;
|
||||
endif;
|
||||
endif; //if NOT ANY (("StopAfter", "StopDate")
|
||||
|
||||
|
||||
if not exist current_ovc.calc_actual_dose
|
||||
and not exist current_ovc.calc_uom_per
|
||||
and "CalcDoseMethod" IS IN order_user_data_code_list
|
||||
and "CalcActualDose" IS IN order_user_data_code_list
|
||||
and "CalcUOMPer" IS IN order_user_data_code_list
|
||||
then
|
||||
current_ovc.calc_actual_dose := first (order_user_data_value_list
|
||||
where order_user_data_code_list = "CalcActualDose");
|
||||
current_ovc.calc_dose_method := first (order_user_data_value_list
|
||||
where order_user_data_code_list = "CalcDoseMethod");
|
||||
current_ovc.calc_uom_per := first (order_user_data_value_list
|
||||
where order_user_data_code_list = "CalcUOMPer");
|
||||
endif; //if not exist current_ovc.calc_actual_dose
|
||||
enddo; //for current_ovc
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
// Update the BACKUP Order Variable Components with the Main Order Form Data
|
||||
//----------------------------------------------------------------------------
|
||||
// The facility can choose which dosing data will appear on the Order Option Grid
|
||||
// and which will appear on the Main Order Form. This algorithm consolidates
|
||||
// all the dosing data for the BACKUP Complex Order onto the OrderVariableComponent Object,
|
||||
// thus eliminating the need to look in more than one place for the data.
|
||||
|
||||
// Loop through the BackUp Order Variable Components and Consolidate Data
|
||||
for backup_ovc in backup_ovc_list do
|
||||
|
||||
if not exist backup_ovc.dosage_low
|
||||
then backup_ovc.dosage_low := backup_order_dosage_low;
|
||||
endif;
|
||||
if not exist backup_ovc.dosage_high
|
||||
then backup_ovc.dosage_high := backup_order_dosage_high;
|
||||
endif;
|
||||
if not exist backup_ovc.uom
|
||||
then backup_ovc.uom := backup_order_uom;
|
||||
endif;
|
||||
if not exist backup_ovc.order_route_code
|
||||
then backup_ovc.order_route_code := backup_order_route_code;
|
||||
endif;
|
||||
if not exist backup_ovc.frequency_code
|
||||
then backup_ovc.frequency_code := backup_order_frequency_code;
|
||||
endif;
|
||||
if not exist backup_ovc.freq_from_time
|
||||
or (backup_ovc.freq_from_time AS NUMBER) = 0
|
||||
then backup_ovc.freq_from_time := backup_order_freq_from_time;
|
||||
endif;
|
||||
if not exist backup_ovc.freq_to_time
|
||||
or (backup_ovc.freq_to_time AS NUMBER) = 0
|
||||
then backup_ovc.freq_to_time := backup_order_freq_to_time;
|
||||
endif;
|
||||
if not exist backup_ovc.freq_uom
|
||||
then backup_ovc.freq_uom := backup_order_freq_uom;
|
||||
endif;
|
||||
|
||||
|
||||
// If StopAfter or StopDate are NOT in the Dosing Option Grid
|
||||
// then get the data from the Main Order Form.
|
||||
if NOT ANY (("StopAfter", "StopDate") IS IN dosing_option_data_item_code_list)
|
||||
then
|
||||
if (backup_ovc.stop_after_value AS NUMBER) = 0
|
||||
then backup_ovc.stop_after_value := backup_order_stop_after_value;
|
||||
endif;
|
||||
if (backup_ovc.stop_after_option_type AS NUMBER) = 0
|
||||
then backup_ovc.stop_after_option_type := backup_order_stop_after_option;
|
||||
endif;
|
||||
if not exist backup_ovc.estimated_stop_dtm
|
||||
then backup_ovc.estimated_stop_dtm := backup_order_stop_dtm ;
|
||||
endif;
|
||||
endif; //if NOT ANY (("StopAfter", "StopDate")
|
||||
|
||||
|
||||
if not exist backup_ovc.calc_actual_dose
|
||||
and not exist backup_ovc.calc_uom_per
|
||||
and "CalcActualDose" IS IN order_user_data_code_list
|
||||
and "CalcUOMPer" IS IN order_user_data_code_list
|
||||
and "CalcDoseMethod" IS IN order_user_data_code_list
|
||||
then
|
||||
backup_ovc.calc_actual_dose := first (backup_order_user_data_value_list
|
||||
where backup_order_user_data_code_list = "CalcActualDose");
|
||||
backup_ovc.calc_dose_method := first (backup_order_user_data_value_list
|
||||
where backup_order_user_data_code_list= "CalcDoseMethod");
|
||||
backup_ovc.calc_uom_per := first (backup_order_user_data_value_list
|
||||
where backup_order_user_data_code_list = "CalcUOMPer");
|
||||
endif; //if not exist backup_ovc.calc_actual_dose
|
||||
enddo; //for backup_ovc
|
||||
|
||||
|
||||
//---------------------------------------------------------------------------------
|
||||
// Update CURRENT and BACKUP Order Variable Components with Data from the DATABASE
|
||||
//---------------------------------------------------------------------------------
|
||||
// When the Child Orders have been generated, the data from the Child Order are the
|
||||
// actual data and are more accurate than the "estimated" data on the Master Order.
|
||||
// For example, the CalculatedStartDtm and the StopDtm in the
|
||||
// Complex Orders{{{SINGLE-QUOTE}}} Order Variable Component objects can get out of date,
|
||||
// since it is not always updated from the Child Orders.
|
||||
// This algorthim will update the Order Variable Component objects from the database.
|
||||
// This algorthim will also add the Child Order{{{SINGLE-QUOTE}}}s OrderStatusLevelNum to objects.
|
||||
|
||||
if update_order_variable_component_data
|
||||
then
|
||||
|
||||
// Loop Through the lists from the Database
|
||||
for DD in (1 seqto count db_complex_child_order_guid_list) do
|
||||
|
||||
// Find the matching CURRENT Order Variable Component
|
||||
found_current_ovc := current_ovc_list
|
||||
where current_ovc_list.Child_Order_GUID =
|
||||
db_complex_child_order_guid_list[DD];
|
||||
|
||||
// Find the matching BACKUP Order Variable Component
|
||||
found_backup_ovc := backup_ovc_list
|
||||
where backup_ovc_list.Child_Order_GUID =
|
||||
db_complex_child_order_guid_list[DD];
|
||||
|
||||
|
||||
// Add the OrderStatusLevelNum to the CURRENT Order Variable Component
|
||||
found_current_ovc.child_order_status_level_num :=
|
||||
db_complex_child_order_status_level_num_list[DD];
|
||||
|
||||
// Replace CalculatedStartDtm and StopDtm for the
|
||||
// CURRENT and BACKUP Order Variable Component
|
||||
found_current_ovc.calculated_start_dtm := db_complex_child_order_significant_dtm_list[DD];
|
||||
found_backup_ovc.calculated_start_dtm := db_complex_child_order_significant_dtm_list[DD];
|
||||
found_current_ovc.estimated_stop_dtm := db_complex_child_order_stop_dtm_list[DD];
|
||||
found_backup_ovc.estimated_stop_dtm := db_complex_child_order_stop_dtm_list[DD];
|
||||
|
||||
|
||||
//Replace the other Dosing Data for the CURRENT and BACKUP Order Variable Component
|
||||
found_current_ovc.dosage_low := db_complex_child_order_dosage_low_list[DD];
|
||||
found_backup_ovc.dosage_low := db_complex_child_order_dosage_low_list[DD];
|
||||
|
||||
found_current_ovc.dosage_high := db_complex_child_order_dosage_high_list[DD];
|
||||
found_backup_ovc.dosage_high := db_complex_child_order_dosage_high_list[DD];
|
||||
|
||||
found_current_ovc.uom := db_complex_child_order_uom_list[DD];
|
||||
found_backup_ovc.uom := db_complex_child_order_uom_list[DD];
|
||||
|
||||
found_current_ovc.order_route_code := db_complex_child_order_route_code_list[DD];
|
||||
found_backup_ovc.order_route_code := db_complex_child_order_route_code_list[DD];
|
||||
|
||||
found_current_ovc.frequency_code := db_complex_child_order_frequency_code_list[DD];
|
||||
found_backup_ovc.frequency_code := db_complex_child_order_frequency_code_list[DD];
|
||||
|
||||
found_current_ovc.freq_from_time := db_complex_child_order_freq_from_time_list[DD];
|
||||
found_backup_ovc.freq_from_time := db_complex_child_order_freq_from_time_list[DD];
|
||||
|
||||
found_current_ovc.freq_to_time := db_complex_child_order_freq_to_time_list[DD];
|
||||
found_backup_ovc.freq_to_time := db_complex_child_order_freq_to_time_list[DD];
|
||||
|
||||
found_current_ovc.freq_uom := db_complex_child_order_freq_uom_list[DD];
|
||||
found_backup_ovc.freq_uom := db_complex_child_order_freq_uom_list[DD];
|
||||
|
||||
found_current_ovc.stop_after_value := db_complex_child_order_stop_after_value_list[DD];
|
||||
found_backup_ovc.stop_after_value := db_complex_child_order_stop_after_value_list[DD];
|
||||
|
||||
found_current_ovc.stop_after_option_type :=
|
||||
db_complex_child_order_stop_after_option_list[DD];
|
||||
found_backup_ovc.stop_after_option_type :=
|
||||
db_complex_child_order_stop_after_option_list[DD];
|
||||
|
||||
|
||||
if "CalcActualDose" IS IN db_complex_child_order_user_data_code_list
|
||||
and "CalcUOMPer" IS IN db_complex_child_order_user_data_code_list
|
||||
and "CalcDoseMethod" IS IN db_complex_child_order_user_data_code_list
|
||||
then
|
||||
temp_db_calc_actual_dose := first (db_complex_child_order_user_data_value_list
|
||||
where db_complex_child_order_user_data_code_list = "CalcActualDose"
|
||||
and db_complex_child_order_user_data_code_guid_list =
|
||||
db_complex_child_order_guid_list[DD]);
|
||||
found_current_ovc.calc_actual_dose := temp_db_calc_actual_dose;
|
||||
found_backup_ovc.calc_actual_dose := temp_db_calc_actual_dose;
|
||||
|
||||
|
||||
temp_db_calc_dose_method := first (db_complex_child_order_user_data_value_list
|
||||
where db_complex_child_order_user_data_code_list= "CalcDoseMethod"
|
||||
and db_complex_child_order_user_data_code_guid_list =
|
||||
db_complex_child_order_guid_list[DD]);
|
||||
found_current_ovc.calc_dose_method := temp_db_calc_dose_method;
|
||||
found_backup_ovc.calc_dose_method := temp_db_calc_dose_method;
|
||||
|
||||
|
||||
temp_db_calc_uom_per := first (db_complex_child_order_user_data_value_list
|
||||
where db_complex_child_order_user_data_code_list = "CalcUOMPer"
|
||||
and db_complex_child_order_user_data_code_guid_list =
|
||||
db_complex_child_order_guid_list[DD]);
|
||||
found_current_ovc.calc_uom_per := temp_db_calc_uom_per;
|
||||
found_backup_ovc.calc_uom_per := temp_db_calc_uom_per;
|
||||
|
||||
endif; //if "CalcActualDose"
|
||||
enddo; //for DD
|
||||
|
||||
|
||||
//-------------------------------------------------------------------------------------
|
||||
// Update CURRENT Order Variable Components with Data from the UNSUBMITTED Child Order
|
||||
//-------------------------------------------------------------------------------------
|
||||
// When the Child Order is modified, the data from the Unsubmitted Child Order contains the
|
||||
// changed data. The Child Order{{{SINGLE-QUOTE}}}s data are more accurate than the data on the Master Order.
|
||||
// For example, if the Child Order{{{SINGLE-QUOTE}}}s route changed and the route field is NOT on the
|
||||
// dosing option grid, then the route on the Master Order is not updated.
|
||||
// The Master Order{{{SINGLE-QUOTE}}}s Order Variable Component objects can get out of date,
|
||||
// since it is not always updated from the Child Orders.
|
||||
// This algorthim will update the CURRENT Order Variable Component objects from the
|
||||
// Unsubmitted Child Order.
|
||||
// Note that the BACKUP Order Variable Component objects are not updated by this algorithm.
|
||||
|
||||
// Loop Through the lists from the Unsubmitted Orders
|
||||
for UU in (1 seqto count unsub_complex_child_order_guid_list) do
|
||||
|
||||
// Find the matching CURRENT Order Variable Component
|
||||
found_current_ovc := current_ovc_list
|
||||
where current_ovc_list.Child_Order_GUID =
|
||||
unsub_complex_child_order_guid_list[UU];
|
||||
|
||||
// Replace CalculatedStartDtm and StopDtm for the CURRENT Order Variable Component
|
||||
// from the Unsubmitted Orders
|
||||
found_current_ovc.calculated_start_dtm :=
|
||||
unsub_complex_child_order_significant_dtm_list[UU];
|
||||
|
||||
found_current_ovc.estimated_stop_dtm :=
|
||||
unsub_complex_child_order_stop_dtm_list[UU];
|
||||
|
||||
|
||||
//Replace the other Dosing Data for the CURRENT Order Variable Component
|
||||
found_current_ovc.dosage_low := unsub_complex_child_order_dosage_low_list[UU];
|
||||
found_current_ovc.dosage_high := unsub_complex_child_order_dosage_high_list[UU];
|
||||
found_current_ovc.uom := unsub_complex_child_order_uom_list[UU];
|
||||
found_current_ovc.order_route_code := unsub_complex_child_order_route_code_list[UU];
|
||||
found_current_ovc.frequency_code := unsub_complex_child_order_frequency_code_list[UU];
|
||||
|
||||
if exist unsub_complex_child_order_additional_guid_list
|
||||
then
|
||||
found_current_ovc.freq_from_time :=
|
||||
first (unsub_complex_child_order_freq_from_time_list
|
||||
where unsub_complex_child_order_additional_guid_list =
|
||||
unsub_complex_child_order_guid_list [UU]);
|
||||
|
||||
found_current_ovc.freq_to_time :=
|
||||
first (unsub_complex_child_order_freq_to_time_list
|
||||
where unsub_complex_child_order_additional_guid_list =
|
||||
unsub_complex_child_order_guid_list [UU]);
|
||||
|
||||
found_current_ovc.freq_uom :=
|
||||
first (unsub_complex_child_order_freq_uom_list
|
||||
where unsub_complex_child_order_additional_guid_list =
|
||||
unsub_complex_child_order_guid_list [UU]);
|
||||
|
||||
found_current_ovc.stop_after_value :=
|
||||
first (unsub_complex_child_order_stop_after_value_list
|
||||
where unsub_complex_child_order_additional_guid_list =
|
||||
unsub_complex_child_order_guid_list [UU]);
|
||||
|
||||
found_current_ovc.stop_after_option_type :=
|
||||
first (unsub_complex_child_order_stop_after_option_list
|
||||
where unsub_complex_child_order_additional_guid_list =
|
||||
unsub_complex_child_order_guid_list [UU]);
|
||||
endif; //if exist unsub_complex_child_order_additional_guid_list
|
||||
|
||||
|
||||
if "CalcActualDose" IS IN unsub_complex_child_order_user_data_code_list
|
||||
and "CalcUOMPer" IS IN unsub_complex_child_order_user_data_code_list
|
||||
and "CalcDoseMethod" IS IN unsub_complex_child_order_user_data_code_list
|
||||
then
|
||||
found_current_ovc.calc_actual_dose :=
|
||||
first (unsub_complex_child_order_user_data_value_list
|
||||
where unsub_complex_child_order_user_data_code_list = "CalcActualDose"
|
||||
and unsub_complex_child_order_user_data_code_guid_list =
|
||||
unsub_complex_child_order_guid_list [UU]);
|
||||
|
||||
found_current_ovc.calc_dose_method :=
|
||||
first (unsub_complex_child_order_user_data_value_list
|
||||
where unsub_complex_child_order_user_data_code_list = "CalcDoseMethod"
|
||||
and unsub_complex_child_order_user_data_code_guid_list =
|
||||
unsub_complex_child_order_guid_list [UU]);
|
||||
|
||||
found_current_ovc.calc_uom_per :=
|
||||
first (unsub_complex_child_order_user_data_value_list
|
||||
where unsub_complex_child_order_user_data_code_list = "CalcUOMPer"
|
||||
and unsub_complex_child_order_user_data_code_guid_list =
|
||||
unsub_complex_child_order_guid_list [UU]);
|
||||
endif; //if "CalcActualDose"
|
||||
enddo; //for UU
|
||||
endif; //if update_order_variable_component_data
|
||||
|
||||
//Always Conclude True
|
||||
Conclude True;
|
||||
;;
|
||||
action:
|
||||
// Return the list of CURRENT and BACKUP Order_Variable_Compenent Objects
|
||||
return current_ovc_list, backup_ovc_list;
|
||||
;;
|
||||
Urgency: 50;;
|
||||
end:
|
||||
1971
MLMStripper/bin/Debug/STD/STD_FUNC_DOSAGE_RULES.mlm
Normal file
1971
MLMStripper/bin/Debug/STD/STD_FUNC_DOSAGE_RULES.mlm
Normal file
File diff suppressed because it is too large
Load Diff
710
MLMStripper/bin/Debug/STD/STD_FUNC_DOSAGE_TRACKER.mlm
Normal file
710
MLMStripper/bin/Debug/STD/STD_FUNC_DOSAGE_TRACKER.mlm
Normal file
@@ -0,0 +1,710 @@
|
||||
maintenance:
|
||||
|
||||
title: Track the Average and Total Daily Doses ;;
|
||||
mlmname: STD_FUNC_DOSAGE_TRACKER;;
|
||||
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: This MLM tracks the Average Daily Dose and the Total Daily Dose.
|
||||
;;
|
||||
explanation: This MLM calculates the Average Daily Dose and the Total Daily Dose
|
||||
by using two approaches:
|
||||
1. The CONVERSION FACTOR approach does the calculation by multiplying the single dose
|
||||
by a conversion factor that is based on the order{{{SINGLE-QUOTE}}}s frequency, or if Prescription.
|
||||
|
||||
2. The SUMMED DOSES approach uses the estimated dose administration times to sort
|
||||
the single doses into 24-hour intervals. Then each 24-hour interval is summed
|
||||
to calculate the Average and Total doses.
|
||||
;;
|
||||
keywords: single dose; average daily dose; total daily dose; dosage range
|
||||
;;
|
||||
knowledge:
|
||||
type: data-driven;;
|
||||
data:
|
||||
|
||||
med_data_list := ARGUMENT;
|
||||
|
||||
|
||||
// Set to true if logging is needed.
|
||||
log_execution_info := false;
|
||||
|
||||
|
||||
//Declare MLMs that can be called
|
||||
calc_freqmult_daily := MLM {{{SINGLE-QUOTE}}}sys_calc_freqmult_daily{{{SINGLE-QUOTE}}};
|
||||
calc_freqmult_average:= MLM {{{SINGLE-QUOTE}}}sys_calc_freqmult_average{{{SINGLE-QUOTE}}};
|
||||
func_dosage_trim := MLM {{{SINGLE-QUOTE}}}std_func_dosage_trim{{{SINGLE-QUOTE}}};
|
||||
func_calc_method := MLM {{{SINGLE-QUOTE}}}STD_FUNC_DOSAGE_CALC_METHOD{{{SINGLE-QUOTE}}};
|
||||
|
||||
//Declare the Dose_Tracker_Object
|
||||
Dose_Tracker_Object := OBJECT [
|
||||
Med_Data_GUID,
|
||||
med_order_type,
|
||||
med_name,
|
||||
interval_begin_dtm,
|
||||
interval_end_dtm,
|
||||
num_doses_in_24hrs, // indicates how many number of doses should be in 24hr
|
||||
num_doses, // indicates how many doses would be administered in 24hr
|
||||
total_dose_low,
|
||||
total_dose_high,
|
||||
uom,
|
||||
route,
|
||||
start_date ];
|
||||
|
||||
|
||||
//Declare the Sum_Tracker_Object
|
||||
Sum_Tracker_Object := OBJECT
|
||||
[interval_begin_dtm,
|
||||
interval_end_dtm,
|
||||
is_last_24hr_interval,
|
||||
has_full_24hrs_doses,
|
||||
med_order_type,
|
||||
med_name,
|
||||
route,
|
||||
total_dose_low,
|
||||
total_dose_high,
|
||||
uom,
|
||||
start_date ];
|
||||
|
||||
|
||||
//Declare the Total_Tracker_Object
|
||||
Total_Tracker_Object := OBJECT
|
||||
[
|
||||
sort_number,
|
||||
interval_begin_dtm_list,
|
||||
is_last_24hr_interval,
|
||||
has_full_24hrs_doses,
|
||||
med_order_type,
|
||||
med_name,
|
||||
route,
|
||||
total_dose_low,
|
||||
total_dose_high,
|
||||
uom,
|
||||
dose_calc_method_number,
|
||||
total_calc_med_dose_low,
|
||||
total_calc_med_dose_high,
|
||||
calc_text,
|
||||
retrieved_dose_range_data,
|
||||
found_total_daily_dose,
|
||||
missing_height,
|
||||
missing_weight,
|
||||
processed_missing_data_msg,
|
||||
met_criteria_under_24_hours,
|
||||
processed_for_printing,
|
||||
dose_range_check_method,
|
||||
outside_total_daily_dose,
|
||||
suppress_alert,
|
||||
alert_msg_for_total,
|
||||
met_criteria_has_shift_frequency,
|
||||
start_date ];
|
||||
|
||||
|
||||
//Declare the Average_Tracker_Object
|
||||
Average_Tracker_Object := OBJECT
|
||||
[
|
||||
sort_number,
|
||||
interval_begin_dtm_list,
|
||||
is_last_24hr_interval,
|
||||
has_full_24hrs_doses,
|
||||
med_order_type,
|
||||
med_name,
|
||||
route,
|
||||
average_dose_low,
|
||||
average_dose_high,
|
||||
uom,
|
||||
dose_calc_method_number,
|
||||
average_calc_med_dose_low,
|
||||
average_calc_med_dose_high,
|
||||
calc_text,
|
||||
retrieved_dose_range_data,
|
||||
found_average_daily_dose,
|
||||
processed_missing_data_msg,
|
||||
met_criteria_under_24_hours,
|
||||
processed_for_printing,
|
||||
irregular_schedule_used,
|
||||
user_scheduled_weekly_used,
|
||||
dose_range_check_method,
|
||||
outside_average_daily_dose,
|
||||
suppress_alert,
|
||||
alert_msg_for_average,
|
||||
met_criteria_has_shift_frequency,
|
||||
start_date ];
|
||||
|
||||
;;
|
||||
evoke:
|
||||
;;
|
||||
logic:
|
||||
|
||||
// Initialize Variables
|
||||
dose_tracker_list := ();
|
||||
sum_tracker_list := ();
|
||||
total_tracker_list := ();
|
||||
average_tracker_list := ();
|
||||
|
||||
Calculation_Method := call func_calc_method with med_data_list;
|
||||
|
||||
if Calculation_Method = "CONVERSION"
|
||||
then
|
||||
|
||||
for med_data in med_data_list do
|
||||
|
||||
// Significant_date is important in several calculations and cannot
|
||||
// be NULL. Set it to be the first calculated admin time.
|
||||
if med_data.order_med_significant_date is null
|
||||
then
|
||||
med_data.order_med_significant_date := first med_data.admin_dtm_list;
|
||||
endif;
|
||||
|
||||
//-----------------------------
|
||||
//Calculate Total Daily Dose
|
||||
//-----------------------------
|
||||
|
||||
// Find the Total_Tracker_Object
|
||||
// The Med Order Type, Medication Name, and UOM must match
|
||||
// Route must match or both be NULL
|
||||
found_total_tracker := total_tracker_list where
|
||||
(total_tracker_list.med_order_type = med_data.med_order_type
|
||||
and total_tracker_list.med_name = med_data.order_med_name
|
||||
and (total_tracker_list.route = med_data.order_med_route
|
||||
or ((total_tracker_list.route is NULL)
|
||||
and (med_data.order_med_route is NULL)))
|
||||
and total_tracker_list.uom = med_data.order_med_units);
|
||||
//and total_tracker_list.start_date = med_data.order_med_significant_date );
|
||||
|
||||
|
||||
if not exist found_total_tracker
|
||||
then
|
||||
//Calculate the Total Daily Dose for the Highs and Low Doses
|
||||
|
||||
//Create a new object
|
||||
total_instance := new Total_Tracker_Object;
|
||||
total_tracker_list := total_tracker_list, total_instance;
|
||||
|
||||
//Populate the data
|
||||
total_instance.dose_range_check_method := "Conversion Factor";
|
||||
total_instance.med_order_type := med_data.med_order_type;
|
||||
total_instance.med_name := med_data.order_med_name;
|
||||
total_instance.route := med_data.order_med_route;
|
||||
total_instance.uom := med_data.order_med_units;
|
||||
total_instance.dose_calc_method_number := med_data.calc_dose_method;
|
||||
total_instance.calc_text := med_data.calc_text;
|
||||
total_instance.start_date := med_data.order_med_significant_date;
|
||||
|
||||
if (med_data.is_order)
|
||||
then
|
||||
// Call an MLM to calculate the conversion factor for Total Daily Dose
|
||||
conversion_factor_ave := call calc_freqmult_daily
|
||||
with med_data.order_med_frequency,
|
||||
med_data.freq_from_time,
|
||||
med_data.freq_uom;
|
||||
else
|
||||
conversion_factor_ave := med_data.freq_multiplier;
|
||||
endif;
|
||||
|
||||
// Calculate the Low and High Doses for Total Daily Dose
|
||||
// by multiplying the doses with the conversion factor
|
||||
// AND Store the Doses
|
||||
temp_total_dose_low := med_data.order_med_dose_low * conversion_factor_ave;
|
||||
temp_total_dose_high := med_data.order_med_dose_high * conversion_factor_ave;
|
||||
|
||||
// Trim the Excess Decimals
|
||||
rounded_trim_numbers_list := call func_dosage_trim with
|
||||
med_data.order_med_dose_low, // a single number
|
||||
(temp_total_dose_high, temp_total_dose_low); // a list of numbers
|
||||
|
||||
// Store Doses
|
||||
total_instance.total_dose_high := rounded_trim_numbers_list[1];
|
||||
total_instance.total_dose_low := rounded_trim_numbers_list[2];
|
||||
|
||||
endif; //not exist found_total_tracker
|
||||
|
||||
|
||||
|
||||
//-----------------------------
|
||||
//Calculate Average Daily Dose
|
||||
//-----------------------------
|
||||
|
||||
// Find the Average_Tracker_Object
|
||||
// The Med Order Type, Medication Name, and UOM must match
|
||||
// Route must match or both be NULL
|
||||
found_average_tracker := average_tracker_list where
|
||||
(average_tracker_list.med_order_type = med_data.med_order_type
|
||||
and average_tracker_list.med_name = med_data.order_med_name
|
||||
and (average_tracker_list.route = med_data.order_med_route
|
||||
or ((average_tracker_list.route is NULL)
|
||||
and (med_data.order_med_route is NULL)))
|
||||
and average_tracker_list.uom = med_data.order_med_units );
|
||||
|
||||
|
||||
if not exist found_average_tracker
|
||||
then
|
||||
//Calculate an Average for the Highs and Low Doses
|
||||
|
||||
//Create a new object
|
||||
average_instance := new Average_Tracker_Object;
|
||||
average_tracker_list := average_tracker_list, average_instance;
|
||||
|
||||
//Populate the data
|
||||
average_instance.dose_range_check_method := "Conversion Factor";
|
||||
average_instance.med_order_type := med_data.med_order_type;
|
||||
average_instance.med_name := med_data.order_med_name;
|
||||
average_instance.route := med_data.order_med_route;
|
||||
average_instance.uom := med_data.order_med_units;
|
||||
average_instance.dose_calc_method_number := med_data.calc_dose_method;
|
||||
average_instance.calc_text := med_data.calc_text;
|
||||
average_instance.start_date := med_data.order_med_significant_date;
|
||||
|
||||
// Call an MLM to calculate the conversion factor for Average Daily Dose
|
||||
conversion_factor_ave := call calc_freqmult_average
|
||||
with med_data.order_med_frequency,
|
||||
med_data.freq_from_time,
|
||||
med_data.freq_uom;
|
||||
|
||||
// Calculate the Low and High Doses for Average Daily Dose
|
||||
// by multiplying the doses with the conversion factor
|
||||
// AND Store the Doses
|
||||
temp_average_dose_low := med_data.order_med_dose_low * conversion_factor_ave;
|
||||
temp_average_dose_high := med_data.order_med_dose_high * conversion_factor_ave;
|
||||
|
||||
// no rounding for average dose for proper daily dose checking
|
||||
average_instance.average_dose_high := temp_average_dose_high;
|
||||
average_instance.average_dose_low := temp_average_dose_low;
|
||||
|
||||
endif; //not exist found_average_tracker
|
||||
enddo; //for med_data
|
||||
|
||||
|
||||
//**************************************************************
|
||||
// Use the SUMMED-DOSE Dosage-Range Checking (newer approach )
|
||||
//**************************************************************
|
||||
else
|
||||
//-----------------------------------------
|
||||
//Create and Populate Dose_Tracker_Objects
|
||||
//-----------------------------------------
|
||||
|
||||
// Remove NULL from the Admin_Dtm_List before doing a MIN function
|
||||
temp_admin_dtm_list := ();
|
||||
for med_data in med_data_list do
|
||||
if exist med_data.admin_dtm_list
|
||||
then
|
||||
temp_admin_dtm_list := temp_admin_dtm_list, med_data.admin_dtm_list;
|
||||
endif;
|
||||
enddo; //for med_data
|
||||
|
||||
//Get the Earliest Administration Date-Time for the Medication Order
|
||||
order_begin_dtm := MIN temp_admin_dtm_list;
|
||||
|
||||
// Loop Through Each Med_Data Object
|
||||
for EE in med_data_list do
|
||||
|
||||
// Significant_date is important in several calculations and cannot
|
||||
// be NULL. Set it to be the first calculated admin time.
|
||||
if EE.order_med_significant_date is null
|
||||
then
|
||||
EE.order_med_significant_date := first EE.admin_dtm_list;
|
||||
endif;
|
||||
|
||||
// Only create Dose_Tracker_Objects if the medication has a dose.
|
||||
// If a medication has a dose, then the order_med_dose_low must have a value.
|
||||
// Medication orders such as IV-solutions and Master Complex Orders do not have doses.
|
||||
// So their order_med_dose_low is NULL. However, their components do have doses.
|
||||
if exist EE.order_med_dose_low
|
||||
then
|
||||
|
||||
// Find the dose instance based on the med GUID and Name.
|
||||
dose_instance := last (dose_tracker_list where
|
||||
(dose_tracker_list.Med_Data_GUID = EE.med_data_guid
|
||||
and dose_tracker_list.order_med_name = EE.order_med_name));
|
||||
|
||||
dMultiplier := call calc_freqmult_average
|
||||
with EE.order_med_frequency,
|
||||
EE.freq_from_time,
|
||||
EE.freq_uom;
|
||||
|
||||
num_doses_in_24hrs := 1;
|
||||
if dMultiplier is not null
|
||||
then
|
||||
num_doses_in_24hrs := int floor of dMultiplier;
|
||||
endif;
|
||||
|
||||
// Use the Medication{{{SINGLE-QUOTE}}}s Administation Date to Put the Doses in the Correct Object.
|
||||
for admin_date in EE.admin_dtm_list do
|
||||
|
||||
// If a instance doesn{{{SINGLE-QUOTE}}}t yet exist or the admin date is beyond
|
||||
// the current instance{{{SINGLE-QUOTE}}}s end date then create a new one.
|
||||
if not exists dose_instance OR
|
||||
(admin_date >= dose_instance.interval_end_dtm)
|
||||
then
|
||||
// Create a new Dose_Tracker_Object
|
||||
dose_instance := new Dose_Tracker_Object;
|
||||
|
||||
//Add to the List of objects
|
||||
dose_tracker_list := dose_tracker_list, dose_instance;
|
||||
|
||||
//Populate the new Dose_Tracker_Object with basic information
|
||||
dose_instance.Med_Data_GUID := EE.med_data_guid;
|
||||
dose_instance.med_order_type := EE.med_order_type;
|
||||
dose_instance.med_name := EE.order_med_name;
|
||||
dose_instance.uom := EE.order_med_units;
|
||||
dose_instance.route := EE.order_med_route;
|
||||
dose_instance.total_dose_low := 0;
|
||||
dose_instance.total_dose_high := 0;
|
||||
dose_instance.num_doses_in_24hrs := num_doses_in_24hrs;
|
||||
dose_instance.num_doses := 0;
|
||||
dose_instance.start_date := EE.order_med_significant_date;
|
||||
|
||||
//Calculate the Begin and End Time Intervals
|
||||
//And Set Them
|
||||
length_of_time := admin_date - order_begin_dtm;
|
||||
multiplier := truncate (length_of_time / 24 hours) ;
|
||||
dose_instance.interval_begin_dtm := order_begin_dtm + (multiplier * 24 hours);
|
||||
dose_instance.interval_end_dtm := dose_instance.interval_begin_dtm + 24 hours;
|
||||
endif; //if exist found_dose_tracker
|
||||
|
||||
|
||||
//Populate Dose_Tracker with Doses
|
||||
if exist EE.order_med_dose_low
|
||||
then //use the low dose for dose low,
|
||||
//otherwise the dose is null and we do not add null to a number.
|
||||
dose_instance.total_dose_low := dose_instance.total_dose_low +
|
||||
(EE.order_med_dose_low as number) ;
|
||||
endif;
|
||||
if exist EE.order_med_dose_high
|
||||
then //use the high dose for dose high
|
||||
dose_instance.total_dose_high := dose_instance.total_dose_high +
|
||||
(EE.order_med_dose_high as number);
|
||||
elseif exist EE.order_med_dose_low
|
||||
then //use the low dose for dose high
|
||||
dose_instance.total_dose_high := dose_instance.total_dose_high +
|
||||
(EE.order_med_dose_low as number);
|
||||
endif; //if exist EE.order_med_dose_high
|
||||
|
||||
// count the number of doses in 24 hr interval based on admin times.
|
||||
dose_instance.num_doses := dose_instance.num_doses + 1;
|
||||
|
||||
enddo; //for admin_date
|
||||
endif; //if exist EE.order_med_dose_low
|
||||
enddo; //for EE
|
||||
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
// Sum the Dose for Each 24-Hour Interval Across OrderVariableComponents
|
||||
//------------------------------------------------------------------------
|
||||
// Different Routes and UOMs must be summed separately
|
||||
|
||||
|
||||
// Loop Through Each Dose_Tracker_Object
|
||||
// And determine which Sum_Tracker_Object to Use
|
||||
for FF in dose_tracker_list do
|
||||
// Use the Interval_Begin_Dtm to Put the Doses in the Correct Object.
|
||||
// Find the Dose_Tracker_Object
|
||||
// The Medication Name, Date Intervals, and UOM must be the same
|
||||
// and the Routes must match or both be NULL.
|
||||
found_sum_tracker := sum_tracker_list where
|
||||
((sum_tracker_list.route = FF.route or
|
||||
(sum_tracker_list.route is null) and (FF.route is null))
|
||||
and sum_tracker_list.uom = FF.uom
|
||||
and sum_tracker_list.med_name = FF.med_name
|
||||
and sum_tracker_list.interval_begin_dtm = FF.interval_begin_dtm);
|
||||
|
||||
if exist found_sum_tracker
|
||||
then
|
||||
// Use the Existing Sum_Tracker_Object
|
||||
sum_instance := last (found_sum_tracker);
|
||||
else
|
||||
//Otherwise Create a new Sum_Tracker_Object
|
||||
sum_instance := new Sum_Tracker_Object;
|
||||
|
||||
//Add to the List of objects
|
||||
sum_tracker_list := sum_tracker_list, sum_instance;
|
||||
|
||||
//Populate the new Sum_Tracker_Object with basic information
|
||||
sum_instance.med_order_type := FF.med_order_type;
|
||||
sum_instance.med_name := FF.med_name;
|
||||
sum_instance.interval_begin_dtm := FF.interval_begin_dtm;
|
||||
sum_instance.interval_end_dtm := FF.interval_end_dtm;
|
||||
sum_instance.uom := FF.uom;
|
||||
sum_instance.route := FF.route;
|
||||
sum_instance.total_dose_low := 0;
|
||||
sum_instance.total_dose_high := 0;
|
||||
sum_instance.start_date := FF.start_date;
|
||||
|
||||
endif; //if exist found_sum_tracker
|
||||
|
||||
if FF.num_doses_in_24hrs = FF.num_doses
|
||||
then
|
||||
sum_instance.has_full_24hrs_doses := true;
|
||||
else
|
||||
sum_instance.has_full_24hrs_doses := false;
|
||||
endif;
|
||||
|
||||
if FF = last (dose_tracker_list)
|
||||
then
|
||||
sum_instance.is_last_24hr_interval := true;
|
||||
else
|
||||
sum_instance.is_last_24hr_interval := false;
|
||||
endif;
|
||||
|
||||
//Populate Sum_Tracker with Doses
|
||||
sum_instance.total_dose_low := sum_instance.total_dose_low + FF.total_dose_low ;
|
||||
sum_instance.total_dose_high := sum_instance.total_dose_high + FF.total_dose_high ;
|
||||
|
||||
enddo; //for FF
|
||||
|
||||
|
||||
//------------------------------
|
||||
// Calculate Total Daily Dose
|
||||
//------------------------------
|
||||
|
||||
for GG in (1 seqto count sum_tracker_list) do
|
||||
// Find the Total_Tracker_Object
|
||||
// The Med Order Type, Medication Name, UOM, Dose Low, and Dose High must match
|
||||
// Route must match or both be NULL
|
||||
found_total_tracker := total_tracker_list where
|
||||
(total_tracker_list.med_order_type = sum_tracker_list[GG].med_order_type
|
||||
and total_tracker_list.med_name = sum_tracker_list[GG].med_name
|
||||
and (total_tracker_list.route = sum_tracker_list[GG].route or
|
||||
((total_tracker_list.route is NULL) and (sum_tracker_list[GG].route is NULL)))
|
||||
and total_tracker_list.uom = sum_tracker_list[GG].uom
|
||||
and total_tracker_list.total_dose_low = sum_tracker_list[GG].total_dose_low
|
||||
and total_tracker_list.total_dose_high = sum_tracker_list[GG].total_dose_high);
|
||||
|
||||
if exist found_total_tracker
|
||||
then
|
||||
//Use existing object
|
||||
total_instance := last found_total_tracker;
|
||||
|
||||
//Add DTM to the list
|
||||
if exist total_instance.interval_begin_dtm_list
|
||||
then
|
||||
total_instance.interval_begin_dtm_list :=
|
||||
total_instance.interval_begin_dtm_list,
|
||||
sum_tracker_list[GG].interval_begin_dtm;
|
||||
endif; //if exist total_instance.interval_begin_dtm_list
|
||||
else
|
||||
//Create a new object
|
||||
total_instance := new Total_Tracker_Object;
|
||||
|
||||
//Add the total_instance to the list
|
||||
total_tracker_list := total_tracker_list, total_instance;
|
||||
|
||||
//Populate Total_Tracker_Object
|
||||
total_instance.dose_range_check_method := "Summed Doses";
|
||||
total_instance.med_order_type := sum_tracker_list[GG].med_order_type;
|
||||
total_instance.med_name := sum_tracker_list[GG].med_name;
|
||||
total_instance.route := sum_tracker_list[GG].route;
|
||||
total_instance.total_dose_low := sum_tracker_list[GG].total_dose_low;
|
||||
total_instance.total_dose_high := sum_tracker_list[GG].total_dose_high;
|
||||
total_instance.uom := sum_tracker_list[GG].uom;
|
||||
total_instance.dose_calc_method_number :=
|
||||
sum_tracker_list[GG].dose_calc_method_number;
|
||||
total_instance.interval_begin_dtm_list :=
|
||||
sum_tracker_list[GG].interval_begin_dtm;
|
||||
total_instance.is_last_24hr_interval := sum_tracker_list[GG].is_last_24hr_interval;
|
||||
total_instance.has_full_24hrs_doses := sum_tracker_list[GG].has_full_24hrs_doses;
|
||||
total_instance.start_date := sum_tracker_list[GG].start_date;
|
||||
|
||||
|
||||
endif; //if exist found_total_tracker
|
||||
|
||||
|
||||
// Set the Calc Method and Calc_Text
|
||||
temp_object := first (med_data_list where
|
||||
(med_data_list.med_order_type = total_instance.med_order_type
|
||||
and med_data_list.order_med_name = total_instance.med_name
|
||||
and (med_data_list.order_med_route = total_instance.route
|
||||
or ((med_data_list.order_med_route is NULL)
|
||||
and (total_instance.route is NULL)))));
|
||||
|
||||
total_instance.dose_calc_method_number := temp_object.calc_dose_method;
|
||||
total_instance.calc_text := temp_object.calc_text;
|
||||
enddo; //for GG
|
||||
|
||||
//-----------------------------
|
||||
//Calculate Average Daily Dose
|
||||
//-----------------------------
|
||||
|
||||
|
||||
for HH in (1 seqto count total_tracker_list) do
|
||||
// Find the Average_Tracker_Object
|
||||
// The Med Order Type, Medication Name, and UOM must match
|
||||
// Route must match or both be NULL
|
||||
found_average_tracker := average_tracker_list where
|
||||
(average_tracker_list.med_order_type = total_tracker_list[HH].med_order_type
|
||||
and average_tracker_list.med_name = total_tracker_list[HH].med_name
|
||||
and (average_tracker_list.route = total_tracker_list[HH].route
|
||||
or ((average_tracker_list.route is NULL)
|
||||
and (total_tracker_list[HH].route is NULL)))
|
||||
and average_tracker_list.uom = total_tracker_list[HH].uom );
|
||||
|
||||
//Find the Total_Tracker_Objects
|
||||
// The Med Order Type, Medication Name, and UOM must match
|
||||
// Route must match or both be NULL
|
||||
found_total_tracker := total_tracker_list where
|
||||
(total_tracker_list.med_order_type = total_tracker_list[HH].med_order_type
|
||||
and total_tracker_list.med_name = total_tracker_list[HH].med_name
|
||||
and (total_tracker_list.route = total_tracker_list[HH].route
|
||||
or ((total_tracker_list.route is NULL)
|
||||
and (total_tracker_list[HH].route is NULL)))
|
||||
and total_tracker_list.uom = total_tracker_list[HH].uom );
|
||||
|
||||
if found_total_tracker[1].med_order_type = "Complex Order"
|
||||
and not exist found_average_tracker
|
||||
then
|
||||
//Copy Total_Tracker data to the Average_Tracker
|
||||
//Do NOT calculate an Average for the Highs and Low Doses
|
||||
|
||||
for JJ in (1 seqto count found_total_tracker) do
|
||||
//Create a new object
|
||||
average_instance := new Average_Tracker_Object;
|
||||
average_tracker_list := average_tracker_list, average_instance;
|
||||
|
||||
//Populate the data
|
||||
average_instance.dose_range_check_method := "Summed Doses";
|
||||
average_instance.med_order_type := found_total_tracker[JJ].med_order_type;
|
||||
average_instance.med_name := found_total_tracker[JJ].med_name;
|
||||
average_instance.route := found_total_tracker[JJ].route;
|
||||
average_instance.uom := found_total_tracker[JJ].uom;
|
||||
average_instance.dose_calc_method_number :=
|
||||
found_total_tracker[JJ].dose_calc_method_number;
|
||||
average_instance.calc_text := found_total_tracker[JJ].calc_text;
|
||||
average_instance.interval_begin_dtm_list :=
|
||||
found_total_tracker[JJ].interval_begin_dtm_list;
|
||||
average_instance.average_dose_low := found_total_tracker[JJ].total_dose_low;
|
||||
average_instance.average_dose_high := found_total_tracker[JJ].total_dose_high;
|
||||
average_instance.is_last_24hr_interval := found_total_tracker[JJ].is_last_24hr_interval;
|
||||
average_instance.has_full_24hrs_doses := found_total_tracker[JJ].has_full_24hrs_doses;
|
||||
average_instance.start_date := found_total_tracker[JJ].start_date;
|
||||
|
||||
enddo; //for JJ
|
||||
elseif found_total_tracker[1].med_order_type is in ( "Regular", "IV-Additive")
|
||||
and not exist found_average_tracker
|
||||
then
|
||||
//Calculate an Average for the Highs and Low Doses
|
||||
|
||||
//Create a new object
|
||||
average_instance := new Average_Tracker_Object;
|
||||
average_tracker_list := average_tracker_list, average_instance;
|
||||
|
||||
//Populate the data
|
||||
average_instance.dose_range_check_method := "Summed Doses" ;
|
||||
average_instance.med_order_type := last found_total_tracker.med_order_type;
|
||||
average_instance.med_name := last found_total_tracker.med_name;
|
||||
average_instance.route := last found_total_tracker.route;
|
||||
average_instance.uom := last found_total_tracker.uom;
|
||||
average_instance.dose_calc_method_number :=
|
||||
last found_total_tracker.dose_calc_method_number;
|
||||
average_instance.calc_text := last found_total_tracker.calc_text;
|
||||
average_instance.start_date := last found_total_tracker.start_date;
|
||||
|
||||
//Calculate Average Daily for Low and High Doses
|
||||
temp_low := 0;
|
||||
temp_high := 0;
|
||||
temp_min_dtm := null;
|
||||
temp_max_dtm := null;
|
||||
for KK in (1 seqto count found_total_tracker) do
|
||||
temp_number_of_dates := count found_total_tracker[KK].interval_begin_dtm_list;
|
||||
temp_low := temp_low
|
||||
+ (found_total_tracker[KK].total_dose_low * temp_number_of_dates);
|
||||
temp_high := temp_high
|
||||
+ (found_total_tracker[KK].total_dose_high * temp_number_of_dates);
|
||||
|
||||
// Get the Min and Max DTM from the CURRENT Total Tracker
|
||||
temp_min_dtm_in_tracker := min (found_total_tracker[KK].interval_begin_dtm_list);
|
||||
temp_max_dtm_in_tracker := max (found_total_tracker[KK].interval_begin_dtm_list);
|
||||
|
||||
// Find the Minimum Dtm for the group of FOUND Total Trackers
|
||||
if not exist temp_min_dtm
|
||||
then temp_min_dtm := temp_min_dtm_in_tracker;
|
||||
elseif exist temp_min_dtm
|
||||
and temp_min_dtm_in_tracker < temp_min_dtm
|
||||
then temp_min_dtm := temp_min_dtm_in_tracker;
|
||||
endif;
|
||||
|
||||
// Find the Maximum Dtm for the group of FOUND Total Trackers
|
||||
if not exist temp_max_dtm
|
||||
then temp_max_dtm := temp_max_dtm_in_tracker;
|
||||
elseif exist temp_max_dtm
|
||||
and temp_max_dtm_in_tracker > temp_max_dtm
|
||||
then temp_max_dtm := temp_max_dtm_in_tracker;
|
||||
endif; //if not exist temp_max_dtm
|
||||
enddo; //for KK
|
||||
|
||||
//Store the entire list of dates from the found_total_tracker, not just the last one
|
||||
for LL in (1 seqto count found_total_tracker) do
|
||||
if exist average_instance.interval_begin_dtm_list
|
||||
then
|
||||
average_instance.interval_begin_dtm_list :=
|
||||
average_instance.interval_begin_dtm_list,
|
||||
found_total_tracker[LL].interval_begin_dtm_list;
|
||||
else
|
||||
average_instance.interval_begin_dtm_list :=
|
||||
found_total_tracker[LL].interval_begin_dtm_list;
|
||||
endif; //if LL
|
||||
enddo; //for LL
|
||||
|
||||
//Calculate the Total Number of Days the Patient receives Medications
|
||||
// Since we are using the interval_begin_dtm_list
|
||||
// which are the beginning of the 24-hour interval,
|
||||
// we need to adjust the number of days by 24 hours
|
||||
// since the patient can receive medication until
|
||||
// the end of the 24-hour interval
|
||||
|
||||
num_days_rounded_up := Truncate ((temp_max_dtm - temp_min_dtm + 24 hours )/ 1 day);
|
||||
|
||||
//Calculate the Low and High Doses by dividing the doses with the number of days
|
||||
//AND Store the Doses
|
||||
temp_average_dose_low := temp_low / num_days_rounded_up;
|
||||
temp_average_dose_high := temp_high / num_days_rounded_up;
|
||||
|
||||
|
||||
// Find the Single Dose for the current Average_Tracker.
|
||||
found_med_data := med_data_list where
|
||||
(med_data_list.med_order_type = average_instance.med_order_type
|
||||
and med_data_list.order_med_name = average_instance.med_name
|
||||
and (med_data_list.order_med_route = average_instance.route
|
||||
or ((med_data_list.order_med_route is NULL)
|
||||
and (average_instance.route is NULL)))
|
||||
and med_data_list.order_med_units = average_instance.uom );
|
||||
|
||||
// Store Doses - no rounding for average dose for proper daily dose checking
|
||||
average_instance.average_dose_high := temp_average_dose_high;
|
||||
average_instance.average_dose_low := temp_average_dose_low;
|
||||
endif; //if found_total_tracker[1].med_order_type = "Complex Order"
|
||||
enddo; //for HH
|
||||
endif; //if med_data.med_order_type is in ("Regular", "IV-Additive")
|
||||
|
||||
total_tracker_count := count total_tracker_list;
|
||||
total_tracker_list.sort_number := 1 seqto total_tracker_count;
|
||||
|
||||
average_tracker_count := count average_tracker_list;
|
||||
average_tracker_list.sort_number := 1 seqto average_tracker_count;
|
||||
|
||||
//Always Conclude True;
|
||||
Conclude True;
|
||||
;;
|
||||
action:
|
||||
return total_tracker_list, average_tracker_list;
|
||||
;;
|
||||
Urgency: 50;;
|
||||
end:
|
||||
127
MLMStripper/bin/Debug/STD/STD_FUNC_DOSAGE_TRIM.mlm
Normal file
127
MLMStripper/bin/Debug/STD/STD_FUNC_DOSAGE_TRIM.mlm
Normal file
@@ -0,0 +1,127 @@
|
||||
maintenance:
|
||||
|
||||
title: Trim Excess Decimals from Numbers;;
|
||||
mlmname: STD_FUNC_DOSAGE_TRIM;;
|
||||
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: Trims excess decimals from number(s) by rounding them to a specific
|
||||
number of decimals, based on a template number.
|
||||
;;
|
||||
explanation: A list of numbers is rounded and trimmed to 1 decimal place more
|
||||
than the template number with the most decimal places.
|
||||
Example: the template number has 2 decimal places (e.g. 450.25),
|
||||
then the list of numbers is rounded to 3 decimals (e.g. 20.333333, 50.7777777)
|
||||
and becomes (20.333, 50.778).
|
||||
;;
|
||||
keywords: single dose; average daily dose; total daily dose; dosage range
|
||||
;;
|
||||
knowledge:
|
||||
type: data-driven;;
|
||||
data:
|
||||
(template_numbers_list, // A list of numbers that is used as a template for trimming decimals
|
||||
trim_numbers_list // One or more numbers that need to be trimmed.
|
||||
) := ARGUMENT;
|
||||
|
||||
standard_libs := mlm {{{SINGLE-QUOTE}}}std_include_libs{{{SINGLE-QUOTE}}};
|
||||
include standard_libs;
|
||||
|
||||
using namespace "System";
|
||||
|
||||
// Set to true if logging is needed.
|
||||
log_execution_info := false;
|
||||
;;
|
||||
evoke:
|
||||
;;
|
||||
logic:
|
||||
|
||||
if template_numbers_list is number
|
||||
then
|
||||
template_numbers_list := , template_numbers_list;
|
||||
endif;
|
||||
|
||||
if all (template_numbers_list is number)
|
||||
and all (trim_numbers_list is number)
|
||||
then
|
||||
// Initalize Variables
|
||||
rounded_trim_numbers_list := ();
|
||||
max_decimals := 0;
|
||||
|
||||
for temp_num in template_numbers_list do
|
||||
// Convert number to Characters and extract them into a list
|
||||
initial_string := "" || temp_num;
|
||||
|
||||
// Check for Scientific Notation
|
||||
// and convert to all digits
|
||||
if initial_string matches pattern "%E%"
|
||||
then
|
||||
initial_string := temp_num formatted with "%f";
|
||||
endif; // if "E"
|
||||
|
||||
net_string := initial_string as {{{SINGLE-QUOTE}}}String{{{SINGLE-QUOTE}}};
|
||||
|
||||
decimal_index := call net_string.IndexOf with (".");
|
||||
if (decimal_index >= 0)
|
||||
then
|
||||
number_of_decimals := LENGTH initial_string - (decimal_index + 1);
|
||||
else
|
||||
number_of_decimals := 0;
|
||||
endif;
|
||||
|
||||
if (number_of_decimals > max_decimals)
|
||||
then
|
||||
max_decimals := number_of_decimals;
|
||||
longest_num := temp_num;
|
||||
endif;
|
||||
enddo;
|
||||
|
||||
|
||||
// Adjust by one decimal
|
||||
max_decimals := max_decimals + 1;
|
||||
|
||||
// Create the string template for format the number
|
||||
// Template example: "%.3f"
|
||||
string_template := "%." || max_decimals ||"f";
|
||||
|
||||
// Create a list of numbers with the required number of decimals
|
||||
for temp_num in trim_numbers_list do
|
||||
// Check that a number is being formatted.
|
||||
// Otherwise formatting something that is not a number
|
||||
// will throw an execution error.
|
||||
// Return a NULL if we do not have a number.
|
||||
if temp_num is number
|
||||
then rounded_num := (temp_num formatted with string_template) AS NUMBER ;
|
||||
else rounded_num := null;
|
||||
endif;
|
||||
rounded_trim_numbers_list := rounded_trim_numbers_list, rounded_num;
|
||||
enddo; //for temp_num
|
||||
endif; //if template_number is number
|
||||
|
||||
Conclude True;
|
||||
;;
|
||||
action:
|
||||
Return rounded_trim_numbers_list;
|
||||
;;
|
||||
Urgency: 50;;
|
||||
end:
|
||||
105
MLMStripper/bin/Debug/STD/STD_FUNC_DOSAGE_TRIM_ADJUSTED.mlm
Normal file
105
MLMStripper/bin/Debug/STD/STD_FUNC_DOSAGE_TRIM_ADJUSTED.mlm
Normal file
@@ -0,0 +1,105 @@
|
||||
maintenance:
|
||||
|
||||
title: Trim Excess Decimals from Numbers;;
|
||||
mlmname: STD_FUNC_DOSAGE_TRIM_ADJUSTED;;
|
||||
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: Applies conversion factor to the list of numbers, and if the conversion factor
|
||||
is small and introduces extra significant digits, it shifts the template number to
|
||||
add extra significant digits
|
||||
;;
|
||||
explanation: A list of numbers is rounded and trimmed to 1 decimal place more
|
||||
than the template number with the most decimal places and conversion factor.
|
||||
Example: the template number has 2 decimal places (e.g. 450.25),
|
||||
then the list of numbers is rounded to 3 decimals (e.g. 20.333333, 50.7777777)
|
||||
and becomes (20.333, 50.778).
|
||||
|
||||
The conversion factor is applied to the list of numbers.
|
||||
If the conversion factor introduces extra significant digit, it adds the significant digits
|
||||
to the template number.
|
||||
Example: the template number has 2 decimal places (e.g. 450.25), and the conversion factor is 0.1
|
||||
then the list of numbers is rounded to 3 decimals (e.g. 2.0333333, 5.07777777)
|
||||
and becomes (2.0333, 5.0778).
|
||||
;;
|
||||
keywords: single dose; average daily dose; total daily dose; dosage range
|
||||
;;
|
||||
knowledge:
|
||||
type: data-driven;;
|
||||
data:
|
||||
(template_numbers_list, // A list of numbers that a used as a template for trimming decimals (based on the one with the most decimals)
|
||||
conversion_factor, // A number to convert the trim_numbers_list
|
||||
trim_numbers_list // One or more numbers that need to be trimmed.
|
||||
) := ARGUMENT;
|
||||
|
||||
|
||||
// Set to true if logging is needed.
|
||||
log_execution_info := false;
|
||||
|
||||
func_dosage_trim := MLM {{{SINGLE-QUOTE}}}STD_func_dosage_trim{{{SINGLE-QUOTE}}};
|
||||
;;
|
||||
evoke:
|
||||
;;
|
||||
logic:
|
||||
if template_numbers_list is number
|
||||
then
|
||||
template_numbers_list := , template_numbers_list;
|
||||
endif;
|
||||
|
||||
if all (template_numbers_list is number)
|
||||
and conversion_factor is number
|
||||
and all (trim_numbers_list is number)
|
||||
then
|
||||
divisor := 1;
|
||||
|
||||
// See how many factors of 10 we can find
|
||||
// Every divisor of 10 shifts the number by one decimal place
|
||||
// 0.1 => 1/0.1 = 10 => a factor of 10
|
||||
// 0.05 => 1/0.05 = 20 => shifts the digits by a factor of 10
|
||||
// 0.01 => 1/0.01 => 100 => shifts digits by a factor of 100
|
||||
if (conversion_factor >0) and (conversion_factor < 1)
|
||||
then
|
||||
val := 1/conversion_factor;
|
||||
|
||||
while (val > 10)
|
||||
do
|
||||
divisor := divisor * 10;
|
||||
val := val/10;
|
||||
enddo;
|
||||
endif;
|
||||
|
||||
// Adjust the significant digits of the template number based on the conversion factor
|
||||
shifted_template_numbers_list := template_numbers_list / divisor;
|
||||
converted_trim_numbers_list := trim_numbers_list * conversion_factor;
|
||||
|
||||
(rounded_trim_numbers_list) := call func_dosage_trim with (shifted_template_numbers_list, converted_trim_numbers_list);
|
||||
endif; //if template_number is number
|
||||
|
||||
Conclude True;
|
||||
;;
|
||||
action:
|
||||
Return rounded_trim_numbers_list;
|
||||
;;
|
||||
Urgency: 50;;
|
||||
end:
|
||||
394
MLMStripper/bin/Debug/STD/STD_FUNC_DOSAGE_XML_PARAMS.mlm
Normal file
394
MLMStripper/bin/Debug/STD/STD_FUNC_DOSAGE_XML_PARAMS.mlm
Normal file
@@ -0,0 +1,394 @@
|
||||
maintenance:
|
||||
|
||||
title: Generate XML parameters to get dose range data;;
|
||||
mlmname: STD_Func_Dosage_XML_Params;;
|
||||
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: Generate XML input parameters for getting dose range data from
|
||||
item-catalog or multum.
|
||||
;;
|
||||
explanation: This MLM assists the STD_Dosage MLM with dose-range checking.
|
||||
It formats the input XML for the SCMGetItemCatDosageRangePr and
|
||||
SCMMultumGrouperDosageRangePR.
|
||||
;;
|
||||
keywords: dosage range, multum, item catalog, order, prescription
|
||||
;;
|
||||
knowledge:
|
||||
type: data-driven;;
|
||||
data:
|
||||
// Set to true if logging is needed.
|
||||
log_execution_info := false;
|
||||
|
||||
(
|
||||
// Common medication data
|
||||
drc_grouper_id,
|
||||
multum_dnum,
|
||||
multum_mmdc,
|
||||
order_med_route,
|
||||
order_med_route_id,
|
||||
is_generic_route,
|
||||
order_med_significant_date,
|
||||
order_med_units,
|
||||
order_med_uom_id,
|
||||
multum_freq_id,
|
||||
med_order_type,
|
||||
is_order,
|
||||
// Patient data
|
||||
patient_birthday_info_on_order,
|
||||
has_valid_birthdate,
|
||||
wt_kg,
|
||||
BSA_number_rounded,
|
||||
intl_patient_gender,
|
||||
// Item Catalog only
|
||||
for_item_catalog,
|
||||
catalog_item_obj,
|
||||
// Multum only
|
||||
has_liver_disease_bit,
|
||||
dialysis_type_str,
|
||||
serum_creatinine,
|
||||
// Flags and constants
|
||||
alert_if_missing_flags,
|
||||
patient_info,
|
||||
core_uom_const
|
||||
):= ARGUMENT;
|
||||
|
||||
Name_Value_Object := OBJECT [name, val];
|
||||
|
||||
// XML parameter
|
||||
indent := " ";
|
||||
indent1 := indent;
|
||||
indent2 := indent || indent;
|
||||
newline := "\n";
|
||||
|
||||
// Set the medication parameters
|
||||
med_info_list := (
|
||||
(new Name_Value_Object with "GrouperID", drc_grouper_id),
|
||||
(new Name_Value_Object with "DNum", multum_dnum),
|
||||
(new Name_Value_Object with "MMDC", multum_mmdc),
|
||||
(new Name_Value_Object with "UOMID", order_med_uom_id),
|
||||
(new Name_Value_Object with "RouteID", order_med_route_id),
|
||||
(new Name_Value_Object with "FrequencyID", multum_freq_id)
|
||||
);
|
||||
|
||||
if for_item_catalog and exists catalog_item_obj then
|
||||
|
||||
catalog_med_info_list := (
|
||||
(new Name_Value_Object with "CatalogMasterItemGUID", catalog_item_obj.GUID),
|
||||
(new Name_Value_Object with "UOM", order_med_units),
|
||||
(new Name_Value_Object with "Route", order_med_route)
|
||||
);
|
||||
med_info_list := med_info_list, catalog_med_info_list;
|
||||
endif;
|
||||
|
||||
med_params_xml :=
|
||||
indent1 ||"<Medication " || newline;
|
||||
for med_item in med_info_list
|
||||
do
|
||||
if exists med_item.val
|
||||
then
|
||||
med_params_xml := med_params_xml ||
|
||||
indent2 || med_item.name || "={{{SINGLE-QUOTE}}}" || XMLEX(med_item.val) || "{{{SINGLE-QUOTE}}}" || newline;
|
||||
endif;
|
||||
enddo;
|
||||
med_params_xml := med_params_xml ||
|
||||
indent1 ||"/>" || newline;
|
||||
|
||||
// Patient Info
|
||||
age_params_xml := "";
|
||||
if has_valid_birthdate
|
||||
then
|
||||
age_unit_list := (
|
||||
(new Name_Value_Object with core_uom_const.day_string, patient_birthday_info_on_order.age_day_value),
|
||||
(new Name_Value_Object with core_uom_const.week_string, patient_birthday_info_on_order.age_week_value),
|
||||
(new Name_Value_Object with core_uom_const.month_string, patient_birthday_info_on_order.age_month_value),
|
||||
(new Name_Value_Object with core_uom_const.year_string, patient_birthday_info_on_order.age_year_value),
|
||||
(new Name_Value_Object with core_uom_const.hour_string, patient_birthday_info_on_order.age_hour_value)
|
||||
);
|
||||
|
||||
//[New born birth-time missing]: when new born < 4 days is missing birth time and >= 1 day, add AgeMin value to it
|
||||
age_unit_min_list := ();
|
||||
if patient_birthday_info_on_order.is_estimated_birthday = true and patient_birthday_info_on_order.age_day_value >= 1.0
|
||||
then
|
||||
age_unit_min_list := (
|
||||
(new Name_Value_Object with core_uom_const.day_string, patient_birthday_info_on_order.age_day_min_value),
|
||||
(new Name_Value_Object with core_uom_const.week_string, patient_birthday_info_on_order.age_week_min_value),
|
||||
(new Name_Value_Object with core_uom_const.month_string, patient_birthday_info_on_order.age_month_min_value),
|
||||
(new Name_Value_Object with core_uom_const.year_string, patient_birthday_info_on_order.age_year_min_value),
|
||||
(new Name_Value_Object with core_uom_const.hour_string, patient_birthday_info_on_order.age_hour_min_value)
|
||||
);
|
||||
endif;
|
||||
|
||||
for unit_item_index in (1 seqto count age_unit_list)
|
||||
do
|
||||
// age_unit_list and the age_unit_min_list are in the same unit sequence
|
||||
// day, week, month, year, hour
|
||||
unit_item := age_unit_list[unit_item_index];
|
||||
unit_min_item := age_unit_min_list[unit_item_index];
|
||||
|
||||
age_params_xml := age_params_xml ||
|
||||
indent2 || "<Item type={{{SINGLE-QUOTE}}}Age{{{SINGLE-QUOTE}}} "
|
||||
|| "unit={{{SINGLE-QUOTE}}}" || XMLEX(unit_item.name) || "{{{SINGLE-QUOTE}}} "
|
||||
|| "val={{{SINGLE-QUOTE}}}" || XMLEX(unit_item.val formatted with "%.16f") || "{{{SINGLE-QUOTE}}} ";
|
||||
|
||||
if exists unit_min_item
|
||||
then
|
||||
//[New born birth-time missing]: item will be lik:
|
||||
// <Item type={{{SINGLE-QUOTE}}}{{{SINGLE-QUOTE}}}Age{{{SINGLE-QUOTE}}}{{{SINGLE-QUOTE}}} unit={{{SINGLE-QUOTE}}}{{{SINGLE-QUOTE}}}day{{{SINGLE-QUOTE}}}{{{SINGLE-QUOTE}}} val={{{SINGLE-QUOTE}}}{{{SINGLE-QUOTE}}}2.4270833333333335{{{SINGLE-QUOTE}}}{{{SINGLE-QUOTE}}} min_val={{{SINGLE-QUOTE}}}{{{SINGLE-QUOTE}}}1.4277777777777778{{{SINGLE-QUOTE}}}{{{SINGLE-QUOTE}}} />
|
||||
age_params_xml := age_params_xml || "min_val={{{SINGLE-QUOTE}}}" || XMLEX(unit_min_item.val formatted with "%.16f") || "{{{SINGLE-QUOTE}}} ";
|
||||
endif;
|
||||
age_params_xml := age_params_xml || "/>" || newline;
|
||||
|
||||
enddo;
|
||||
|
||||
endif;
|
||||
|
||||
bsa_params_xml := "";
|
||||
if BSA_number_rounded is number and BSA_number_rounded > 0
|
||||
then
|
||||
bsa_params_xml :=
|
||||
indent2 || "<Item type={{{SINGLE-QUOTE}}}BSA{{{SINGLE-QUOTE}}} unit={{{SINGLE-QUOTE}}}M2{{{SINGLE-QUOTE}}} val={{{SINGLE-QUOTE}}}" || XMLEX(BSA_number_rounded) || "{{{SINGLE-QUOTE}}} />" || newline;
|
||||
endif;
|
||||
|
||||
weight_params_xml := "";
|
||||
if wt_kg is number and wt_kg > 0
|
||||
then
|
||||
// Convert patient weight to grams
|
||||
wt_gm:= wt_kg * 1000;
|
||||
|
||||
weight_lb_value := wt_gm/453.6; // pound
|
||||
weight_ounce_value := wt_gm/28.35; // ounce
|
||||
|
||||
wt_unit_list:= (
|
||||
(new Name_Value_Object with core_uom_const.gm_string, wt_gm),
|
||||
(new Name_Value_Object with core_uom_const.ounce_string, weight_ounce_value),
|
||||
(new Name_Value_Object with core_uom_const.lb_string, weight_lb_value),
|
||||
(new Name_Value_Object with core_uom_const.kg_string, wt_kg)
|
||||
);
|
||||
|
||||
for unit_item in wt_unit_list
|
||||
do
|
||||
weight_params_xml := weight_params_xml ||
|
||||
indent2 || "<Item type={{{SINGLE-QUOTE}}}Weight{{{SINGLE-QUOTE}}} "
|
||||
|| "unit={{{SINGLE-QUOTE}}}" || XMLEX(unit_item.name) || "{{{SINGLE-QUOTE}}} "
|
||||
|| "val={{{SINGLE-QUOTE}}}" || XMLEX(unit_item.val) || "{{{SINGLE-QUOTE}}} "
|
||||
|| "/>" || newline;
|
||||
enddo;
|
||||
endif;
|
||||
|
||||
gender_params_xml := "";
|
||||
if exists intl_patient_gender
|
||||
then
|
||||
gender_params_xml :=
|
||||
indent1 || "<Gender val={{{SINGLE-QUOTE}}}" || XMLEX(intl_patient_gender) || "{{{SINGLE-QUOTE}}}/>" || newline;
|
||||
endif;
|
||||
|
||||
//[New born birth-time missing]: add MissingBabyBirthTime
|
||||
birth_time_missing_xml := "";
|
||||
if patient_birthday_info_on_order.is_estimated_birthday = true
|
||||
then
|
||||
if patient_birthday_info_on_order.age_day_value >= 1.0
|
||||
then
|
||||
missing_baby_birthTime_value := 1;
|
||||
else
|
||||
missing_baby_birthTime_value := 2;
|
||||
endif;
|
||||
|
||||
birth_time_missing_xml :=
|
||||
indent1 || "<MissingBabyBirthTime val={{{SINGLE-QUOTE}}}" || XMLEX(missing_baby_birthTime_value) || "{{{SINGLE-QUOTE}}}/>" || newline;
|
||||
endif;
|
||||
|
||||
liver_params_xml := "";
|
||||
dialysis_params_xml := "";
|
||||
creatinine_params_xml := "";
|
||||
|
||||
if not for_item_catalog
|
||||
then
|
||||
if exists has_liver_disease_bit
|
||||
then
|
||||
liver_params_xml :=
|
||||
indent2 || "<LiverDisease val={{{SINGLE-QUOTE}}}" || XMLEX(has_liver_disease_bit) || "{{{SINGLE-QUOTE}}}/>" || newline;
|
||||
endif;
|
||||
|
||||
if exists dialysis_type_str
|
||||
then
|
||||
dialysis_params_xml :=
|
||||
indent2 || "<DialysisType val={{{SINGLE-QUOTE}}}" || XMLEX(dialysis_type_str) || "{{{SINGLE-QUOTE}}}/>" || newline;
|
||||
endif;
|
||||
|
||||
if exists serum_creatinine
|
||||
then
|
||||
creatinine_params_xml :=
|
||||
indent2 || "<SerumCreatinine val={{{SINGLE-QUOTE}}}" || XMLEX(serum_creatinine) || "{{{SINGLE-QUOTE}}}/>" || newline;
|
||||
endif;
|
||||
endif;
|
||||
|
||||
patient_params_xml :=
|
||||
indent1 ||"<Patient>" || newline ||
|
||||
age_params_xml ||
|
||||
bsa_params_xml ||
|
||||
weight_params_xml ||
|
||||
gender_params_xml ||
|
||||
birth_time_missing_xml ||
|
||||
liver_params_xml ||
|
||||
dialysis_params_xml ||
|
||||
creatinine_params_xml ||
|
||||
indent1 ||"</Patient>" || newline;
|
||||
|
||||
get_dosage_for_missing_weight :=
|
||||
( alert_if_missing_flags.patient_weight
|
||||
and ( patient_info.Weight.is_missing or patient_info.Weight.not_current )
|
||||
);
|
||||
|
||||
get_dosage_for_missing_BSA := get_dosage_for_missing_weight
|
||||
or
|
||||
( alert_if_missing_flags.patient_height
|
||||
and ( patient_info.Height.is_missing or patient_info.Height.not_current )
|
||||
);
|
||||
|
||||
is_gender_missing := Patient_info.Gender.is_missing or intl_patient_gender in ("U", "O");
|
||||
|
||||
get_dosage_for_missing_gender :=
|
||||
( ( alert_if_missing_flags.patient_gender and is_gender_missing )
|
||||
or ( alert_if_missing_flags.unmapped_gender and Patient_info.Gender.is_unmapped )
|
||||
);
|
||||
|
||||
if (is_order)
|
||||
then
|
||||
missing_route := order_med_route is null;
|
||||
missing_uom := order_med_units is null;
|
||||
else
|
||||
missing_route := order_med_route is null AND order_med_route_id is null;
|
||||
missing_uom := order_med_units is null AND order_med_uom_id is null;
|
||||
endif;
|
||||
|
||||
|
||||
if (for_item_catalog)
|
||||
then
|
||||
// For item catalog, there is no "unmapped" concept
|
||||
unmapped_route := false;
|
||||
unmapped_uom := false;
|
||||
else
|
||||
unmapped_route := (not missing_route) and order_med_route_id is null;
|
||||
unmapped_uom := (not missing_uom) and order_med_uom_id is null;
|
||||
endif;
|
||||
|
||||
get_dosage_for_missing_route :=
|
||||
( ( alert_if_missing_flags.route and missing_route )
|
||||
or ( alert_if_missing_flags.unmapped_route and unmapped_route)
|
||||
);
|
||||
|
||||
get_dosage_for_missing_uom :=
|
||||
( ( alert_if_missing_flags.uom and missing_uom)
|
||||
or ( alert_if_missing_flags.unmapped_uom and unmapped_uom )
|
||||
);
|
||||
|
||||
get_dosage_for_missing_grouper :=
|
||||
( alert_if_missing_flags.cannot_check_DNUM_Rx_to_Multum
|
||||
and drc_grouper_id is null
|
||||
and not is_order
|
||||
and not for_item_catalog
|
||||
);
|
||||
|
||||
// - Return other routes if the current route is unrecognized route
|
||||
// and the cannot check unrecognized route flag is on
|
||||
// - Return other routes if the current route is not an unrecognized route
|
||||
// and the inapplicable route flag is on
|
||||
get_dosage_for_route_match_not_found :=
|
||||
( alert_if_missing_flags.cannot_check_generic_route
|
||||
and is_generic_route
|
||||
)
|
||||
OR
|
||||
( alert_if_missing_flags.inapplicable_route
|
||||
and not is_generic_route
|
||||
and not for_item_catalog
|
||||
);
|
||||
|
||||
|
||||
get_dosage_for_uom_conversion := alert_if_missing_flags.uom_conversion;
|
||||
|
||||
if for_item_catalog and not is_order
|
||||
then
|
||||
get_dosage_for_ic_dnum := alert_if_missing_flags.cannot_check_Rx_to_IC;
|
||||
endif;
|
||||
|
||||
if not for_item_catalog and is_order
|
||||
then
|
||||
get_dosage_for_any_freq := (med_order_type = "Complex Order");
|
||||
endif;
|
||||
|
||||
if for_item_catalog
|
||||
then
|
||||
get_dosage_for_missing_age := alert_if_missing_flags.patient_age and (not has_valid_birthdate);
|
||||
endif;
|
||||
|
||||
missing_data_flags_list := (
|
||||
(new Name_Value_Object with "ReturnDataForMissingWeight", get_dosage_for_missing_weight),
|
||||
(new Name_Value_Object with "ReturnDataForMissingBSA", get_dosage_for_missing_BSA),
|
||||
(new Name_Value_Object with "ReturnDataForMissingGender", get_dosage_for_missing_gender),
|
||||
(new Name_Value_Object with "ReturnDataForMissingGrouperBasedOnDnum", get_dosage_for_missing_grouper),
|
||||
(new Name_Value_Object with "ReturnDataForMissingRoute", get_dosage_for_missing_route),
|
||||
(new Name_Value_Object with "ReturnDataForRouteMatchNotFound", get_dosage_for_route_match_not_found),
|
||||
(new Name_Value_Object with "ReturnDataForMissingUOM", get_dosage_for_missing_uom),
|
||||
(new Name_Value_Object with "ReturnDataForUomConversionIssue", get_dosage_for_uom_conversion),
|
||||
(new Name_Value_Object with "ReturnDataByDnumWhenNoMatchFound", get_dosage_for_ic_dnum),
|
||||
(new Name_Value_Object with "ReturnDailyDoseForAnyFreq", get_dosage_for_any_freq),
|
||||
(new Name_Value_Object with "ReturnDataForMissingAge", get_dosage_for_missing_age)
|
||||
);
|
||||
|
||||
missing_data_flag_name_val_xml := "";
|
||||
for unit_item in missing_data_flags_list
|
||||
do
|
||||
if unit_item.val then bit_val := 1; else bit_val := 0; endif;
|
||||
missing_data_flag_name_val_xml := missing_data_flag_name_val_xml ||
|
||||
indent2 || unit_item.name || "={{{SINGLE-QUOTE}}}" || XMLEX(bit_val) || "{{{SINGLE-QUOTE}}}" || newline;
|
||||
enddo;
|
||||
|
||||
missing_data_flags_xml :=
|
||||
indent1 || "<MissingData " || newline ||
|
||||
missing_data_flag_name_val_xml || newline ||
|
||||
indent1 || "/>" || newline;
|
||||
|
||||
input_param_xml := "\n<ROOT>\n" ||
|
||||
med_params_xml ||
|
||||
patient_params_xml ||
|
||||
missing_data_flags_xml ||
|
||||
"</ROOT>" || newline;
|
||||
|
||||
debug_str_input_param_xml := SQL(input_param_xml);
|
||||
;;
|
||||
priority: 50
|
||||
;;
|
||||
evoke:
|
||||
;;
|
||||
logic:
|
||||
|
||||
/* Always conclude true to return variables to calling MLM */
|
||||
CONCLUDE TRUE;
|
||||
;;
|
||||
action:
|
||||
return (input_param_xml, missing_route, unmapped_route, missing_uom, unmapped_uom, uom_conversion_issue);
|
||||
;;
|
||||
Urgency: 50;;
|
||||
end:
|
||||
207
MLMStripper/bin/Debug/STD/STD_FUNC_DRUG_INTERACTION_ACTIONS.mlm
Normal file
207
MLMStripper/bin/Debug/STD/STD_FUNC_DRUG_INTERACTION_ACTIONS.mlm
Normal file
@@ -0,0 +1,207 @@
|
||||
maintenance:
|
||||
|
||||
title: Process Actions on Alerts for Drug Interactions;;
|
||||
mlmname: STD_FUNC_DRUG_INTERACTION_ACTIONS;;
|
||||
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: This MLM is used by the Drug Interaction checking MLMs to call another
|
||||
MLM to create the AlertAction object and to populate them with data.
|
||||
;;
|
||||
explanation: This MLM will do the following:
|
||||
1. Call the STD_Func_Create_Alert_Action_Object MLM to create an instance
|
||||
of the AlertAction object.
|
||||
2. Process the data that was sent to it and populate each AlertAction object.
|
||||
3. Create a list of the objects and return it to the call program.
|
||||
;;
|
||||
keywords:
|
||||
;;
|
||||
knowledge:
|
||||
type: data-driven;;
|
||||
data:
|
||||
/***************Make Changes To Spelling And Flags In This Section***************/
|
||||
/* Set to true if logging is needed.*/
|
||||
log_execution_info := false;
|
||||
|
||||
/********************************************************************************/
|
||||
|
||||
(aoa_evoking_drug_list, //Drugs that have interactions
|
||||
evoking_combined_med_type_list, //Evoking Data Values for a Regular or IV additives
|
||||
aoa_interaction_severity_list, //Interacting Severities
|
||||
aoa_interacting_drug_list, //Drugs that interact with the evoking drugs
|
||||
aoa_concomit_order_name_list, //All containing orders
|
||||
aoa_concomit_order_guid_list, //All orders including additives
|
||||
aoa_concomit_order_catalog_item_guid_list,
|
||||
aoa_concomit_item_type_list, // Regular or IVAdditive
|
||||
aoa_concomit_item_status_list, // Evoking, Unsubmitted, or Existing
|
||||
aoa_concomit_is_suspended_list,
|
||||
evoking_catalog_item_guid,
|
||||
evoking_order_guid,
|
||||
evoking_order_name)
|
||||
:= Argument;
|
||||
|
||||
// Declare the MLM that can be called
|
||||
func_create_alert_action_object := MLM {{{SINGLE-QUOTE}}}STD_Func_Create_Alert_Action_Object{{{SINGLE-QUOTE}}};
|
||||
|
||||
// Declare string constants
|
||||
Additive_string := "Additive";
|
||||
DC_Cancel_string := "DC-Cancel";
|
||||
Delete_string := "Delete";
|
||||
Evoking_string := "Current Order";
|
||||
Existing_string := "Existing";
|
||||
IVSolution_string := "IVSolution";
|
||||
Modify_string := "Modify";
|
||||
Regular_string := "Regular";
|
||||
Suspend_string := "Suspend";
|
||||
Unsubmitted_string := "Unsubmitted";
|
||||
Status_Unsubmitted_string := "Unsubmitted Order";
|
||||
Status_Unapprove_string := "Unapproved";
|
||||
|
||||
;;
|
||||
evoke:
|
||||
;;
|
||||
logic:
|
||||
//-----------------------------------------------------
|
||||
// Process The Lists to Extract Data To Create Actions
|
||||
//-----------------------------------------------------
|
||||
// Initialize
|
||||
alert_action_list := ();
|
||||
|
||||
// Loop through the list of interacting drugs
|
||||
action_index_list := 1 seqto count (aoa_evoking_drug_list);
|
||||
for AA in action_index_list do
|
||||
|
||||
// Get the drug-drug interaction pair and its severity
|
||||
aoa_evoking_drug := aoa_evoking_drug_list[AA];
|
||||
aoa_interacting_drug := aoa_interacting_drug_list[AA];
|
||||
aoa_interaction_severity := aoa_interaction_severity_list[AA];
|
||||
aoa_evoking_med_type := evoking_combined_med_type_list[AA];
|
||||
|
||||
//--------------------//
|
||||
// Create the Actions //
|
||||
//--------------------//
|
||||
// Loop through the sublist of drugs //
|
||||
sub_index_list := 1 seqto count aoa_concomit_order_guid_list;
|
||||
for BB in sub_index_list do
|
||||
aoa_order_guid := aoa_concomit_order_guid_list[BB];
|
||||
aoa_catalog_item_guid := aoa_concomit_order_catalog_item_guid_list[BB];
|
||||
aoa_med_type := aoa_concomit_item_type_list[BB];
|
||||
aoa_status_type := aoa_concomit_item_status_list[BB];
|
||||
aoa_is_suspended := aoa_concomit_is_suspended_list[BB];
|
||||
aoa_action_item_name := aoa_concomit_order_name_list[BB];
|
||||
|
||||
// Only process EXISTING and UNSUBMITTED Orders, NOT EVOKING
|
||||
if aoa_status_type <> Evoking_string
|
||||
then
|
||||
//---------------------------------------------------//
|
||||
// Create the ShortMessage for the Actions on Alerts //
|
||||
//---------------------------------------------------//
|
||||
//Add the front part of the message.
|
||||
If aoa_evoking_med_type = Regular_string
|
||||
then
|
||||
short_message := "The current order for "
|
||||
|| aoa_evoking_drug ||" has a drug interaction with ";
|
||||
elseif aoa_evoking_med_type = IVSolution_string
|
||||
then
|
||||
short_message := "The current order for "
|
||||
|| aoa_evoking_drug ||" has a drug interaction with ";
|
||||
elseif aoa_evoking_med_type = Additive_string
|
||||
then
|
||||
short_message := "The current order has an IV-additive, "
|
||||
|| aoa_evoking_drug ||", that has a drug interaction with ";
|
||||
endif; //aoa_evoking_med_type
|
||||
|
||||
//Add the middle part of the message.
|
||||
if aoa_med_type = Regular_string
|
||||
then short_message := short_message || aoa_interacting_drug ;
|
||||
elseif aoa_med_type = IVSolution_string
|
||||
then short_message := short_message || aoa_interacting_drug ;
|
||||
elseif aoa_med_type = Additive_string
|
||||
then short_message := short_message || "the IV-additive, "
|
||||
|| aoa_interacting_drug ;
|
||||
endif; //if aoa_med_type
|
||||
|
||||
//Add the back part of the message.
|
||||
short_message := short_message
|
||||
|| ". The severity is: "|| aoa_interaction_severity ||".";
|
||||
|
||||
//----------------------------------------------//
|
||||
// Create the Alert Action Objects and Populate //
|
||||
//----------------------------------------------//
|
||||
// Create the Modify, Delete, DC-Cancel, and Suspend actions
|
||||
// and Apply the following business rules
|
||||
// 1. Any order any be modified.
|
||||
// 2. Only Unsubmitted orders can be deleted
|
||||
// 3. Only Existing orders can be dc-cancelled
|
||||
// 4. Do not suspend an order, if the order is already suspended.
|
||||
|
||||
// Create the correct action_event_list for EXISTING and
|
||||
// UNSUBMITTED orders
|
||||
if (aoa_status_type = Status_Unsubmitted_string or aoa_status_type = Status_Unapprove_string)
|
||||
then
|
||||
aoa_action_item_status := Unsubmitted_string;
|
||||
action_event_list := Delete_string, Modify_string;
|
||||
else // existing
|
||||
aoa_action_item_status := Existing_string;
|
||||
|
||||
//Do NOT suspend an order that is already suspended.
|
||||
if aoa_is_suspended
|
||||
then action_event_list := DC_Cancel_string, Modify_string;
|
||||
else action_event_list := DC_Cancel_string, Modify_string,
|
||||
Suspend_string;
|
||||
endif; //if is_suspended
|
||||
endif;
|
||||
|
||||
for aoa_action_event in action_event_list do
|
||||
|
||||
/* Create the Alert Action object and partially populate it */
|
||||
instance := call func_create_alert_action_object
|
||||
with "CV3Order", "CV3Order";
|
||||
|
||||
/* Finish populating the Alert Action object */
|
||||
instance.EvokingEnterpriseItemID := (evoking_catalog_item_guid as string);
|
||||
instance.EvokingObjectID := (evoking_order_guid as string);
|
||||
instance.EvokingObjectName := evoking_order_name;
|
||||
instance.ActionItemStatus := aoa_action_item_status;
|
||||
instance.ActionEvent := aoa_action_event;
|
||||
instance.ActionItemID := (aoa_order_guid as string);
|
||||
instance.ActionItemName := aoa_action_item_name;
|
||||
instance.ActionEnterpriseItemID := (aoa_catalog_item_guid as string);
|
||||
instance.mlmname := "STD_Drug_Interaction";
|
||||
instance.ShortMessage := short_message;
|
||||
|
||||
// Save the Alert Action objects to a List
|
||||
alert_action_list := alert_action_list, instance;
|
||||
enddo; //for aoa_action_event
|
||||
endif; //if aoa_status_type
|
||||
enddo; //for BB
|
||||
enddo; //for AA
|
||||
|
||||
// Always Conclude True to Return objects
|
||||
Conclude true;
|
||||
;;
|
||||
action:
|
||||
return alert_action_list;
|
||||
;;
|
||||
end:
|
||||
142
MLMStripper/bin/Debug/STD/STD_FUNC_DUP_ACTIONS.mlm
Normal file
142
MLMStripper/bin/Debug/STD/STD_FUNC_DUP_ACTIONS.mlm
Normal file
@@ -0,0 +1,142 @@
|
||||
maintenance:
|
||||
|
||||
title: Set the Actions for the Duplicate Order Alert;;
|
||||
mlmname: STD_FUNC_DUP_ACTIONS;;
|
||||
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: This MLM is used by the Duplicate Order checking MLMs to call another
|
||||
MLM to create the AlertAction object and to populate them with data.
|
||||
;;
|
||||
explanation: This MLM will do the following:
|
||||
1. Call the STD_Func_Create_Alert_Action_Object MLM to create an instance
|
||||
of the AlertAction object.
|
||||
2. Process the data that was sent to it and populate each AlertAction object.
|
||||
3. Create a list of the objects and return it to the call program.
|
||||
;;
|
||||
keywords:
|
||||
;;
|
||||
knowledge:
|
||||
type: data-driven;;
|
||||
data:
|
||||
|
||||
/***************Make Changes To Spelling And Flags In This Section***************/
|
||||
/* Set to true if logging is needed.*/
|
||||
log_execution_info := false;
|
||||
|
||||
/********************************************************************************/
|
||||
|
||||
// Instantiate the variables associated with the Arguments
|
||||
(evoking_object_guid, //GUID of the Evoking Object
|
||||
matching_aoa_action_item_status_list, //List of STRINGs for the ActionItemStatus
|
||||
matching_aoa_order_guid_list, //List of GUIDs for the ActionItemID
|
||||
matching_aoa_order_name_list, //List of STRINGs for the ActionItemName
|
||||
matching_aoa_master_guid_list, //List of GUIDs for ActionEnterpriseItemID
|
||||
matching_aoa_short_message_list) //LIst of STRINGs for the ShortMessage
|
||||
:= ARGUMENT;
|
||||
|
||||
// Declare the MLM that can be called by this MLM
|
||||
func_create_alert_action_object := MLM {{{SINGLE-QUOTE}}}STD_Func_Create_Alert_Action_Object{{{SINGLE-QUOTE}}};
|
||||
|
||||
// Execute only when this MLM is called by the editor
|
||||
if called_by_editor then
|
||||
obj := read last
|
||||
{ Order: THIS
|
||||
WHERE GUID = evoking_object_guid };
|
||||
EvokingObject := obj;
|
||||
endif;
|
||||
|
||||
//---------------------------------------------
|
||||
// Call the MLM to Create AlertAction Objects
|
||||
//---------------------------------------------
|
||||
|
||||
// Get data from the Evoking Object
|
||||
(evoking_catalog_item_guid,
|
||||
evoking_object_name):= read last
|
||||
{Order: OrderCatalogMasterItemGUID, Name
|
||||
REFERENCING EvokingObject };
|
||||
|
||||
|
||||
// Set Values for AlertAction data
|
||||
evoking_object_table := "CV3Order";
|
||||
action_item_table := "CV3Order";
|
||||
mlm_name := "STD_DUPLICATE";
|
||||
alert_action_object_list := ();
|
||||
counter_list := 1 seqto (count matching_aoa_order_guid_list );
|
||||
|
||||
for JJ in counter_list do
|
||||
// Process Through the Lists
|
||||
// to Set Variables that will populate the AlertAction object
|
||||
action_item_name := matching_aoa_order_name_list[JJ];
|
||||
action_item_catalog_item_guid := matching_aoa_master_guid_list[JJ];
|
||||
action_item_guid := matching_aoa_order_guid_list [JJ];
|
||||
action_item_status := matching_aoa_action_item_status_list [JJ];
|
||||
short_message := matching_aoa_short_message_list[JJ];
|
||||
|
||||
// Create the correct action_event_list for EXISTING and UNSUBMITTED orders
|
||||
if action_item_status = "Existing"
|
||||
then
|
||||
//Do NOT suspend an order that is already suspended.
|
||||
if is_suspended
|
||||
then action_event_list := "DC-Cancel", "Modify";
|
||||
else action_event_list := "DC-Cancel", "Modify", "Suspend";
|
||||
endif; //if is_suspended
|
||||
elseif action_item_status = "Unsubmitted"
|
||||
then action_event_list := "Delete", "Modify";
|
||||
endif;
|
||||
|
||||
for action_event in action_event_list do
|
||||
|
||||
// Create the AlertAction Object 2 Times
|
||||
alert_action_obj:= call func_create_alert_action_object with
|
||||
(evoking_object_table,
|
||||
action_item_table) ;
|
||||
|
||||
// Set the Shared Values for a Single Instance of the AlertAction Object
|
||||
alert_action_obj.EvokingEnterpriseItemID := evoking_catalog_item_guid;
|
||||
alert_action_obj.EvokingObjectID := evoking_object_guid;
|
||||
alert_action_obj.EvokingObjectName := evoking_object_name;
|
||||
alert_action_obj.ActionEvent := action_event;
|
||||
alert_action_obj.ActionItemStatus := action_item_status;
|
||||
alert_action_obj.ActionItemID := action_item_guid;
|
||||
alert_action_obj.ActionItemName := action_item_name;
|
||||
alert_action_obj.ActionEnterpriseItemID := action_item_catalog_item_guid;
|
||||
alert_action_obj.MLMName := mlm_name;
|
||||
alert_action_obj.ShortMessage := short_message;
|
||||
|
||||
// Add AlertAction object to a list
|
||||
alert_action_object_list := alert_action_object_list, alert_action_obj;
|
||||
|
||||
enddo; //for action_event
|
||||
enddo; //for JJ
|
||||
;;
|
||||
evoke:
|
||||
;;
|
||||
logic:
|
||||
conclude true;
|
||||
;;
|
||||
action:
|
||||
return alert_action_object_list;
|
||||
;;
|
||||
end:
|
||||
69
MLMStripper/bin/Debug/STD/STD_FUNC_DUP_DURATION.mlm
Normal file
69
MLMStripper/bin/Debug/STD/STD_FUNC_DUP_DURATION.mlm
Normal file
@@ -0,0 +1,69 @@
|
||||
maintenance:
|
||||
|
||||
title: Calculate Durations for Advanced Duplicate Order Checking MLM;;
|
||||
mlmname: STD_FUNC_DUP_DURATION;;
|
||||
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 durations for the Advanced Duplicate-Order Checking MLM.
|
||||
;;
|
||||
explanation: Pass in a number and a string representation of time units, and
|
||||
it will converted the information into an ARDEN Duration.
|
||||
The expected spellings are:
|
||||
"minutes", "hours", "days", "weeks", "months", and "hours".
|
||||
;;
|
||||
keywords: Duplicate Order; Duration; Calculation;
|
||||
;;
|
||||
knowledge:
|
||||
type: data-driven;;
|
||||
data:
|
||||
|
||||
(some_number,
|
||||
time_unit) := ARGUMENT;
|
||||
|
||||
If time_unit = "minutes"
|
||||
then answer:= some_number MINUTES;
|
||||
elseif time_unit = "hours"
|
||||
then answer:= some_number HOURS;
|
||||
elseif time_unit = "days"
|
||||
then answer:= some_number DAYS;
|
||||
elseif time_unit = "weeks"
|
||||
then answer:= some_number WEEKS;
|
||||
elseif time_unit = "months"
|
||||
then answer:= some_number MONTHS;
|
||||
elseif time_unit = "years"
|
||||
then answer:= some_number YEARS;
|
||||
endif; /*if time_unit = */
|
||||
|
||||
|
||||
;;
|
||||
evoke:
|
||||
;;
|
||||
logic:
|
||||
Conclude True;
|
||||
;;
|
||||
action:
|
||||
Return (answer);
|
||||
;;
|
||||
end:
|
||||
400
MLMStripper/bin/Debug/STD/STD_FUNC_DUP_MESSAGES.mlm
Normal file
400
MLMStripper/bin/Debug/STD/STD_FUNC_DUP_MESSAGES.mlm
Normal file
@@ -0,0 +1,400 @@
|
||||
maintenance:
|
||||
|
||||
title: Alert Messages for Advanced Duplicate Order Checking MLM;;
|
||||
mlmname: STD_FUNC_DUP_MESSAGES;;
|
||||
arden: version 2.5;;
|
||||
version: 18.4;;
|
||||
institution: Allscripts, Standard MLM;;
|
||||
author: Allscripts Healthcare Solutions, Inc.;;
|
||||
specialist: ;;
|
||||
date: 2018-10-26;;
|
||||
validation: testing;;
|
||||
|
||||
/* P r o p r i e t a r y N o t i c e */
|
||||
/* Unpublished (c) 2013 - 2018 Allscripts Healthcare, LLC. and/or its affiliates. All Rights Reserved.
|
||||
|
||||
P r o p r i e t a r y N o t i c e: This software has been provided pursuant to a License Agreement, with
|
||||
Allscripts Healthcare, LLC. and/or its affiliates, containing restrictions on its use. This software contains
|
||||
valuable trade secrets and proprietary information of Allscripts Healthcare, LLC. and/or its affiliates and is
|
||||
protected by trade secret and copyright law. This software may not be copied or distributed in any form or medium,
|
||||
disclosed to any third parties, or used in any manner not provided for in said License Agreement except with prior
|
||||
written authorization from Allscripts Healthcare, LLC. and/or its affiliates. Notice to U.S. Government Users:
|
||||
This software is {{{SINGLE-QUOTE}}}Commercial Computer Software{{{SINGLE-QUOTE}}}.
|
||||
|
||||
All product names are the trademarks or registered trademarks of Allscripts Healthcare, LLC. and/or its affiliates.
|
||||
*/
|
||||
/* P r o p r i e t a r y N o t i c e */
|
||||
|
||||
library:
|
||||
purpose: Selects the appropriate alert message for the Advanced Duplicate-Order
|
||||
Checking MLM{{{SINGLE-QUOTE}}}s alerts and actions.
|
||||
;;
|
||||
explanation: The number of possible messages for the Advanced Duplicate-Order
|
||||
Checking MLM is large. This MLM encapsulates the messages, so that all
|
||||
changes to the messages can be done in one MLM.
|
||||
;;
|
||||
keywords: Duplicate Order; Alert; Message;
|
||||
;;
|
||||
knowledge:
|
||||
type: data-driven;;
|
||||
data:
|
||||
|
||||
/***************Make Changes To Spelling And Flags In This Section***************/
|
||||
/* Set to true if logging is needed.*/
|
||||
log_execution_info := false;
|
||||
|
||||
/********************************************************************************/
|
||||
|
||||
(order_name,
|
||||
order_status_code,
|
||||
order_without_specific_stop_date,
|
||||
exact_msg,
|
||||
performed_msg,
|
||||
scheduled_msg,
|
||||
exact_type,
|
||||
subset_type,
|
||||
superset_type,
|
||||
same_order_type,
|
||||
partial_match_type,
|
||||
conflict_type,
|
||||
possible_conflict_type,
|
||||
no_std_message_type,
|
||||
matching_name_list,
|
||||
matching_significant_date_list,
|
||||
matching_requested_date_list,
|
||||
matching_entered_date_list,
|
||||
matching_stop_date_list,
|
||||
matching_msg_type_list,
|
||||
matching_msg_text_list,
|
||||
matching_time_msg_list,
|
||||
matching_class_list,
|
||||
matching_summary_list,
|
||||
matching_order_status_list,
|
||||
matching_order_type_code_list,
|
||||
matching_alternate_order_type_list,
|
||||
matching_is_script_list,
|
||||
community_resultedOrder_alert_text ):= ARGUMENT;
|
||||
|
||||
/* Gets the Full text description of the OrderStatusCode */
|
||||
(status_code_list,
|
||||
status_description_list):= read { "SELECT Code, Description FROM CV3OrderStatus WHERE Active = 1" };
|
||||
;;
|
||||
evoke:
|
||||
;;
|
||||
logic:
|
||||
indent_string:= " ";
|
||||
hyphen_string:= "-----";
|
||||
|
||||
// Substitutes the Status Description for the Status Code
|
||||
order_status := first (status_description_list where (status_code_list = order_status_code ));
|
||||
|
||||
/*---------------------------------*/
|
||||
/* Picks the correct alert message */
|
||||
/*---------------------------------*/
|
||||
|
||||
//Initialize variables
|
||||
long_alert_msg:= "";
|
||||
short_message := "";
|
||||
matching_short_message_list := ();
|
||||
|
||||
processing_list:= 1 seqto (count matching_name_list);
|
||||
for k in processing_list do
|
||||
// Gets duplicate order information
|
||||
dup_order_found:= processing_list = k;
|
||||
dup_order_name:= first (matching_name_list where dup_order_found);
|
||||
dup_order_significant_date:= first (matching_significant_date_list where dup_order_found);
|
||||
dup_order_entered_date := first (matching_entered_date_list where dup_order_found);
|
||||
dup_order_requested_date := first(matching_requested_date_list where dup_order_found);
|
||||
dup_order_stop_date:= first (matching_stop_date_list where dup_order_found);
|
||||
dup_order_msg_type:= first (matching_msg_type_list where dup_order_found);
|
||||
dup_order_msg_text:= first (matching_msg_text_list where dup_order_found);
|
||||
dup_order_time_msg:= first (matching_time_msg_list where dup_order_found);
|
||||
dup_order_class_msg:= first (matching_class_list where dup_order_found);
|
||||
dup_order_summary:= first (matching_summary_list where dup_order_found);
|
||||
dup_order_status_code:= first (matching_order_status_list where dup_order_found);
|
||||
dup_order_type_code:= first (matching_order_type_code_list where dup_order_found);
|
||||
dup_alternate_order_type := first(matching_alternate_order_type_list where dup_order_found);
|
||||
dup_is_script := first(matching_is_script_list where dup_order_found);
|
||||
|
||||
// Format dates, removing milliseconds
|
||||
if exist dup_order_significant_date then
|
||||
dup_order_significant_date_formatted := dup_order_significant_date formatted with "%.4t";
|
||||
else
|
||||
dup_order_significant_date_formatted := "";
|
||||
endif;
|
||||
|
||||
if exist dup_order_requested_date then
|
||||
dup_order_requested_date_formatted := dup_order_requested_date formatted with "%.4t";
|
||||
else
|
||||
dup_order_requested_date_formatted := "";
|
||||
endif;
|
||||
|
||||
if exist dup_order_entered_date then
|
||||
dup_order_entered_date_formatted := dup_order_entered_date formatted with "%.4t";
|
||||
else
|
||||
dup_order_entered_date_formatted := "";
|
||||
endif;
|
||||
|
||||
if exist dup_order_stop_date then
|
||||
dup_order_stop_date_formatted := dup_order_stop_date formatted with "%.4t";
|
||||
else
|
||||
dup_order_stop_date_formatted := "";
|
||||
endif;
|
||||
|
||||
// Eliminates NULLs from printing in the alert message
|
||||
if dup_order_msg_text is null
|
||||
then
|
||||
dup_order_msg_text:= "";
|
||||
endif;
|
||||
|
||||
if (dup_order_summary is not null AND dup_order_summary <> "")
|
||||
then
|
||||
dup_order_summary := hyphen_string || dup_order_summary;
|
||||
else
|
||||
dup_order_summary := "";
|
||||
endif;
|
||||
|
||||
dup_order_status := "Unsubmitted";
|
||||
if ( dup_order_status_code <> "Unsubmitted" )
|
||||
then
|
||||
// Substitutes the Status Description for the Status Code
|
||||
dup_order_status := first (status_description_list where (status_code_list = dup_order_status_code ));
|
||||
endif;
|
||||
|
||||
dup_date_prefix := "Start Date: ";
|
||||
dup_date_str := dup_order_significant_date_formatted;
|
||||
dup_status_suffix := "Order";
|
||||
|
||||
if (dup_alternate_order_type = 2)
|
||||
then
|
||||
if (dup_order_requested_date is NULL or dup_order_requested_date = "" or dup_order_requested_date = "null")
|
||||
then
|
||||
dup_date_prefix := "Entered Date: ";
|
||||
endif;
|
||||
|
||||
if (dup_is_script)
|
||||
then
|
||||
dup_status_suffix := "Prescription";
|
||||
else
|
||||
dup_status_suffix := "Home Medication";
|
||||
endif;
|
||||
elseif (dup_alternate_order_type = 1)
|
||||
then
|
||||
dup_status_suffix := "";
|
||||
elseif (dup_alternate_order_type = 3)
|
||||
then
|
||||
dup_order_name := dup_order_name || "{{+B}} (" || community_resultedOrder_alert_text || "){{-B}}";
|
||||
endif;
|
||||
|
||||
// Creates the beginning of the long alert message
|
||||
long_alert_msg:= long_alert_msg
|
||||
|| dup_order_name || dup_order_summary || "\n"
|
||||
|| dup_date_prefix || dup_date_str || "\n"
|
||||
|| "Status: " || dup_order_status || " " || dup_status_suffix || "\n" ;
|
||||
|
||||
// Creates the rest of the long alert message
|
||||
If dup_order_msg_type = exact_type
|
||||
then
|
||||
If dup_order_time_msg = exact_msg
|
||||
then
|
||||
short_message :=
|
||||
"Warning duplicate order - " || dup_order_name
|
||||
|| " has already been ordered for the same date and time. "
|
||||
|| dup_order_msg_text
|
||||
;
|
||||
elseif dup_order_time_msg = performed_msg
|
||||
then
|
||||
if order_without_specific_stop_date
|
||||
then
|
||||
short_message :=
|
||||
"Warning - potential duplicate - " || dup_order_name
|
||||
|| " was performed " || dup_order_significant_date_formatted || ". "
|
||||
|| dup_order_msg_text
|
||||
;
|
||||
else
|
||||
short_message :=
|
||||
"Warning - potential duplicate - " || dup_order_name
|
||||
|| " was started " || dup_order_significant_date_formatted || ". "
|
||||
|| dup_order_msg_text
|
||||
;
|
||||
endif; /* if order_without_specific_stop_date */
|
||||
elseif dup_order_time_msg = scheduled_msg
|
||||
then
|
||||
if order_without_specific_stop_date
|
||||
then
|
||||
short_message :=
|
||||
"Warning - potential duplicate - " || dup_order_name
|
||||
|| " has already been scheduled on " || dup_order_significant_date_formatted
|
||||
|| ". Consider cancelling one of the items. "
|
||||
|| dup_order_msg_text
|
||||
;
|
||||
else
|
||||
short_message :=
|
||||
"Warning - potential duplicate - " || dup_order_name
|
||||
|| " has already been scheduled to start on "
|
||||
|| dup_order_significant_date_formatted
|
||||
|| ". Consider cancelling one of the items. "
|
||||
|| dup_order_msg_text
|
||||
;
|
||||
endif; /* if order_without_specific_stop_date */
|
||||
|
||||
|
||||
else
|
||||
short_message :=
|
||||
"Error Message 1: Cannot find a message for an EXACT match."
|
||||
;
|
||||
endif; /* if dup_order_time_msg */
|
||||
elseif dup_order_msg_type = subset_type
|
||||
then
|
||||
If dup_order_time_msg = exact_msg
|
||||
then
|
||||
short_message :=
|
||||
"Warning duplicate order - Your current order for " || order_name
|
||||
|| " includes the " || dup_order_name
|
||||
|| " which has already been ordered for the same date and time. "
|
||||
|| dup_order_msg_text
|
||||
;
|
||||
elseif dup_order_time_msg = performed_msg
|
||||
then
|
||||
short_message :=
|
||||
"Warning - potential duplicate - Your current order for " || order_name
|
||||
|| " includes the " || dup_order_name
|
||||
|| " which was performed on " || dup_order_significant_date_formatted || ". "
|
||||
|| dup_order_msg_text
|
||||
;
|
||||
elseif dup_order_time_msg = scheduled_msg
|
||||
then
|
||||
short_message :=
|
||||
"Warning - potential duplicate - Your current order for " || order_name
|
||||
|| " includes the " || dup_order_name
|
||||
|| " which is already scheduled for " || dup_order_significant_date_formatted
|
||||
|| ". Consider cancelling the " || dup_order_name || ". "
|
||||
|| dup_order_msg_text
|
||||
;
|
||||
else
|
||||
short_message :=
|
||||
"Error Message 2: Cannot find a message for a SUBSET match."
|
||||
;
|
||||
endif; /* if dup_order_time_msg */
|
||||
elseif dup_order_msg_type = superset_type
|
||||
then
|
||||
If dup_order_time_msg = exact_msg
|
||||
then
|
||||
short_message :=
|
||||
"Warning duplicate order - Your current order for " || order_name
|
||||
|| " is included in the " || dup_order_name
|
||||
|| " which has already been ordered for the same date and time. "
|
||||
|| dup_order_msg_text
|
||||
;
|
||||
elseif dup_order_time_msg = performed_msg
|
||||
then
|
||||
short_message :=
|
||||
"Warning - potential duplicate - Your current order for " || order_name
|
||||
|| " is included in the " || dup_order_name
|
||||
|| " which has already been performed on "
|
||||
|| dup_order_significant_date_formatted || ". "
|
||||
|| dup_order_msg_text
|
||||
;
|
||||
elseif dup_order_time_msg = scheduled_msg
|
||||
then
|
||||
short_message :=
|
||||
"Warning - potential duplicate - Your current order for " || order_name
|
||||
|| " is included in the " || dup_order_name
|
||||
|| " which is scheduled on " || dup_order_significant_date_formatted
|
||||
|| ". Consider cancelling one of the items. "
|
||||
|| dup_order_msg_text
|
||||
;
|
||||
else
|
||||
short_message :=
|
||||
"Error Message 3: Cannot find a message for a SUPERSET match."
|
||||
;
|
||||
endif; /* if dup_order_time_msg */
|
||||
elseif dup_order_msg_type = partial_match_type
|
||||
then
|
||||
If dup_order_time_msg = exact_msg
|
||||
then
|
||||
short_message :=
|
||||
"Warning - duplicate order - " || dup_order_name
|
||||
|| " has already been ordered for the same date and time. Both "
|
||||
|| order_name || " and " || dup_order_name
|
||||
|| " have some items in common. "
|
||||
|| dup_order_msg_text
|
||||
;
|
||||
elseif dup_order_time_msg = performed_msg
|
||||
then
|
||||
short_message :=
|
||||
"Warning - potential duplicate - " || dup_order_name
|
||||
|| " was already performed on " || dup_order_significant_date_formatted
|
||||
|| ". Both " || order_name || " and " || dup_order_name
|
||||
|| " have some items in common. "
|
||||
|| dup_order_msg_text
|
||||
;
|
||||
elseif dup_order_time_msg = scheduled_msg
|
||||
then
|
||||
short_message :=
|
||||
"Warning - potential duplicate - " || dup_order_name
|
||||
|| " is already scheduled on " || dup_order_significant_date_formatted
|
||||
|| ". Both " || order_name || " and " || dup_order_name
|
||||
|| " have some items in common. "
|
||||
|| dup_order_msg_text
|
||||
;
|
||||
else
|
||||
short_message :=
|
||||
"Error Message 4: Cannot find a message for a PARTIAL MATCH. "
|
||||
;
|
||||
endif; /* if dup_order_time_msg */
|
||||
elseif dup_order_msg_type = same_order_type
|
||||
then
|
||||
//Avoid Printing NULL for dup_order_class_msg
|
||||
if exist dup_order_class_msg
|
||||
then print_dup_order_class_msg := ", " || dup_order_class_msg || ",";
|
||||
else print_dup_order_class_msg := "";
|
||||
endif;
|
||||
short_message :=
|
||||
"An order for " || dup_order_name
|
||||
|| " is of the same type" || print_dup_order_class_msg
|
||||
|| " as your current order for " || order_name || ". "
|
||||
|| dup_order_msg_text
|
||||
;
|
||||
elseif dup_order_msg_type = conflict_type
|
||||
then
|
||||
short_message :=
|
||||
"A scheduled order for " || dup_order_name
|
||||
|| " conflicts with your current order for " || order_name
|
||||
|| ". Either modify the stop date of your current order,"
|
||||
|| " modify the date of the scheduled order, or cancel the future order. "
|
||||
|| dup_order_msg_text
|
||||
;
|
||||
elseif dup_order_msg_type = possible_conflict_type
|
||||
then
|
||||
short_message :=
|
||||
"An order for " || dup_order_name
|
||||
|| " may conflict with your current order for " || order_name
|
||||
|| ". Please review. "
|
||||
|| dup_order_msg_text
|
||||
;
|
||||
elseif dup_order_msg_type = no_std_message_type
|
||||
then
|
||||
short_message :=
|
||||
dup_order_msg_text
|
||||
;
|
||||
else
|
||||
short_message :=
|
||||
"Error Message 5: Undefined Message Type for the item ordered."
|
||||
;
|
||||
endif; /*if dup_order_msg_type */
|
||||
|
||||
|
||||
//Add the Message to the lists
|
||||
matching_short_message_list := matching_short_message_list, short_message;
|
||||
long_alert_msg:= long_alert_msg ||short_message || "\n\n";
|
||||
|
||||
enddo; /* for k */
|
||||
|
||||
/* Always conclude true to return values to the calling program */
|
||||
conclude true;
|
||||
;;
|
||||
action:
|
||||
RETURN (order_status, long_alert_msg, matching_short_message_list );
|
||||
;;
|
||||
end:
|
||||
1013
MLMStripper/bin/Debug/STD/STD_FUNC_DUP_RETRIEVE_ORDERS.mlm
Normal file
1013
MLMStripper/bin/Debug/STD/STD_FUNC_DUP_RETRIEVE_ORDERS.mlm
Normal file
File diff suppressed because it is too large
Load Diff
657
MLMStripper/bin/Debug/STD/STD_FUNC_DUP_RULES.mlm
Normal file
657
MLMStripper/bin/Debug/STD/STD_FUNC_DUP_RULES.mlm
Normal file
@@ -0,0 +1,657 @@
|
||||
maintenance:
|
||||
|
||||
title: Rules for Advanced Duplicate Order Checking;;
|
||||
mlmname: STD_FUNC_DUP_RULES;;
|
||||
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: Process the orders according to the rules stated in std_duplicate.mlm.
|
||||
Returns information on the duplicate orders to std_duplicate.mlm.
|
||||
;;
|
||||
explanation: See the explanation in std_duplicate.mlm
|
||||
;;
|
||||
keywords: Duplicate Order;
|
||||
;;
|
||||
knowledge:
|
||||
type: data-driven;;
|
||||
data:
|
||||
|
||||
/***************Make Changes To Spelling And Flags In This Section***************/
|
||||
/* Set to true if logging is needed.*/
|
||||
log_execution_info := false;
|
||||
|
||||
/********************************************************************************/
|
||||
|
||||
/* Only Change these Internal Representations when the C++ code changes */
|
||||
canc_code:= "CANC";
|
||||
canp_code:= "CANP";
|
||||
cand_code:= "CAND";
|
||||
cant_code:= "CANT";
|
||||
compa_code:= "COMPA";
|
||||
disc_code:= "DISC";
|
||||
discd_code:= "DISCD";
|
||||
disct_code:= "DISCT";
|
||||
hold_code:= "HOLD";
|
||||
hisi_code:= "HISI";
|
||||
hise_code:= "HISE";
|
||||
|
||||
/* Do Not Change these Internal MLM Variables */
|
||||
exact_msg:= "exact";
|
||||
performed_msg:= "performed";
|
||||
scheduled_msg:= "scheduled";
|
||||
exact_type:= "exact";
|
||||
subset_type:= "subset";
|
||||
superset_type:= "superset";
|
||||
same_order_type:= "same order type";
|
||||
partial_match_type:= "partial match";
|
||||
conflict_type:= "conflict";
|
||||
possible_conflict_type:= "possible conflict";
|
||||
no_std_message_type:= "no std message";
|
||||
|
||||
/* IV-Additive TYPES are used to store additives in CV3OrderComponent.Type */
|
||||
/* If more than two IV-additive types are used, add them to this list */
|
||||
/* Note: Type 3 was used for calculated IV-dosage in CV3.1.2, */
|
||||
/* but is not used in SCM 3.0 or SCM 3.01 */
|
||||
iv_additive_type_list:= 0, 3 ;
|
||||
|
||||
check_medication_like_orders := false;
|
||||
|
||||
(order_name,
|
||||
order_guid,
|
||||
order_status_code,
|
||||
order_level_num,
|
||||
order_summary_line,
|
||||
item_catalog_guid,
|
||||
chart_guid,
|
||||
client_visit_guid,
|
||||
order_significant_date,
|
||||
order_requested_date,
|
||||
order_entered_date,
|
||||
order_stop_date,
|
||||
order_is_conditional,
|
||||
patient_loc_group,
|
||||
lowest_status_level_for_diagnostics,
|
||||
highest_status_level_for_diagnostics,
|
||||
lowest_status_level_for_meds,
|
||||
highest_status_level_for_meds,
|
||||
complex_master_order_type,
|
||||
complex_child_order_type,
|
||||
order_is_for_discharge,
|
||||
order_alternate_order_type,
|
||||
order_is_script,
|
||||
at_in_house_session_list,
|
||||
at_discharge_session_list,
|
||||
at_historical_session_list,
|
||||
at_outpatient_session_list,
|
||||
enable_community_data_results_alerts,
|
||||
enable_Diagnostic_Duplicate_Check_by_Community_Order_Name,
|
||||
evoking_object,
|
||||
evoking_object_type):= ARGUMENT;
|
||||
|
||||
/* Declares MLMs which can be called */
|
||||
calc_duration:= MLM {{{SINGLE-QUOTE}}}std_func_dup_duration{{{SINGLE-QUOTE}}};
|
||||
get_orders:= MLM {{{SINGLE-QUOTE}}}std_func_dup_retrieve_orders{{{SINGLE-QUOTE}}};
|
||||
|
||||
/* Gets the Client GUID */
|
||||
client_guid := read last {ClientInfo: GUID};
|
||||
|
||||
/* Gets the evoking order{{{SINGLE-QUOTE}}}s Item-Catalog name, Policy guid and IsOngoingOrder */
|
||||
/* which indicates if this is a medication like order or diagnostic like order */
|
||||
/* IsOngoingOrder = False means this is a medication like order */
|
||||
/* IsOngoingOrder = True means this is a diagnostic like order */
|
||||
(catalog_name,
|
||||
duplicate_policy_guid,
|
||||
order_without_specific_stop_date ) := read last
|
||||
{"SELECT Name, DuplicatePolicyGUID, IsOngoingOrder "
|
||||
|| " FROM CV3OrderCatalogMasterItem "
|
||||
|| " WHERE GUID = " || SQL(item_catalog_guid)
|
||||
|| " AND Active = 1 "};
|
||||
|
||||
if (order_alternate_order_type = 2) //if an outpatient order
|
||||
then
|
||||
order_without_specific_stop_date := false;
|
||||
endif;
|
||||
|
||||
/* Continue if "check for duplicates" is marked in the Item-Catalog */
|
||||
If exist duplicate_policy_guid
|
||||
then
|
||||
/* Gets evoking order{{{SINGLE-QUOTE}}}s duplicate policy information */
|
||||
(order_loc_group_guid_list,
|
||||
order_scope_list,
|
||||
order_performed_time_list,
|
||||
order_performed_unit_list,
|
||||
order_exact_time_list,
|
||||
order_exact_unit_list,
|
||||
order_scheduled_time_list,
|
||||
order_scheduled_unit_list,
|
||||
loc_is_excluded_list) := read
|
||||
{"SELECT LocationGroupGUID, SearchScope, PastTime, PastTimeUnits,"
|
||||
|| " ExactTime, ExactTimeUnits, FutureTime, FutureTimeUnits, IsExcluded"
|
||||
|| " FROM CV3OrderDuplicatePolicyDtl "
|
||||
|| " WHERE OrderDuplicatePolicyGUID = " || SQL(duplicate_policy_guid)
|
||||
|| " AND LocationGroupGUID IN (0, " || SQL(patient_loc_group)|| " )"
|
||||
|| " AND Active = 1 "};
|
||||
|
||||
/* Matches patient{{{SINGLE-QUOTE}}}s location group to the item-catalog{{{SINGLE-QUOTE}}}s location group and */
|
||||
/* Determines if the match excludes the location from duplicate checking */
|
||||
If exist order_scope_list
|
||||
then
|
||||
If any (patient_loc_group = order_loc_group_guid_list)
|
||||
then
|
||||
loc_group_found := patient_loc_group = order_loc_group_guid_list;
|
||||
else
|
||||
loc_group_found := order_loc_group_guid_list is null;
|
||||
endif;
|
||||
loc_is_excluded := last (loc_is_excluded_list where loc_group_found);
|
||||
endif; /* if exist order_loc_group_guid_list */
|
||||
|
||||
|
||||
/* Continue if there is a location group match or a default location group */
|
||||
/* and the location is not excluded from duplicate checking */
|
||||
If any loc_group_found and not loc_is_excluded
|
||||
then
|
||||
/*--------------------------------------------------*/
|
||||
/* Finds the scope and times for the location group */
|
||||
/*--------------------------------------------------*/
|
||||
order_loc_grp:= last (order_loc_group_guid_list where loc_group_found);
|
||||
order_scope:= last (order_scope_list where loc_group_found);
|
||||
order_performed_time:= last (order_performed_time_list where loc_group_found);
|
||||
order_performed_unit:= last (order_performed_unit_list where loc_group_found);
|
||||
order_exact_time:= last (order_exact_time_list where loc_group_found);
|
||||
order_exact_unit:= last (order_exact_unit_list where loc_group_found);
|
||||
order_scheduled_time:= last (order_scheduled_time_list where loc_group_found);
|
||||
order_scheduled_unit:= last (order_scheduled_unit_list where loc_group_found);
|
||||
|
||||
/*-----------------------------------*/
|
||||
/* Sets check_medication_like_orders */
|
||||
/*-----------------------------------*/
|
||||
If NOT order_without_specific_stop_date
|
||||
then
|
||||
check_medication_like_orders:= true;
|
||||
endif; /* If NOT order_without_specific_stop_date */
|
||||
|
||||
/*-------------------------------------*/
|
||||
/* Converts EXACT TIME into Arden Time */
|
||||
/*-------------------------------------*/
|
||||
If order_exact_time > 0 and order_exact_unit is string
|
||||
then
|
||||
exact_duration:= call calc_duration with
|
||||
(order_exact_time, order_exact_unit);
|
||||
If order_exact_unit = "days"
|
||||
then exact_low_time:= (day floor of order_significant_date)
|
||||
- exact_duration ;
|
||||
exact_high_time:= (day floor of order_significant_date)
|
||||
+ exact_duration + (1 day) - (1 second);
|
||||
else exact_low_time:= order_significant_date - exact_duration;
|
||||
exact_high_time:= order_significant_date + exact_duration;
|
||||
endif; /* if order_exact_unit = */
|
||||
else
|
||||
exact_low_time:= order_significant_date;
|
||||
exact_high_time:= order_significant_date;
|
||||
endif; /* if order_exact_time > 0 ...*/
|
||||
|
||||
/*-----------------------------------------*/
|
||||
/* Converts PERFORMED TIME into Arden Time */
|
||||
/*-----------------------------------------*/
|
||||
If order_performed_time > 0 and order_performed_unit is string
|
||||
then
|
||||
performed_duration:= call calc_duration with
|
||||
(order_performed_time, order_performed_unit);
|
||||
If order_performed_unit = "days"
|
||||
then past_time:= (day floor of order_significant_date)
|
||||
- performed_duration;
|
||||
else past_time:= order_significant_date - performed_duration;
|
||||
endif; /* if order_performed_unit = */
|
||||
else
|
||||
past_time:= exact_low_time;
|
||||
endif; /* if order_performed_time > 0 ...*/
|
||||
|
||||
/*-----------------------------------------*/
|
||||
/* Converts SCHEDULED TIME into Arden Time */
|
||||
/*-----------------------------------------*/
|
||||
If order_scheduled_time > 0 and order_scheduled_unit is string
|
||||
then
|
||||
scheduled_duration:= call calc_duration with
|
||||
(order_scheduled_time, order_scheduled_unit);
|
||||
If order_scheduled_unit = "days"
|
||||
then future_time:= (day floor of order_significant_date)
|
||||
+ scheduled_duration + (1 day) - (1 second);
|
||||
else future_time:= order_significant_date + scheduled_duration;
|
||||
endif; /* if order_scheduled_unit = */
|
||||
else
|
||||
future_time:= exact_high_time;
|
||||
endif; /* if order_scheduled_time > 0 ...*/
|
||||
|
||||
|
||||
/*********************************************/
|
||||
/* Retrieve ITEMS and CLASSES for Duplicates */
|
||||
/*********************************************/
|
||||
/* Gets the evoking order{{{SINGLE-QUOTE}}}s list of duplicates (ITEMS and CLASSES) */
|
||||
/* from the Item-Catalog */
|
||||
(cat_dup_item_name_list,
|
||||
cat_dup_item_guid_list,
|
||||
cat_class_name_list,
|
||||
cat_class_value_list,
|
||||
cat_message_type_list,
|
||||
cat_message_list) := read
|
||||
{"SELECT DuplicateItemName, DuplicateItemGUID, ClassTypeCode, "
|
||||
|| " ClassValue, MessageType, MessageText "
|
||||
|| " FROM CV3CatalogItemDuplicate "
|
||||
|| " WHERE OrderCatalogMasterItemGUID = " || SQL(item_catalog_guid)
|
||||
|| " AND Active = 1 "};
|
||||
|
||||
/* If there are any classes associated with the order */
|
||||
/* then get the GUIDs of the items */
|
||||
If exist cat_class_value_list
|
||||
then
|
||||
SQL_string := "";
|
||||
index_list_jj := 1 seqto count (cat_class_value_list);
|
||||
for JJ in index_list_jj do
|
||||
single_class_value := cat_class_value_list[JJ];
|
||||
single_class_type:= cat_class_name_list[JJ];
|
||||
|
||||
If exist single_class_value
|
||||
and exist single_class_type
|
||||
then
|
||||
/* Create the SQL fragment of ClassTypeCode and ClassValue */
|
||||
/* to retrieve data from CV3CatalogItemDuplicate table */
|
||||
if SQL_string = ""
|
||||
then
|
||||
SQL_string := SQL_string
|
||||
|| "( ClassTypeCode = " || SQL(single_class_type)
|
||||
|| " AND ClassValue = " || SQL(single_class_value) || ")";
|
||||
else
|
||||
SQL_string := SQL_string
|
||||
|| " OR ( ClassTypeCode = " || SQL(single_class_type)
|
||||
|| " AND ClassValue = " || SQL(single_class_value) || ")";
|
||||
endif;
|
||||
endif; /* if exist single_class_value */
|
||||
enddo; // for JJ
|
||||
|
||||
/* Initialize variables */
|
||||
other_class_message_type_list := ();
|
||||
other_class_message_list := ();
|
||||
|
||||
/* Get the Other OrderCatalogMasterItemGUIDs and their Class Information */
|
||||
(other_class_guid_list,
|
||||
other_class_type_list,
|
||||
other_class_value_list ) := read
|
||||
{"SELECT OrderCatalogMasterItemGUID, "
|
||||
|| " ClassTypeCode, ClassValue "
|
||||
|| " FROM CV3CatalogItemDuplicate "
|
||||
|| " WHERE (" || SQL_string || ")"
|
||||
|| " AND OrderCatalogMasterItemGUID <> "
|
||||
|| SQL(item_catalog_guid)
|
||||
|| " ORDER BY OrderCatalogMasterItemGUID " };
|
||||
|
||||
// Find the MessageType and MessageText that go with the
|
||||
// ClassTypeCode and ClassValue and add them to the appropriate lists
|
||||
if exist other_class_type_list
|
||||
and exist other_class_value_list
|
||||
then
|
||||
index_list_kk := 1 seqto count (other_class_type_list);
|
||||
for KK in index_list_kk do
|
||||
temp_class_type := other_class_type_list[KK];
|
||||
temp_class_value := other_class_value_list[KK];
|
||||
|
||||
found_class_info :=
|
||||
(cat_class_name_list = temp_class_type)
|
||||
and (cat_class_value_list = temp_class_value);
|
||||
temp_message_type :=
|
||||
first (cat_message_type_list where found_class_info);
|
||||
temp_message :=
|
||||
first (cat_message_list where found_class_info);
|
||||
other_class_message_type_list:=
|
||||
other_class_message_type_list, temp_message_type ;
|
||||
other_class_message_list:=
|
||||
other_class_message_list, temp_message ;
|
||||
enddo; //for KK
|
||||
endif;
|
||||
endif; /* if exist cat_class_value_list */
|
||||
|
||||
/*-----------------------------------------------------------------------*/
|
||||
/* Retrieve the orders from the DATABASE and the UNSUBMITTED orders list */
|
||||
/* AND Get Data for ACTIONS ON ALERTS (aoa_) */
|
||||
/*-----------------------------------------------------------------------*/
|
||||
(order_name_list,
|
||||
order_guid_list,
|
||||
significant_date_list,
|
||||
requested_date_list,
|
||||
entered_date_list,
|
||||
stop_date_list,
|
||||
is_conditional_list,
|
||||
is_suspended_list,
|
||||
order_status_code_list,
|
||||
order_status_level_list,
|
||||
order_type_code_list,
|
||||
order_alternate_type_list,
|
||||
order_is_script_list,
|
||||
summary_list,
|
||||
master_GUID_list,
|
||||
aoa_action_item_status_list,
|
||||
aoa_order_name_list,
|
||||
aoa_master_guid_list) := call get_orders with
|
||||
(client_guid,
|
||||
chart_guid,
|
||||
client_visit_guid,
|
||||
order_guid,
|
||||
order_name,
|
||||
order_is_conditional,
|
||||
order_scope,
|
||||
past_time,
|
||||
future_time,
|
||||
check_medication_like_orders,
|
||||
lowest_status_level_for_diagnostics,
|
||||
highest_status_level_for_diagnostics,
|
||||
lowest_status_level_for_meds,
|
||||
highest_status_level_for_meds,
|
||||
hold_code,
|
||||
canc_code,
|
||||
canp_code,
|
||||
cand_code,
|
||||
cant_code,
|
||||
compa_code,
|
||||
disc_code,
|
||||
discd_code,
|
||||
disct_code,
|
||||
hisi_code,
|
||||
hise_code,
|
||||
iv_additive_type_list,
|
||||
complex_master_order_type,
|
||||
complex_child_order_type,
|
||||
order_is_for_discharge,
|
||||
order_alternate_order_type,
|
||||
order_is_script,
|
||||
at_in_house_session_list,
|
||||
at_discharge_session_list,
|
||||
at_historical_session_list,
|
||||
at_outpatient_session_list,
|
||||
enable_community_data_results_alerts,
|
||||
enable_Diagnostic_Duplicate_Check_by_Community_Order_Name,
|
||||
evoking_object,
|
||||
evoking_object_type);
|
||||
|
||||
endif; /* if any loc_group_found and not loc_is_excluded */
|
||||
endif; /* if exist duplicate_policy_guid */
|
||||
;;
|
||||
evoke:
|
||||
;;
|
||||
logic:
|
||||
If NOT exist duplicate_policy_guid
|
||||
OR NOT (any loc_group_found)
|
||||
OR loc_is_excluded
|
||||
then conclude false;
|
||||
endif;
|
||||
|
||||
/*-----------------------*/
|
||||
/* Initializes Variables */
|
||||
/*-----------------------*/
|
||||
matching_guid_list:= ();
|
||||
matching_name_list:= ();
|
||||
matching_order_guid_list:= ();
|
||||
matching_significant_date_list := ();
|
||||
matching_requested_date_list := ();
|
||||
matching_entered_date_list := ();
|
||||
matching_stop_date_list:= ();
|
||||
matching_msg_type_list:= ();
|
||||
matching_msg_text_list:= ();
|
||||
matching_time_msg_list:= ();
|
||||
matching_summary_list:= ();
|
||||
matching_class_list:= ();
|
||||
matching_order_status_code_list:= ();
|
||||
matching_order_type_code_list:= ();
|
||||
matching_alternate_order_type_list := ();
|
||||
matching_is_script_list := ();
|
||||
dup_item_guid_list:= cat_dup_item_guid_list;
|
||||
class_name_list:= cat_class_name_list;
|
||||
class_value_list:= cat_class_value_list;
|
||||
message_type_list:= cat_message_type_list;
|
||||
message_list:= cat_message_list;
|
||||
|
||||
/*-------------------------------------------------------------------*/
|
||||
/* Adds extra information to DUP_ITEM_GUID_LIST and associated lists */
|
||||
/*-------------------------------------------------------------------*/
|
||||
|
||||
/* Adds the evoking object{{{SINGLE-QUOTE}}}s OrderCatalogMasterItemGUID and other data, */
|
||||
/* if the list of items from item-catalog--duplicate checking panel does not include it */
|
||||
If (item_catalog_guid is not in dup_item_guid_list)
|
||||
and (item_catalog_guid is in master_guid_list)
|
||||
then
|
||||
dup_item_guid_list:= item_catalog_guid, dup_item_guid_list;
|
||||
class_name_list:= null, class_name_list;
|
||||
class_value_list:= null, class_value_list;
|
||||
message_type_list:= exact_type, message_type_list;
|
||||
message_list:= null, message_list;
|
||||
endif; /* if item_catalog_guid is not in... */
|
||||
|
||||
|
||||
/* Adds other OrderCatalogMasterItemGUIDs and other data, based on CLASS matches */
|
||||
If exist other_class_guid_list
|
||||
then
|
||||
dup_item_guid_list:= dup_item_guid_list, other_class_guid_list;
|
||||
class_name_list:= class_name_list, other_class_type_list;
|
||||
class_value_list:= class_value_list, other_class_value_list;
|
||||
message_type_list:= message_type_list, other_class_message_type_list;
|
||||
message_list:= message_list, other_class_message_list;
|
||||
endif; /* if exist other_class_guid_list */
|
||||
|
||||
/*---------------------------------------------------------------*/
|
||||
/* Finds all possible duplicates among the ITEMS and the CLASSES */
|
||||
/*---------------------------------------------------------------*/
|
||||
|
||||
If any(dup_item_guid_list is in master_guid_list)
|
||||
then
|
||||
index_list_nn := 1 seqto count (dup_item_guid_list);
|
||||
for NN in index_list_nn do
|
||||
item_master_guid := dup_item_guid_list[NN];
|
||||
if exist item_master_guid
|
||||
then
|
||||
/* Create most of the matching lists */
|
||||
master_guid_found:= item_master_guid = master_guid_list;
|
||||
temp_guid:= master_guid_list where master_guid_found;
|
||||
temp_name:= order_name_list where master_guid_found;
|
||||
temp_order_guid:= order_guid_list where master_guid_found;
|
||||
temp_signif:= significant_date_list where master_guid_found;
|
||||
temp_requested := requested_date_list where master_guid_found;
|
||||
temp_entered := entered_date_list where master_guid_found;
|
||||
temp_stop:= stop_date_list where master_guid_found;
|
||||
temp_summary:= summary_list where master_guid_found;
|
||||
temp_status:= order_status_code_list where master_guid_found;
|
||||
temp_type_code:= order_type_code_list where master_guid_found;
|
||||
temp_alternate_order_type := order_alternate_type_list where master_guid_found;
|
||||
temp_is_script := order_is_script_list where master_guid_found;
|
||||
|
||||
matching_guid_list:= matching_guid_list, temp_guid;
|
||||
matching_name_list:= matching_name_list, temp_name;
|
||||
matching_order_guid_list:= matching_order_guid_list, temp_order_guid;
|
||||
matching_significant_date_list := matching_significant_date_list, temp_signif;
|
||||
matching_requested_date_list := matching_requested_date_list, temp_requested;
|
||||
matching_entered_date_list := matching_entered_date_list, temp_entered;
|
||||
matching_stop_date_list:= matching_stop_date_list, temp_stop;
|
||||
matching_summary_list:= matching_summary_list, temp_summary;
|
||||
matching_order_status_code_list:= matching_order_status_code_list, temp_status;
|
||||
matching_order_type_code_list:= matching_order_type_code_list, temp_type_code;
|
||||
matching_alternate_order_type_list := matching_alternate_order_type_list, temp_alternate_order_type;
|
||||
matching_is_script_list := matching_is_script_list, temp_is_script;
|
||||
|
||||
/* Get the associated message type and message text */
|
||||
temp_msg_type:= message_type_list[NN];
|
||||
temp_msg_text:= message_list [NN];
|
||||
temp_class_value:= class_value_list[NN];
|
||||
|
||||
For one_cat_guid in temp_guid do
|
||||
/* Attach associated message type and message text to their matching lists */
|
||||
matching_msg_type_list:= matching_msg_type_list, temp_msg_type;
|
||||
matching_msg_text_list:= matching_msg_text_list, temp_msg_text;
|
||||
matching_class_list:= matching_class_list, temp_class_value;
|
||||
|
||||
/* Set the time messages */
|
||||
order_time:= time of one_cat_guid;
|
||||
relative_date:= now;
|
||||
|
||||
If order_time >= exact_low_time AND order_time <= exact_high_time
|
||||
then correct_msg:= exact_msg;
|
||||
elseif order_time < relative_date
|
||||
then correct_msg:= performed_msg;
|
||||
elseif order_time > relative_date
|
||||
then correct_msg:= scheduled_msg;
|
||||
else correct_msg:= null;
|
||||
endif; /* if order_time */
|
||||
matching_time_msg_list:= matching_time_msg_list, correct_msg;
|
||||
enddo; // For one_cat_guid
|
||||
endif; //if exist item_master_guid
|
||||
enddo; // for NN
|
||||
endif; /* if any(dup_item_guid_list...*/
|
||||
|
||||
|
||||
/*----------------------------------------------*/
|
||||
/* Determines if the order is being checked for */
|
||||
/* CONFLICTING ORDERS or WASTING RESOURCES */
|
||||
/*----------------------------------------------*/
|
||||
/* If it is for Conflicting Orders (check_medication_like_orders = true), */
|
||||
/* then look for overlapping dates */
|
||||
/* Otherwise all matched orders are considered duplicates */
|
||||
|
||||
has_overlapping_dates_list:= ();
|
||||
If check_medication_like_orders and (exist matching_significant_date_list)
|
||||
then
|
||||
index_list:= 1 seqto(count matching_significant_date_list);
|
||||
for D in index_list do
|
||||
index_found:= index_list = D;
|
||||
prior_significant_date:= first (matching_significant_date_list where index_found);
|
||||
prior_stop_date:= first (matching_stop_date_list where index_found);
|
||||
|
||||
/* There are only two conditions when an order with "significant" */
|
||||
/* and "stop" dates is not considered a duplicate. */
|
||||
/* If one of these conditions occurs, then then a duplicate flag */
|
||||
/* is set to false */
|
||||
If (prior_stop_date is time
|
||||
and order_significant_date > prior_stop_date)
|
||||
OR
|
||||
(order_stop_date is time
|
||||
and order_stop_date < prior_significant_date)
|
||||
then
|
||||
has_overlapping_dates_list:= has_overlapping_dates_list, FALSE;
|
||||
else
|
||||
has_overlapping_dates_list:= has_overlapping_dates_list, TRUE;
|
||||
endif; /* if prior_stop_date... */
|
||||
enddo; /* for D in index_list */
|
||||
|
||||
|
||||
/* Removes orders that do not have over-lapping dates */
|
||||
if exist has_overlapping_dates_list
|
||||
then
|
||||
overlaps_found:= has_overlapping_dates_list = true;
|
||||
matching_guid_list:= matching_guid_list where overlaps_found;
|
||||
matching_name_list:= matching_name_list where overlaps_found;
|
||||
matching_order_guid_list:= matching_order_guid_list where overlaps_found;
|
||||
matching_significant_date_list := matching_significant_date_list where overlaps_found;
|
||||
matching_requested_date_list := matching_requested_date_list where overlaps_found;
|
||||
matching_entered_date_list := matching_entered_date_list where overlaps_found;
|
||||
matching_stop_date_list:= matching_stop_date_list where overlaps_found;
|
||||
matching_msg_type_list:= matching_msg_type_list where overlaps_found;
|
||||
matching_msg_text_list:= matching_msg_text_list where overlaps_found;
|
||||
matching_time_msg_list:= matching_time_msg_list where overlaps_found;
|
||||
matching_summary_list:= matching_summary_list where overlaps_found;
|
||||
matching_order_status_code_list:=
|
||||
matching_order_status_code_list where overlaps_found;
|
||||
matching_order_type_code_list:=
|
||||
matching_order_type_code_list where overlaps_found;
|
||||
matching_alternate_order_type_list := matching_alternate_order_type_list where overlaps_found;
|
||||
matching_is_script_list := matching_is_script_list where overlaps_found;
|
||||
endif; /* if any has_overlapping_dates_list */
|
||||
endif;
|
||||
|
||||
/*--------------------------------------------------------------*/
|
||||
/* Finds the Matching Data Needed for Action on Alerts */
|
||||
/*--------------------------------------------------------------*/
|
||||
// This assumes that the lists for order_name_list, order_GUID_list, master_GUID_list
|
||||
// and aoa_action_item_status_list are parallel lists of equal length.
|
||||
// It creates a list of Matching ACTION ITEM STATUSES that are associated
|
||||
// with the Matching_Name_List and the Master_GUID_List.
|
||||
|
||||
// Create a list of boolean values that indicates the positions that
|
||||
// have a matching GUID and NAME.
|
||||
found_matching_guid_and_name := (master_guid_list is in matching_GUID_list)
|
||||
and (order_name_list is in matching_name_list);
|
||||
|
||||
// Extract a sublist of Matching Action Item Statuses.
|
||||
matching_aoa_action_item_status_list := aoa_action_item_status_list
|
||||
where found_matching_guid_and_name;
|
||||
|
||||
// Extract a sublist of Matching CV3OrderGUIDs
|
||||
matching_aoa_order_guid_list := order_guid_list
|
||||
where found_matching_guid_and_name;
|
||||
|
||||
// Create a list of Matching Order Names (ie. unsubstituted with
|
||||
// order components when there are IV Additives).
|
||||
matching_aoa_order_name_list := aoa_order_name_list
|
||||
where found_matching_guid_and_name;
|
||||
|
||||
// Create a list of Matching CV3OrderCatalogMasterItemGUIDs
|
||||
// (ie. unsubstituted with order components when there are IV Additives).
|
||||
matching_aoa_master_guid_list := aoa_master_guid_list
|
||||
where found_matching_guid_and_name;
|
||||
|
||||
/*--------------------------------------------------*/
|
||||
/* Concludes True To Return Data To The Calling MLM */
|
||||
/*--------------------------------------------------*/
|
||||
conclude true;
|
||||
|
||||
;;
|
||||
action:
|
||||
return( exact_msg,
|
||||
performed_msg,
|
||||
scheduled_msg,
|
||||
exact_type,
|
||||
subset_type,
|
||||
superset_type,
|
||||
same_order_type,
|
||||
partial_match_type,
|
||||
conflict_type,
|
||||
possible_conflict_type,
|
||||
no_std_message_type,
|
||||
order_without_specific_stop_date,
|
||||
matching_name_list,
|
||||
matching_order_guid_list,
|
||||
matching_significant_date_list,
|
||||
matching_requested_date_list,
|
||||
matching_entered_date_list,
|
||||
matching_stop_date_list,
|
||||
matching_msg_type_list,
|
||||
matching_msg_text_list,
|
||||
matching_time_msg_list,
|
||||
matching_class_list,
|
||||
matching_summary_list,
|
||||
matching_order_status_code_list,
|
||||
matching_order_type_code_list,
|
||||
matching_alternate_order_type_list,
|
||||
matching_is_script_list,
|
||||
matching_aoa_action_item_status_list,
|
||||
matching_aoa_order_guid_list,
|
||||
matching_aoa_order_name_list,
|
||||
matching_aoa_master_guid_list
|
||||
);
|
||||
;;
|
||||
end:
|
||||
184
MLMStripper/bin/Debug/STD/STD_FUNC_DUP_SUPPRESS_CHECKING.mlm
Normal file
184
MLMStripper/bin/Debug/STD/STD_FUNC_DUP_SUPPRESS_CHECKING.mlm
Normal file
@@ -0,0 +1,184 @@
|
||||
maintenance:
|
||||
|
||||
title: Suppress Duplicate Order Checking Within an Order Set;;
|
||||
mlmname: STD_FUNC_DUP_SUPPRESS_CHECKING;;
|
||||
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: The purpose of this MLM is to determine which OrderSetGUID and OrderSubsetGUID
|
||||
should be avoided so that the orders in the PARENT and/or CHILD Order Set
|
||||
will NOT be retrieved. When an order is NOT retrieved, then duplicate order
|
||||
checking is suppressed for that order.
|
||||
;;
|
||||
explanation:
|
||||
RULE 1. If the IsDupCheckingSuppressed is TRUE in the PARENT ORDER SET
|
||||
Then exclude ALL the orders in the CURRENT order SET
|
||||
for both the PARENT & CHILD ORDER SETS.
|
||||
Returns the Parent{{{SINGLE-QUOTE}}}s OrderSetGUID with a GUID,
|
||||
but the Child{{{SINGLE-QUOTE}}}s OrderSubsetGUID is an empty list.
|
||||
|
||||
RULE 2. ELSE IF the IsDupCheckingSuppressed is FALSE or NULL in the PARENT ORDER SET
|
||||
and the Order Set is NOT a Linked-Set (i.e. order set type <> 4)
|
||||
and the IsDupCheckingSuppressed is TRUE in the CHILD ORDER SET
|
||||
and EXCLUDE all the orders in the CURRENT order SET
|
||||
for the CHILD ORDER SET ONLY.
|
||||
Returns the Parent{{{SINGLE-QUOTE}}}s OrderSetGUID as an empty list,
|
||||
and the Child{{{SINGLE-QUOTE}}}s OrderSubsetGUID has a GUID.
|
||||
|
||||
RULE 3. ELSE Do NOT EXCLUDE ANY Orders from Duplicate Order Checking.
|
||||
Returns the Parent{{{SINGLE-QUOTE}}}s OrderSetGUID as an empty list
|
||||
and the Child{{{SINGLE-QUOTE}}}s OrderSubsetGUID as an empty list.
|
||||
;;
|
||||
keywords:
|
||||
;;
|
||||
knowledge:
|
||||
type: data-driven;;
|
||||
data:
|
||||
(order_name, //String--the name of the Evoking Order
|
||||
order_guid ) //GUID--the GUID of the Evoking Order
|
||||
:= ARGUMENT;
|
||||
|
||||
/***************Make Changes To Spelling And Flags In This Section***************/
|
||||
/* Set to true if logging is needed.*/
|
||||
log_execution_info := false;
|
||||
|
||||
/********************************************************************************/
|
||||
|
||||
/* This block executes only when this MLM is called by the editor */
|
||||
if called_by_editor
|
||||
then
|
||||
// Set the EvokingObject to object that is used by the STD_Duplicate MLM
|
||||
// so that the EvokingObjects are the same.
|
||||
// This is NOT necessary to do during run-time because there is only
|
||||
// one EvokingObject.
|
||||
EvokingObject := read last
|
||||
{ Order: THIS
|
||||
WHERE Name = order_name
|
||||
and GUID = order_guid
|
||||
};
|
||||
endif;
|
||||
|
||||
// Get Information from the Evoking Order
|
||||
(o_order_name,
|
||||
o_order_significant_dtm,
|
||||
o_order_set_name,
|
||||
o_order_set_type,
|
||||
o_order_set_GUID,
|
||||
o_order_subset_name,
|
||||
o_order_subset_type,
|
||||
o_order_subset_GUID,
|
||||
o_order_set_obj,
|
||||
o_order_subset_obj ) := read last
|
||||
{Order: Name, SignificantDtm,
|
||||
OrderSetName, OrderSetType, OrderSetGUID,
|
||||
OrderSubsetName, OrderSubsetType, OrderSubsetGUID,
|
||||
OrderSet,
|
||||
OrderSubset
|
||||
Referencing EvokingObject};
|
||||
|
||||
|
||||
// Get Information from the Parent Order Set
|
||||
if exist o_order_set_obj
|
||||
then
|
||||
(os_parent_order_set_name,
|
||||
os_parent_start_dtm,
|
||||
os_parent_GUID,
|
||||
os_parent_order_catalog_set_obj ) := read last
|
||||
{OrderSet: OrderSetName, StartDtm, GUID, OrderCatalogSet
|
||||
Referencing o_order_set_obj };
|
||||
|
||||
(ocs_parent_name,
|
||||
ocs_parent_GUID,
|
||||
ocs_parent_type,
|
||||
ocs_parent_is_dup_checking_suppressed,
|
||||
ocs_parent_duplicate_policy_GUID ) := read last
|
||||
{OrderCatalogSet: Name, GUID, Type,
|
||||
IsDupCheckingSuppressed, DuplicatePolicyGUID
|
||||
Referencing os_parent_order_catalog_set_obj };
|
||||
endif; //if exist o_order_set_obj
|
||||
|
||||
|
||||
// Get Information from the Child Order Set
|
||||
if exist o_order_subset_obj
|
||||
then
|
||||
(os_child_order_set_name,
|
||||
os_child_start_dtm,
|
||||
os_child_GUID,
|
||||
os_child_order_catalog_set_GUID,
|
||||
os_child_order_catalog_set_obj ) := read last
|
||||
{OrderSet: OrderSetName, StartDtm, GUID, OrderCatalogSetGUID, OrderCatalogSet
|
||||
Referencing o_order_subset_obj };
|
||||
|
||||
(ocs_child_name,
|
||||
ocs_child_GUID,
|
||||
ocs_child_type,
|
||||
ocs_child_is_dup_checking_suppressed,
|
||||
ocs_child_duplicate_policy_GUID ) := read last
|
||||
{OrderCatalogSet: Name, GUID, Type,
|
||||
IsDupCheckingSuppressed, DuplicatePolicyGUID
|
||||
Referencing os_child_order_catalog_set_obj };
|
||||
endif; //if exist o_order_subset_obj
|
||||
;;
|
||||
evoke:
|
||||
;;
|
||||
logic:
|
||||
|
||||
//-----------------------------------
|
||||
// RULE 1--Exclude ALL Orders in Set
|
||||
//-----------------------------------
|
||||
If ocs_parent_is_dup_checking_suppressed
|
||||
then
|
||||
avoid_parent_order_set_GUID := o_order_set_GUID;
|
||||
avoid_child_order_set_GUID := ();
|
||||
|
||||
//------------------------------------------
|
||||
//RULE 2--Exclude Orders in Child Order Set
|
||||
//------------------------------------------
|
||||
ElseIf
|
||||
(NOT ocs_parent_is_dup_checking_suppressed
|
||||
OR ocs_parent_is_dup_checking_suppressed is NULL)
|
||||
AND o_order_set_type <> 4
|
||||
AND ocs_child_is_dup_checking_suppressed
|
||||
then
|
||||
avoid_parent_order_set_GUID := ();
|
||||
avoid_child_order_set_GUID := o_order_subset_GUID;
|
||||
|
||||
//----------------------------------
|
||||
//RULE 3--Do NOT exclude ANY Orders
|
||||
//----------------------------------
|
||||
Else
|
||||
avoid_parent_order_set_GUID := ();
|
||||
avoid_child_order_set_GUID := ();
|
||||
endif; // if ocs_parent_is_dup_checking_suppressed
|
||||
|
||||
|
||||
//Alway Conclude True to Return an Answer
|
||||
Conclude True;
|
||||
;;
|
||||
action:
|
||||
RETURN
|
||||
avoid_parent_order_set_GUID, //OrderSetGUID or an empty list
|
||||
avoid_child_order_set_GUID; //OrderSubsetGUID or an empty list
|
||||
;;
|
||||
end:
|
||||
110
MLMStripper/bin/Debug/STD/STD_FUNC_FILTER_VPO_GEN_DICTIONARY.mlm
Normal file
110
MLMStripper/bin/Debug/STD/STD_FUNC_FILTER_VPO_GEN_DICTIONARY.mlm
Normal file
@@ -0,0 +1,110 @@
|
||||
maintenance:
|
||||
|
||||
title: Community Data;;
|
||||
mlmname: STD_FUNC_FILTER_VPO_GEN_DICTIONARY;;
|
||||
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) 2014 - 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:
|
||||
This functional MLM is called by other STD_Filter_VPO MLMs that generate
|
||||
VPO filter criteria.
|
||||
This MLM converts the field value list into two .Net dictionaries:
|
||||
(1) Dictionary with field name as key, and exclude flag as value
|
||||
(2) Dictionary with field name as key, and a list of field values to filter
|
||||
;;
|
||||
explanation:
|
||||
The argument passed into the MLM is:
|
||||
* field_value_list - list of FieldValueObjects defined as
|
||||
NameValueObject := OBJECT [ field_name, include_flag, value_list ];
|
||||
|
||||
The data returned by the MLM are:
|
||||
* exclusion_criteria_dictionary_object -
|
||||
Collections.Generic.Dictionary< String, Boolean>
|
||||
with field_name as key, and exclude_flag as value
|
||||
* name_value_dictionary_object -
|
||||
Collections.Generic.Dictionary< String, Collections.Generic.List<String> >
|
||||
with field_name as key, and Collections.Generic.List<String> list containing
|
||||
value_list as value
|
||||
;;
|
||||
keywords:
|
||||
Fused Agent;
|
||||
Community Data;
|
||||
VPO filter;
|
||||
dbMotion Data;
|
||||
;;
|
||||
citations:
|
||||
;;
|
||||
knowledge:
|
||||
type: data-driven;;
|
||||
data:
|
||||
// Specify which .NET assemblies need to be loaded
|
||||
using "mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089";
|
||||
using namespace "System";
|
||||
using namespace "System.Exception";
|
||||
using namespace "System.Windows.Forms";
|
||||
|
||||
// Arguments are passed in from the calling C++ program or MLM
|
||||
( field_value_list
|
||||
) := argument;
|
||||
|
||||
exclusion_criteria_dictionary_object := new net_object {{{SINGLE-QUOTE}}}Collections.Generic.Dictionary< String, Boolean>{{{SINGLE-QUOTE}}};
|
||||
name_value_dictionary_object := new net_object {{{SINGLE-QUOTE}}}Collections.Generic.Dictionary< String, Collections.Generic.List<String> >{{{SINGLE-QUOTE}}};
|
||||
|
||||
// Only add the fields that have both include flag and the field value list specified
|
||||
field_criteria_list := field_value_list as list; // this ensures single item is also a list
|
||||
|
||||
for field_criteria in field_criteria_list
|
||||
do
|
||||
if exists field_criteria.value_list AND count field_criteria.value_list > 0
|
||||
then
|
||||
field_name_obj := field_criteria.field_name as {{{SINGLE-QUOTE}}}String{{{SINGLE-QUOTE}}};
|
||||
|
||||
exclude_field_obj := (not field_criteria.include_flag) as {{{SINGLE-QUOTE}}}Boolean{{{SINGLE-QUOTE}}};
|
||||
|
||||
value_list_obj := new net_object {{{SINGLE-QUOTE}}}Collections.Generic.List< String >{{{SINGLE-QUOTE}}};
|
||||
field_values := field_criteria.value_list as list;
|
||||
|
||||
for value_item in field_values
|
||||
do
|
||||
void := call value_list_obj.Add with (value_item as {{{SINGLE-QUOTE}}}String{{{SINGLE-QUOTE}}});
|
||||
enddo;
|
||||
|
||||
void := call exclusion_criteria_dictionary_object.Add with field_name_obj, exclude_field_obj;
|
||||
void := call name_value_dictionary_object.Add with field_name_obj, value_list_obj;
|
||||
endif;
|
||||
enddo;
|
||||
|
||||
;;
|
||||
priority: 50
|
||||
;;
|
||||
evoke:
|
||||
;;
|
||||
logic:
|
||||
conclude true;
|
||||
;;
|
||||
action:
|
||||
return (exclusion_criteria_dictionary_object, name_value_dictionary_object);
|
||||
;;
|
||||
Urgency: 50;;
|
||||
end:
|
||||
@@ -0,0 +1,95 @@
|
||||
maintenance:
|
||||
|
||||
title: Community Data;;
|
||||
mlmname: STD_FUNC_FILTER_VPO_GEN_PROPERTY_DICTIONARY;;
|
||||
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) 2014 - 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:
|
||||
This functional MLM is called by other STD_Filter_VPO MLMs that generate
|
||||
VPO filter criteria.
|
||||
This MLM converts the field value list into a .Net dictionary with field
|
||||
name as key, an boolean as value
|
||||
;;
|
||||
explanation:
|
||||
The argument passed into the MLM is:
|
||||
* field_value_list - list of FieldValueObjects defined as
|
||||
PropertyValueObject := OBJECT [ field_name, value ];
|
||||
|
||||
The data returned by the MLM are:
|
||||
* property_dictionary_object -
|
||||
Collections.Generic.Dictionary< String, Boolean >
|
||||
with field_name as key, and object as value
|
||||
;;
|
||||
keywords:
|
||||
Fused Agent;
|
||||
Community Data;
|
||||
VPO filter;
|
||||
dbMotion Data;
|
||||
;;
|
||||
citations:
|
||||
;;
|
||||
knowledge:
|
||||
type: data-driven;;
|
||||
data:
|
||||
// Specify which .NET assemblies need to be loaded
|
||||
using "mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089";
|
||||
using namespace "System";
|
||||
using namespace "System.Exception";
|
||||
using namespace "System.Windows.Forms";
|
||||
|
||||
// Arguments are passed in from the calling C++ program or MLM
|
||||
( field_value_list ) := argument;
|
||||
|
||||
|
||||
property_dictionary_object := new net_object {{{SINGLE-QUOTE}}}Collections.Generic.Dictionary< String, Boolean>{{{SINGLE-QUOTE}}};
|
||||
|
||||
// Only add the fields that have both include flag and the field value list specified
|
||||
field_property_list := field_value_list as list; // this ensures single item is also a list
|
||||
|
||||
for field_property in field_property_list
|
||||
do
|
||||
if exists field_property_list AND count field_property_list > 0
|
||||
then
|
||||
field_name_obj := field_property.field_name as {{{SINGLE-QUOTE}}}String{{{SINGLE-QUOTE}}};
|
||||
|
||||
field_value_obj := field_property.value as {{{SINGLE-QUOTE}}}Boolean{{{SINGLE-QUOTE}}};
|
||||
|
||||
void := call property_dictionary_object.Add with field_name_obj, field_value_obj;
|
||||
endif;
|
||||
enddo;
|
||||
|
||||
;;
|
||||
priority: 50
|
||||
;;
|
||||
evoke:
|
||||
;;
|
||||
logic:
|
||||
conclude true;
|
||||
;;
|
||||
action:
|
||||
return property_dictionary_object;
|
||||
;;
|
||||
Urgency: 50;;
|
||||
end:
|
||||
134
MLMStripper/bin/Debug/STD/STD_FUNC_FORMAT_MEDICATION.mlm
Normal file
134
MLMStripper/bin/Debug/STD/STD_FUNC_FORMAT_MEDICATION.mlm
Normal file
@@ -0,0 +1,134 @@
|
||||
maintenance:
|
||||
|
||||
title: Formats medications to be displayed in alert message;;
|
||||
mlmname: STD_FUNC_FORMAT_MEDICATION;;
|
||||
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: Formats medication text to return to calling MLM for use in alert messages.
|
||||
;;
|
||||
explanation: This MLM returns "msg_text" to the calling MLM. The variable "msg_text"
|
||||
contains the order name, summary line, start date, stop date and status.
|
||||
Each order is separated by a line.
|
||||
Order items that were found to match, are printed in blue or if an
|
||||
additive, an additional line indicates that the additive is contained in
|
||||
the order above.
|
||||
Example: D5W
|
||||
KCL 30 mEq, 100ml hourly QD
|
||||
starting on March 1, 2001, to March 17, 2001. STATUS:Active
|
||||
KCL contained in IV order above. (this is printed in blue)
|
||||
|
||||
This MLM relys on calling MLM to send
|
||||
- a list indicating if the item is an order or component
|
||||
- a list of each item{{{SINGLE-QUOTE}}}s GUIDs
|
||||
- a list of each item{{{SINGLE-QUOTE}}}s name
|
||||
- a list of each order item{{{SINGLE-QUOTE}}}s summary lines
|
||||
- a list of each order item{{{SINGLE-QUOTE}}}s request date
|
||||
- a list of each order item{{{SINGLE-QUOTE}}}s stop date
|
||||
- a list of each order item{{{SINGLE-QUOTE}}}s status code
|
||||
- a list of which items matched
|
||||
;;
|
||||
keywords:
|
||||
;;
|
||||
knowledge:
|
||||
type: data-driven;;
|
||||
data:
|
||||
(order_component_list, // List indicating if an order or component
|
||||
guid_list, // List of each item{{{SINGLE-QUOTE}}}s GUIDs
|
||||
order_name_list, // List of each item{{{SINGLE-QUOTE}}}s name
|
||||
summary_line_list, // List of each order item{{{SINGLE-QUOTE}}}s summary lines
|
||||
order_significant_date_list, // List of each order item{{{SINGLE-QUOTE}}}s request date
|
||||
order_stop_date_list, // List of each order item{{{SINGLE-QUOTE}}}s stop date
|
||||
order_status_desc_list, // List of each order item{{{SINGLE-QUOTE}}}s status code
|
||||
match_med_found ) // List of which items matched
|
||||
:= ARGUMENT;
|
||||
;;
|
||||
evoke:
|
||||
;;
|
||||
logic:
|
||||
msg_text := "";
|
||||
index_list := 1 seqto (count order_name_list);
|
||||
|
||||
for i in index_list do
|
||||
// Process each item on the order item lists
|
||||
previous_guid := guid;
|
||||
order_or_component := last(first i from order_component_list);
|
||||
guid := last(first i from guid_list);
|
||||
order_name := last(first i from order_name_list);
|
||||
summary_line := last(first i from summary_line_list);
|
||||
order_start_date := last(first i from order_significant_date_list);
|
||||
order_stop_date := last(first i from order_stop_date_list);
|
||||
order_status_desc := last(first i from order_status_desc_list);
|
||||
matching_med := last(first i from match_med_found);
|
||||
|
||||
// Formats each item name, summary line, startdate, and stopdate
|
||||
if i > 1 then msg_text := msg_text || "\n"; endif;
|
||||
if exist order_or_component then
|
||||
|
||||
// Check to see if item in list is an order or a component
|
||||
if order_or_component = "order"
|
||||
then
|
||||
if exist order_name then
|
||||
msg_text := msg_text ||"______________________________________"|| "\n";
|
||||
If matching_med then
|
||||
// Format differently for matches found on order name V.S. additive
|
||||
msg_text := msg_text || "{{+B}}{{+c}}"|| order_name ||"{{-c}}{{-B}}";
|
||||
else
|
||||
msg_text := msg_text || "{{+B}}"|| order_name ||"{{-B}}" ;
|
||||
endif; // Format order message
|
||||
endif; // if exist order_name
|
||||
|
||||
if exist summary_line then msg_text := msg_text || " "
|
||||
|| summary_line;
|
||||
endif;
|
||||
if exist order_start_date then
|
||||
temp_start_date := order_start_date formatted with "%.2t";
|
||||
msg_text := msg_text || "\n starting on "|| temp_start_date;
|
||||
endif;
|
||||
if exist order_stop_date then
|
||||
temp_stop_date := order_stop_date formatted with "%.2t";
|
||||
msg_text := msg_text|| " to "|| temp_stop_date;
|
||||
endif;
|
||||
|
||||
if exist order_status_desc then
|
||||
msg_text := msg_text|| "{{+B}}" || " Status: "|| order_status_desc || "{{-B}}";
|
||||
endif;
|
||||
|
||||
else if exist order_name then
|
||||
// Format additional line to indicate which additives matched
|
||||
msg_text := msg_text || "{{+c}}"|| order_name
|
||||
|| " contained in IV order above. {{-C}}"; endif;
|
||||
endif;
|
||||
|
||||
endif;// Check to see if item in list is order or component
|
||||
|
||||
|
||||
enddo;
|
||||
|
||||
conclude TRUE;
|
||||
;;
|
||||
action:
|
||||
return msg_text ;
|
||||
;;
|
||||
end:
|
||||
109
MLMStripper/bin/Debug/STD/STD_FUNC_FORMAT_RESULT.mlm
Normal file
109
MLMStripper/bin/Debug/STD/STD_FUNC_FORMAT_RESULT.mlm
Normal file
@@ -0,0 +1,109 @@
|
||||
maintenance:
|
||||
|
||||
title: Formats results to be displayed in alert message;;
|
||||
mlmname: STD_FUNC_FORMAT_RESULT;;
|
||||
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: Formats result text to return to calling MLM for use in alert messages.
|
||||
;;
|
||||
explanation: This MLM returns "msg_text" to the calling MLM. The variable "msg_text"
|
||||
contains the result name, value, text, unit of measure, and the
|
||||
performed date of all tests that were sent in to this MLM.
|
||||
|
||||
Example: Serum Potassium 3.5 mmol/L on March 15, 2001 10:15 am.
|
||||
Serum Potassium 3.8 mmol/L on March 17, 2001 8:30 am.
|
||||
|
||||
This MLM relys on calling MLM to send
|
||||
- a list of result names
|
||||
- a list of result values
|
||||
- a list of any text sent with values
|
||||
- a list of unit of measures sent with values
|
||||
- a list of date tests were performed
|
||||
|
||||
;;
|
||||
keywords:
|
||||
;;
|
||||
knowledge:
|
||||
type: data-driven;;
|
||||
data:
|
||||
|
||||
(result_name_list, // List of result names
|
||||
result_value_list, // List of result values
|
||||
result_text_list, // List of any text sent with values
|
||||
result_uom_list, // List of unit of measures sent with values
|
||||
result_performed_date_list, // List of date tests were performed
|
||||
result_community_source_list, // list of community source
|
||||
include_community_source, // flag to indicate if source should be added to aler
|
||||
community_results_alert_text // optional
|
||||
):= ARGUMENT;
|
||||
|
||||
;;
|
||||
evoke:
|
||||
;;
|
||||
logic:
|
||||
msg_text := "";
|
||||
|
||||
index_list := 1 seqto (count result_name_list);
|
||||
|
||||
for I in index_list do
|
||||
// Process each item on the lists
|
||||
result_name := last (first I from result_name_list);
|
||||
result_value := last (first I from result_value_list);
|
||||
result_text := last (first I from result_text_list);
|
||||
result_uom := last (first I from result_uom_list);
|
||||
result_performed_date := last (first I from result_performed_date_list);
|
||||
result_community_source := last (first I from result_community_source_list);
|
||||
|
||||
// Format each item for the message
|
||||
if I > 1 then msg_text := msg_text || "\n"; endif;
|
||||
if exist result_name then msg_text := msg_text || result_name; endif;
|
||||
if exist result_value then msg_text := msg_text || " " || result_value; endif;
|
||||
if exist result_text then msg_text := msg_text || " " || result_text; endif;
|
||||
if exist result_uom then msg_text := msg_text || " " || result_uom; endif;
|
||||
if exist result_performed_date then
|
||||
msg_text := (msg_text, " on ", result_performed_date)
|
||||
formatted with "%s%s%.4t";
|
||||
endif;
|
||||
|
||||
if exist result_community_source then
|
||||
|
||||
if exist community_results_alert_text AND
|
||||
community_results_alert_text <> "" then
|
||||
community_source_suffix := "(" || community_results_alert_text;
|
||||
if ( include_community_source ) then
|
||||
community_source_suffix := community_source_suffix || " Source: " || result_community_source;
|
||||
endif;
|
||||
msg_text := msg_text || " {{+B}}" || community_source_suffix || "){{-B}}";
|
||||
|
||||
endif;
|
||||
endif;
|
||||
enddo;
|
||||
|
||||
conclude TRUE;
|
||||
;;
|
||||
action:
|
||||
return msg_text ;
|
||||
;;
|
||||
end:
|
||||
88
MLMStripper/bin/Debug/STD/STD_FUNC_HM_AUTO_ASSIGNMENT.mlm
Normal file
88
MLMStripper/bin/Debug/STD/STD_FUNC_HM_AUTO_ASSIGNMENT.mlm
Normal file
@@ -0,0 +1,88 @@
|
||||
maintenance:
|
||||
|
||||
title: Health Management Auto assignment MLM;;
|
||||
mlmname: STD_FUNC_HM_AUTO_ASSIGNMENT;;
|
||||
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: This is a standard function MLM that is used
|
||||
to insert a queue entry for the Health Management
|
||||
auto assignment functionality.
|
||||
|
||||
;;
|
||||
explanation: This MLM is called with 3 parameters.
|
||||
|
||||
clientGUID - The client GUID for the current patient
|
||||
|
||||
userGUID - The user GUID for the current logged on user
|
||||
|
||||
updateDatabase - Should only be set to true if the MLM needs to
|
||||
write data to the queue. Generally set to false when the
|
||||
calling MLM is being run from the MLM editor.
|
||||
|
||||
The CDS Scheduled Service must be running and the MLM
|
||||
SCH_HM_AUTO_ASSIGNMENT_EXECUTE must be loaded and in production.
|
||||
|
||||
;;
|
||||
keywords: HealthManagement, AutoAssignment
|
||||
;;
|
||||
knowledge:
|
||||
type: data-driven;;
|
||||
data:
|
||||
(clientGUID,
|
||||
userGUID,
|
||||
updateDatabase
|
||||
):= ARGUMENT;
|
||||
|
||||
log_execution_info := false;
|
||||
|
||||
// Do not run if called by the editor
|
||||
if ( updateDatabase ) then
|
||||
|
||||
if clientGUID is null or userGUID is null then
|
||||
result := null;
|
||||
else
|
||||
// Insert into the Auto Assignment Queue
|
||||
// Using the stored procedure
|
||||
|
||||
result := read last { "Execute SXAHMAutoAssignmentScheduleInsPr @clientGUID=" ||
|
||||
SQL(clientGUID) || ", @userGUID=" || SQL(userGUID) };
|
||||
|
||||
endif;
|
||||
endif;
|
||||
;;
|
||||
priority: 50
|
||||
;;
|
||||
evoke:
|
||||
;;
|
||||
logic:
|
||||
|
||||
conclude true;
|
||||
|
||||
;;
|
||||
action:
|
||||
return result;
|
||||
;;
|
||||
Urgency: 50;;
|
||||
end:
|
||||
151
MLMStripper/bin/Debug/STD/STD_FUNC_HM_MARKASDONE.mlm
Normal file
151
MLMStripper/bin/Debug/STD/STD_FUNC_HM_MARKASDONE.mlm
Normal file
@@ -0,0 +1,151 @@
|
||||
maintenance:
|
||||
|
||||
title: Standard MLM to mark an HM Event as done;;
|
||||
mlmname: STD_FUNC_HM_MARKASDONE;;
|
||||
arden: version 2.5;;
|
||||
version: 18.4;;
|
||||
institution: AllScripts;;
|
||||
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: Standard Function MLM containing the necessary logic to Mark a
|
||||
Health Management immunization or wellness event as done.
|
||||
;;
|
||||
explanation: Do not make any changes to this MLM unless instructed to do so
|
||||
by Allscripts.
|
||||
|
||||
This MLM accepts several parameters which it uses to set properties on
|
||||
several .NET object which are then used to mark a Health Management
|
||||
immunization or wellness event as done.
|
||||
|
||||
Parameter List:
|
||||
ClientGUID
|
||||
The Id for the current patient on which the trigger event is
|
||||
occuring.
|
||||
|
||||
locationGUID
|
||||
The location group Id where the health management item was marked
|
||||
as done.
|
||||
|
||||
linkedItemId
|
||||
An Id to an order or some other data type that is being processed
|
||||
by the calling MLM. If it is linked to a scheduled event occurrence
|
||||
the linked occurrence will be maked as done. If the Id is NULL or
|
||||
is not linked then the code will determine if it needs to create a
|
||||
new scheduled event occurrence.
|
||||
|
||||
linkedItemType
|
||||
The type of the linked item. Only order (0) is supported at this time.
|
||||
|
||||
updateDatabase
|
||||
A flag used to determine if the actual Mark as Done functionality
|
||||
will be called. If set to false it will go through all the look
|
||||
ups and will indicate what will happen.
|
||||
|
||||
recordOnlyIfEventActive
|
||||
A flag that determines if the event being processed must be
|
||||
currently assigned to the patient and what state it should be. If true
|
||||
then the event must be assigned to the patient and it must be active.
|
||||
If false the the event must be assigned but it doesn{{{SINGLE-QUOTE}}}t need to be active.
|
||||
|
||||
recordOnlyIfPatientAssignedEvent
|
||||
A flag that determines if the event needs to be already assigned before
|
||||
it can be marked as done. If true then the event must be assigned, the
|
||||
code will then check the flag recordOnlyIfEventActive. If false then
|
||||
the event will be added as long as it exists and is active in the catalog.
|
||||
|
||||
eventOccurrenceObj
|
||||
immunizationObj
|
||||
vaccineMedicationLotObj
|
||||
consentDocumentObj
|
||||
educationalMaterialsObj
|
||||
The data objects used to create the new Health Management client
|
||||
event occurrence and mark it as done. For a wellness and immunization
|
||||
events the object eventOccurrenceObj is required. For immunization
|
||||
the immunizationObj is also manditory. All other objects are
|
||||
optional.
|
||||
|
||||
|
||||
;;
|
||||
keywords:
|
||||
;;
|
||||
knowledge:
|
||||
type: data-driven;;
|
||||
data:
|
||||
|
||||
standard_libs := MLM {{{SINGLE-QUOTE}}}std_include_libs{{{SINGLE-QUOTE}}};
|
||||
include standard_libs;
|
||||
|
||||
using "Eclipsys.Clinicals.Common";
|
||||
|
||||
using "Sunrise.Clinicals.HealthManagement";
|
||||
using namespace "Sunrise.Clinicals.HealthManagement";
|
||||
using namespace "Sunrise.Clinicals.HealthManagement.DataObjects";
|
||||
|
||||
// Parameters passed to MLM.
|
||||
( clientGUID,
|
||||
locationGroupGuid,
|
||||
linkedItemId,
|
||||
linkedItemType,
|
||||
updateDatabase,
|
||||
recordOnlyIfPatientAssignedEvent,
|
||||
recordOnlyIfEventActive,
|
||||
eventOccurrenceObj,
|
||||
immunizationObj,
|
||||
vaccineMedicationLotObj,
|
||||
consentDocumentObj,
|
||||
educationalMaterialsObj,
|
||||
linkOrderToEventOccurrence
|
||||
) := argument;
|
||||
|
||||
HMAction_MLM := MLM {{{SINGLE-QUOTE}}}STD_FUNC_HM_PERFORM_ACTION{{{SINGLE-QUOTE}}};
|
||||
|
||||
(mlmStatus, outputMessage) := call HMAction_MLM
|
||||
with clientGUID,
|
||||
locationGroupGuid,
|
||||
linkedItemId,
|
||||
0,
|
||||
updateDatabase,
|
||||
recordOnlyIfPatientAssignedEvent,
|
||||
recordOnlyIfEventActive,
|
||||
"MAD",
|
||||
eventOccurrenceObj,
|
||||
immunizationObj,
|
||||
vaccineMedicationLotObj,
|
||||
consentDocumentObj,
|
||||
educationalMaterialsObj,
|
||||
null, //notGivenReasonDef,
|
||||
linkOrderToEventOccurrence;
|
||||
|
||||
;;
|
||||
priority: 50
|
||||
;;
|
||||
evoke:
|
||||
;;
|
||||
logic:
|
||||
conclude true;
|
||||
;;
|
||||
action:
|
||||
|
||||
return mlmStatus, outputMessage;
|
||||
;;
|
||||
Urgency: 50;;
|
||||
end:
|
||||
87
MLMStripper/bin/Debug/STD/STD_FUNC_HM_MARKASNOTDONE.mlm
Normal file
87
MLMStripper/bin/Debug/STD/STD_FUNC_HM_MARKASNOTDONE.mlm
Normal file
@@ -0,0 +1,87 @@
|
||||
maintenance:
|
||||
|
||||
title: Standard MLM to mark an HM Event as not done;;
|
||||
mlmname: STD_FUNC_HM_MARKASNOTDONE;;
|
||||
arden: version 2.5;;
|
||||
version: 18.4;;
|
||||
institution: AllScripts;;
|
||||
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: Standard Function MLM containing the necessary logic to Mark a
|
||||
Health Management immunization or wellness event as not done.
|
||||
;;
|
||||
explanation:
|
||||
;;
|
||||
keywords:
|
||||
;;
|
||||
citations:
|
||||
;;
|
||||
knowledge:
|
||||
type: data-driven;;
|
||||
data:
|
||||
|
||||
// Parameters passed to MLM.
|
||||
( clientGUID,
|
||||
locationGroupGUID,
|
||||
linkedItemId,
|
||||
linkedItemType,
|
||||
updateDatabase,
|
||||
recordOnlyIfPatientAssignedEvent,
|
||||
recordOnlyIfEventActive,
|
||||
eventOccurrenceObj,
|
||||
immunizationObj,
|
||||
notGivenReasonObj,
|
||||
exemptionDocumentObj,
|
||||
linkOrderToEventOccurrence
|
||||
) := argument;
|
||||
|
||||
HMAction_MLM := MLM {{{SINGLE-QUOTE}}}STD_FUNC_HM_PERFORM_ACTION{{{SINGLE-QUOTE}}};
|
||||
|
||||
(mlmStatus, outputMessage) := call HMAction_MLM
|
||||
with clientGUID,
|
||||
locationGroupGuid,
|
||||
linkedItemId,
|
||||
0,
|
||||
updateDatabase,
|
||||
recordOnlyIfPatientAssignedEvent,
|
||||
recordOnlyIfEventActive,
|
||||
"MAND",
|
||||
eventOccurrenceObj,
|
||||
immunizationObj,
|
||||
null, //vaccineMedicationLotObj
|
||||
exemptionDocumentObj,
|
||||
null, //educationalMaterialsObj
|
||||
notGivenReasonObj,
|
||||
linkOrderToEventOccurrence;
|
||||
;;
|
||||
priority: 50
|
||||
;;
|
||||
evoke:
|
||||
;;
|
||||
logic:
|
||||
conclude true;
|
||||
;;
|
||||
action:
|
||||
return mlmStatus, outputMessage;
|
||||
;;
|
||||
Urgency: 50;;
|
||||
end:
|
||||
486
MLMStripper/bin/Debug/STD/STD_FUNC_HM_PERFORM_ACTION.mlm
Normal file
486
MLMStripper/bin/Debug/STD/STD_FUNC_HM_PERFORM_ACTION.mlm
Normal file
@@ -0,0 +1,486 @@
|
||||
maintenance:
|
||||
|
||||
title: Standard MLM to mark an HM Event as done;;
|
||||
mlmname: STD_FUNC_HM_PERFORM_ACTION;;
|
||||
arden: version 2.5;;
|
||||
version: 18.4;;
|
||||
institution: AllScripts;;
|
||||
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) 2016 - 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: Standard Function MLM containing the necessary logic to Mark a
|
||||
Health Management immunization or wellness event as done.
|
||||
;;
|
||||
explanation: Do not make any changes to this MLM unless instructed to do so
|
||||
by Allscripts.
|
||||
|
||||
This MLM accepts several parameters which it uses to set properties on
|
||||
several .NET object which are then used to mark a Health Management
|
||||
immunization or wellness event as done.
|
||||
|
||||
Parameter List:
|
||||
ClientGUID
|
||||
The Id for the current patient on which the trigger event is
|
||||
occuring.
|
||||
|
||||
locationGUID
|
||||
The location group Id where the health management item was marked
|
||||
as done.
|
||||
|
||||
linkedItemId
|
||||
An Id to an order or some other data type that is being processed
|
||||
by the calling MLM. If it is linked to a scheduled event occurrence
|
||||
the linked occurrence will be maked as done. If the Id is NULL or
|
||||
is not linked then the code will determine if it needs to create a
|
||||
new scheduled event occurrence.
|
||||
|
||||
linkedItemType
|
||||
The type of the linked item. Only order (0) is supported at this time.
|
||||
|
||||
updateDatabase
|
||||
A flag used to determine if the actual Mark as Done functionality
|
||||
will be called. If set to false it will go through all the look
|
||||
ups and will indicate what will happen.
|
||||
|
||||
recordOnlyIfEventActive
|
||||
A flag that determines if the event being processed must be
|
||||
currently assigned to the patient and what state it should be. If true
|
||||
then the event must be assigned to the patient and it must be active.
|
||||
If false the the event must be assigned but it doesn{{{SINGLE-QUOTE}}}t need to be active.
|
||||
|
||||
recordOnlyIfPatientAssignedEvent
|
||||
A flag that determines if the event needs to be already assigned before
|
||||
it can be marked as done. If true then the event must be assigned, the
|
||||
code will then check the flag recordOnlyIfEventActive. If false then
|
||||
the event will be added as long as it exists and is active in the catalog.
|
||||
hmAction
|
||||
The type of action performed (Only "MAD" and "MAND" are supported right now)
|
||||
eventOccurrenceObj
|
||||
immunizationObj
|
||||
vaccineMedicationLotObj
|
||||
consentDocumentObj
|
||||
educationalMaterialsObj
|
||||
The data objects used to create the new Health Management client
|
||||
event occurrence and mark it as done. For a wellness and immunization
|
||||
events the object eventOccurrenceObj is required. For immunization
|
||||
the immunizationObj is also manditory. All other objects are
|
||||
optional.
|
||||
notGivenReasonObj
|
||||
linkOrderToEventOccurrence
|
||||
|
||||
;;
|
||||
keywords:
|
||||
;;
|
||||
knowledge:
|
||||
type: data-driven;;
|
||||
data:
|
||||
|
||||
standard_libs := MLM {{{SINGLE-QUOTE}}}std_include_libs{{{SINGLE-QUOTE}}};
|
||||
include standard_libs;
|
||||
|
||||
using "Eclipsys.Clinicals.Common";
|
||||
|
||||
using "Sunrise.Clinicals.HealthManagement";
|
||||
using "Sunrise.Clinicals.HealthManagement.ServiceInterfaces";
|
||||
using namespace "Sunrise.Clinicals.HealthManagement";
|
||||
using namespace "Sunrise.Clinicals.HealthManagement.ServiceInterfaces";
|
||||
using namespace "Sunrise.Clinicals.HealthManagement.DataObjects";
|
||||
|
||||
// Parameters passed to MLM.
|
||||
( clientGUID,
|
||||
locationGUID,
|
||||
linkedItemId,
|
||||
linkedItemType,
|
||||
updateDatabase,
|
||||
recordOnlyIfPatientAssignedEvent,
|
||||
recordOnlyIfEventActive,
|
||||
hmAction,
|
||||
eventOccurrenceObj,
|
||||
immunizationObj,
|
||||
vaccineMedicationLotObj,
|
||||
consentDocumentObj,
|
||||
educationalMaterialsObj,
|
||||
notGivenReasonObj,
|
||||
linkOrderToEventOccurrence
|
||||
) := argument;
|
||||
|
||||
log_execution_info := false;
|
||||
|
||||
outputMessage := null;
|
||||
|
||||
// Status levels
|
||||
// 1 = No client event on schedule
|
||||
// 2 = Success
|
||||
// 3 = Failure
|
||||
mlmStatus := 2;
|
||||
|
||||
// Validate parameters
|
||||
if (eventOccurrenceObj is null OR eventOccurrenceObj.eventName is null OR
|
||||
clientGUID is null OR
|
||||
eventOccurrenceObj.actionProviderId is null )
|
||||
then
|
||||
outputMessage := "The MLM STD_FUNC_HM_PERFORM_ACTION was called with invalid parameters.\n";
|
||||
mlmStatus := 3;
|
||||
else
|
||||
|
||||
// Test for the existance of the event
|
||||
if recordOnlyIfPatientAssignedEvent
|
||||
then
|
||||
|
||||
// If true then check for an active schedule, otherwise the status
|
||||
// doesn{{{SINGLE-QUOTE}}}t matter
|
||||
if recordOnlyIfEventActive
|
||||
then
|
||||
activeClientEventTest := " AND ce.EventStatusType=0 ";
|
||||
else
|
||||
activeClientEventTest := " ";
|
||||
endif;
|
||||
|
||||
// Find the matching Health Management Event from the mapped Ancillary Name.
|
||||
(eventId,
|
||||
eventType,
|
||||
eventTypeDesc ) := read last { "select e.EventID,e.Type,e1.ReferenceString as [TypeDesc] " ||
|
||||
" from SXAHMEvent e " ||
|
||||
" inner join SXAHMClientEvent ce on e.EventID = ce.EventID " ||
|
||||
" inner join CV3EnumReference e1 on e1.TableName = {{{SINGLE-QUOTE}}}SXAHMEvent{{{SINGLE-QUOTE}}} " ||
|
||||
" and e1.ColumnName={{{SINGLE-QUOTE}}}Type{{{SINGLE-QUOTE}}} and e1.EnumValue=e.Type " ||
|
||||
"where e.Active=1 AND e.Name = " || SQL(eventOccurrenceObj.eventName) ||
|
||||
activeClientEventTest ||
|
||||
" AND ce.ClientGUID = " || SQL(clientGUID) };
|
||||
else
|
||||
// Make sure there is an Event for the mapped name, doesn{{{SINGLE-QUOTE}}}t have to be on the patient{{{SINGLE-QUOTE}}}s
|
||||
// schedule
|
||||
(eventId,
|
||||
eventType,
|
||||
eventTypeDesc ) := read last { "select e.EventID,e.Type,e1.ReferenceString as [TypeDesc] " ||
|
||||
" from SXAHMEvent e " ||
|
||||
" inner join CV3EnumReference e1 on e1.TableName = {{{SINGLE-QUOTE}}}SXAHMEvent{{{SINGLE-QUOTE}}} " ||
|
||||
" and e1.ColumnName={{{SINGLE-QUOTE}}}Type{{{SINGLE-QUOTE}}} and e1.EnumValue=e.Type " ||
|
||||
"where e.Active=1 AND e.Name = " || SQL(eventOccurrenceObj.eventName) };
|
||||
|
||||
|
||||
endif;
|
||||
|
||||
// If found, get the necessary data from the other parameter objects
|
||||
// and then call the occurrence mark as done logic
|
||||
if eventId is not null
|
||||
then
|
||||
|
||||
try
|
||||
|
||||
placeOrder := false;
|
||||
|
||||
//Get Pending occurrence ID for current eventID
|
||||
(eventOccurrenceId, linkId) := read last { "SELECT seo.ScheduledEventOccurrenceID, oli.LinkedItemID FROM SXAHMScheduledEventOccurrence seo " ||
|
||||
" LEFT OUTER JOIN SXAHMOccurrenceLinkedItemXRef oli ON ( oli.ScheduledEventOccurrenceID = seo.ScheduledEventOccurrenceID AND oli.LinkedItemType =" || linkedItemType || ") " ||
|
||||
" WHERE seo.OccurrenceStatusType=0 " ||
|
||||
" AND seo.EventID=" || SQL(eventId) ||
|
||||
" AND seo.ClientGUID=" || SQL(clientGUID) };
|
||||
|
||||
|
||||
// Get the location facility time zone, from the location guid
|
||||
(locationTZNowDateTime) := read last { "DECLARE @EnterpriseNow DateTime " ||
|
||||
" SELECT @EnterpriseNow = CurDate FROM dbo.SXADBGetEnterpriseNowTblFn(); " ||
|
||||
" SELECT top 1 tz.LocalDate as locationTZNowDateTime " ||
|
||||
" FROM CV3Location locn " ||
|
||||
" left join CV3LocnFacility lf on ( iif( locn.IsFacility = 1 , locn.Guid, locn.FacilityGUID ) = lf.FacilityGUID ) " ||
|
||||
" CROSS APPLY dbo.SXADBConvertEnterpriseToLocalTblFn(lf.TimeZone, @EnterpriseNow) tz " ||
|
||||
" WHERE locn.GUID = " || SQL(locationGUID) };
|
||||
|
||||
eventOccurrenceMgr := new net_object {{{SINGLE-QUOTE}}}EventOccurrenceManager{{{SINGLE-QUOTE}}};
|
||||
if ( eventOccurrenceId is not null ) then
|
||||
eventOccurrence := call eventOccurrenceMgr.GetEventOccurrence with eventOccurrenceId as {{{SINGLE-QUOTE}}}System.Int64{{{SINGLE-QUOTE}}},
|
||||
locationTZNowDateTime as {{{SINGLE-QUOTE}}}System.Nullable<System.DateTime>{{{SINGLE-QUOTE}}};
|
||||
else
|
||||
eventOccurrence := call {{{SINGLE-QUOTE}}}EventOccurrenceBObj{{{SINGLE-QUOTE}}}.CreateEventOccurrence with eventId as {{{SINGLE-QUOTE}}}System.Int32{{{SINGLE-QUOTE}}};
|
||||
eventOccurrence.ClientPrimaryKey := (clientGUID as number) as {{{SINGLE-QUOTE}}}System.Int64{{{SINGLE-QUOTE}}};
|
||||
endif;
|
||||
|
||||
if linkOrderToEventOccurrence and linkId is null and linkedItemId is not null then
|
||||
placeOrder := true;
|
||||
endif;
|
||||
|
||||
continueProcess := true;
|
||||
|
||||
if hmAction = "MAD" then
|
||||
strAction := "Done";
|
||||
elseif(hmAction = "MAND") then
|
||||
strAction := "not Done";
|
||||
endif;
|
||||
|
||||
// If the Mapped Event is an immunization then look for immumization and medication
|
||||
// lot information.
|
||||
if eventTypeDesc = "Immunization" then
|
||||
|
||||
//Find if Vaccine exist.
|
||||
if immunizationObj.VaccineName is not null OR
|
||||
immunizationObj.CVXCode is not null then
|
||||
(vaccineId,
|
||||
vaccineName,
|
||||
vaccineCVXCode ) := read last { "SELECT vci.VaccineCatalogItemID, Name, CVXCode FROM SXAHMEventVaccineXRef vxref " ||
|
||||
" INNER JOIN SXAHMVaccineCatalogItem vci ON (vci.VaccineCatalogItemID = vxref.VaccineID) " ||
|
||||
" WHERE vxref.EventID =" || SQL(eventId) || " AND vci.Active = 1 AND (vci.Name =" || SQL(immunizationObj.VaccineName) || " OR vci.CVXCode =" || SQL(immunizationObj.CVXCode) || " ) " };
|
||||
endif;
|
||||
|
||||
if(vaccineId is null) then
|
||||
if immunizationObj.VaccineName is not null
|
||||
then
|
||||
vaccineInfo := "Vaccine name: " || immunizationObj.VaccineName ;
|
||||
endif;
|
||||
if immunizationObj.CVXCode is not null
|
||||
then
|
||||
vaccineInfo := vaccineInfo || "\nCVX Code: " || immunizationObj.CVXCode;
|
||||
endif;
|
||||
if vaccineInfo is null
|
||||
then
|
||||
vaccineInfo := "No vaccine data has been assigned to the order";
|
||||
else
|
||||
vaccineInfo := vaccineInfo || "\n is not configured for this event";
|
||||
endif;
|
||||
|
||||
outputMessage := "Cannot mark the immunization event {{{SINGLE-QUOTE}}}" || eventOccurrenceObj.eventName || "{{{SINGLE-QUOTE}}} as " || strAction || ".\n";
|
||||
outputMessage := outputMessage || vaccineInfo;
|
||||
|
||||
mlmStatus := 3;
|
||||
continueProcess := false;
|
||||
endif;
|
||||
endif;
|
||||
|
||||
if(continueProcess) then
|
||||
|
||||
//Place Order first
|
||||
if(placeOrder AND updateDatabase) then
|
||||
//If created a new occurrence, we need to save it first
|
||||
if(eventOccurrence.PrimaryKey = 0)then
|
||||
x := call eventOccurrence.Insert;
|
||||
endif;
|
||||
|
||||
occLinkedItemData := new net_object {{{SINGLE-QUOTE}}}OccurrenceLinkedItemXRefData{{{SINGLE-QUOTE}}};
|
||||
occLinkedItemData.ScheduledEventOccurrenceId := eventOccurrence.PrimaryKey as {{{SINGLE-QUOTE}}}System.Int64{{{SINGLE-QUOTE}}};
|
||||
occLinkedItemData.LinkedItemId := (linkedItemId as number) as {{{SINGLE-QUOTE}}}System.Int64{{{SINGLE-QUOTE}}};
|
||||
occLinkedItemData.LinkedItemType := linkedItemType as {{{SINGLE-QUOTE}}}System.Int32{{{SINGLE-QUOTE}}};
|
||||
occLinkedItemData.ParentOccurrenceID := eventOccurrence.ParentOccurrencePrimaryKey as {{{SINGLE-QUOTE}}}System.Nullable<System.Int64>{{{SINGLE-QUOTE}}};
|
||||
|
||||
occLinkedItem := new net_object {{{SINGLE-QUOTE}}}OccurrenceLinkedItemXRefBObj{{{SINGLE-QUOTE}}} with (occLinkedItemData);
|
||||
|
||||
x := call eventOccurrence.PlaceOrder with occLinkedItem, true;
|
||||
|
||||
// Need to reload event occurrence, otherwise we have a update issue (MSRowVersion is different)
|
||||
eventOccurrence := call eventOccurrenceMgr.FindPendingEventOccurrenceForClientByEvent with (clientGUID as number) as {{{SINGLE-QUOTE}}}System.Int64{{{SINGLE-QUOTE}}}, eventId as {{{SINGLE-QUOTE}}}System.Int32{{{SINGLE-QUOTE}}},
|
||||
null as {{{SINGLE-QUOTE}}}System.Nullable<System.DateTime>{{{SINGLE-QUOTE}}};
|
||||
endif; //PlaceOrder
|
||||
|
||||
// The objects eventOccurrence, consentDocument and educationMaterials are
|
||||
// used by both Wellness events and Immunization events.
|
||||
|
||||
// Set the Action date and provider information
|
||||
yearAction := (extract year of eventOccurrenceObj.actionDate) as {{{SINGLE-QUOTE}}}System.Int32{{{SINGLE-QUOTE}}};
|
||||
monthAction := (extract month of eventOccurrenceObj.actionDate) as {{{SINGLE-QUOTE}}}System.Int32{{{SINGLE-QUOTE}}};
|
||||
dayAction := (extract day of eventOccurrenceObj.actionDate) as {{{SINGLE-QUOTE}}}System.Int32{{{SINGLE-QUOTE}}};
|
||||
hourAction := extract hour of eventOccurrenceObj.actionDate;
|
||||
minAction := extract minute of eventOccurrenceObj.actionDate;
|
||||
timeString := hourAction formatted with "%02d" || ":" || minAction formatted with "%02d";
|
||||
partialDate := new net_object {{{SINGLE-QUOTE}}}Eclipsys.Clinicals.Common.PartialDate{{{SINGLE-QUOTE}}} with (yearAction, monthAction, dayAction, timeString);
|
||||
eventOccurrence.ActionDateTime := partialDate;
|
||||
eventOccurrence.ActionProviderName := eventOccurrenceObj.actionProviderDisplayName;
|
||||
eventOccurrence.ActionProviderPrimaryKey := (eventOccurrenceObj.actionProviderId as number) as {{{SINGLE-QUOTE}}}System.Int64{{{SINGLE-QUOTE}}};
|
||||
|
||||
|
||||
eventOccurrence.Comment := eventOccurrenceObj.Comment;
|
||||
eventOccurrence.SiteGivenCode := eventOccurrenceObj.SiteGivenCode;
|
||||
eventOccurrence.RouteCode := eventOccurrenceObj.RouteCode;
|
||||
eventOccurrence.IsPartialDose := eventOccurrenceObj.IsPartialDose;
|
||||
|
||||
// set the action user on the history to be the user from the state object. This is the user
|
||||
// who triggered the MLM
|
||||
userGUID := read last {StateInfo: UserGUID };
|
||||
if ( userGUID is not null )
|
||||
then
|
||||
eventOccurrence.NewOccurrenceActionStatusHistory.ActionUserPrimaryKey := (userGUID as number) as {{{SINGLE-QUOTE}}}System.Nullable<System.Int64>{{{SINGLE-QUOTE}}};
|
||||
endif;
|
||||
|
||||
if ( consentDocumentObj is not null )
|
||||
then
|
||||
consentDocument := new net_object {{{SINGLE-QUOTE}}}ConsentDocumentBObj{{{SINGLE-QUOTE}}};
|
||||
|
||||
consentDocument.ConsentTypeCode := consentDocumentObj.TypeCode;
|
||||
consentDocument.ConsentDate := consentDocumentObj.ConsentDate as Time;
|
||||
//consentDocument.ConsentTypeTime := consentDocumentObj.ConsentTime; // Timespan -- not supported
|
||||
consentDocument.ConsentBy := consentDocumentObj.ConsentBy;
|
||||
consentDocument.RelationshipCode := consentDocumentObj.RelationShipCode;
|
||||
consentDocument.DocumentType := consentDocumentObj.DocumentType as {{{SINGLE-QUOTE}}}ConsentDocumentType{{{SINGLE-QUOTE}}};
|
||||
|
||||
x := call eventOccurrence.ConsentDocuments.Add with consentDocument;
|
||||
|
||||
endif;
|
||||
|
||||
if ( educationalMaterialsObj is not null )
|
||||
then
|
||||
educationalMaterials := new net_object {{{SINGLE-QUOTE}}}EducationMaterialBObj{{{SINGLE-QUOTE}}};
|
||||
|
||||
educationalMaterials.EducationalMaterialTypeCode := educationalMaterialsObj.TypeCode;
|
||||
educationalMaterials.IsVis := educationalMaterialsObj.IsVis;
|
||||
educationalMaterials.PublishedDate := educationalMaterialsObj.PublishedDate as Time;
|
||||
educationalMaterials.PresentedDate := educationalMaterialsObj.PresentedDate as Time;
|
||||
|
||||
x := call eventOccurrence.EducationMaterials.Add with educationalMaterials;
|
||||
|
||||
endif;
|
||||
|
||||
if( notGivenReasonObj is not null) then
|
||||
|
||||
reasonType := eventTypeDesc || " " || notGivenReasonObj.ReasonType;
|
||||
|
||||
reasonCode := notGivenReasonObj.ReasonCode;
|
||||
reason := notGivenReasonObj.Reason;
|
||||
|
||||
//If ReasonCode is populated, get the Reason, Otherwise get the ReasonCode.
|
||||
if(reasonCode is not NULL) then
|
||||
reason := read last { "SELECT cr.Reason FROM CV3CodedReason cr WHERE Type = " || SQL(reasonType) || " AND Code = " || SQL(reasonCode) };
|
||||
else
|
||||
reasonCode := read last { "SELECT cr.Code FROM CV3CodedReason cr WHERE Type = " || SQL(reasonType) || " AND Reason = " || SQL(notGivenReasonObj.Reason) };
|
||||
endif;
|
||||
|
||||
codedReason := new net_object {{{SINGLE-QUOTE}}}Sunrise.Clinicals.HealthManagement.ServiceInterfaces.CodedReason{{{SINGLE-QUOTE}}};
|
||||
codedReason.Code := reasonCode;
|
||||
codedReason.Reason := reason;
|
||||
|
||||
actionReason := new net_object {{{SINGLE-QUOTE}}}ActionReason{{{SINGLE-QUOTE}}} with (codedReason);
|
||||
|
||||
eventOccurrence.NewOccurrenceActionStatusHistory.ActionCodedReasonType := reasonType;
|
||||
x := call eventOccurrence.NewOccurrenceActionStatusHistory.ActionReasons.Add with actionReason;
|
||||
eventOccurrence.NewOccurrenceActionStatusHistory.ActionMoreDetail := notGivenReasonObj.MoreDetails;
|
||||
endif;
|
||||
|
||||
|
||||
// If the Mapped Event is an immunization then look for immumization and medication
|
||||
// lot information.
|
||||
if (vaccineId is not null)
|
||||
then
|
||||
immunizationEventOccurrence := eventOccurrence as {{{SINGLE-QUOTE}}}ImmunizationEventOccurrenceBObj{{{SINGLE-QUOTE}}};
|
||||
|
||||
vaccineDose := (vaccineMedicationLotObj.LotDoseAmount as number) as {{{SINGLE-QUOTE}}}System.Nullable<System.Decimal>{{{SINGLE-QUOTE}}};
|
||||
vaccineUom := vaccineMedicationLotObj.LotDoseUom;
|
||||
|
||||
immunizationEventOccurrence.VaccinePrimaryKey := vaccineId;
|
||||
|
||||
immunizationEventOccurrence.DoseAmount := vaccineDose;
|
||||
immunizationEventOccurrence.DoseUom := vaccineUom;
|
||||
|
||||
immunizationEventOccurrence.VaccineProductCode := immunizationObj.VaccineProductCode;
|
||||
immunizationEventOccurrence.VaccineBrandName := immunizationObj.VaccineBrandName;
|
||||
immunizationEventOccurrence.VaccineEligibilityCode := immunizationObj.VaccineEligibilityCode;
|
||||
|
||||
// One or the other, not both.
|
||||
if ( immunizationObj.VaccineManufacturerMVXCode is not null )
|
||||
then
|
||||
immunizationEventOccurrence.VaccineManufacturerMvxCode := immunizationObj.VaccineManufacturerMVXCode;
|
||||
else
|
||||
immunizationEventOccurrence.VaccineManufacturer := immunizationObj.VaccineManufacturer;
|
||||
endif;
|
||||
|
||||
// Set Lot information
|
||||
if (VaccineMedicationLotObj is not null)
|
||||
then
|
||||
vaccineMedicationLotData := new net_object {{{SINGLE-QUOTE}}}VaccineMedicationLotDataBObj{{{SINGLE-QUOTE}}};
|
||||
|
||||
vaccineMedicationLotData.LotNumber := VaccineMedicationLotObj.LotNumber;
|
||||
vaccineMedicationLotData.LotSourceCode := VaccineMedicationLotObj.LotSourceCode;
|
||||
vaccineMedicationLotData.LotExpirationDate := VaccineMedicationLotObj.LotExpirationDate as Time;
|
||||
vaccineMedicationLotData.LotDoseAmount := vaccineDose;
|
||||
vaccineMedicationLotData.LotDoseUom := vaccineUom;
|
||||
vaccineMedicationLotData.RemovedFromStorage := VaccineMedicationLotObj.RemovedFromStorageDate as Time;
|
||||
vaccineMedicationLotData.LotWasteAmount := (VaccineMedicationLotObj.LotWasteAmount as Number) as {{{SINGLE-QUOTE}}}System.Nullable<System.Decimal>{{{SINGLE-QUOTE}}};
|
||||
vaccineMedicationLotData.LotWasteUom := VaccineMedicationLotObj.LotWasteUom;
|
||||
|
||||
x := call immunizationEventOccurrence.VaccineMedicationLots.Add with vaccineMedicationLotData;
|
||||
endif;
|
||||
|
||||
outputMessage := "Marked the vaccine type event occurrence {{{SINGLE-QUOTE}}}" || eventOccurrenceObj.eventName ||
|
||||
"{{{SINGLE-QUOTE}}} as " || strAction || " using vaccine {{{SINGLE-QUOTE}}}" || vaccineName || "{{{SINGLE-QUOTE}}} CVXCode=(" || vaccineCVXCode || ").";
|
||||
else
|
||||
|
||||
outputMessage := "Marked the wellness event occurrence {{{SINGLE-QUOTE}}}" || eventOccurrenceObj.eventName || "{{{SINGLE-QUOTE}}} as " || strAction || ".";
|
||||
|
||||
endif; //vaccineId is not null
|
||||
|
||||
if mlmStatus = 2 AND updateDatabase then
|
||||
|
||||
locationId := (locationGUID as Number) as {{{SINGLE-QUOTE}}}System.Nullable<System.Int64>{{{SINGLE-QUOTE}}};
|
||||
|
||||
// Mark it as done via the manager
|
||||
eventOccurrenceMgr := new net_object {{{SINGLE-QUOTE}}}EventOccurrenceManager{{{SINGLE-QUOTE}}};
|
||||
|
||||
if hmAction = "MAD" then
|
||||
x := call eventOccurrenceMgr.MarkEventOccurrenceDone with eventOccurrence, locationId;
|
||||
elseif(hmAction = "MAND") then
|
||||
x := call eventOccurrenceMgr.MarkEventOccurrenceNotDone with eventOccurrence, locationId;
|
||||
endif; //hmAction = {{{SINGLE-QUOTE}}}MAD{{{SINGLE-QUOTE}}}
|
||||
|
||||
// Re-evaluate based on possible new conditions
|
||||
clientEventMgr := new net_object {{{SINGLE-QUOTE}}}ClientEventManager{{{SINGLE-QUOTE}}};
|
||||
dataChanged := call clientEventMgr.ReEvaluateClientEventOccurrence
|
||||
with (clientGUID as number) as {{{SINGLE-QUOTE}}}System.Int64{{{SINGLE-QUOTE}}},
|
||||
eventId as {{{SINGLE-QUOTE}}}System.Int32{{{SINGLE-QUOTE}}},
|
||||
null as {{{SINGLE-QUOTE}}}System.Nullable<System.DateTime>{{{SINGLE-QUOTE}}};
|
||||
|
||||
endif;
|
||||
|
||||
endif; //continueProcess
|
||||
|
||||
endtry;
|
||||
catch exception ex
|
||||
mlmStatus := 3;
|
||||
outputMessage := "An attempt to Mark as " || strAction || " the Health Management event {{{SINGLE-QUOTE}}}" || eventOccurrenceObj.eventName ||
|
||||
"{{{SINGLE-QUOTE}}} has failed. \nThe reason for the failure is as follows:\n" || ex.Message;
|
||||
endcatch;
|
||||
else
|
||||
// Not an error condititon, just that the evoking object doesn{{{SINGLE-QUOTE}}}t have a matching
|
||||
// Health Management scheduled Client Event.
|
||||
mlmStatus := 1;
|
||||
if recordOnlyIfPatientAssignedEvent
|
||||
then
|
||||
outputMessage := "The Health Management event {{{SINGLE-QUOTE}}}" || eventOccurrenceObj.eventName ||
|
||||
"{{{SINGLE-QUOTE}}} does not exist in the catalog or is not active on the patient{{{SINGLE-QUOTE}}}s chart.\n" ||
|
||||
"No action has been taken.";
|
||||
else
|
||||
outputMessage := "The Health Management event {{{SINGLE-QUOTE}}}" || eventOccurrenceObj.eventName ||
|
||||
"{{{SINGLE-QUOTE}}} does not exist in the catalog.\n" ||
|
||||
"No action has been taken.";
|
||||
endif;
|
||||
endif;
|
||||
|
||||
endif;
|
||||
|
||||
;;
|
||||
priority: 50
|
||||
;;
|
||||
evoke:
|
||||
;;
|
||||
logic:
|
||||
conclude true;
|
||||
;;
|
||||
action:
|
||||
|
||||
return mlmStatus, outputMessage;
|
||||
;;
|
||||
Urgency: 50;;
|
||||
end:
|
||||
@@ -0,0 +1,279 @@
|
||||
maintenance:
|
||||
|
||||
title: Function MLM used to insert a row into the reportable info message queue ;;
|
||||
mlmname: STD_FUNC_INSERT_REPORTABLE_SURVEILLANCE;;
|
||||
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: This is a standard function MLM that is used by all other
|
||||
reportable result/Bio-surveillance MLMs. It takes the parameter
|
||||
values passed in, validates them and then creates a SQL call to
|
||||
insert a row into the SXAReportableInfoMsgQueue table.
|
||||
|
||||
This MLM will return the Xml document generated is successful and
|
||||
NULL if there was nothing to be written.
|
||||
|
||||
;;
|
||||
explanation:
|
||||
3 parameters are passed to this procedure:
|
||||
Message Queue Type - This specifies what type of message is being processed.
|
||||
Valid values are 0,"ReportableResults" or
|
||||
1,"Biosurveillance" or 2,"Case Notification" or 3,"SendLabResults".
|
||||
If invalid or set to NULL it will be defaulted to "ReportableResults".
|
||||
|
||||
Reportable Object List - The objects that need to be reported. This can
|
||||
either be a single ReportableType object or a list
|
||||
of these objects.
|
||||
|
||||
Write To Database - A boolean flag, if true an entry will be written to the
|
||||
database. Generally a value of false is passed when
|
||||
testing this MLM from the editor.
|
||||
|
||||
The reportable Object list will contain objects defined by this structure:
|
||||
|
||||
ReportableType := OBJECT
|
||||
[
|
||||
ParentKey, // Document, Order or Visit GUID (Single)
|
||||
ChildKeys, // Observation, Result or HealthIssue GUID (Single, list or NULL)
|
||||
ObjectType, // "result", "observation", "healthissue", "visit", "subject", "notification", "messageprofileid"
|
||||
Reason
|
||||
];
|
||||
|
||||
This object must be defined in the calling MLM and populated based on the
|
||||
business rules of that MLM.
|
||||
|
||||
ParentKey - This is the GUID for an Order or Document that is the parent
|
||||
for the childKeys. An order will have Result children while
|
||||
a Document will have Observation children.
|
||||
ChildKeys - This property contains either Result or Observation GUIDs
|
||||
depending on the type of the ParentKey. It can contain
|
||||
either a single GUID or list of GUIDs. If a list the GUIDs
|
||||
are all assumed to be of the same type.
|
||||
If NULL, the code will assume that all result items are to
|
||||
be included. A tag in the outgoing message is set so that
|
||||
it is not necessary to actually retrieve all the GUIDs.
|
||||
ObjectType - If the Parent object is a Document then this value must be
|
||||
"observation". If the parent object is an Order then this
|
||||
value must be "result".
|
||||
Reason - This is a coded value that can be included into the parent element.
|
||||
For reportable results this will be the diagnostic code:
|
||||
<Code>^<Description>^<Code Type>
|
||||
413.9^Angina^ICD9
|
||||
For Bio Surveillance messages the reason code is only required for
|
||||
the visit object and is the HL7 message type.
|
||||
|
||||
;;
|
||||
keywords: Biosurveillance
|
||||
;;
|
||||
knowledge:
|
||||
type: data-driven;;
|
||||
data:
|
||||
|
||||
( MsgQueueType,
|
||||
ReportableObjectList, // Single item or list
|
||||
writeToDatabase
|
||||
) := ARGUMENT;
|
||||
|
||||
log_execution_info := false;
|
||||
|
||||
// Set default values
|
||||
parentKeyType := "Order";
|
||||
childKeyType := "Result";
|
||||
parentKeyAttrib := "Results";
|
||||
xmlDoc := null;
|
||||
returnStatus := false;
|
||||
errorMessage := "";
|
||||
fatal_error := false;
|
||||
|
||||
if (writeToDatabase is NULL) then
|
||||
writeToDatabase := true;
|
||||
endif;
|
||||
|
||||
|
||||
// Sanity check on MsgQueueType, defaults to ReportableResult
|
||||
// If all else fails
|
||||
if ( MsgQueueType is not NULL ) then
|
||||
if ( MsgQueueType is not number ) then
|
||||
if ( MsgQueueType = "BioSurveillance" ) then MsgQueueType := 1;
|
||||
elseif ( MsgQueueType = "ReportableResult" ) then MsgQueueType := 0;
|
||||
elseif ( MsgQueueType = "CaseNotification" ) then MsgQueueType := 2;
|
||||
elseif ( MsgQueueType = "SendLabResults" ) then MsgQueueType := 3;
|
||||
else MsgQueueType := 0;
|
||||
endif;
|
||||
endif;
|
||||
else
|
||||
MsgQueueType := 0;
|
||||
endif;
|
||||
|
||||
if ( MsgQueueType is 2 ) then
|
||||
error_message := "Invalid MsgQueueType value - CaseNotification no longer supported";
|
||||
fatal_error := true;
|
||||
endif;
|
||||
|
||||
if not fatal_error then
|
||||
userID := read last { UserInfo: IDCode };
|
||||
|
||||
// If not a list, turn it into one.
|
||||
if (not ReportableObjectList is list) then
|
||||
ReportableObjectList := ,ReportableObjectList;
|
||||
endif;
|
||||
|
||||
// Make sure there is at least one reportable
|
||||
// object.
|
||||
if exists ReportableObjectList
|
||||
then
|
||||
// Build Xml
|
||||
xmlDoc := "";
|
||||
|
||||
for obj in ReportableObjectList do
|
||||
|
||||
if ( obj.ParentKey is not NULL ) then
|
||||
if ( obj.ObjectType = "result") then
|
||||
parentKeyType := "Order";
|
||||
parentKeyAttrib := "Results";
|
||||
childKeyType := "Result";
|
||||
elseif ( obj.ObjectType = "observation") then
|
||||
parentKeyType := "Document";
|
||||
parentKeyAttrib := "ObsItems";
|
||||
childKeyType := "ObsItem";
|
||||
elseif (obj.ObjectType = "healthissue") then
|
||||
parentKeyType := "HealthIssue";
|
||||
parentKeyAttrib := "Diagnosis";
|
||||
childKeyType := "DG1";
|
||||
elseif (obj.ObjectType = "procedure") then
|
||||
parentKeyType := "HealthIssue";
|
||||
parentKeyAttrib := "Diagnosis";
|
||||
childKeyType := "PR1";
|
||||
elseif (obj.ObjectType = "visit") then
|
||||
parentKeyType := "Visit";
|
||||
parentKeyAttrib := null;
|
||||
childKeyType := null;
|
||||
elseif (obj.ObjectType = "subject") then
|
||||
parentKeyType := "Subject";
|
||||
parentKeyAttrib := null;
|
||||
childKeyType := null;
|
||||
elseif (obj.ObjectType = "notification") then
|
||||
parentKeyType := "Notification";
|
||||
parentKeyAttrib := null;
|
||||
childKeyType := null;
|
||||
elseif (obj.ObjectType = "messageprofileid") then
|
||||
parentKeyType := "MessageProfileId";
|
||||
parentKeyAttrib := null;
|
||||
childKeyType := null;
|
||||
elseif (obj.ObjectType = "resultstatus") then
|
||||
parentKeyType := "ResultStatus";
|
||||
parentKeyAttrib := null;
|
||||
childKeyType := null;
|
||||
else
|
||||
parentKeyType := obj.ObjectType;
|
||||
parentKeyAttrib := null;
|
||||
childKeyType := null;
|
||||
endif;
|
||||
|
||||
xmlDoc := xmlDoc || "<" || parentKeyType || " Key={{{SINGLE-QUOTE}}}" || obj.ParentKey || "{{{SINGLE-QUOTE}}}";
|
||||
|
||||
if ( obj.Reason is Not NULL ) then
|
||||
if ( obj.ObjectType = "visit") then
|
||||
xmlDoc := xmlDoc || " Event={{{SINGLE-QUOTE}}}" || xml(obj.Reason) ||"{{{SINGLE-QUOTE}}} ";
|
||||
elseif ( obj.ObjectType in( "subject", "notification", "resultstatus" ) ) then
|
||||
xmlDoc := xmlDoc || " Type={{{SINGLE-QUOTE}}}" || xml(obj.Reason) ||"{{{SINGLE-QUOTE}}} ";
|
||||
elseif ( obj.ObjectType = "messageprofileid" ) then
|
||||
xmlDoc := xmlDoc || " ID={{{SINGLE-QUOTE}}}" || xml(obj.Reason) ||"{{{SINGLE-QUOTE}}} ";
|
||||
elseif( obj.ObjectType in("result", "observation", "healthissue") ) then
|
||||
xmlDoc := xmlDoc || " Reason={{{SINGLE-QUOTE}}}" || xml(obj.Reason) ||"{{{SINGLE-QUOTE}}} ";
|
||||
else
|
||||
xmlDoc := xmlDoc || " Value={{{SINGLE-QUOTE}}}" || xml(obj.Reason) ||"{{{SINGLE-QUOTE}}} ";
|
||||
endif;
|
||||
endif;
|
||||
|
||||
// Visit, Subject, Notification, and MessageProfileId nodes do not have any children
|
||||
if ( parentKeyAttrib is not null ) then
|
||||
if ( obj.ChildKeys is NULL ) then
|
||||
xmlDoc := xmlDoc || " " || parentKeyAttrib || "={{{SINGLE-QUOTE}}}All{{{SINGLE-QUOTE}}} >";
|
||||
else
|
||||
xmlDoc := xmlDoc || " " || parentKeyAttrib || "={{{SINGLE-QUOTE}}}Selected{{{SINGLE-QUOTE}}} >";
|
||||
if ( obj.ChildKeys is NOT list) then
|
||||
obj.ChildKeys := ,obj.ChildKeys; // If not a list make a list
|
||||
endif;
|
||||
|
||||
for child in obj.ChildKeys do
|
||||
if ( child <> "" AND child is not null ) then
|
||||
if ( (child as number) is number) then
|
||||
keyAttribute := "Key";
|
||||
else
|
||||
keyAttribute := "Type";
|
||||
endif;
|
||||
xmlDoc := xmlDoc || "<" || childKeyType || " " ||
|
||||
keyAttribute ||"={{{SINGLE-QUOTE}}}" || child || "{{{SINGLE-QUOTE}}} />";
|
||||
endif;
|
||||
enddo;
|
||||
|
||||
endif;
|
||||
else
|
||||
xmlDoc := xmlDoc || ">";
|
||||
endif;
|
||||
|
||||
xmlDoc := xmlDoc || "</" || parentKeyType || ">";
|
||||
|
||||
endif;
|
||||
enddo;
|
||||
|
||||
if ( xmlDoc <> "" ) then
|
||||
xmlDoc := "<Root>" || xmlDoc || "</Root>";
|
||||
|
||||
// Build SQL Insert logic
|
||||
if ( writeToDatabase ) then
|
||||
result := read last
|
||||
{ "execute SXAReportableInfoMsgQueueInsPr " ||
|
||||
" @ReportableInfoXml = " || SQL(xmlDoc) ||
|
||||
", @MsgQueueType = " || SQL(MsgQueueType) ||
|
||||
", @CreatedBy = " || SQL(userID) };
|
||||
|
||||
endif;
|
||||
returnStatus := true;
|
||||
endif;
|
||||
endif;
|
||||
endif;
|
||||
|
||||
;;
|
||||
priority: 50
|
||||
;;
|
||||
evoke:
|
||||
;;
|
||||
logic:
|
||||
|
||||
conclude returnStatus;
|
||||
|
||||
;;
|
||||
action:
|
||||
if ( xmlDoc = "" ) then xmlDoc := null; endif;
|
||||
|
||||
if fatal_error then
|
||||
return error_message;
|
||||
else
|
||||
return xmlDoc;
|
||||
endif;
|
||||
;;
|
||||
Urgency: 50;;
|
||||
end:
|
||||
238
MLMStripper/bin/Debug/STD/STD_FUNC_MULTUM_REFERENCES.mlm
Normal file
238
MLMStripper/bin/Debug/STD/STD_FUNC_MULTUM_REFERENCES.mlm
Normal file
@@ -0,0 +1,238 @@
|
||||
maintenance:
|
||||
|
||||
title: Retrieve Multum References;;
|
||||
mlmname: STD_FUNC_MULTUM_REFERENCES;;
|
||||
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: This MLM is used to retrieve references from the MULTUM database and format
|
||||
then based on the Vancouver journal standard.
|
||||
;;
|
||||
explanation:
|
||||
This MLM retrieves from the Multum database all the references that are linked to the parameters
|
||||
that are passed in. The parameters used are dependent on the reference type that is being accessed.
|
||||
|
||||
render_style - Support which text formatting codes are used when creating the reference string.
|
||||
RTF - Use RTF code for any formatting that is needed.
|
||||
None - Only use CR, no other formatting is used. Calling MLM is assumed to do any formatting.
|
||||
if NULL or blank then the default will be RTF.
|
||||
|
||||
reference_type - The type of reference to retrieve from the multum database. The following types
|
||||
will be supported. "ddi", "drgint", "allrgy"
|
||||
|
||||
reference_title - A title that will be added to the top of the list of references created by a call to
|
||||
this MLM. Can be empty which indicates that no title is to be included.
|
||||
|
||||
drug_number1 - A multum drug number, only used when the reference_type is "drgint".
|
||||
|
||||
drug_number2 - A multum drug number, only used when the reference_type is "drgint".
|
||||
|
||||
conflict_textId - A conflict Id from the multum database, only used when the reference_type is "ddi".
|
||||
|
||||
|
||||
Three values are returned by this MLM.
|
||||
|
||||
outputString - This is the formatted references as a single string. If there are no references found
|
||||
this string will be null.
|
||||
|
||||
revision_date - The date the Multum database was last updated.
|
||||
|
||||
refCounter - The actual number of references returned from the multum database. If there are no references
|
||||
found this counter will be 0.
|
||||
|
||||
;;
|
||||
keywords: references, Multum
|
||||
;;
|
||||
citations:
|
||||
;;
|
||||
knowledge:
|
||||
type: data-driven;;
|
||||
data:
|
||||
|
||||
(render_style,
|
||||
reference_type,
|
||||
reference_title,
|
||||
drug_number1,
|
||||
drug_number2,
|
||||
conflict_textId,
|
||||
allergenID,
|
||||
functionId ):= ARGUMENT;
|
||||
|
||||
// Defaults
|
||||
default_render_style := "rtf";
|
||||
supported_render_styles := ("rtf", "none");
|
||||
|
||||
// ---------------------------------------------------------------------------------
|
||||
// Do not change any code below
|
||||
|
||||
if render_style is null or render_style = "" or render_style not in supported_render_styles
|
||||
then
|
||||
render_style := default_render_style;
|
||||
endif;
|
||||
|
||||
sqlCommand := "@type=" || SQL(reference_type);
|
||||
|
||||
referenceType := OBJECT [ id, author, title, journal_abbrevation, year_complete, volumn_issue, pages ];
|
||||
|
||||
// Determine which SQL parameters are needed to retrieve the data
|
||||
if reference_type = "ddi" AND conflict_textId is not null
|
||||
then
|
||||
|
||||
sqlCommand := sqlCommand || ", @conflictId=" || SQL(conflict_textId);
|
||||
|
||||
elseif reference_type = "drgint" AND drug_number1 is not null AND drug_number2 is not null
|
||||
then
|
||||
|
||||
sqlCommand := sqlCommand || ", @drugId_1=" || SQL(drug_number1) ||
|
||||
", @drugId_2=" || SQL(drug_number2);
|
||||
|
||||
elseif reference_type = "allrgy" AND allergenID is not null
|
||||
then
|
||||
sqlCommand := sqlCommand || ", @allergenID=" || SQL(allergenID);
|
||||
|
||||
elseif reference_type = "preglact" AND drug_number1 is not null
|
||||
then
|
||||
sqlCommand := sqlCommand || ", @drugId_1=" || SQL(drug_number1) || ", @functionId=" || SQL(functionId);
|
||||
|
||||
else // Invalid reference type
|
||||
sqlCommand := null;
|
||||
endif;
|
||||
|
||||
// Retrieve the data from the Multum database
|
||||
if sqlCommand is not NULL
|
||||
then
|
||||
|
||||
reference_list := read as referenceType { "exec SXACDSMultumReferenceSelPr " || sqlCommand };
|
||||
//debug_sql := "exec SXACDSMultumReferenceSelPr " || sqlCommand;
|
||||
// Get the last revision date of the Multum database, strip out time portion
|
||||
revision_date := read last { "select change_date from SXAMTdatabase_infoSYN" };
|
||||
revision_date := revision_date formatted with "%.2t";
|
||||
|
||||
endif;
|
||||
|
||||
;;
|
||||
priority: 50
|
||||
;;
|
||||
evoke:
|
||||
;;
|
||||
logic:
|
||||
|
||||
refCounter := 0;
|
||||
titleString := null;
|
||||
outputString := null;
|
||||
|
||||
if not exists reference_list
|
||||
then
|
||||
conclude true;
|
||||
endif;
|
||||
|
||||
// ---------------------------------------------------------
|
||||
// Vancouver format style
|
||||
// ---------------------------------------------------------
|
||||
|
||||
if reference_title is not null and length(reference_title) > 0
|
||||
then
|
||||
if render_style = "rtf"
|
||||
then
|
||||
titleString := "{{+B}}{{+g}}" || reference_title || "{{-g}}{{-B}}\n";
|
||||
elseif render_style = "none"
|
||||
then
|
||||
titleString := reference_title || "\n";
|
||||
endif;
|
||||
endif;
|
||||
|
||||
// Build up a single reference for each row returned from Multum
|
||||
for reference in reference_list do
|
||||
singleReference := "";
|
||||
refCounter := refCounter + 1;
|
||||
|
||||
if refCounter = 1 and titleString is not null then
|
||||
outputString := titleString;
|
||||
endif;
|
||||
|
||||
// Cleanup the data first
|
||||
if reference.journal_abbrevation = "O" then reference.journal_abbrevation := null; endif;
|
||||
if reference.year_complete = "0" then reference.year_complete := null; endif;
|
||||
if reference.volumn_issue = "0" then reference.volumn_issue := null; endif;
|
||||
if reference.pages = "0" then reference.pages := null; endif;
|
||||
|
||||
if reference.Author is not null and length(reference.Author) > 0
|
||||
then
|
||||
singleReference := reference.Author || ". ";
|
||||
endif;
|
||||
|
||||
// Title is never null in the Multum database
|
||||
singleReference := singleReference || reference.title || " ";
|
||||
|
||||
if reference.journal_abbrevation is not null and length(reference.journal_abbrevation) > 0
|
||||
then
|
||||
singleReference := singleReference || reference.journal_abbrevation || " ";
|
||||
endif;
|
||||
|
||||
if reference.year_complete is not null and length(reference.year_complete) > 0
|
||||
then
|
||||
singleReference := singleReference || reference.year_complete || "; ";
|
||||
endif;
|
||||
|
||||
if reference.volumn_issue is not null and length(reference.volumn_issue) > 0
|
||||
then
|
||||
singleReference := singleReference || reference.volumn_issue || ": ";
|
||||
endif;
|
||||
|
||||
if reference.pages is not null and length(reference.pages) > 0
|
||||
then
|
||||
singleReference := singleReference || reference.pages || ". ";
|
||||
endif;
|
||||
|
||||
if render_style is in ("rtf", "none")
|
||||
then
|
||||
singleReference := singleReference || "\n\n"; // double spacing between references
|
||||
endif;
|
||||
|
||||
// Build up the final reference string
|
||||
if outputString is null
|
||||
then
|
||||
outputString := refCounter || ". " ||singleReference;
|
||||
else
|
||||
outputString := outputString || refCounter || ". " || singleReference;
|
||||
endif;
|
||||
|
||||
enddo;
|
||||
|
||||
if outputString is not null
|
||||
then
|
||||
if render_style is in ("rtf", "none")
|
||||
then
|
||||
outputString := outputString || "\n";
|
||||
endif;
|
||||
endif;
|
||||
|
||||
conclude true;
|
||||
;;
|
||||
action:
|
||||
|
||||
return outputString, revision_date, refCounter;
|
||||
;;
|
||||
Urgency: 50;;
|
||||
end:
|
||||
179
MLMStripper/bin/Debug/STD/STD_FUNC_ORDER_SET_DUP_MESSAGES.mlm
Normal file
179
MLMStripper/bin/Debug/STD/STD_FUNC_ORDER_SET_DUP_MESSAGES.mlm
Normal file
@@ -0,0 +1,179 @@
|
||||
maintenance:
|
||||
|
||||
title: Alert Messages for Duplicate Order Set Checking MLM;;
|
||||
mlmname: STD_FUNC_ORDER_SET_DUP_MESSAGES;;
|
||||
arden: version 2.5;;
|
||||
version: 18.4;;
|
||||
institution: Allscripts, Standard MLM;;
|
||||
author: Allscripts Healthcare Solutions, Inc.;;
|
||||
specialist: ;;
|
||||
date: 2018-10-26;;
|
||||
validation: testing;;
|
||||
|
||||
/* P r o p r i e t a r y N o t i c e */
|
||||
/* Unpublished (c) 2013 - 2018 Allscripts Healthcare, LLC. and/or its affiliates. All Rights Reserved.
|
||||
|
||||
P r o p r i e t a r y N o t i c e: This software has been provided pursuant to a License Agreement, with
|
||||
Allscripts Healthcare, LLC. and/or its affiliates, containing restrictions on its use. This software contains
|
||||
valuable trade secrets and proprietary information of Allscripts Healthcare, LLC. and/or its affiliates and is
|
||||
protected by trade secret and copyright law. This software may not be copied or distributed in any form or medium,
|
||||
disclosed to any third parties, or used in any manner not provided for in said License Agreement except with prior
|
||||
written authorization from Allscripts Healthcare, LLC. and/or its affiliates. Notice to U.S. Government Users:
|
||||
This software is {{{SINGLE-QUOTE}}}Commercial Computer Software{{{SINGLE-QUOTE}}}.
|
||||
|
||||
All product names are the trademarks or registered trademarks of Allscripts Healthcare, LLC. and/or its affiliates.
|
||||
*/
|
||||
/* P r o p r i e t a r y N o t i c e */
|
||||
|
||||
library:
|
||||
purpose: Selects the appropriate alert message for the Duplicate Order Set
|
||||
Checking MLM{{{SINGLE-QUOTE}}}s alerts.
|
||||
;;
|
||||
explanation: The number of possible messages for the Duplicate Order Set
|
||||
Checking MLM can be large. This MLM encapsulates the messages, so that all
|
||||
changes to the messages can be done in one MLM.
|
||||
;;
|
||||
keywords: Duplicate Order Set; Alert; Message;
|
||||
;;
|
||||
knowledge:
|
||||
type: data-driven;;
|
||||
data:
|
||||
|
||||
/***************Make Changes To Spelling And Flags In This Section***************/
|
||||
/* Set to true if logging is needed.*/
|
||||
log_execution_info := false;
|
||||
|
||||
/********************************************************************************/
|
||||
|
||||
(order_set_name,
|
||||
exact_msg,
|
||||
performed_msg,
|
||||
scheduled_msg,
|
||||
exact_type,
|
||||
subset_type,
|
||||
superset_type,
|
||||
same_set_type,
|
||||
partial_match_type,
|
||||
no_std_message_type,
|
||||
matching_name_list,
|
||||
matching_start_date_list,
|
||||
matching_msg_type_list,
|
||||
matching_msg_text_list,
|
||||
matching_time_msg_list,
|
||||
matching_order_set_status_list ):= ARGUMENT;
|
||||
;;
|
||||
evoke:
|
||||
;;
|
||||
logic:
|
||||
indent_string:= " ";
|
||||
hyphen_string:= "-----";
|
||||
|
||||
/*---------------------------------*/
|
||||
/* Picks the correct alert message */
|
||||
/*---------------------------------*/
|
||||
|
||||
//Initialize variables
|
||||
long_alert_msg:= "";
|
||||
short_message := "";
|
||||
matching_short_message_list := ();
|
||||
|
||||
processing_list:= 1 seqto (count matching_name_list);
|
||||
for k in processing_list do
|
||||
/* Gets duplicate order_set information */
|
||||
dup_order_set_found:= processing_list = k;
|
||||
dup_order_set_name:= first (matching_name_list where dup_order_set_found);
|
||||
dup_order_set_start_date:= first (matching_start_date_list
|
||||
where dup_order_set_found);
|
||||
dup_order_set_msg_type:= first (matching_msg_type_list where dup_order_set_found);
|
||||
dup_order_set_msg_text:= first (matching_msg_text_list where dup_order_set_found);
|
||||
dup_order_set_time_msg:= first (matching_time_msg_list where dup_order_set_found);
|
||||
dup_order_set_type_code:= first (matching_order_set_type_code_list where dup_order_set_found);
|
||||
|
||||
/* Format date, removing milliseconds */
|
||||
if exist dup_order_set_start_date then
|
||||
dup_order_set_start_date_formatted := dup_order_set_start_date formatted with "%.4t";
|
||||
endif;
|
||||
|
||||
/* Eliminates NULLs from printing in the alert message */
|
||||
if dup_order_set_msg_text is null
|
||||
then dup_order_set_msg_text:= "";
|
||||
endif; /* if dup_order_set_msg_text is null */
|
||||
|
||||
/* Creates the beginning of the long alert message */
|
||||
long_alert_msg:= long_alert_msg
|
||||
|| dup_order_set_name || "\n"
|
||||
|| "Date: " || dup_order_set_start_date_formatted || "\n" ;
|
||||
|
||||
/* Creates the rest of the long alert message */
|
||||
If dup_order_set_msg_type = exact_type
|
||||
then
|
||||
short_message :=
|
||||
"Warning potential duplicate - a " || dup_order_set_name
|
||||
|| " has already been ordered on "
|
||||
|| dup_order_set_start_date_formatted || ". "
|
||||
|| dup_order_set_msg_text
|
||||
;
|
||||
elseif dup_order_set_msg_type = subset_type
|
||||
then
|
||||
short_message :=
|
||||
"Warning - potential duplicate - a " || dup_order_set_name
|
||||
|| " has already been ordered on "
|
||||
|| dup_order_set_start_date_formatted
|
||||
|| ". All the items of a " || order_set_name
|
||||
|| " are included in a " || dup_order_set_name || ". "
|
||||
|| dup_order_set_msg_text
|
||||
;
|
||||
elseif dup_order_set_msg_type = superset_type
|
||||
then
|
||||
short_message :=
|
||||
"Warning - potential duplicate - a " || dup_order_set_name
|
||||
|| " which includes a " || order_set_name
|
||||
|| " has already been ordered on "
|
||||
|| dup_order_set_start_date_formatted || ". "
|
||||
|| dup_order_set_msg_text
|
||||
;
|
||||
elseif dup_order_set_msg_type = partial_match_type
|
||||
then
|
||||
short_message :=
|
||||
"Warning - potential duplicate - a " || dup_order_set_name
|
||||
|| " which included most of the items in a " || order_set_name
|
||||
|| " has already been ordered on "
|
||||
|| dup_order_set_start_date_formatted || ". "
|
||||
|| dup_order_set_msg_text
|
||||
;
|
||||
elseif dup_order_set_msg_type = same_set_type
|
||||
then
|
||||
short_message :=
|
||||
"An order set for " || dup_order_set_name
|
||||
|| " which is of the same type"
|
||||
|| " as your order set for " || order_set_name
|
||||
|| " has already been ordered on "
|
||||
|| dup_order_set_start_date_formatted
|
||||
|| ". "
|
||||
|| dup_order_set_msg_text
|
||||
;
|
||||
elseif dup_order_set_msg_type = no_std_message_type
|
||||
then
|
||||
short_message :=
|
||||
dup_order_set_msg_text
|
||||
;
|
||||
else
|
||||
short_message :=
|
||||
"Error Message: Undefined Message Type for the order set."
|
||||
;
|
||||
endif; /*if dup_order_set_msg_type */
|
||||
|
||||
|
||||
//Add the Message to the lists
|
||||
matching_short_message_list := matching_short_message_list, short_message;
|
||||
long_alert_msg:= long_alert_msg ||short_message || "\n\n";
|
||||
|
||||
enddo; /* for k */
|
||||
|
||||
/* Always conclude true to return values to the calling program */
|
||||
conclude true;
|
||||
;;
|
||||
action:
|
||||
RETURN ( long_alert_msg, matching_short_message_list );
|
||||
;;
|
||||
end:
|
||||
173
MLMStripper/bin/Debug/STD/STD_FUNC_ORDER_SET_DUP_RETRIEVE.mlm
Normal file
173
MLMStripper/bin/Debug/STD/STD_FUNC_ORDER_SET_DUP_RETRIEVE.mlm
Normal file
@@ -0,0 +1,173 @@
|
||||
maintenance:
|
||||
|
||||
title: Order Retrievals for Duplicate Order Set Checking;;
|
||||
mlmname: STD_FUNC_ORDER_SET_DUP_RETRIEVE;;
|
||||
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: Retrieves the UNSUBMITTED and DATABASE order sets according to the rules
|
||||
stated in std_duplicate_order_set.mlm. Returns order information to the
|
||||
std_func_order_set_dup_rules.mlm.
|
||||
;;
|
||||
explanation: See the explanation in std_duplicate_order_set.mlm
|
||||
;;
|
||||
keywords: Duplicate Order;
|
||||
;;
|
||||
knowledge:
|
||||
type: data-driven;;
|
||||
data:
|
||||
/***************Make Changes To Spelling And Flags In This Section***************/
|
||||
/* Set to true if logging is needed.*/
|
||||
log_execution_info := false;
|
||||
|
||||
/********************************************************************************/
|
||||
|
||||
/* Arguments that are passed by the calling MLM */
|
||||
(client_guid,
|
||||
chart_guid,
|
||||
client_visit_guid,
|
||||
order_set_guid,
|
||||
order_set_name,
|
||||
order_set_scope,
|
||||
past_time,
|
||||
future_time ):= ARGUMENT;
|
||||
|
||||
/* ScopeLevel from the duplicate policy */
|
||||
/* 1 = This Visit, 2 = This Chart, 3 = All Charts */
|
||||
ScopeLevel := 0;
|
||||
If exist client_guid
|
||||
then
|
||||
/* Sets variable values to retrieve order sets from the database */
|
||||
If order_set_scope = "This Chart"
|
||||
then
|
||||
ScopeLevel := 2;
|
||||
elseif order_set_scope = "This Visit"
|
||||
then
|
||||
ScopeLevel := 1;
|
||||
else
|
||||
ScopeLevel := 3;
|
||||
endif; /* order_set_scope */
|
||||
|
||||
/*----------------------------------*/
|
||||
/* Gets the UNSUBMITTED ORDER SETS */
|
||||
/*----------------------------------*/
|
||||
(unsub_order_set_name_list,
|
||||
unsub_order_set_guid_list,
|
||||
unsub_start_date_list,
|
||||
unsub_order_set_type_code_list,
|
||||
unsub_master_GUID_list,
|
||||
unsub_this_list ):= read
|
||||
{Unsubmitted OrderSet:
|
||||
OrderSetName, GUID, StartDtm,
|
||||
OrderSetType, OrderCatalogSetGUID, THIS
|
||||
WHERE StartDtm >= past_time
|
||||
AND StartDtm <= future_time
|
||||
AND ParentOrderSetGUID IS NULL
|
||||
AND GUID <> order_set_guid
|
||||
};
|
||||
|
||||
|
||||
/*------------------------------*/
|
||||
/* Gets the DATABASE ORDER SETS */
|
||||
/*------------------------------*/
|
||||
(db_order_set_name_list,
|
||||
db_order_set_guid_list,
|
||||
db_start_date_list,
|
||||
db_order_set_type_code_list,
|
||||
db_master_GUID_list ):= read
|
||||
{ "EXEC SCMDuplicateOrderSetCheckingPR "
|
||||
|| SQLEX(order_set_guid) || " ,"
|
||||
|| SQLEX(client_guid) || " ,"
|
||||
|| SQLEX(chart_guid) || " ,"
|
||||
|| SQLEX(client_visit_guid) || " ,"
|
||||
|| SQLEX(past_time) || " ,"
|
||||
|| SQLEX(future_time)|| " ,"
|
||||
|| SQLEX(ScopeLevel)
|
||||
, PrimaryTime = StartDtm};
|
||||
endif; /* If exist client_guid */
|
||||
;;
|
||||
evoke:
|
||||
;;
|
||||
logic:
|
||||
If NOT exist db_order_set_name_list
|
||||
AND NOT exist unsub_order_set_name_list
|
||||
then conclude false;
|
||||
endif;
|
||||
|
||||
/*-----------------------*/
|
||||
/* Initializes Variables */
|
||||
/*-----------------------*/
|
||||
order_set_name_list:= ();
|
||||
order_set_guid_list:= ();
|
||||
start_date_list:= ();
|
||||
order_set_type_code_list:= ();
|
||||
master_GUID_list:= ();
|
||||
|
||||
|
||||
/*-----------------------------------------------------------------*/
|
||||
/* Combines information on "unsubmitted" and "database" order sets */
|
||||
/*-----------------------------------------------------------------*/
|
||||
/*--------------------------------*/
|
||||
/* Process UNSUBMITTED order sets */
|
||||
/*--------------------------------*/
|
||||
If exist unsub_master_guid_list
|
||||
then
|
||||
/* Add the UNSUBMITTED order sets onto the lists for processing */
|
||||
order_set_name_list:= order_set_name_list, unsub_order_set_name_list ;
|
||||
order_set_guid_list:= order_set_guid_list, unsub_order_set_guid_list ;
|
||||
start_date_list:= start_date_list, unsub_start_date_list ;
|
||||
order_set_type_code_list:= order_set_type_code_list, unsub_order_set_type_code_list ;
|
||||
master_GUID_list:= master_GUID_list, unsub_master_GUID_list ;
|
||||
endif; /* if (exist unsub_master_guid_list) */
|
||||
|
||||
|
||||
/*-----------------------------*/
|
||||
/* Process DATABASE order sets */
|
||||
/*-----------------------------*/
|
||||
If exist db_master_guid_list
|
||||
then
|
||||
/* Add the order_sets retrieved from the database onto the lists for processing */
|
||||
order_set_name_list:= order_set_name_list, db_order_set_name_list ;
|
||||
order_set_guid_list:= order_set_guid_list, db_order_set_guid_list ;
|
||||
start_date_list:= start_date_list, db_start_date_list ;
|
||||
order_set_type_code_list:= order_set_type_code_list, db_order_set_type_code_list ;
|
||||
master_GUID_list:= master_GUID_list, db_master_GUID_list ;
|
||||
endif; /* if (exist db_master_guid_list)or... */
|
||||
|
||||
|
||||
/*--------------------------------------------------------*/
|
||||
/* Conclude True to Return Information to the Calling MLM */
|
||||
/*--------------------------------------------------------*/
|
||||
conclude true;
|
||||
;;
|
||||
action:
|
||||
|
||||
Return ( order_set_name_list,
|
||||
order_set_guid_list,
|
||||
start_date_list,
|
||||
order_set_type_code_list,
|
||||
master_GUID_list
|
||||
);
|
||||
;;
|
||||
end:
|
||||
328
MLMStripper/bin/Debug/STD/STD_FUNC_ORDER_SET_DUP_RULES.mlm
Normal file
328
MLMStripper/bin/Debug/STD/STD_FUNC_ORDER_SET_DUP_RULES.mlm
Normal file
@@ -0,0 +1,328 @@
|
||||
maintenance:
|
||||
|
||||
title: Rules for Duplicate Order Set Checking;;
|
||||
mlmname: STD_FUNC_ORDER_SET_DUP_RULES;;
|
||||
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: Process the orders according to the rules stated in std_duplicate_order_set.mlm.
|
||||
Returns information on the duplicate orders to std_duplicate_order_set.mlm.
|
||||
;;
|
||||
explanation: See the explanation in std_duplicate_order_set.mlm
|
||||
;;
|
||||
keywords: Duplicate Order Set;
|
||||
;;
|
||||
knowledge:
|
||||
type: data-driven;;
|
||||
data:
|
||||
|
||||
/***************Make Changes To Spelling And Flags In This Section***************/
|
||||
/* Set to true if logging is needed.*/
|
||||
log_execution_info := false;
|
||||
|
||||
/********************************************************************************/
|
||||
|
||||
/* Do Not Changes these Internal MLM Variables */
|
||||
exact_msg:= "exact";
|
||||
performed_msg:= "performed";
|
||||
scheduled_msg:= "scheduled";
|
||||
exact_type:= "exact";
|
||||
subset_type:= "subset";
|
||||
superset_type:= "superset";
|
||||
same_set_type:= "same set type";
|
||||
partial_match_type:= "partial match";
|
||||
no_std_message_type:= "no std message";
|
||||
|
||||
/*==============================================================================*/
|
||||
|
||||
(order_set_name,
|
||||
order_set_guid,
|
||||
order_set_catalog_guid,
|
||||
chart_guid,
|
||||
client_visit_guid,
|
||||
order_set_start_date,
|
||||
patient_loc_group):= ARGUMENT;
|
||||
|
||||
|
||||
/* Declares MLMs which can be called */
|
||||
calc_duration:= MLM {{{SINGLE-QUOTE}}}std_func_dup_duration{{{SINGLE-QUOTE}}};
|
||||
get_order_sets:= MLM {{{SINGLE-QUOTE}}}std_func_order_set_dup_retrieve{{{SINGLE-QUOTE}}};
|
||||
|
||||
/* Gets the Client GUID */
|
||||
client_guid := read last {ClientInfo: GUID};
|
||||
|
||||
/* Gets the evoking order set{{{SINGLE-QUOTE}}}s Catalog information */
|
||||
(catalog_name,
|
||||
duplicate_policy_guid ):= read last
|
||||
{"SELECT Name, DuplicatePolicyGUID "
|
||||
|| " FROM CV3OrderCatalogSet "
|
||||
|| " WHERE GUID = " || SQL(order_set_catalog_guid)
|
||||
|| " AND Active = 1 "};
|
||||
|
||||
/* Continue if "check for duplicates" is marked in the Item-Catalog */
|
||||
If exist duplicate_policy_guid
|
||||
then
|
||||
/* Gets evoking order set{{{SINGLE-QUOTE}}}s duplicate policy information */
|
||||
(order_set_loc_group_guid_list,
|
||||
order_set_scope_list,
|
||||
order_set_performed_time_list,
|
||||
order_set_performed_unit_list,
|
||||
order_set_exact_time_list,
|
||||
order_set_exact_unit_list,
|
||||
order_set_scheduled_time_list,
|
||||
order_set_scheduled_unit_list,
|
||||
loc_is_excluded_list) := read
|
||||
{"SELECT LocationGroupGUID, SearchScope, PastTime, PastTimeUnits,"
|
||||
|| " ExactTime, ExactTimeUnits, FutureTime, FutureTimeUnits, IsExcluded"
|
||||
|| " FROM CV3OrderDuplicatePolicyDtl "
|
||||
|| " WHERE OrderDuplicatePolicyGUID = " || SQL(duplicate_policy_guid)
|
||||
|| " AND LocationGroupGUID IN (0, " || SQL(patient_loc_group)|| " )"
|
||||
|| " AND Active = 1 "};
|
||||
|
||||
/* Matches patient{{{SINGLE-QUOTE}}}s location group to the item-catalog{{{SINGLE-QUOTE}}}s location group and */
|
||||
/* Determines if the match excludes the location from duplicate checking */
|
||||
If exist order_set_scope_list
|
||||
then
|
||||
If any (patient_loc_group = order_set_loc_group_guid_list)
|
||||
then
|
||||
loc_group_found := patient_loc_group = order_set_loc_group_guid_list;
|
||||
else
|
||||
loc_group_found := order_set_loc_group_guid_list is null;
|
||||
endif;
|
||||
loc_is_excluded := last (loc_is_excluded_list where loc_group_found);
|
||||
endif; /* if exist order_set_loc_group_guid_list */
|
||||
|
||||
|
||||
/* Continue if there is a location group match or a default location group */
|
||||
/* and the location is not excluded from duplicate checking */
|
||||
If any loc_group_found and not loc_is_excluded
|
||||
then
|
||||
/*--------------------------------------------------*/
|
||||
/* Finds the scope and times for the location group */
|
||||
/*--------------------------------------------------*/
|
||||
order_set_loc_grp:= last (order_set_loc_group_guid_list where loc_group_found);
|
||||
order_set_scope:= last (order_set_scope_list where loc_group_found);
|
||||
order_set_performed_time:= last (order_set_performed_time_list where loc_group_found);
|
||||
order_set_performed_unit:= last (order_set_performed_unit_list where loc_group_found);
|
||||
order_set_exact_time:= last (order_set_exact_time_list where loc_group_found);
|
||||
order_set_exact_unit:= last (order_set_exact_unit_list where loc_group_found);
|
||||
order_set_scheduled_time:= last (order_set_scheduled_time_list where loc_group_found);
|
||||
order_set_scheduled_unit:= last (order_set_scheduled_unit_list where loc_group_found);
|
||||
|
||||
|
||||
/*-------------------------------------*/
|
||||
/* Converts EXACT TIME into Arden Time */
|
||||
/*-------------------------------------*/
|
||||
If order_set_exact_time > 0 and order_set_exact_unit is string
|
||||
then
|
||||
exact_duration:= call calc_duration with
|
||||
(order_set_exact_time, order_set_exact_unit);
|
||||
If order_set_exact_unit = "days"
|
||||
then exact_low_time:= (day floor of order_set_start_date)
|
||||
- exact_duration ;
|
||||
exact_high_time:= (day floor of order_set_start_date)
|
||||
+ exact_duration + (1 day) - (1 second);
|
||||
else exact_low_time:= order_set_start_date - exact_duration;
|
||||
exact_high_time:= order_set_start_date + exact_duration;
|
||||
endif; /* if order_set_exact_unit = */
|
||||
else
|
||||
exact_low_time:= order_set_start_date;
|
||||
exact_high_time:= order_set_start_date;
|
||||
endif; /* if order_set_exact_time > 0 ...*/
|
||||
|
||||
/*-----------------------------------------*/
|
||||
/* Converts PERFORMED TIME into Arden Time */
|
||||
/*-----------------------------------------*/
|
||||
If order_set_performed_time > 0 and order_set_performed_unit is string
|
||||
then
|
||||
performed_duration:= call calc_duration with
|
||||
(order_set_performed_time, order_set_performed_unit);
|
||||
If order_set_performed_unit = "days"
|
||||
then past_time:= (day floor of order_set_start_date)
|
||||
- performed_duration;
|
||||
else past_time:= order_set_start_date - performed_duration;
|
||||
endif; /* if order_set_performed_unit = */
|
||||
else
|
||||
past_time:= exact_low_time;
|
||||
endif; /* if order_set_performed_time > 0 ...*/
|
||||
|
||||
/*-----------------------------------------*/
|
||||
/* Converts SCHEDULED TIME into Arden Time */
|
||||
/*-----------------------------------------*/
|
||||
If order_set_scheduled_time > 0 and order_set_scheduled_unit is string
|
||||
then
|
||||
scheduled_duration:= call calc_duration with
|
||||
(order_set_scheduled_time, order_set_scheduled_unit);
|
||||
If order_set_scheduled_unit = "days"
|
||||
then future_time:= (day floor of order_set_start_date)
|
||||
+ scheduled_duration + (1 day) - (1 second);
|
||||
else future_time:= order_set_start_date + scheduled_duration;
|
||||
endif; /* if order_set_scheduled_unit = */
|
||||
else
|
||||
future_time:= exact_high_time;
|
||||
endif; /* if order_set_scheduled_time > 0 ...*/
|
||||
|
||||
|
||||
/* Gets the evoking order set{{{SINGLE-QUOTE}}}s list of duplicate sets */
|
||||
/* in the Order Set Catalog */
|
||||
(cat_dup_item_name_list,
|
||||
cat_dup_item_guid_list,
|
||||
cat_message_type_list,
|
||||
cat_message_list) := read
|
||||
{"SELECT DuplicateSetName, DuplicateSetGUID, "
|
||||
|| " MessageType, MessageText "
|
||||
|| " FROM CV3CatalogSetDuplicate "
|
||||
|| " WHERE OrderCatalogSetGUID = " || SQL(order_set_catalog_guid)
|
||||
|| " AND Active = 1 "};
|
||||
|
||||
/*--------------------------------------------------------------------------*/
|
||||
/* Retrieve the order sets from the DATABASE and the UNSUBMITTED order sets */
|
||||
/*--------------------------------------------------------------------------*/
|
||||
(order_set_name_list,
|
||||
order_set_guid_list,
|
||||
start_date_list,
|
||||
order_set_type_code_list,
|
||||
master_GUID_list ):= call get_order_sets with
|
||||
(client_guid,
|
||||
chart_guid,
|
||||
client_visit_guid,
|
||||
order_set_guid,
|
||||
order_set_name,
|
||||
order_set_scope,
|
||||
past_time,
|
||||
future_time );
|
||||
|
||||
endif; /* if any loc_group_found and not loc_is_excluded */
|
||||
endif; /* if exist duplicate_policy_guid */
|
||||
;;
|
||||
evoke:
|
||||
;;
|
||||
logic:
|
||||
If NOT exist duplicate_policy_guid
|
||||
OR NOT (any loc_group_found)
|
||||
OR loc_is_excluded
|
||||
then conclude false;
|
||||
endif;
|
||||
|
||||
/*-----------------------*/
|
||||
/* Initializes Variables */
|
||||
/*-----------------------*/
|
||||
matching_guid_list:= ();
|
||||
matching_name_list:= ();
|
||||
matching_order_set_guid_list:= ();
|
||||
matching_start_date_list:= ();
|
||||
matching_msg_type_list:= ();
|
||||
matching_msg_text_list:= ();
|
||||
matching_time_msg_list:= ();
|
||||
matching_order_set_type_code_list:= ();
|
||||
dup_item_guid_list:= cat_dup_item_guid_list;
|
||||
message_type_list:= cat_message_type_list;
|
||||
message_list:= cat_message_list;
|
||||
|
||||
/*-------------------------------------------------------------------*/
|
||||
/* Adds extra information to DUP_ITEM_GUID_LIST and associated lists */
|
||||
/*-------------------------------------------------------------------*/
|
||||
|
||||
/* Adds the evoking object{{{SINGLE-QUOTE}}}s OrderCatalogMasterItemGUID and other data, */
|
||||
/* if the list of items from item-catalog--duplicate checking panel does not include it */
|
||||
If (order_set_catalog_guid is not in dup_item_guid_list)
|
||||
and (order_set_catalog_guid is in master_guid_list)
|
||||
then
|
||||
dup_item_guid_list:= order_set_catalog_guid, dup_item_guid_list;
|
||||
message_type_list:= exact_type, message_type_list;
|
||||
message_list:= null, message_list;
|
||||
endif; /* if order_set_catalog_guid is not in... */
|
||||
|
||||
|
||||
/*------------------------------------------------*/
|
||||
/* Finds all possible duplicates among the ITEMS */
|
||||
/*------------------------------------------------*/
|
||||
|
||||
If any(dup_item_guid_list is in master_guid_list)
|
||||
then
|
||||
for item_master_guid in dup_item_guid_list do
|
||||
master_guid_found:= item_master_guid = master_guid_list;
|
||||
temp_guid:= master_guid_list where master_guid_found;
|
||||
temp_name:= order_set_name_list where master_guid_found;
|
||||
temp_order_set_guid:= order_set_guid_list where master_guid_found;
|
||||
temp_start_date:= start_date_list where master_guid_found;
|
||||
temp_type_code:= order_set_type_code_list where master_guid_found;
|
||||
matching_guid_list:= matching_guid_list, temp_guid;
|
||||
matching_name_list:= matching_name_list, temp_name;
|
||||
matching_order_set_guid_list:= matching_order_set_guid_list, temp_order_set_guid;
|
||||
matching_start_date_list:= matching_start_date_list, temp_start_date;
|
||||
matching_order_set_type_code_list:= matching_order_set_type_code_list, temp_type_code;
|
||||
|
||||
|
||||
/* Find associated message type and message text */
|
||||
For K in temp_guid do
|
||||
item_guid_found:= dup_item_guid_list = K;
|
||||
temp_msg_type:= first(message_type_list where item_guid_found);
|
||||
temp_msg_text:= first(message_list where item_guid_found);
|
||||
matching_msg_type_list:= matching_msg_type_list, temp_msg_type;
|
||||
matching_msg_text_list:= matching_msg_text_list, temp_msg_text;
|
||||
|
||||
/* Set the time messages */
|
||||
order_set_time:= time of K;
|
||||
relative_date:= now;
|
||||
|
||||
If order_set_time >= exact_low_time AND order_set_time <= exact_high_time
|
||||
then correct_msg:= exact_msg;
|
||||
elseif order_set_time < relative_date
|
||||
then correct_msg:= performed_msg;
|
||||
elseif order_set_time > relative_date
|
||||
then correct_msg:= scheduled_msg;
|
||||
else correct_msg:= null;
|
||||
endif; /* if order_set_time */
|
||||
matching_time_msg_list:= matching_time_msg_list, correct_msg;
|
||||
enddo; /* for K */
|
||||
enddo; /* for item_master_guid...*/
|
||||
endif; /* if any(dup_item_guid_list...*/
|
||||
|
||||
|
||||
/*--------------------------------------------------*/
|
||||
/* Concludes True To Return Data To The Calling MLM */
|
||||
/*--------------------------------------------------*/
|
||||
conclude true;
|
||||
|
||||
;;
|
||||
action:
|
||||
return( exact_msg,
|
||||
performed_msg,
|
||||
scheduled_msg,
|
||||
exact_type,
|
||||
subset_type,
|
||||
superset_type,
|
||||
same_set_type,
|
||||
partial_match_type,
|
||||
no_std_message_type,
|
||||
matching_name_list,
|
||||
matching_order_set_guid_list,
|
||||
matching_start_date_list,
|
||||
matching_msg_type_list,
|
||||
matching_msg_text_list,
|
||||
matching_time_msg_list,
|
||||
matching_order_set_type_code_list );
|
||||
;;
|
||||
end:
|
||||
162
MLMStripper/bin/Debug/STD/STD_FUNC_RETRIEVE_MATCHING_RESULTS.mlm
Normal file
162
MLMStripper/bin/Debug/STD/STD_FUNC_RETRIEVE_MATCHING_RESULTS.mlm
Normal file
@@ -0,0 +1,162 @@
|
||||
maintenance:
|
||||
|
||||
title: Results retrieved for matching result name within a given interval;;
|
||||
mlmname: STD_FUNC_RETRIEVE_MATCHING_RESULTS;;
|
||||
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: Retrieves a list of valid numeric results to return to the calling MLM.
|
||||
Note, values such as "specimen hemolyzed", ">500", or "2+" are not
|
||||
considered valid numeric results.
|
||||
;;
|
||||
explanation: This MLM processes information received to return matching results
|
||||
from the database or the current result returned via HL7.
|
||||
The retrieval is performed based on a SQL query or a pointer to the object.
|
||||
If a pointer is sent in from the calling MLM, an object query for the
|
||||
current result is performed. If a pointer is not sent, then a SQL query is
|
||||
performed based on the chart guid, visit guid, present time and past interval.
|
||||
This information is sent by the calling MLM in the following parameters:
|
||||
- client guid used for SQL search
|
||||
- chart guid used for SQL search,
|
||||
- visit guid used for SQL search
|
||||
- start range for SQL search
|
||||
- end range for SQL search
|
||||
- result name string used for SQL query OR pointer used for Object
|
||||
- result scope whether all charts, this visit or this chart
|
||||
|
||||
This MLM returns lists of result information that contain:
|
||||
- the result guid,
|
||||
- chart guid for that result,
|
||||
- visit guid for that result,
|
||||
- the result name,
|
||||
- the performed date and time for the result,
|
||||
- any text for the result,
|
||||
- the unit of measure for the result,
|
||||
- the result value as a string,
|
||||
- the most recent result found in the database as a number,
|
||||
- the current result as just received via HL7 as a number;
|
||||
|
||||
;;
|
||||
keywords:
|
||||
;;
|
||||
knowledge:
|
||||
type: data-driven;;
|
||||
data:
|
||||
(client_guid, // Client guid used for SQL search
|
||||
chart_guid, // Chart guid used for SQL search,
|
||||
client_visit_guid, // Visit guid used for SQL search
|
||||
present_time, // End range for SQL search, could be the last PerformedDtm
|
||||
past_time, // Start range for SQL search, could be the first PerformedDtm
|
||||
result_info, // String used for SQL query (result item name) or pointer used for Object
|
||||
result_scope, // Indicator to check all visits, this visit, or this chart.
|
||||
include_community // Indicator to include community results. Only applicable to "All" scope
|
||||
)
|
||||
:= ARGUMENT;
|
||||
|
||||
if exists include_community then
|
||||
local_include_community := include_community;
|
||||
else
|
||||
local_include_community := FALSE;
|
||||
endif;
|
||||
|
||||
if result_info is string
|
||||
then
|
||||
// Get result data from database using SQL
|
||||
(result_guid,
|
||||
result_name,
|
||||
result_dtm,
|
||||
result_str,
|
||||
result_uom,
|
||||
result_value_str,
|
||||
result_community_source) := read
|
||||
{ "Execute CV3ResultsForCDSMatchingFnSelPr "
|
||||
|| " @ClientGUID = " || SQL(client_guid)
|
||||
|| ", @ChartGUID = " || SQL(chart_guid)
|
||||
|| ", @ClientvisitGUID = " || SQL(client_visit_guid)
|
||||
|| ", @Scope= " || sql(result_scope)
|
||||
|| ", @PerformedDtmFrom = " || sql(past_time)
|
||||
|| ", @ItemName = " || sql(result_info) ||", @IncludeCmty = " || sql(local_include_community),
|
||||
PrimaryTime = PerformedDtm};
|
||||
|
||||
// Convert result values in string to number
|
||||
converted_results := result_value_str as number;
|
||||
|
||||
// Set found index to positions where valid numeric result is found
|
||||
found_valid_result := converted_results is number;
|
||||
|
||||
// Set lists to inlcude data for only valid numeric results
|
||||
result_guid := result_guid where found_valid_result;
|
||||
result_name := result_name where found_valid_result;
|
||||
result_dtm := result_dtm where found_valid_result;
|
||||
result_str := result_str where found_valid_result;
|
||||
result_uom := result_uom where found_valid_result;
|
||||
result_value_str := result_value_str where found_valid_result;
|
||||
result_community_source := result_community_source where found_valid_result;
|
||||
|
||||
// Set most recent result;
|
||||
recent_last_result := last(result_value_str) as number;
|
||||
|
||||
elseif exist result_info
|
||||
then
|
||||
// Get result information from the object
|
||||
(result_guid,
|
||||
result_chart_guid,
|
||||
result_visit_guid,
|
||||
result_name,
|
||||
result_dtm,
|
||||
result_str,
|
||||
result_uom,
|
||||
result_value_str) := read last
|
||||
{Observation: GUID, ChartGUID, ClientVisitGUID, Itemname,
|
||||
PerformedDtm, Text, UnitOfMeasure, Value
|
||||
REFERENCING result_info};
|
||||
|
||||
// Convert current result value in string to number
|
||||
current_result := result_value_str as number;
|
||||
|
||||
endif;
|
||||
;;
|
||||
evoke:
|
||||
;;
|
||||
logic:
|
||||
if exist result_info
|
||||
then conclude TRUE;
|
||||
else conclude FALSE;
|
||||
endif;
|
||||
;;
|
||||
action:
|
||||
return
|
||||
result_guid,
|
||||
result_chart_guid,
|
||||
result_visit_guid,
|
||||
result_name,
|
||||
result_dtm,
|
||||
result_str,
|
||||
result_uom,
|
||||
result_value_str,
|
||||
recent_last_result,
|
||||
current_result,
|
||||
result_community_source;
|
||||
;;
|
||||
end:
|
||||
752
MLMStripper/bin/Debug/STD/STD_FUNC_RETRIEVE_MEDICATIONS.mlm
Normal file
752
MLMStripper/bin/Debug/STD/STD_FUNC_RETRIEVE_MEDICATIONS.mlm
Normal file
@@ -0,0 +1,752 @@
|
||||
maintenance:
|
||||
|
||||
title: Active medications retrieved with class type and value matching result;;
|
||||
mlmname: STD_FUNC_RETRIEVE_MEDICATIONS;;
|
||||
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: Retrieves a list of medications to return to the calling MLM.
|
||||
;;
|
||||
explanation: This MLM processes information received to return matching medications
|
||||
from the database or the current result returned via HL7.
|
||||
The retrieval is performed based on a SQL query or a pointer to the object.
|
||||
If a pointer is sent in from the calling MLM, an object query for the
|
||||
current order is performed.
|
||||
|
||||
If a pointer is not sent, then a SQL query is performed based on the chart
|
||||
guid, visit guid, and a list of medications or a list of class types and
|
||||
values. All active orders that match are returned.
|
||||
|
||||
If a pointer is sent, the order pointed to is compared to a list of medications
|
||||
or class types and values. If the order matches the information is returned.
|
||||
|
||||
This information is received from the calling MLM in the following parameters:
|
||||
- a STRING indicating SQL query
|
||||
OR
|
||||
- pointer to Evoking Object
|
||||
|
||||
AND
|
||||
- a list of medications to match
|
||||
OR
|
||||
- a list of class types and values to match
|
||||
|
||||
AND
|
||||
- a client guid
|
||||
AND
|
||||
- a chart guid to match
|
||||
OR
|
||||
- a visit guid to match
|
||||
|
||||
|
||||
This MLM returns lists of medication order information that contain:
|
||||
- an indicator for whether this is an order or component,
|
||||
- the chart guid of the order,
|
||||
- the client guid of the order,
|
||||
- the visit guid of the order,
|
||||
- the high dosage for the order,
|
||||
- the low dosage for the order,
|
||||
- the date and time the order was entered,
|
||||
- the form of the medication, ie, {{{SINGLE-QUOTE}}}Tablet{{{SINGLE-QUOTE}}}
|
||||
- the frequency for the order,
|
||||
- the order guid,
|
||||
- a flag for whether the order is conditional,
|
||||
- a flag for whether the order is held,
|
||||
- a flag for whether the order is prn,
|
||||
- a flag for whether the order is suspended,
|
||||
- the order name,
|
||||
- the order catalog master item guid,
|
||||
- the order priority,
|
||||
- the order route,
|
||||
- the order status code,
|
||||
- the order status description as defined by the site,
|
||||
- the order status level number,
|
||||
- the requested date and time of the order,
|
||||
- the significant date and time(requested, scheduled, or performed,
|
||||
- the stop date and time of the order,
|
||||
- the order summary line as defined by the site,
|
||||
- the associated system order priority,
|
||||
- the unit of measure for the order,
|
||||
- a flag indicating whether this order is a match;
|
||||
|
||||
;;
|
||||
keywords:
|
||||
;;
|
||||
knowledge:
|
||||
type: data-driven;;
|
||||
data:
|
||||
|
||||
(med_info, // STRING indicating SQL query or pointer to Evoking Object
|
||||
|
||||
medications_list, // Only return information on medications in this list
|
||||
// If Null, returns all active medications for scope/class
|
||||
|
||||
class_type, // Class type list used to validate against via SQL query
|
||||
// If Null, returns all active medications for scope/med list)
|
||||
|
||||
class_value, // Class value used to validate against via SQL query
|
||||
// If Null returns all active medications for scope/med list)
|
||||
|
||||
client_guid, // Chart Guid used to filter db query
|
||||
|
||||
chart_guid, // Chart Guid used to filter db query if medication_scope = Chart
|
||||
|
||||
client_visit_guid, // Visit Guid used to filter db query if medication_scope = Visit
|
||||
|
||||
medication_scope) // Indicator to check all visits, this visit, or this chart.
|
||||
:= ARGUMENT;
|
||||
|
||||
// Set to true if logging is needed.
|
||||
log_execution_info := false;
|
||||
|
||||
/* Set this flag to true to include historical session type orders
|
||||
when checking the current order */
|
||||
include_historical_session_type_orders := FALSE;
|
||||
|
||||
/* Set this flag to false to exclude discharge session type orders
|
||||
when checking the current order */
|
||||
include_discharge_session_type_orders := TRUE;
|
||||
|
||||
/* Set this flag to false to exclude standard session type orders
|
||||
when checking the current order */
|
||||
include_in_house_session_type_orders := TRUE;
|
||||
|
||||
/* Set this flag to false to exclude outpatient rx type orders
|
||||
when checking the current order */
|
||||
include_outpatient_rx_session_type_orders := TRUE;
|
||||
|
||||
/* Set this flag to false to exclude outpatient hx type orders
|
||||
when checking the current order */
|
||||
include_outpatient_hx_session_type_orders := FALSE;
|
||||
|
||||
/* Declare MLMs that can be called */
|
||||
func_session_type_filter := MLM {{{SINGLE-QUOTE}}}STD_FUNC_SESSION_TYPE_FILTER{{{SINGLE-QUOTE}}};
|
||||
|
||||
if med_info is string then
|
||||
|
||||
// Set scope for SQL search
|
||||
if medication_scope = "All" then
|
||||
scope_info := " WHERE O.ClientGUID = " || SQL(client_guid);
|
||||
|
||||
elseif medication_scope = "Chart" then
|
||||
scope_info := " WHERE O.ClientGUID = " || SQL(client_guid) ||
|
||||
" AND O.ChartGUID = " || SQL(chart_guid);
|
||||
else
|
||||
scope_info := " WHERE O.ClientGUID = " || SQL(client_guid) ||
|
||||
" AND O.ChartGUID = " || SQL(chart_guid) ||
|
||||
" AND O.ClientVisitGUID = " || SQL(client_visit_guid);
|
||||
endif; // Set scope for SQL search
|
||||
|
||||
if exist medications_list
|
||||
then
|
||||
// Set the med list into a string so it can be used in the
|
||||
// "Where" statement below to return current ORDERS
|
||||
sql_medications_list_string := "";
|
||||
counter:= 0;
|
||||
for temp_med in medications_list do
|
||||
counter:= counter + 1;
|
||||
If counter = 1
|
||||
then
|
||||
sql_medications_list_string := "(" || SQL(temp_med) || ")";
|
||||
else
|
||||
sql_medications_list_string := sql_medications_list_string || ", (" || SQL(temp_med) || ")";
|
||||
endif;
|
||||
enddo;
|
||||
|
||||
order_med_list_filter:= " AND Exists (select 1 from @Tmp T where CV3OrderComponent.Name = T.Name OR CV3Order.Name = T.Name) ";
|
||||
|
||||
component_med_list_filter:= " AND Exists (select 1 from @Tmp T where CV3OrderComponent.Name = T.Name) ";
|
||||
|
||||
elseif exist class_type and exist class_value
|
||||
then
|
||||
if exist class_value then
|
||||
|
||||
// Set the med list into a string so it can be used in the
|
||||
// "Where" statement below to return current ORDERS
|
||||
|
||||
sql_class_value_string := "";
|
||||
counter := 0;
|
||||
for temp_value in class_value do
|
||||
counter := counter + 1;
|
||||
If counter = 1
|
||||
then
|
||||
sql_class_value_string := SQL(temp_value);
|
||||
else
|
||||
sql_class_value_string := sql_class_value_string || ", " || SQL(temp_value);
|
||||
endif;
|
||||
enddo;
|
||||
|
||||
// Set up the SQL query for the order items and their components
|
||||
// that match the classes and values
|
||||
order_med_list_filter:= " AND CV3CatalogClassTypeValue.Value IN ("
|
||||
|| sql_class_value_string || " )"
|
||||
|| " AND CV3CatalogClassTypeValue.ClassTypeGUID = "
|
||||
|| "(SELECT guid from CV3ClassType where Code ="
|
||||
|| SQL(class_type)||")";
|
||||
|
||||
component_med_list_filter:= " AND CV3CatalogClassTypeValue.Value IN ("
|
||||
|| sql_class_value_string || " )"
|
||||
|| " AND CV3CatalogClassTypeValue.ClassTypeGUID = "
|
||||
|| "(SELECT guid from CV3ClassType where Code = "
|
||||
|| SQL(class_type)||")" ;
|
||||
endif;
|
||||
endif;
|
||||
|
||||
if (sql_medications_list_string is null) OR (sql_medications_list_string = "") then
|
||||
sql_insert_values_string := " ";
|
||||
else
|
||||
sql_insert_values_string := " INSERT INTO @Tmp VALUES " || sql_medications_list_string;
|
||||
endif;
|
||||
|
||||
sql_query1 := "DECLARE @Tmp TABLE (Name varchar(200) primary key) "
|
||||
|| sql_insert_values_string
|
||||
|| " SELECT an_order_or_component = {{{SINGLE-QUOTE}}}order{{{SINGLE-QUOTE}}}, O.ChartGUID, "
|
||||
|| " O.ClientGUID, O.ClientVisitGUID, "
|
||||
|| " CombinedDoseHigh = DosageHigh, CombinedDose = DosageLow, Entered, "
|
||||
|| " CombinedForm = FormCode, FrequencyCode, O.GUID, IsConditional, "
|
||||
|| " IsHeld, IsPRN, IsSuspended, CombinedName = O.Name, "
|
||||
|| " CombinedOCMItemGUID = O.OrderCatalogMasterItemGUID, "
|
||||
|| " OrderPriorityCode, CombinedRoute = OrderRouteCode, "
|
||||
|| " OrderStatusCode, CV3OrderStatus.Description, OrderStatusLevelNum, "
|
||||
|| " RequestedDtm, SignificantDtm, StopDtm, CombinedSummary = SummaryLine,"
|
||||
|| " SystemOrderPriorityCode, CombinedUOM = CV3MedicationExtension.UOM "
|
||||
|| " FROM CV3AllOrdersVw as O " || " JOIN CV3MedicationExtension "
|
||||
|| " ON O.GUID = CV3MedicationExtension.GUID "
|
||||
|| " LEFT OUTER JOIN CV3OrderComponent "
|
||||
|| " ON (O.ClientGUID = CV3OrderComponent.ClientGUID "
|
||||
|| " AND O.GUID = CV3OrderComponent.OrderGUID) "
|
||||
|| " LEFT OUTER JOIN CV3OrderAddnlInfo AS OAI "
|
||||
|| " ON ( O.ClientGUID = OAI.ClientGUID AND O.GUID = OAI.GUID ) "
|
||||
|| " JOIN CV3CatalogClassTypeValue "
|
||||
|| " ON (O.OrderCatalogMasterItemGUID = CV3CatalogClassTypeValue.CatalogMasterGUID "
|
||||
|| " OR CV3OrderComponent.OrderCatalogMasterItemGUID = CV3CatalogClassTypeValue.CatalogMasterGUID) "
|
||||
|| " JOIN CV3OrderStatus "
|
||||
|| " ON O.OrderStatusCode = CV3OrderStatus.Code"
|
||||
|| scope_info
|
||||
|| " AND O.TypeCode = {{{SINGLE-QUOTE}}}Medication{{{SINGLE-QUOTE}}} "
|
||||
|| " AND OrderStatusLevelNum <= 50 "
|
||||
|| order_med_list_filter;
|
||||
|
||||
sql_query2 := " UNION "
|
||||
|| " SELECT an_order_or_component = {{{SINGLE-QUOTE}}}component{{{SINGLE-QUOTE}}}, O.ChartGUID, "
|
||||
|| " O.ClientGUID, O.ClientVisitGUID, "
|
||||
|| " CombinedDoseHigh = NULL, CombinedDose = CV3OrderComponent.Dosage,"
|
||||
|| " Entered, CombinedForm = NULL, FrequencyCode, O.GUID, "
|
||||
|| " IsConditional, IsHeld, IsPRN, IsSuspended, "
|
||||
|| " CombinedName = CV3OrderComponent.Name,"
|
||||
|| " CombinedOCMItemGUID = CV3OrderComponent.OrderCatalogMasterItemGUID, "
|
||||
|| " OrderPriorityCode, CombinedRoute = NULL, OrderStatusCode, "
|
||||
|| " CV3OrderStatus.Description, OrderStatusLevelNum, RequestedDtm, "
|
||||
|| " SignificantDtm, StopDtm = NULL, CombinedSummary = NULL,"
|
||||
|| " SystemOrderPriorityCode, CombinedUOM = CV3OrderComponent.UOM "
|
||||
|| " FROM CV3AllOrdersVw as O " || " JOIN CV3OrderComponent "
|
||||
|| " ON (O.ClientGUID = CV3OrderComponent.ClientGUID "
|
||||
|| " AND O.GUID = CV3OrderComponent.OrderGUID ) "
|
||||
|| " LEFT OUTER JOIN CV3OrderAddnlInfo AS OAI "
|
||||
|| " ON ( O.ClientGUID = OAI.ClientGUID AND O.GUID = OAI.GUID ) "
|
||||
|| " JOIN CV3CatalogClassTypeValue "
|
||||
|| " ON CV3OrderComponent.OrderCatalogMasterItemGUID = CV3CatalogClassTypeValue.CatalogMasterGUID "
|
||||
|| " JOIN CV3OrderStatus "
|
||||
|| " ON O.OrderStatusCode = CV3OrderStatus.Code "
|
||||
|| scope_info
|
||||
|| " AND O.TypeCode = {{{SINGLE-QUOTE}}}Medication{{{SINGLE-QUOTE}}} "
|
||||
|| " AND OrderStatusLevelNum <= 50 "
|
||||
|| " AND (CV3OrderComponent.Type = 0 "
|
||||
|| " OR CV3OrderComponent.Type = 3) "
|
||||
|| component_med_list_filter;
|
||||
|
||||
if (not include_in_house_session_type_orders)
|
||||
then
|
||||
sql_query1 := sql_query1 || " AND (O.AlternateOrderType <> 0 OR O.IsForDischarge = 1) ";
|
||||
sql_query2 := sql_query2 || " AND (O.AlternateOrderType <> 0 OR O.IsForDischarge = 1) ";
|
||||
endif;
|
||||
|
||||
if (not include_historical_session_type_orders)
|
||||
then
|
||||
sql_query1 := sql_query1 || " AND O.AlternateOrderType <> 1 ";
|
||||
sql_query2 := sql_query2 || " AND O.AlternateOrderType <> 1 ";
|
||||
endif;
|
||||
|
||||
if (not include_discharge_session_type_orders)
|
||||
then
|
||||
sql_query1 := sql_query1 || " AND O.IsForDischarge = 0 ";
|
||||
sql_query2 := sql_query2 || " AND O.IsForDischarge = 0 ";
|
||||
endif;
|
||||
|
||||
if (not include_outpatient_rx_session_type_orders)
|
||||
then
|
||||
sql_query1 := sql_query1 || " AND NOT(O.AlternateOrderType = 2 AND OAI.IsScript = 1) ";
|
||||
sql_query2 := sql_query2 || " AND NOT(O.AlternateOrderType = 2 AND OAI.IsScript = 1) ";
|
||||
endif;
|
||||
|
||||
if (not include_outpatient_hx_session_type_orders)
|
||||
then
|
||||
sql_query1 := sql_query1 || " AND NOT(O.AlternateOrderType = 2 AND OAI.IsScript = 0) ";
|
||||
sql_query2 := sql_query2 || " AND NOT(O.AlternateOrderType = 2 AND OAI.IsScript = 0) ";
|
||||
endif;
|
||||
|
||||
// Get medication orders(including additives) from DB using SQL query
|
||||
(an_order_or_component,
|
||||
chart_guid,
|
||||
client_guid,
|
||||
client_visit_guid,
|
||||
dosage_high,
|
||||
dosage_low,
|
||||
entereddtm,
|
||||
form_code,
|
||||
frequency_code,
|
||||
guid,
|
||||
is_conditional,
|
||||
is_held,
|
||||
is_prn,
|
||||
is_suspend,
|
||||
name,
|
||||
order_catalog_master_item_guid,
|
||||
order_priority_code,
|
||||
order_route_code,
|
||||
order_status_code,
|
||||
order_status_desc,
|
||||
order_status_level_num,
|
||||
request_dtm,
|
||||
significant_dtm,
|
||||
stop_dtm,
|
||||
summary_line,
|
||||
system_order_priority_code,
|
||||
uom) := read { " " || sql_query1 || sql_query2 || " order by SignificantDtm, O.GUID, an_order_or_component desc, CombinedName" };
|
||||
//,PrimaryTime = SignificantDtm };
|
||||
//end - Get medication orders(including additives) from DB using SQL query
|
||||
|
||||
// Initialize variables
|
||||
match_med_found := ();
|
||||
item_class_value := ();
|
||||
|
||||
// For each item indicate whether the item or component is the match.
|
||||
|
||||
// Mark matches found for medication lists
|
||||
if exist medications_list then
|
||||
list_index := 1 seqto (count name);
|
||||
for A in list_index do
|
||||
temp_name := last(first A from name);
|
||||
if temp_name is in (medications_list) then
|
||||
match_med_found := match_med_found, TRUE;
|
||||
else
|
||||
match_med_found := match_med_found, FALSE;
|
||||
endif;
|
||||
enddo;
|
||||
|
||||
// Mark matches found for class types
|
||||
elseif exists class_type then
|
||||
list_index := 1 seqto (count name);
|
||||
for A in list_index do
|
||||
|
||||
// Get the Master GUID for this component item
|
||||
temp_ocmi_guid := last(first A from order_catalog_master_item_guid);
|
||||
temp_name := last(first A from name);
|
||||
|
||||
// Get the real class type and value for each item returned on lists
|
||||
(the_name,
|
||||
the_type,
|
||||
the_value)
|
||||
:= read
|
||||
{" SELECT Name, Code, Value "
|
||||
|| " FROM CV3OrderCatalogMasterItem LEFT OUTER JOIN CV3CatalogClassTypeValue "
|
||||
|| " ON CV3OrderCatalogMasterItem.GUID = CV3CatalogClassTypeValue.CatalogMasterGUID "
|
||||
|| " JOIN CV3ClassType "
|
||||
|| " ON CV3ClassType.GUID = CV3CatalogClassTypeValue.ClassTypeGUID "
|
||||
|| " WHERE CV3OrderCatalogMasterItem.GUID = "
|
||||
|| SQL(temp_ocmi_guid )
|
||||
|| " AND CV3ClassType.Code = "
|
||||
|| SQL(class_type)};
|
||||
|
||||
if last(the_value) is in class_value
|
||||
then
|
||||
// Mark the match as found and add value to list
|
||||
match_med_found := match_med_found, TRUE;
|
||||
item_class_value := item_class_value, the_value;
|
||||
else
|
||||
// Mark the match as not found and set value to NULL
|
||||
match_med_found := match_med_found, FALSE;
|
||||
item_class_value := item_class_value, NULL;
|
||||
endif;
|
||||
enddo;
|
||||
endif;
|
||||
|
||||
elseif exist med_info
|
||||
then
|
||||
//Get medication orders from object if the item name
|
||||
// or the component name(additive) is in med filter list
|
||||
|
||||
//Initialize variables
|
||||
chart_guid := ();
|
||||
client_guid :=();
|
||||
client_visit_guid := ();
|
||||
dosage_high := ();
|
||||
dosage_low := ();
|
||||
entereddtm := ();
|
||||
form_code := ();
|
||||
frequency_code := ();
|
||||
guid := ();
|
||||
is_conditional := ();
|
||||
is_held := ();
|
||||
is_prn := ();
|
||||
is_suspend := ();
|
||||
name := ();
|
||||
order_catalog_master_item_guid := ();
|
||||
order_component := ();
|
||||
order_route_code := ();
|
||||
order_status_code := ();
|
||||
order_status_desc := ();
|
||||
order_status_level_num := ();
|
||||
significant_dtm := ();
|
||||
stop_dtm := ();
|
||||
summary_line := ();
|
||||
uom := ();
|
||||
match_med_found := ();
|
||||
item_class_value := ();
|
||||
|
||||
|
||||
// Get main order data from Evoking Object
|
||||
(temp_chart_guid,
|
||||
temp_client_guid,
|
||||
temp_client_visit_guid,
|
||||
temp_dosage_high,
|
||||
temp_dosage_low,
|
||||
temp_entereddtm,
|
||||
temp_form_code,
|
||||
temp_frequency_code,
|
||||
temp_guid,
|
||||
temp_is_conditional,
|
||||
temp_is_held,
|
||||
temp_is_prn,
|
||||
temp_is_suspended,
|
||||
temp_order_name,
|
||||
temp_order_catalog_master_item_guid,
|
||||
temp_order_priority_code,
|
||||
temp_order_component,
|
||||
temp_order_route_code,
|
||||
temp_order_status_code,
|
||||
temp_order_status_level_num,
|
||||
temp_request_dtm,
|
||||
temp_significant_dtm,
|
||||
temp_stop_dtm,
|
||||
temp_summary_line,
|
||||
temp_order_sys_priority,
|
||||
temp_uom ) := read last
|
||||
{Order: ChartGUID, ClientGUID, ClientVisitGUID,
|
||||
DosageHigh, DosageLow, Entered, FormCode, FrequencyCode, GUID,
|
||||
IsConditional, IsHeld, IsPRN, IsSuspended,
|
||||
Name, OrderCatalogMasterItemGUID, OrderPriorityCode, OrderComponent,
|
||||
OrderRouteCode, OrderStatusCode, OrderStatusLevelNum, RequestedDtm,
|
||||
SignificantDtm, StopDtm, SummaryLine, SystemOrderPriorityCode, UOM
|
||||
REFERENCING med_info };
|
||||
|
||||
// put the order definitions found into their place in the lists
|
||||
an_order_or_component := "order";
|
||||
chart_guid := temp_chart_guid;
|
||||
client_guid := temp_client_guid;
|
||||
client_visit_guid := temp_client_visit_guid;
|
||||
dosage_high := temp_dosage_high;
|
||||
dosage_low := temp_dosage_low;
|
||||
entereddtm := temp_entereddtm;
|
||||
form_code := temp_form_code;
|
||||
frequency_code := temp_frequency_code;
|
||||
guid := temp_guid;
|
||||
is_conditional := temp_is_conditional;
|
||||
is_held := temp_is_held;
|
||||
is_prn := temp_is_prn;
|
||||
is_suspend := temp_is_suspended;
|
||||
name := temp_order_name;
|
||||
order_catalog_master_item_guid := temp_order_catalog_master_item_guid;
|
||||
order_priority_code := temp_order_priority_code;
|
||||
order_route_code := temp_order_route_code;
|
||||
order_status_code := temp_order_status_code;
|
||||
order_status_desc := read
|
||||
{"SELECT Description FROM CV3OrderStatus "
|
||||
||"WHERE Code = "||SQL(temp_order_status_code)};
|
||||
order_status_level_num := temp_order_status_level_num;
|
||||
request_dtm := temp_request_dtm;
|
||||
significant_dtm := temp_significant_dtm;
|
||||
stop_dtm := temp_stop_dtm;
|
||||
summary_line := temp_summary_line;
|
||||
system_order_priority_code := temp_order_sys_priority;
|
||||
uom := temp_uom;
|
||||
|
||||
// Check to see if medication list or class type is used
|
||||
If exists medications_list then
|
||||
// If order name in list, then set flag.
|
||||
if name is in medications_list
|
||||
then
|
||||
match_med_found := (TRUE);
|
||||
else
|
||||
match_med_found := (FALSE);
|
||||
endif;
|
||||
else
|
||||
if exists class_type then
|
||||
(the_type,
|
||||
the_value)
|
||||
:= read
|
||||
{" SELECT Code, Value "
|
||||
||" FROM CV3OrderCatalogMasterItem JOIN CV3CatalogClassTypeValue "
|
||||
||" ON CV3OrderCatalogMasterItem.GUID = CV3CatalogClassTypeValue.CatalogMasterGUID "
|
||||
||" JOIN CV3ClassType "
|
||||
||" ON CV3ClassType.GUID = CV3CatalogClassTypeValue.ClassTypeGUID "
|
||||
||" WHERE CV3OrderCatalogMasterItem.GUID = "
|
||||
||SQL(temp_order_catalog_master_item_guid)};
|
||||
|
||||
// If there is class assigned to the item, check to see if it is a match
|
||||
if exists the_type then
|
||||
class_index := 1 seqto (count the_type);
|
||||
for I in class_index do
|
||||
temp_med_class_type := last(first I from the_type);
|
||||
temp_med_class_value := last(first I from the_value);
|
||||
if temp_med_class_type = class_type then
|
||||
if (temp_med_class_value is in class_value)
|
||||
then
|
||||
match_med_found := (TRUE);
|
||||
item_class_value := (temp_med_class_value);
|
||||
else
|
||||
match_med_found := (FALSE);
|
||||
item_class_value := (NULL);
|
||||
endif;
|
||||
endif;
|
||||
// Mark as found if class and value match
|
||||
enddo;
|
||||
else
|
||||
// If there is no class assigned to the item, set match to FALSE
|
||||
match_med_found := (FALSE);
|
||||
endif;
|
||||
|
||||
else
|
||||
match_med_found := (FALSE);
|
||||
item_class_value := (NULL);
|
||||
endif;
|
||||
endif;
|
||||
|
||||
// Retrieve medication IV Additive data if OrderComponent objects exist
|
||||
if exist temp_order_component
|
||||
then
|
||||
// Get the additive names from order component object
|
||||
(iv_dosage_list,
|
||||
iv_dosage_to_list,
|
||||
iv_name_list,
|
||||
iv_order_catalog_master_item_guid_list,
|
||||
iv_uom_list,
|
||||
component_type) := read
|
||||
{OrderComponent: Dosage, DosageTo, Name,
|
||||
OrderCatalogMasterItemGUID, Uom, Type
|
||||
REFERENCING temp_order_component
|
||||
where (Dosage AS Number) > 0 };
|
||||
|
||||
|
||||
index_iv := 1 seqto (count iv_name_list);
|
||||
|
||||
// Get additive list for those that match medications list
|
||||
if exist medications_list then
|
||||
for A in index_iv do
|
||||
temp_iv_name := last(first A from iv_name_list);
|
||||
if temp_iv_name is in medications_list then
|
||||
// Synch the field lists of components to the order
|
||||
an_order_or_component := an_order_or_component,"component";
|
||||
chart_guid := chart_guid, temp_chart_guid;
|
||||
client_guid := client_guid, temp_client_guid;
|
||||
client_visit_guid := client_visit_guid, temp_client_visit_guid;
|
||||
dosage_high := dosage_high, last(first A from iv_dosage_to_list);
|
||||
dosage_low := dosage_low, last(first A from iv_dosage_list);
|
||||
entereddtm := entereddtm, NULL;
|
||||
form_code := form_code, NULL;
|
||||
frequency_code := frequency_code, NULL;
|
||||
guid := guid, temp_guid;
|
||||
is_conditional := is_conditional, NULL;
|
||||
is_held := is_held, NULL;
|
||||
is_prn := is_prn, temp_is_prn;
|
||||
is_suspend := is_suspend, NULL;
|
||||
name := name, temp_iv_name;
|
||||
order_catalog_master_item_guid := order_catalog_master_item_guid,
|
||||
last(first A from iv_order_catalog_master_item_guid_list);
|
||||
order_priority_code := order_priority_code, NULL;
|
||||
order_route_code := order_route_code, NULL;
|
||||
order_status_code := order_status_code, NULL;
|
||||
order_status_desc := order_status_desc, NULL;
|
||||
order_status_level_num := order_status_level_num, NULL;
|
||||
request_dtm := request_dtm, NULL;
|
||||
significant_dtm := significant_dtm, temp_significant_dtm;
|
||||
stop_dtm := stop_dtm, temp_stop_dtm;
|
||||
summary_line := summary_line, NULL;
|
||||
system_order_priority_code := system_order_priority_code, NULL;
|
||||
uom := uom, last(first A from iv_uom_list);
|
||||
|
||||
// If order name in list, then set flag.
|
||||
if name is in medications_list then
|
||||
match_med_found := match_med_found, TRUE;
|
||||
else
|
||||
match_med_found := match_med_found, FALSE;
|
||||
endif;
|
||||
endif; // If med in list
|
||||
enddo; // Get additive list for those that match medications list
|
||||
|
||||
elseif exists class_type then
|
||||
|
||||
// Get additive list for those that match class type and value
|
||||
for A in index_iv do
|
||||
// Get the Master GUID for this component item
|
||||
temp_ocmi_guid := last(first A from iv_order_catalog_master_item_guid_list);
|
||||
|
||||
// Get the class type and value for this components master item
|
||||
(the_name,
|
||||
the_type,
|
||||
the_value)
|
||||
:= read
|
||||
{" SELECT Name, Code, Value "
|
||||
||" FROM CV3OrderCatalogMasterItem JOIN CV3CatalogClassTypeValue "
|
||||
||" ON CV3OrderCatalogMasterItem.GUID = CV3CatalogClassTypeValue.CatalogMasterGUID "
|
||||
||" JOIN CV3ClassType "
|
||||
||" ON CV3ClassType.GUID = CV3CatalogClassTypeValue.ClassTypeGUID "
|
||||
||" WHERE CV3OrderCatalogMasterItem.GUID = "
|
||||
||SQL(temp_ocmi_guid)};
|
||||
|
||||
class_index := 1 seqto (count the_type);
|
||||
// Check each class type and value for each item.
|
||||
for I in class_index do
|
||||
temp_med_class_type := last(first I from the_type);
|
||||
temp_med_class_value := last(first I from the_value);
|
||||
|
||||
if temp_med_class_type = class_type then
|
||||
if temp_med_class_value is in class_value then
|
||||
|
||||
// Add and synch the field lists of components to the order
|
||||
match_med_found := match_med_found, TRUE;
|
||||
item_class_value := item_class_value, temp_med_class_value;
|
||||
an_order_or_component := an_order_or_component,"component";
|
||||
chart_guid := chart_guid, temp_chart_guid;
|
||||
client_guid := client_guid, temp_client_guid;
|
||||
client_visit_guid := client_visit_guid, temp_client_visit_guid;
|
||||
dosage_high := dosage_high, last(first A from iv_dosage_to_list);
|
||||
dosage_low := dosage_low, last(first A from iv_dosage_list);
|
||||
entereddtm := entereddtm, NULL;
|
||||
form_code := form_code, NULL;
|
||||
frequency_code := frequency_code, NULL;
|
||||
guid := guid, temp_guid;
|
||||
is_conditional := is_conditional, NULL;
|
||||
is_held := is_held, NULL;
|
||||
is_prn := is_prn, temp_is_prn;
|
||||
is_suspend := is_suspend, NULL;
|
||||
name := name, last(first A from iv_name_list);
|
||||
order_catalog_master_item_guid := order_catalog_master_item_guid,
|
||||
temp_ocmi_guid;
|
||||
order_priority_code := order_priority_code, NULL;
|
||||
order_route_code := order_route_code, NULL;
|
||||
order_status_code := order_status_code, NULL;
|
||||
order_status_desc := order_status_desc, NULL;
|
||||
order_status_level_num := order_status_level_num, NULL;
|
||||
request_dtm := request_dtm, NULL;
|
||||
significant_dtm := significant_dtm, temp_significant_dtm;
|
||||
stop_dtm := stop_dtm, temp_stop_dtm;
|
||||
summary_line := summary_line, NULL;
|
||||
system_order_priority_code := system_order_priority_code, NULL;
|
||||
uom := uom, last(first A from iv_uom_list);
|
||||
endif;
|
||||
endif;
|
||||
enddo; // Check each class type and value for each item.
|
||||
enddo; // Get additive list for those that match class type and value
|
||||
|
||||
else
|
||||
// Get the entire list of additives
|
||||
for A in index_iv do
|
||||
temp_component_type := last(first A from component_type);
|
||||
|
||||
// // Type of 0 or 3 are IV additives
|
||||
if temp_component_type is in (0,3) then
|
||||
chart_guid := chart_guid, temp_chart_guid;
|
||||
client_visit_guid := client_visit_guid, temp_client_visit_guid;
|
||||
dosage_high := dosage_high, last(first A from iv_dosage_to_list);
|
||||
dosage_low := dosage_low, last(first A from iv_dosage_list);
|
||||
frequency_code := frequency_code, NULL;
|
||||
guid := guid, temp_guid;
|
||||
is_conditional := is_conditional, NULL;
|
||||
is_prn := is_prn, temp_is_prn;
|
||||
name := name, last(first A from iv_name_list);
|
||||
order_catalog_master_item_guid := order_catalog_master_item_guid,
|
||||
last(first A from iv_order_catalog_master_item_guid_list);
|
||||
order_component := temp_order_component;
|
||||
order_route_code := order_route_code, NULL;
|
||||
order_status_code := order_status_code, NULL;
|
||||
order_status_desc := order_status_desc, NULL;
|
||||
order_status_level_num := order_status_level_num, NULL;
|
||||
significant_dtm := significant_dtm, temp_significant_dtm;
|
||||
stop_dtm := stop_dtm, temp_stop_dtm;
|
||||
summary_line := summary_line, NULL;
|
||||
uom := uom, last(first A from iv_uom_list);
|
||||
endif; // Type of 0 or 3 are IV additives
|
||||
enddo; // Get the entire list of additives
|
||||
endif; // Exist medicaitons list else class type else all additives.
|
||||
endif; //exist temp_order_component
|
||||
|
||||
//end - Get medication orders from object if the item name
|
||||
// or the component name(additive) is in med filter list
|
||||
|
||||
endif;
|
||||
;;
|
||||
evoke:
|
||||
;;
|
||||
logic:
|
||||
if exist med_info
|
||||
then conclude TRUE;
|
||||
else conclude FALSE;
|
||||
endif;
|
||||
|
||||
;;
|
||||
action:
|
||||
return
|
||||
an_order_or_component,
|
||||
chart_guid,
|
||||
client_guid,
|
||||
client_visit_guid,
|
||||
dosage_high,
|
||||
dosage_low,
|
||||
entereddtm,
|
||||
form_code,
|
||||
frequency_code,
|
||||
guid,
|
||||
is_conditional,
|
||||
is_held,
|
||||
is_prn,
|
||||
is_suspend,
|
||||
name,
|
||||
order_catalog_master_item_guid,
|
||||
order_priority_code,
|
||||
order_route_code,
|
||||
order_status_code,
|
||||
order_status_desc,
|
||||
order_status_level_num,
|
||||
request_dtm,
|
||||
significant_dtm,
|
||||
stop_dtm,
|
||||
summary_line,
|
||||
system_order_priority_code,
|
||||
uom,
|
||||
match_med_found,
|
||||
item_class_value;
|
||||
|
||||
;;
|
||||
|
||||
end:
|
||||
350
MLMStripper/bin/Debug/STD/STD_FUNC_SESSION_TYPE_FILTER.mlm
Normal file
350
MLMStripper/bin/Debug/STD/STD_FUNC_SESSION_TYPE_FILTER.mlm
Normal file
@@ -0,0 +1,350 @@
|
||||
maintenance:
|
||||
|
||||
title: Get Filter Query And Bit Flags Based on Session Types ;;
|
||||
mlmname: STD_FUNC_SESSION_TYPE_FILTER;;
|
||||
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: Returns the order table name, SQL filter query and session type bit
|
||||
flags depending on the session types lists or include flags AND whether
|
||||
the current order is of in house, historical or discharge session type.
|
||||
;;
|
||||
explanation: Sites are allowed to configure whether they want to check the
|
||||
current order entered (may be of Standard, Discharge, or
|
||||
Historical session type) against existing or unsubmitted orders of
|
||||
Standard, Discharge, or Historical session types of any combination.
|
||||
|
||||
Depending on the passed in arguments, the order table name and filter
|
||||
query will be set to filter the existing database orders accordingly.
|
||||
The session type bit flags will be set to filter the unsubmitted
|
||||
orders accordingly.
|
||||
|
||||
The following is a description of the arguments passed in:
|
||||
|
||||
at_in_house_session_list - existing/unsubmitted orders belonging to
|
||||
this list of session types will be checked
|
||||
against the current inhouse order
|
||||
at_historical_session_list - existing/unsubmitted orders belonging to
|
||||
this list of session types will be checked
|
||||
against the current historical order
|
||||
at_discharge_session_list - existing/unsubmitted orders belonging to
|
||||
this list of session types will be checked
|
||||
against the current discharge order
|
||||
at_outpatient_session_list -
|
||||
at_prescription_session_list - existing/unsubmitted prescriptions
|
||||
belonging to this list of session types
|
||||
will be checked against the current prescriptions
|
||||
at_prescription_historical_session_list - existing/unsubmitted prescriptions
|
||||
belonging to this list of session types
|
||||
will be checked against the current
|
||||
historical prescriptions
|
||||
use_community_medication - if community medication is found in the list,
|
||||
this flag indicates whether to use community medication
|
||||
if corresponding list is null (use_lists is false),
|
||||
this flag indicates checking against
|
||||
community medication
|
||||
order_is_for_discharge - indicates whether current order
|
||||
is entered in discharge session or
|
||||
in house session
|
||||
order_alternate_order_type - indicates whether current order
|
||||
is entered in historical session or
|
||||
not
|
||||
prescription_type - indicates the session type of the current prescription
|
||||
;;
|
||||
keywords:
|
||||
Session Type
|
||||
;;
|
||||
knowledge:
|
||||
type: data-driven;;
|
||||
data:
|
||||
/***************Make Changes To Spelling And Flags In This Section***************/
|
||||
/* Set to true if logging is needed.*/
|
||||
log_execution_info := false;
|
||||
|
||||
/********************************************************************************/
|
||||
|
||||
(at_in_house_session_list, /* list of session types for current
|
||||
inhouse order */
|
||||
at_historical_session_list, /* list of session types for current
|
||||
historical order */
|
||||
at_discharge_session_list, /* list of session types for current
|
||||
discharge order */
|
||||
at_outpatient_session_list, /* list of session types for current
|
||||
outpatient order */
|
||||
at_prescription_session_list, /* list of session types for current
|
||||
prescriptions */
|
||||
at_prescription_historical_session_list, /* list of session types for current
|
||||
historical prescriptions */
|
||||
use_community_medication, /* indicates whether to use
|
||||
community medication, if community
|
||||
medication session is found in the list.
|
||||
If corresponding list is null,
|
||||
this flag specifies whether to check
|
||||
against community medication or not
|
||||
*/
|
||||
order_is_for_discharge, /* indicates whether current order
|
||||
is entered in discharge session */
|
||||
order_alternate_type, /* indicates current order type */
|
||||
prescription_type) /* indicates the session type of
|
||||
the current prescription */
|
||||
:= ARGUMENT;
|
||||
|
||||
/* Constant strings to denote the different session types */
|
||||
discharge_order_session_str := "Discharge";
|
||||
in_house_order_session_str := "Inhouse";
|
||||
historical_session_str := "Historical";
|
||||
outpatient_rx_session_str := "Outpatient Rx";
|
||||
outpatient_hx_session_str := "Outpatient Hx";
|
||||
in_house_rx_session_str := "Prescriptions";
|
||||
historical_rx_session_str := "Historical Prescriptions";
|
||||
community_med_session_str := "Community Medication";
|
||||
|
||||
// Initialize the default values for the session type inclusion flag
|
||||
// in case the list corresponding to the current order/historical order/prescription is null
|
||||
include_in_house_session_type_orders := false;
|
||||
include_historical_session_type_orders := false;
|
||||
include_discharge_session_type_orders := false;
|
||||
include_outpatient_rx_session_type_orders := false;
|
||||
include_outpatient_hx_session_type_orders := false;
|
||||
|
||||
// Initialize the default values for the session type inclusion flag
|
||||
// in case the list corresponding to the current order/historical order is null
|
||||
// Please note the flags do not affect the result if the current medication is a prescription
|
||||
include_prescriptions := false;
|
||||
include_historical_prescriptions := false;
|
||||
include_community_medication := false;
|
||||
|
||||
// Enum values for Rx, Hx, Community Medication defined
|
||||
enum_rx_type_Rx := 1;
|
||||
enum_rx_type_Hx := 3;
|
||||
enum_rx_type_Community_Med := 5;
|
||||
|
||||
/* Flags to include the orders belonging to the respective session
|
||||
types during duplicate checking. Flags are set based on the site
|
||||
configured list variables in STD_DUPLICATE namely
|
||||
at_discharge_session_list, at_in_house_session_list, or
|
||||
at_historical_session_list.
|
||||
*/
|
||||
session_type_list_count := 0;
|
||||
|
||||
valid_input_list := (discharge_order_session_str, in_house_order_session_str, historical_session_str,
|
||||
outpatient_rx_session_str, outpatient_hx_session_str, in_house_rx_session_str, historical_rx_session_str, community_med_session_str);
|
||||
|
||||
at_in_house_session_list := at_in_house_session_list WHERE it is in valid_input_list;
|
||||
at_historical_session_list := at_historical_session_list WHERE it is in valid_input_list;
|
||||
at_discharge_session_list := at_discharge_session_list WHERE it is in valid_input_list;
|
||||
at_outpatient_session_list := at_outpatient_session_list WHERE it is in valid_input_list;
|
||||
at_prescription_session_list := at_prescription_session_list WHERE it is in valid_input_list;
|
||||
at_prescription_historical_session_list := at_prescription_historical_session_list WHERE it is in valid_input_list;
|
||||
|
||||
// Use the configured session types list for in-house session
|
||||
session_type_list := at_in_house_session_list;
|
||||
|
||||
if (count(session_type_list) = 0) then
|
||||
session_type_list := (in_house_order_session_str);
|
||||
endif;
|
||||
|
||||
// Use the configured session types list for discharge session
|
||||
if (order_is_for_discharge is not null) AND (order_is_for_discharge) then
|
||||
session_type_list := at_discharge_session_list;
|
||||
|
||||
if (count(session_type_list) = 0) then
|
||||
session_type_list := (discharge_order_session_str);
|
||||
endif;
|
||||
endif;
|
||||
|
||||
// Use the configured session types list for historical session
|
||||
if (order_alternate_type is not null) AND (order_alternate_type = 1) then
|
||||
session_type_list := at_historical_session_list;
|
||||
|
||||
if (count(session_type_list) = 0) then
|
||||
session_type_list := (historical_session_str);
|
||||
endif;
|
||||
endif;
|
||||
|
||||
// Use the configured session types list for outpatient session
|
||||
if (order_alternate_type is not null) AND (order_alternate_type = 2) then
|
||||
session_type_list := at_outpatient_session_list;
|
||||
|
||||
if (count(session_type_list) = 0) then
|
||||
session_type_list := (outpatient_rx_session_str, outpatient_hx_session_str);
|
||||
endif;
|
||||
endif;
|
||||
|
||||
if (prescription_type is not null) then
|
||||
if (prescription_type = enum_rx_type_Rx) then
|
||||
session_type_list := at_prescription_session_list;
|
||||
elseif (prescription_type = enum_rx_type_Hx) then
|
||||
session_type_list := at_prescription_historical_session_list;
|
||||
endif;
|
||||
|
||||
// If the session type list is empty, set it to the default value
|
||||
if (count(session_type_list) = 0) then
|
||||
session_type_list := (in_house_rx_session_str, historical_rx_session_str);
|
||||
|
||||
if (use_community_medication) then
|
||||
session_type_list := session_type_list, community_med_session_str;
|
||||
endif;
|
||||
endif;
|
||||
endif;
|
||||
|
||||
// Include the existing discharge session orders
|
||||
if discharge_order_session_str in session_type_list then
|
||||
include_discharge_session_type_orders := true;
|
||||
endif;
|
||||
|
||||
// Include the existing in-house session orders
|
||||
if in_house_order_session_str in session_type_list then
|
||||
include_in_house_session_type_orders := true;
|
||||
endif;
|
||||
|
||||
// Include the existing historical session orders
|
||||
if historical_session_str in session_type_list then
|
||||
include_historical_session_type_orders := true;
|
||||
endif;
|
||||
|
||||
// Include the existing outpatient rx session orders
|
||||
if outpatient_rx_session_str in session_type_list then
|
||||
include_outpatient_rx_session_type_orders := true;
|
||||
endif;
|
||||
|
||||
// Include the existing outpatient hx session orders
|
||||
if outpatient_hx_session_str in session_type_list then
|
||||
include_outpatient_hx_session_type_orders := true;
|
||||
endif;
|
||||
|
||||
// Include the existing in-house session prescriptions
|
||||
if in_house_rx_session_str in session_type_list then
|
||||
include_prescriptions := true;
|
||||
endif;
|
||||
|
||||
// Include the existing historical session prescriptions
|
||||
if historical_rx_session_str in session_type_list then
|
||||
include_historical_prescriptions := true;
|
||||
endif;
|
||||
|
||||
if community_med_session_str in session_type_list
|
||||
and use_community_medication
|
||||
then
|
||||
include_community_medication := true;
|
||||
else
|
||||
include_community_medication := false;
|
||||
endif;
|
||||
|
||||
if (session_type_list is null)
|
||||
then
|
||||
session_type_list_count := 0;
|
||||
else
|
||||
session_type_list_count := count(session_type_list);
|
||||
endif;
|
||||
|
||||
filter_orders_sql_query := "";
|
||||
order_table_name := "CV3AllOrdersVw";
|
||||
|
||||
session_flag := OBJECT [name, value];
|
||||
session_inhouse_flag := new session_flag with in_house_order_session_str, include_in_house_session_type_orders;
|
||||
session_historical_flag := new session_flag with historical_session_str, include_historical_session_type_orders;
|
||||
session_discharge_flag := new session_flag with discharge_order_session_str, include_discharge_session_type_orders;
|
||||
session_outpatient_rx_flag := new session_flag with outpatient_rx_session_str, include_outpatient_rx_session_type_orders;
|
||||
session_outpatient_hx_flag := new session_flag with outpatient_hx_session_str, include_outpatient_hx_session_type_orders;
|
||||
session_type_flags := (session_inhouse_flag, session_historical_flag, session_discharge_flag, session_outpatient_rx_flag, session_outpatient_hx_flag);
|
||||
|
||||
//discharge_flag := first(session_type_flags.value where session_type_flags.name = "Outpatient Rx");
|
||||
|
||||
if ( not include_in_house_session_type_orders ) then
|
||||
filter_orders_sql_query := filter_orders_sql_query || " AND O.AlternateOrderType <> 0 ";
|
||||
endif;
|
||||
|
||||
if ( not include_historical_session_type_orders ) then
|
||||
filter_orders_sql_query := filter_orders_sql_query || " AND O.AlternateOrderType <> 1 ";
|
||||
endif;
|
||||
|
||||
if ( not include_discharge_session_type_orders ) then
|
||||
filter_orders_sql_query := filter_orders_sql_query || " AND O.IsForDischarge = 0 ";
|
||||
endif;
|
||||
|
||||
if ( include_outpatient_rx_session_type_orders ) then
|
||||
if ( include_outpatient_hx_session_type_orders ) then
|
||||
;
|
||||
else
|
||||
filter_orders_sql_query := filter_orders_sql_query || " AND O.AlternateOrderType = 2 AND OAI.IsScript <> 0 ";
|
||||
endif;
|
||||
else
|
||||
if ( include_outpatient_hx_session_type_orders ) then
|
||||
filter_orders_sql_query := filter_orders_sql_query || " AND O.AlternateOrderType = 2 AND OAI.IsScript <> 1 ";
|
||||
else
|
||||
filter_orders_sql_query := filter_orders_sql_query || " AND O.AlternateOrderType <> 2 ";
|
||||
endif;
|
||||
endif;
|
||||
|
||||
filter_prescriptions_query := "";
|
||||
rx_types_list := ();
|
||||
|
||||
if (include_prescriptions) then
|
||||
rx_types_list := rx_types_list, enum_rx_type_Rx;
|
||||
endif;
|
||||
|
||||
if (include_historical_prescriptions) then
|
||||
rx_types_list := rx_types_list, enum_rx_type_Hx;
|
||||
endif;
|
||||
|
||||
if (include_community_medication) then
|
||||
rx_types_list := rx_types_list, enum_rx_type_Community_Med;
|
||||
endif;
|
||||
|
||||
rx_types_count := count(rx_types_list);
|
||||
index_list := 1 seqto rx_types_count;
|
||||
|
||||
for AA in index_list do
|
||||
if (AA = 1) then
|
||||
enum_rx_type_str := rx_types_list[AA];
|
||||
else
|
||||
enum_rx_type_str := enum_rx_type_str || ", " ||
|
||||
rx_types_list[AA];
|
||||
endif;
|
||||
enddo;
|
||||
|
||||
;;
|
||||
priority: 50
|
||||
;;
|
||||
evoke:
|
||||
;;
|
||||
logic:
|
||||
conclude true;
|
||||
;;
|
||||
action:
|
||||
return( order_table_name,
|
||||
filter_orders_sql_query,
|
||||
session_type_flags,
|
||||
enum_rx_type_str,
|
||||
rx_types_list,
|
||||
include_in_house_session_type_orders,
|
||||
include_historical_session_type_orders,
|
||||
include_discharge_session_type_orders,
|
||||
include_outpatient_rx_session_type_orders,
|
||||
include_outpatient_hx_session_type_orders,
|
||||
include_community_medication );
|
||||
;;
|
||||
Urgency: 50;;
|
||||
end:
|
||||
208
MLMStripper/bin/Debug/STD/STD_FUNC_TASK_DURATION.mlm
Normal file
208
MLMStripper/bin/Debug/STD/STD_FUNC_TASK_DURATION.mlm
Normal file
@@ -0,0 +1,208 @@
|
||||
maintenance:
|
||||
|
||||
title: Calculate Durations for Tasks;;
|
||||
mlmname: STD_FUNC_TASK_DURATION;;
|
||||
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 durations based on the standard times and
|
||||
on a percentage of a frequency.
|
||||
;;
|
||||
explanation: Pass in a number and a string representation of time units, and
|
||||
it will converted the information into an ARDEN Duration.
|
||||
The expected spellings are:
|
||||
"minutes", "hours", "days", "weeks", "months", "hours", and "task %".
|
||||
|
||||
In addition, the facility must map its Dictionary Codes to the Core UOM in the
|
||||
Units of Measure Dictionary. To calculate the DURATION from "task %",
|
||||
the MLM converts the facility-defined units of measure to the
|
||||
system-defined values in the Unit of Measure Dictionary called CoreUOM.
|
||||
The expected CoreUOM are:
|
||||
"s", "min", "hr", "day", "week", "month", "year"
|
||||
;;
|
||||
keywords: Duration; Calculation;
|
||||
;;
|
||||
knowledge:
|
||||
type: data-driven;;
|
||||
data:
|
||||
|
||||
(some_number,
|
||||
time_unit,
|
||||
frequency_unit) := ARGUMENT;
|
||||
|
||||
/* System-defined units of measures 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";
|
||||
|
||||
|
||||
/*-------------------------------------------*/
|
||||
/* Convert standard TIME units to a duration */
|
||||
/*-------------------------------------------*/
|
||||
If time_unit is in ("minutes", "hours", "days", "weeks", "months", "years")
|
||||
then
|
||||
if time_unit = "minutes"
|
||||
then answer:= some_number MINUTES;
|
||||
elseif time_unit = "hours"
|
||||
then answer:= some_number HOURS;
|
||||
elseif time_unit = "days"
|
||||
then answer:= some_number DAYS;
|
||||
elseif time_unit = "weeks"
|
||||
then answer:= some_number WEEKS;
|
||||
elseif time_unit = "months"
|
||||
then answer:= some_number MONTHS;
|
||||
elseif time_unit = "years"
|
||||
then answer:= some_number YEARS;
|
||||
|
||||
endif; /* if time_unit */
|
||||
endif; /* If time_unit is in */
|
||||
|
||||
|
||||
/*---------------------------*/
|
||||
/* Get FREQUENCY information */
|
||||
/*---------------------------*/
|
||||
if time_unit = "Task %"
|
||||
and exist frequency_unit
|
||||
then
|
||||
/* Gets the Frequency information from the Enterprise data */
|
||||
(frequency_code,
|
||||
frequency_type,
|
||||
time_from_value,
|
||||
time_to_value,
|
||||
time_uom,
|
||||
time_core_uom):= read last
|
||||
{"SELECT f.Code, f.DefinitionType, f.TimeFromValue, f.TimeToValue,"
|
||||
|| " f.TimeUom, u.CoreUOM "
|
||||
|| " FROM CV3Frequency AS f JOIN CV3UnitOfMeasure AS u"
|
||||
|| " ON f.TimeUom = u.Code "
|
||||
|| " WHERE f.Code = " || SQL (frequency_unit) };
|
||||
|
||||
|
||||
/* Handle frequency templates <qxh> and <qxm> by parsing the frequency string */
|
||||
/* If changes are made to this code, also change them in SYS_CALC_FREQMULT_DAILY */
|
||||
/* This is a temporary workaround for frequency templates */
|
||||
If NOT Exist frequency_type
|
||||
then
|
||||
/* 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*)};
|
||||
|
||||
/* 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 (frequency_unit, h_delim);
|
||||
get_M:= call func_get_str with (frequency_unit, m_delim);
|
||||
|
||||
/* Remove the front Q, so xH or xM is left */
|
||||
trim_Q:= call func_get_token with (frequency_unit, 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 */
|
||||
time_from_value := freq_num_str as number;
|
||||
|
||||
endif; /* If NOT Exist frequency_type */
|
||||
endif; /*if time_unit = "Task %"*/
|
||||
;;
|
||||
evoke:
|
||||
;;
|
||||
logic:
|
||||
|
||||
/*---------------------------------*/
|
||||
/* Convert FREQUENCY to a duration */
|
||||
/*---------------------------------*/
|
||||
if exist time_core_uom
|
||||
and time_unit = "Task %"
|
||||
then
|
||||
|
||||
if time_core_uom = day_string then
|
||||
if frequency_type = 1 /* y times per day */
|
||||
then frequency_duration:= (1/ time_from_value) * 1 day ;
|
||||
else frequency_duration:= time_from_value * 1 day;
|
||||
endif;
|
||||
elseif time_core_uom = hour_string then
|
||||
if frequency_type = 1 /* y times per hour */
|
||||
then frequency_duration:= (1/ time_from_value) * 1 hour ;
|
||||
else frequency_duration:= time_from_value * 1 hour ;
|
||||
endif;
|
||||
elseif time_core_uom = minute_string then
|
||||
if frequency_type = 1 /* y times per minute*/
|
||||
then frequency_duration:= (1/ time_from_value) * 1 minute ;
|
||||
else frequency_duration:= time_from_value * 1 minute ;
|
||||
endif;
|
||||
elseif time_core_uom = second_string then
|
||||
if frequency_type = 1 /* y times per second */
|
||||
then frequency_duration:= (1/time_from_value) * 1 second ;
|
||||
else frequency_duration:= time_from_value * 1 second ;
|
||||
endif;
|
||||
elseif time_core_uom = week_string then
|
||||
if frequency_type = 1 /* y times per week */
|
||||
then frequency_duration:= (1/time_from_value) * 1 week ;
|
||||
else frequency_duration:= time_from_value * 1 week ;
|
||||
endif;
|
||||
elseif time_core_uom = month_string then
|
||||
if frequency_type = 1 /* y times per month */
|
||||
then frequency_duration:= (1/time_from_value) * 1 month;
|
||||
else frequency_duration:= time_from_value * 1 month;
|
||||
endif;
|
||||
elseif time_core_uom = year_string then
|
||||
if frequency_type = 1 /* y times per year */
|
||||
then frequency_duration:= (1/time_from_value) * 1 year ;
|
||||
else frequency_duration:= time_from_value * 1 year ;
|
||||
endif;
|
||||
endif; /* if time_core_uom */
|
||||
|
||||
/* Calculate Task % answer */
|
||||
answer := frequency_duration * (SOME_NUMBER/100);
|
||||
endif; /* if exist time_core_uom */
|
||||
|
||||
|
||||
/************************/
|
||||
/* Always conclude true */
|
||||
/************************/
|
||||
Conclude True;
|
||||
;;
|
||||
action:
|
||||
Return answer;
|
||||
;;
|
||||
end:
|
||||
334
MLMStripper/bin/Debug/STD/STD_FUNC_TASK_MESSAGES.mlm
Normal file
334
MLMStripper/bin/Debug/STD/STD_FUNC_TASK_MESSAGES.mlm
Normal file
@@ -0,0 +1,334 @@
|
||||
maintenance:
|
||||
|
||||
title: Alert Messages for Duplicate Task Checking MLM;;
|
||||
mlmname: STD_FUNC_TASK_MESSAGES;;
|
||||
arden: version 2.5;;
|
||||
version: 18.4;;
|
||||
institution: Allscripts, Standard MLM;;
|
||||
author: Allscripts Healthcare Solutions, Inc.;;
|
||||
specialist: ;;
|
||||
date: 2018-10-26;;
|
||||
validation: testing;;
|
||||
|
||||
/* P r o p r i e t a r y N o t i c e */
|
||||
/* Unpublished (c) 2013 - 2018 Allscripts Healthcare, LLC. and/or its affiliates. All Rights Reserved.
|
||||
|
||||
P r o p r i e t a r y N o t i c e: This software has been provided pursuant to a License Agreement, with
|
||||
Allscripts Healthcare, LLC. and/or its affiliates, containing restrictions on its use. This software contains
|
||||
valuable trade secrets and proprietary information of Allscripts Healthcare, LLC. and/or its affiliates and is
|
||||
protected by trade secret and copyright law. This software may not be copied or distributed in any form or medium,
|
||||
disclosed to any third parties, or used in any manner not provided for in said License Agreement except with prior
|
||||
written authorization from Allscripts Healthcare, LLC. and/or its affiliates. Notice to U.S. Government Users:
|
||||
This software is {{{SINGLE-QUOTE}}}Commercial Computer Software{{{SINGLE-QUOTE}}}.
|
||||
|
||||
All product names are the trademarks or registered trademarks of Allscripts Healthcare, LLC. and/or its affiliates.
|
||||
*/
|
||||
/* P r o p r i e t a r y N o t i c e */
|
||||
|
||||
library:
|
||||
purpose: Selects the appropriate alert message for the Duplicate-Task
|
||||
Checking MLM.
|
||||
;;
|
||||
explanation: This MLM encapsulates the messages, so that all
|
||||
changes to the messages can be done in one MLM.
|
||||
;;
|
||||
keywords: Duplicate Task; Alert; Message;
|
||||
;;
|
||||
knowledge:
|
||||
type: data-driven;;
|
||||
data:
|
||||
|
||||
(task_name,
|
||||
task_status_code,
|
||||
is_primary_task,
|
||||
order_type_code,
|
||||
exact_msg,
|
||||
performed_msg,
|
||||
scheduled_msg,
|
||||
same_item_type,
|
||||
same_therapeutic_class_type,
|
||||
similar_task_type,
|
||||
conflict_type,
|
||||
possible_conflict_type,
|
||||
no_std_message_type,
|
||||
matching_task_name_list,
|
||||
matching_significant_date_list,
|
||||
matching_msg_type_list,
|
||||
matching_msg_text_list,
|
||||
matching_time_msg_list,
|
||||
matching_class_list,
|
||||
matching_latest_scheduled_dtm_list,
|
||||
matching_order_name_list,
|
||||
matching_order_type_code_list,
|
||||
matching_performed_to_dtm_list,
|
||||
matching_process_type_list,
|
||||
matching_schedule_type_code_list,
|
||||
matching_task_status_list ):= ARGUMENT;
|
||||
|
||||
;;
|
||||
evoke:
|
||||
;;
|
||||
logic:
|
||||
/* Intialize variables */
|
||||
indent_string:= " ";
|
||||
|
||||
|
||||
|
||||
/*---------------------------------*/
|
||||
/* Picks the correct alert message */
|
||||
/*---------------------------------*/
|
||||
long_alert_msg:= "";
|
||||
processing_list:= 1 seqto (count matching_task_name_list);
|
||||
for k in processing_list do
|
||||
/* Gets duplicate task information */
|
||||
dup_task_found:= processing_list = k;
|
||||
dup_task_name:= first (matching_task_name_list where dup_task_found);
|
||||
dup_task_significant_date:= first (matching_significant_date_list
|
||||
where dup_task_found);
|
||||
dup_task_msg_type:= first (matching_msg_type_list where dup_task_found);
|
||||
dup_task_msg_text:= first (matching_msg_text_list where dup_task_found);
|
||||
dup_task_time_msg:= first (matching_time_msg_list where dup_task_found);
|
||||
dup_task_class_msg:= first (matching_class_list where dup_task_found);
|
||||
dup_task_latest_scheduled_dtm:= first (matching_latest_scheduled_dtm_list
|
||||
where dup_task_found);
|
||||
dup_order_name:= first (matching_order_name_list where dup_task_found);
|
||||
dup_order_type_code:= first (matching_order_type_code_list
|
||||
where dup_task_found);
|
||||
dup_task_performed_to_dtm:= first (matching_performed_to_dtm_list
|
||||
where dup_task_found);
|
||||
dup_task_process_type:= first (matching_process_type_list where dup_task_found);
|
||||
dup_task_schedule_type_code:= first (matching_schedule_type_code_list
|
||||
where dup_task_found);
|
||||
dup_task_status_code:= first (matching_task_status_list where dup_task_found);
|
||||
|
||||
|
||||
/*--------------------------------------*/
|
||||
/* Sets Variables for the Alert Message */
|
||||
/*--------------------------------------*/
|
||||
|
||||
/* Set Code 10 */
|
||||
if dup_task_status_code = "performed"
|
||||
then db10_task_schedule_type := "Already performed";
|
||||
else
|
||||
if dup_task_schedule_type_code = "scheduled"
|
||||
then db10_task_schedule_type := "Scheduled";
|
||||
elseif dup_task_schedule_type_code = "unscheduled"
|
||||
then db10_task_schedule_type := "Unscheduled";
|
||||
elseif dup_task_schedule_type_code = "PRN"
|
||||
then db10_task_schedule_type := "Pending PRN";
|
||||
elseif dup_task_schedule_type_code = "continuous"
|
||||
then db10_task_schedule_type := "Pending continuous";
|
||||
elseif dup_task_schedule_type_code = "ToSchedule"
|
||||
and dup_task_process_type = 4
|
||||
then db10_task_schedule_type :=
|
||||
"To be scheduled starting when first done";
|
||||
else db10_task_schedule_type := dup_task_schedule_type_code;
|
||||
endif; /* if dup_task_schedule_type_code */
|
||||
endif; /* if dup_task_status_code */
|
||||
|
||||
|
||||
/* Set Code 11 */
|
||||
if dup_task_status_code = "performed"
|
||||
then
|
||||
if exist dup_task_performed_to_dtm
|
||||
then db11_date_label := "Date from: ";
|
||||
else db11_date_label := "Date: ";
|
||||
endif; /* if exist dup_task_performed_to_dtm */
|
||||
elseif dup_task_status_code <> "performed"
|
||||
then
|
||||
if dup_task_schedule_type_code = "scheduled"
|
||||
then db11_date_label := "Date: ";
|
||||
else db11_date_label := "Earliest Date: ";
|
||||
endif; /* if dup_task_schedule_type_code */
|
||||
endif; /* if dup_task_status_code */
|
||||
|
||||
|
||||
/* Set Codes 13 and 14 */
|
||||
if dup_task_status_code = "performed"
|
||||
and exist dup_task_performed_to_dtm
|
||||
then
|
||||
db13_to_label := " to: ";
|
||||
db14_end_date := dup_task_performed_to_dtm formatted with "%.4t";
|
||||
elseif dup_task_status_code <> "performed"
|
||||
and exist dup_task_latest_scheduled_dtm
|
||||
then
|
||||
db13_to_label := " to latest date: ";
|
||||
db14_end_date := dup_task_latest_scheduled_dtm formatted with "%.4t";
|
||||
else
|
||||
db13_to_label := "";
|
||||
db14_end_date := "";
|
||||
endif; /*
|
||||
if dup_task_status_code */
|
||||
|
||||
/* Set task string */
|
||||
if is_primary_task
|
||||
then
|
||||
task_string := "task";
|
||||
else
|
||||
task_string := "follow-up task";
|
||||
endif;
|
||||
|
||||
/* Set Code A */
|
||||
if (is_primary_task AND
|
||||
order_type_code = "Medication")
|
||||
then
|
||||
a_type_of_order := "medication administration";
|
||||
else
|
||||
a_type_of_order := task_string;
|
||||
endif; /* if order_type_code */
|
||||
|
||||
|
||||
/* Set Code B */
|
||||
if dup_task_schedule_type_code = "scheduled"
|
||||
then b_verb := "scheduled";
|
||||
else b_verb := "created";
|
||||
endif; /* if dup_task_schedule_type_code */
|
||||
|
||||
|
||||
/* Set Code D */
|
||||
if dup_task_schedule_type_code = "unscheduled"
|
||||
then d_task_schedule_type := "unscheduled";
|
||||
elseif dup_task_schedule_type_code = "PRN"
|
||||
then d_task_schedule_type := "PRN";
|
||||
elseif dup_task_schedule_type_code = "continuous"
|
||||
then d_task_schedule_type := "continuous";
|
||||
else d_task_schedule_type := "" ;
|
||||
endif; /* if dup_task_schedule_type_code */
|
||||
|
||||
/* Set up {{{SINGLE-QUOTE}}}another{{{SINGLE-QUOTE}}} varible text */
|
||||
if d_task_schedule_type = ""
|
||||
then another := "another";
|
||||
else another := "another ";
|
||||
endif;
|
||||
|
||||
/* Set Code C */
|
||||
if dup_task_msg_type = same_item_type
|
||||
then
|
||||
if order_type_code = "Medication"
|
||||
then
|
||||
c_msg_type_text := another || d_task_schedule_type
|
||||
|| " dose of the same medication";
|
||||
else
|
||||
c_msg_type_text := another || d_task_schedule_type
|
||||
|| " " || task_string || " of the same";
|
||||
endif;
|
||||
elseif dup_task_msg_type = same_therapeutic_class_type
|
||||
then
|
||||
c_msg_type_text := another || d_task_schedule_type
|
||||
|| " administration of a medication in the same therapeutic class";
|
||||
elseif dup_task_msg_type = similar_task_type
|
||||
then
|
||||
c_msg_type_text := another || d_task_schedule_type
|
||||
|| " " || task_string ||" of a similar type";
|
||||
elseif dup_task_msg_type = conflict_type
|
||||
then
|
||||
c_msg_type_text := another || d_task_schedule_type
|
||||
|| " conflicting " || task_string ;
|
||||
elseif dup_task_msg_type = possible_conflict_type
|
||||
then
|
||||
c_msg_type_text := another || d_task_schedule_type
|
||||
|| " possibly conflicting " || task_string;
|
||||
endif; /* if dup_task_msg_type */
|
||||
|
||||
|
||||
/* Set Code E */
|
||||
if dup_task_status_code = "performed"
|
||||
then e_occurrence_status := "had already been done";
|
||||
elseif dup_task_status_code <> "performed"
|
||||
then
|
||||
if dup_task_schedule_type_code = "scheduled"
|
||||
then e_occurrence_status := "was scheduled";
|
||||
elseif dup_task_schedule_type_code = "ToSchedule"
|
||||
and dup_task_process_type = 4 /* When 1ST GIVEN */
|
||||
then e_occurrence_status :=
|
||||
"was to be scheduled starting when first done";
|
||||
else e_occurrence_status := "was pending";
|
||||
endif; /* if dup_task_schedule_type_code */
|
||||
endif; /* if dup_task_status_code */
|
||||
|
||||
|
||||
/* Set Codes F and H */
|
||||
if (is_primary_task
|
||||
and dup_order_type_code = "Medication"
|
||||
and order_type_code = "Medication")
|
||||
then
|
||||
f_too_close := "two doses might be given too close together";
|
||||
h_was_done := "dose of " || dup_order_name ||" was given";
|
||||
else
|
||||
// two tasks(follow-up tasks) might be performed too close together
|
||||
f_too_close := "two "|| task_string || "s might be performed too close together";
|
||||
h_was_done := "time " || dup_order_name ||" was done";
|
||||
endif;
|
||||
|
||||
/* Set Code G */
|
||||
if (is_primary_task AND dup_order_type_code = "Medication")
|
||||
then
|
||||
g_doing_something := "giving this dose";
|
||||
else
|
||||
g_doing_something := "performing this " || task_string ;
|
||||
endif; /* if is_primary_task AND dup_order_type_code */
|
||||
|
||||
/* Eliminates NULLs from printing in the alert message */
|
||||
if dup_task_msg_text is null
|
||||
then
|
||||
dup_task_msg_text:= "";
|
||||
print_cr := "";
|
||||
else
|
||||
print_cr := "\n\n" ;
|
||||
endif; /* if dup_task_msg_text is null */
|
||||
|
||||
/*-------------------------------------------------*/
|
||||
/* Creates the BEGINNING of the Long Alert Message */
|
||||
/*-------------------------------------------------*/
|
||||
|
||||
if exist dup_task_significant_date then
|
||||
formatted_dup_task_significant_date
|
||||
:= dup_task_significant_date formatted with "%.4t";
|
||||
endif; //check for task significant date
|
||||
|
||||
long_alert_msg:= long_alert_msg
|
||||
|| indent_string || "{{+B}}{{+C}}"|| dup_task_name
|
||||
||"{{-C}}{{-B}}"|| "\n"
|
||||
|| indent_string || "( " || db10_task_schedule_type || " )\n"
|
||||
|| indent_string || db11_date_label
|
||||
|| formatted_dup_task_significant_date
|
||||
|| db13_to_label || db14_end_date || "\n";
|
||||
|
||||
|
||||
/*--------------------------------------------*/
|
||||
/* Creates the REST of the Long Alert Message */
|
||||
/*--------------------------------------------*/
|
||||
if dup_task_msg_type = no_std_message_type
|
||||
then
|
||||
long_alert_msg:= long_alert_msg
|
||||
|| dup_task_msg_text
|
||||
|| "\n\n";
|
||||
elseif dup_task_msg_type is in (same_item_type, same_therapeutic_class_type,
|
||||
similar_task_type , conflict_type , possible_conflict_type )
|
||||
then
|
||||
long_alert_msg:= long_alert_msg
|
||||
||"At the time this " || a_type_of_order
|
||||
|| " was " || b_verb ||", " || c_msg_type_text || ","
|
||||
|| " which is listed immediately above, "
|
||||
|| e_occurrence_status || "."
|
||||
|| " There is the potential that " || f_too_close ||"."
|
||||
|| " Before " || g_doing_something
|
||||
|| ", you should confirm that enough time has elapsed"
|
||||
|| " since the last " || h_was_done || ". "
|
||||
|| print_cr || dup_task_msg_text
|
||||
|| "\n\n";
|
||||
else
|
||||
long_alert_msg:= long_alert_msg
|
||||
|| "Error Message: Undefined Message Type for the item ordered."
|
||||
|| "\n\n";
|
||||
endif; /*if dup_task_msg_type */
|
||||
enddo; /* for k */
|
||||
|
||||
|
||||
/* Always conclude true to return the alert message to the calling program */
|
||||
conclude true;
|
||||
;;
|
||||
action:
|
||||
RETURN long_alert_msg;
|
||||
;;
|
||||
end:
|
||||
328
MLMStripper/bin/Debug/STD/STD_FUNC_TASK_RETRIEVAL.mlm
Normal file
328
MLMStripper/bin/Debug/STD/STD_FUNC_TASK_RETRIEVAL.mlm
Normal file
@@ -0,0 +1,328 @@
|
||||
maintenance:
|
||||
|
||||
title: Task Retrievals for Duplicate Task Checking;;
|
||||
mlmname: STD_FUNC_TASK_RETRIEVAL;;
|
||||
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: Retrieves OrderTaskOccurrences according to the rules stated in
|
||||
std_duplicate_task.mlm. Returns information to the calling MLM.
|
||||
;;
|
||||
explanation: See the explanation in std_duplicate.mlm
|
||||
;;
|
||||
keywords: Duplicate Task;
|
||||
;;
|
||||
knowledge:
|
||||
type: data-driven;;
|
||||
data:
|
||||
|
||||
/* Arguments that are passed by the calling MLM */
|
||||
(client_guid,
|
||||
chart_guid,
|
||||
client_visit_guid,
|
||||
task_occurrence_guid,
|
||||
task_name,
|
||||
task_scope,
|
||||
is_primary_task,
|
||||
originating_order_guid,
|
||||
past_time,
|
||||
future_time,
|
||||
tasks_to_be_canceled_string,
|
||||
schedule_type_code,
|
||||
order_task_guid ):= ARGUMENT;
|
||||
|
||||
/* Set to true if logging is needed.*/
|
||||
log_execution_info := false;
|
||||
|
||||
If exist client_guid
|
||||
then
|
||||
/*------------------------------------------------------------------*/
|
||||
/* Set Variables to Retrieve OrderTaskOccurrences from the Database */
|
||||
/*------------------------------------------------------------------*/
|
||||
|
||||
/* Set the OrderTaskOccurrence{{{SINGLE-QUOTE}}}s scope by using the patient{{{SINGLE-QUOTE}}}s GUIDs */
|
||||
If task_scope = "This Chart"
|
||||
then
|
||||
ID_equals_patient_GUID := "o.ClientGUID = " || SQL(client_guid)
|
||||
|| " AND t.ChartGUID = " || SQL(chart_guid);
|
||||
elseif task_scope = "This Visit"
|
||||
then
|
||||
ID_equals_patient_GUID := "o.ClientGUID = " || SQL(client_guid)
|
||||
|| " AND t.ChartGUID = " || SQL(chart_guid)
|
||||
|| " AND ord.ClientVisitGUID = " || SQL(client_visit_guid);
|
||||
else
|
||||
ID_equals_patient_GUID := "o.ClientGUID = " || SQL(client_guid);
|
||||
endif; /* task_scope */
|
||||
|
||||
|
||||
/* Set the OrderTaskOccurrences that are in memory to be canceled */
|
||||
If exist tasks_to_be_canceled_string
|
||||
then
|
||||
ignore_these_task_occurrences := SQL(task_occurrence_guid) || ","
|
||||
|| tasks_to_be_canceled_string;
|
||||
else
|
||||
ignore_these_task_occurrences := SQL(task_occurrence_guid);
|
||||
endif; /* tasks_to_be_canceled_string */
|
||||
|
||||
|
||||
/* When there is a CONTINUOUS order task (CV3OrderTask.ScheduleTypeCode) */
|
||||
/* Exclude the OrderTaskOccurrences that have the same OrderTaskGUID */
|
||||
If schedule_type_code = "Continuous"
|
||||
then
|
||||
AND_exclude_order_task_guid := " AND o.OrderTaskGUID <> "
|
||||
|| SQL(order_task_guid);
|
||||
else
|
||||
AND_exclude_order_task_guid := "";
|
||||
endif; /* If schedule_type_code */
|
||||
|
||||
// Select same kind of task (primary or follow-up)
|
||||
if is_primary_task
|
||||
then
|
||||
AND_match_task_sequence_number := " AND t.TaskSeqNum = 0";
|
||||
AND_exclude_follow_up_task_from_same_order := "";
|
||||
else
|
||||
AND_match_task_sequence_number := " AND t.TaskSeqNum <> 0";
|
||||
AND_exclude_follow_up_task_from_same_order := " AND t.OrderGUID <> "
|
||||
|| SQL(originating_order_guid);
|
||||
endif;
|
||||
|
||||
/*---------------------------------------*/
|
||||
/* Get the DATABASE OrderTaskOccurrences */
|
||||
/*---------------------------------------*/
|
||||
(db_order_name_list,
|
||||
db_order_type_code_list,
|
||||
db_significant_date_list,
|
||||
db_scheduled_dtm_list,
|
||||
db_earliest_scheduled_dtm_list,
|
||||
db_latest_scheduled_dtm_list,
|
||||
db_performed_from_dtm_list,
|
||||
db_performed_to_dtm_list,
|
||||
db_cds_occurrence_type_list,
|
||||
db_order_guid_list,
|
||||
db_order_task_guid_list,
|
||||
db_task_name_list,
|
||||
db_task_status_code_list,
|
||||
db_process_type_list,
|
||||
db_schedule_type_code_list,
|
||||
db_master_GUID_list,
|
||||
db_level_number_list ) := read
|
||||
{ "SELECT ord.Name, ord.TypeCode, "
|
||||
||" tzSignificant.TimeValue as SignificantDtmOffset,"
|
||||
||" tzScheduled.TimeValue as ScheduledDtmOffset,"
|
||||
||" tzEarliest.TimeValue as EarliestScheduledDtmOffset,"
|
||||
||" tzLatest.TimeValue as LatestScheduledDtmOffset,"
|
||||
||" tzPerformedFrom.TimeValue as PerformedFromDtmOffset,"
|
||||
||" tzPerformedTo.TimeValue as PerformedToDtmOffset,"
|
||||
||" o.CDSOccurrenceType,"
|
||||
||" o.OrderGUID, o.OrderTaskGUID, o.TaskName, o.TaskStatusCode,"
|
||||
||" t.ProcessType, t.ScheduleTypeCode, t.OrderCatalogMasterItemGUID,"
|
||||
||" ts.LevelNumber "
|
||||
||" FROM CV3OrderTask as t "
|
||||
||" JOIN CV3Order as ord"
|
||||
||" ON t.OrderGUID = ord.GUID AND t.ChartGUID = ord.ChartGUID AND t.ClientGUID = ord.ClientGUID "
|
||||
||" JOIN CV3OrderTaskOccurrence as o "
|
||||
||" ON o.OrderTaskGUID = t.GUID AND o.OrderGUID = t.OrderGUID AND o.ClientGUID = t.ClientGUID "
|
||||
||" JOIN CV3TaskStatus as ts "
|
||||
||" ON o.TaskStatusCode = ts.Code "
|
||||
||" JOIN CV3ClientVisit as cv "
|
||||
||" ON ord.ClientVisitGUID = cv.GUID AND ord.ClientGUID = cv.ClientGUID "
|
||||
||" CROSS APPLY dbo.SXADBConvertLocalToOffsetTblFn(cv.TimeZone, o.ScheduledDtm) tzScheduled "
|
||||
||" CROSS APPLY dbo.SXADBConvertLocalToOffsetTblFn(cv.TimeZone, o.SignificantDtm) tzSignificant "
|
||||
||" CROSS APPLY dbo.SXADBConvertLocalToOffsetTblFn(cv.TimeZone, o.EarliestScheduledDtm) tzEarliest "
|
||||
||" CROSS APPLY dbo.SXADBConvertLocalToOffsetTblFn(cv.TimeZone, o.LatestScheduledDtm) tzLatest "
|
||||
||" CROSS APPLY dbo.SXADBConvertLocalToOffsetTblFn(cv.TimeZone, o.PerformedFromDtm) tzPerformedFrom "
|
||||
||" CROSS APPLY dbo.SXADBConvertLocalToOffsetTblFn(cv.TimeZone, o.PerformedToDtm) tzPerformedTo "
|
||||
||" WHERE t.ClientGUID = " || SQL (client_guid)
|
||||
||" AND " || ID_equals_patient_GUID
|
||||
||" AND o.CDSOccurrenceType >= 0 "
|
||||
||" AND ts.LevelNumber In (50,60) "
|
||||
||" AND o.TaskStatusCode <> {{{SINGLE-QUOTE}}}Not Performed{{{SINGLE-QUOTE}}} "
|
||||
||" AND o.IsSuspended = 0 "
|
||||
||" AND o.GUID NOT IN (" || ignore_these_task_occurrences || ")"
|
||||
|| AND_exclude_order_task_guid
|
||||
|| AND_match_task_sequence_number
|
||||
|| AND_exclude_follow_up_task_from_same_order
|
||||
||" AND t.ScheduleTypeCode In "
|
||||
||" ({{{SINGLE-QUOTE}}}Continuous{{{SINGLE-QUOTE}}},{{{SINGLE-QUOTE}}}ToSchedule{{{SINGLE-QUOTE}}},{{{SINGLE-QUOTE}}}Scheduled{{{SINGLE-QUOTE}}},{{{SINGLE-QUOTE}}}Unscheduled{{{SINGLE-QUOTE}}},{{{SINGLE-QUOTE}}}PRN{{{SINGLE-QUOTE}}})"
|
||||
||" AND ((ts.LevelNumber = 60 "
|
||||
||" AND (o.SignificantDtm between " || SQL(past_time)
|
||||
|| " and " || SQL(future_time)|| "))"
|
||||
||" OR "
|
||||
||" (ts.LevelNumber = 50 "
|
||||
||" AND ( (o.ScheduledDtm between " || SQL(past_time)
|
||||
|| " and " || SQL(future_time)|| ")"
|
||||
||" OR (o.EarliestScheduledDtm between " || SQL(past_time)
|
||||
|| " and " || SQL(future_time)|| ")"
|
||||
||" OR (o.LatestScheduledDtm between " || SQL(past_time)
|
||||
|| " and " || SQL(future_time)|| ")"
|
||||
||" OR ((o.EarliestScheduledDtm <= " || SQL(future_time)
|
||||
||") and (o.LatestScheduledDtm is null))"
|
||||
||" OR ((o.EarliestScheduledDtm <= " || SQL(past_time)
|
||||
|| ") and (o.LatestScheduledDtm >= "
|
||||
|| SQL(future_time)|| "))"
|
||||
||" )))"
|
||||
,PrimaryTime = SignificantDtmOffset };
|
||||
|
||||
endif; /* If exist client_guid */
|
||||
|
||||
/*-----------------------------------------------------*/
|
||||
/* Get the Unsubmitted OrderTaskOccurrences from CACHE */
|
||||
/*-----------------------------------------------------*/
|
||||
|
||||
/* Initialize Variables */
|
||||
unsub_master_GUID_list := ();
|
||||
unsub_order_name_list := ();
|
||||
unsub_order_type_code_list := ();
|
||||
unsub_process_type_list := ();
|
||||
unsub_schedule_type_code_list := ();
|
||||
unsub_significant_date_list := ();
|
||||
unsub_latest_scheduled_dtm_list := ();
|
||||
unsub_performed_to_dtm_list := ();
|
||||
unsub_task_name_list := ();
|
||||
unsub_task_status_code_list := ();
|
||||
unsub_task_guid_list := ();
|
||||
|
||||
/* Only get the cached data if the schedule_type_code <> "Continuous" */
|
||||
If is_primary_task AND ( schedule_type_code <> "Continuous" )
|
||||
then
|
||||
|
||||
(unsub_latest_scheduled_dtm_list,
|
||||
unsub_performed_to_dtm_list,
|
||||
unsub_task_name_list,
|
||||
unsub_task_status_code_list,
|
||||
unsub_task_guid_list,
|
||||
unsub_significant_date_list ) := read
|
||||
{Unsubmitted OrderTaskOccurrence: LatestScheduledDtm,
|
||||
PerformedToDtm, TaskName, TaskStatusCode,
|
||||
guid, significantdtm
|
||||
WHERE CDSOccurrenceType >= 0
|
||||
AND TaskStatusCode IS IN ("Pending", "OverDue", "Rescheduled", "Performed" )
|
||||
AND GUID <> task_occurrence_guid
|
||||
AND IsSuspended = FALSE
|
||||
AND (
|
||||
SignificantDtm IS WITHIN past_time to future_time
|
||||
OR ScheduledDtm IS WITHIN past_time to future_time
|
||||
OR EarliestScheduledDtm IS WITHIN past_time to future_time
|
||||
OR LatestScheduledDtm IS WITHIN past_time to future_time
|
||||
OR (EarliestScheduledDtm <= future_time and LatestScheduledDtm is null)
|
||||
OR (EarliestScheduledDtm <= past_time and LatestScheduledDtm >= future_time)
|
||||
)};
|
||||
|
||||
/* OrderTaskOccurrence Object */
|
||||
(order_obj,
|
||||
order_task_obj):= read last
|
||||
{OrderTaskOccurrence: Order, OrderTask
|
||||
REFERENCING EvokingObject };
|
||||
|
||||
/* OrderTask object */
|
||||
(unsub_master_GUID,
|
||||
unsub_process_type,
|
||||
unsub_schedule_type_code) := read last
|
||||
{OrderTask: OrderCatalogMasterItemGUID, ProcessType, ScheduleTypeCode
|
||||
REFERENCING order_task_obj };
|
||||
|
||||
/* Order object */
|
||||
(unsub_order_name,
|
||||
unsub_order_type_code,
|
||||
unsub_significant_date ) := read last
|
||||
{Order: Name, TypeCode, SignificantDtm
|
||||
REFERENCING order_obj };
|
||||
|
||||
/* Create equal sized lists */
|
||||
index_list := 1 seqto count(unsub_task_name_list);
|
||||
|
||||
for J in index_list do
|
||||
unsub_master_GUID_list := unsub_master_GUID_list,
|
||||
unsub_master_GUID;
|
||||
unsub_order_name_list := unsub_order_name_list,
|
||||
unsub_order_name;
|
||||
unsub_order_type_code_list := unsub_order_type_code_list,
|
||||
unsub_order_type_code;
|
||||
unsub_process_type_list := unsub_process_type_list,
|
||||
unsub_process_type;
|
||||
unsub_schedule_type_code_list := unsub_schedule_type_code_list,
|
||||
unsub_schedule_type_code;
|
||||
enddo;
|
||||
|
||||
endif; /* If schedule_type_code <> "Continuous" */
|
||||
|
||||
/*---------------------------------------------*/
|
||||
/* Append Unsubmitted and Database Information */
|
||||
/*---------------------------------------------*/
|
||||
if is_primary_task
|
||||
AND (exist DB_TASK_NAME_LIST or exist UNSUB_TASK_NAME_LIST)
|
||||
then
|
||||
latest_scheduled_dtm_list := unsub_latest_scheduled_dtm_list,
|
||||
db_latest_scheduled_dtm_list;
|
||||
master_GUID_list := unsub_master_GUID_list,
|
||||
db_master_GUID_list;
|
||||
order_name_list := unsub_order_name_list,
|
||||
db_order_name_list;
|
||||
order_type_code_list := unsub_order_type_code_list,
|
||||
db_order_type_code_list;
|
||||
performed_to_dtm_list := unsub_performed_to_dtm_list,
|
||||
db_performed_to_dtm_list;
|
||||
process_type_list := unsub_process_type_list,
|
||||
db_process_type_list;
|
||||
schedule_type_code_list := unsub_schedule_type_code_list,
|
||||
db_schedule_type_code_list;
|
||||
significant_date_list := unsub_significant_date_list,
|
||||
db_significant_date_list;
|
||||
task_name_list := unsub_task_name_list,
|
||||
db_task_name_list;
|
||||
task_status_code_list := unsub_task_status_code_list,
|
||||
db_task_status_code_list;
|
||||
else
|
||||
latest_scheduled_dtm_list := db_latest_scheduled_dtm_list;
|
||||
master_GUID_list := db_master_GUID_list;
|
||||
order_name_list := db_order_name_list;
|
||||
order_type_code_list := db_order_type_code_list;
|
||||
performed_to_dtm_list := db_performed_to_dtm_list;
|
||||
process_type_list := db_process_type_list;
|
||||
schedule_type_code_list := db_schedule_type_code_list;
|
||||
significant_date_list := db_significant_date_list;
|
||||
task_name_list := db_task_name_list;
|
||||
task_status_code_list := db_task_status_code_list;
|
||||
endif; /* exist task_name_list */
|
||||
;;
|
||||
evoke:
|
||||
;;
|
||||
logic:
|
||||
|
||||
/* Always conclude true to return information to the calling MLM */
|
||||
conclude true;
|
||||
;;
|
||||
action:
|
||||
Return ( latest_scheduled_dtm_list,
|
||||
master_GUID_list,
|
||||
order_name_list,
|
||||
order_type_code_list,
|
||||
performed_to_dtm_list,
|
||||
process_type_list,
|
||||
schedule_type_code_list,
|
||||
significant_date_list,
|
||||
task_name_list,
|
||||
task_status_code_list );
|
||||
;;
|
||||
end:
|
||||
561
MLMStripper/bin/Debug/STD/STD_FUNC_TASK_RULES.mlm
Normal file
561
MLMStripper/bin/Debug/STD/STD_FUNC_TASK_RULES.mlm
Normal file
@@ -0,0 +1,561 @@
|
||||
maintenance:
|
||||
|
||||
title: Rules for Duplicate Task Checking;;
|
||||
mlmname: STD_FUNC_TASK_RULES;;
|
||||
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: Process the OrderTaskOccurrences according to the rules
|
||||
stated in the std_duplicate_task.mlm.
|
||||
Returns information on the duplicate task occurrences to the calling MLM.
|
||||
;;
|
||||
explanation: See the explanation in std_duplicate_task.mlm
|
||||
;;
|
||||
keywords: Duplicate Task;
|
||||
;;
|
||||
knowledge:
|
||||
type: data-driven;;
|
||||
data:
|
||||
/***************Make Changes To Spelling And Flags In This Section***************/
|
||||
/* Set to true if logging is needed.*/
|
||||
log_execution_info := false;
|
||||
|
||||
/********************************************************************************/
|
||||
|
||||
/* Do Not Changes these Internal MLM Variables */
|
||||
exact_msg:= "exact";
|
||||
performed_msg:= "performed";
|
||||
scheduled_msg:= "scheduled";
|
||||
same_item_type:= "same item";
|
||||
same_therapeutic_class_type:= "same therapeutic class";
|
||||
similar_task_type:= "similar task";
|
||||
conflict_type:= "conflict";
|
||||
possible_conflict_type:= "possible conflict";
|
||||
no_std_message_type:= "no std message";
|
||||
|
||||
/*==============================================================================*/
|
||||
|
||||
(task_name,
|
||||
task_occurrence_guid,
|
||||
task_status_code,
|
||||
task_summary_line,
|
||||
is_primary_task,
|
||||
originating_order_guid,
|
||||
item_catalog_guid,
|
||||
chart_guid,
|
||||
client_visit_guid,
|
||||
task_significant_date,
|
||||
patient_loc_group,
|
||||
task_catalog_item_guid,
|
||||
frequency_unit,
|
||||
tasks_to_be_canceled_string,
|
||||
schedule_type_code,
|
||||
order_task_guid ):= ARGUMENT;
|
||||
|
||||
|
||||
/* Declares MLMs which can be called */
|
||||
func_task_duration:= MLM {{{SINGLE-QUOTE}}}std_func_task_duration{{{SINGLE-QUOTE}}};
|
||||
func_task_retrieval:= MLM {{{SINGLE-QUOTE}}}std_func_task_retrieval{{{SINGLE-QUOTE}}};
|
||||
|
||||
/* Gets the Client GUID */
|
||||
client_guid := read last {ClientInfo: GUID};
|
||||
|
||||
/* Gets the evoking task occurrence{{{SINGLE-QUOTE}}}s Duplicate Policy */
|
||||
(catalog_name,
|
||||
duplicate_policy_guid ):= read last
|
||||
{"SELECT Name, DuplicatePolicyGUID "
|
||||
|| " FROM CV3CatalogItemTask "
|
||||
|| " WHERE GUID = " || SQL(task_catalog_item_guid)
|
||||
|| " AND Active = 1 "};
|
||||
|
||||
/* Continue if "check for duplicates" is marked in the Item-Catalog */
|
||||
If exist duplicate_policy_guid
|
||||
then
|
||||
/* Gets evoking OrderTaskOccurrence{{{SINGLE-QUOTE}}}s duplicate policy information */
|
||||
(task_loc_group_guid_list,
|
||||
task_scope_list,
|
||||
task_performed_time_list,
|
||||
task_performed_unit_list,
|
||||
task_exact_time_list,
|
||||
task_exact_unit_list,
|
||||
task_scheduled_time_list,
|
||||
task_scheduled_unit_list,
|
||||
loc_is_excluded_list) := read
|
||||
{"SELECT LocationGroupGUID, SearchScope, PastTime, PastTimeUnits,"
|
||||
|| " ExactTime, ExactTimeUnits, FutureTime, FutureTimeUnits, IsExcluded"
|
||||
|| " FROM CV3OrderDuplicatePolicyDtl "
|
||||
|| " WHERE OrderDuplicatePolicyGUID = " || SQL(duplicate_policy_guid)
|
||||
|| " AND LocationGroupGUID IN (0, " || SQL(patient_loc_group)|| " )"
|
||||
|| " AND Active = 1 "};
|
||||
|
||||
|
||||
/* Matches patient{{{SINGLE-QUOTE}}}s location group to the item-catalog{{{SINGLE-QUOTE}}}s location group and */
|
||||
/* Determines if the match excludes the location from duplicate checking */
|
||||
If exist task_scope_list
|
||||
then
|
||||
If any (patient_loc_group = task_loc_group_guid_list)
|
||||
then
|
||||
loc_group_found := patient_loc_group = task_loc_group_guid_list;
|
||||
else
|
||||
loc_group_found := task_loc_group_guid_list is null;
|
||||
endif;
|
||||
loc_is_excluded := last (loc_is_excluded_list where loc_group_found);
|
||||
endif; /* if exist task_loc_group_guid_list */
|
||||
|
||||
|
||||
/* Continue if there is a location group match or a default location group */
|
||||
/* and the location is not excluded from duplicate checking */
|
||||
If any loc_group_found and not loc_is_excluded
|
||||
then
|
||||
/*--------------------------------------------------*/
|
||||
/* Finds the scope and times for the location group */
|
||||
/*--------------------------------------------------*/
|
||||
task_loc_grp:= last (task_loc_group_guid_list
|
||||
where loc_group_found);
|
||||
task_scope:= last (task_scope_list
|
||||
where loc_group_found);
|
||||
task_performed_time:= last (task_performed_time_list
|
||||
where loc_group_found);
|
||||
task_performed_unit:= last (task_performed_unit_list
|
||||
where loc_group_found);
|
||||
task_exact_time:= last (task_exact_time_list
|
||||
where loc_group_found);
|
||||
task_exact_unit:= last (task_exact_unit_list
|
||||
where loc_group_found);
|
||||
task_scheduled_time:= last (task_scheduled_time_list
|
||||
where loc_group_found);
|
||||
task_scheduled_unit:= last (task_scheduled_unit_list
|
||||
where loc_group_found);
|
||||
|
||||
|
||||
/*-------------------------------------*/
|
||||
/* Converts EXACT TIME into Arden Time */
|
||||
/*-------------------------------------*/
|
||||
If task_exact_time >= 0
|
||||
and task_exact_unit is string
|
||||
then
|
||||
exact_duration := call func_task_duration with
|
||||
(task_exact_time, task_exact_unit, frequency_unit);
|
||||
If task_exact_unit = "days"
|
||||
then exact_low_time:= (day floor of task_significant_date)
|
||||
- exact_duration ;
|
||||
exact_high_time:= (day floor of task_significant_date)
|
||||
+ exact_duration + (1 day) - (1 second);
|
||||
else exact_low_time:= task_significant_date - exact_duration;
|
||||
exact_high_time:= task_significant_date + exact_duration;
|
||||
endif; /* if task_exact_unit = */
|
||||
endif; /* If task_exact_time >= 0 */
|
||||
|
||||
if exact_duration is NOT Duration
|
||||
then
|
||||
xxx_debug1:= "made EXACT time substitution";
|
||||
/* Substitute times */
|
||||
exact_low_time:= task_significant_date;
|
||||
exact_high_time:= task_significant_date;
|
||||
endif; /* if exact_duration is NOT Duration */
|
||||
|
||||
/*-----------------------------------------*/
|
||||
/* Converts PERFORMED TIME into Arden Time */
|
||||
/*-----------------------------------------*/
|
||||
If task_performed_time >= 0 and task_performed_unit is string
|
||||
then
|
||||
performed_duration := call func_task_duration with
|
||||
(task_performed_time, task_performed_unit, frequency_unit);
|
||||
If task_performed_unit = "days"
|
||||
then past_time:= (day floor of task_significant_date)
|
||||
- performed_duration;
|
||||
else past_time:= task_significant_date - performed_duration;
|
||||
endif; /* if task_performed_unit = */
|
||||
endif; /* if task_performed_time >= 0 ...*/
|
||||
|
||||
if performed_duration is NOT Duration
|
||||
then
|
||||
xxx_debug2:= "made PAST time substitution";
|
||||
/* Substitute times */
|
||||
if task_exact_unit = "Task %"
|
||||
then
|
||||
past_time:= task_significant_date - 12 hours;
|
||||
substituted_past_frequency_date := true;
|
||||
else
|
||||
past_time:= task_significant_date;
|
||||
endif; /* if task_exact_unit = "Task %" */
|
||||
endif; /* if performed_duration is NOT Duration */
|
||||
|
||||
|
||||
/*-----------------------------------------*/
|
||||
/* Converts SCHEDULED TIME into Arden Time */
|
||||
/*-----------------------------------------*/
|
||||
If task_scheduled_time >= 0 and task_scheduled_unit is string
|
||||
then
|
||||
scheduled_duration := call func_task_duration with
|
||||
(task_scheduled_time, task_scheduled_unit, frequency_unit);
|
||||
If task_scheduled_unit = "days"
|
||||
then future_time:= (day floor of task_significant_date)
|
||||
+ scheduled_duration + (1 day) - (1 second);
|
||||
else future_time:= task_significant_date + scheduled_duration;
|
||||
endif; /* if task_scheduled_unit = */
|
||||
endif; /* if task_scheduled_time >= 0 ...*/
|
||||
|
||||
if scheduled_duration is NOT Duration
|
||||
then
|
||||
xxx_debug3:= "made FUTURE time substitution";
|
||||
/* Substitute times */
|
||||
if task_exact_unit = "Task %"
|
||||
then
|
||||
future_time:= task_significant_date + 12 hours;
|
||||
substituted_future_frequency_date := true;
|
||||
else
|
||||
future_time:= task_significant_date;
|
||||
endif; /* if task_exact_unit = "Task %" */
|
||||
endif; /* if scheduled_duration is NOT Duration */
|
||||
|
||||
|
||||
/*---------------------------------------------------------*/
|
||||
/* Determine if the Time Intervals are GOOD. */
|
||||
/* Also determine if there was a frequency substitutition */
|
||||
/* so the user can be warned that a complete check */
|
||||
/* was not done */
|
||||
/*---------------------------------------------------------*/
|
||||
|
||||
/* Check if the past and future are valid times */
|
||||
has_time_interval := all ((past_time, future_time)are time);
|
||||
|
||||
|
||||
/* Check if the past or future dates used a frequency substitution */
|
||||
If substituted_past_frequency_date
|
||||
OR substituted_future_frequency_date
|
||||
then has_unknown_frequency := true;
|
||||
else has_unknown_frequency := false;
|
||||
endif; /* If substituted_past_frequency_date */
|
||||
|
||||
|
||||
/* Only continue duplicate check if there are good dates for the */
|
||||
/* time-interval for duplicates */
|
||||
if has_time_interval
|
||||
then
|
||||
/*---------------------------------------------------------------------*/
|
||||
/* Get evoking task{{{SINGLE-QUOTE}}}s Duplicate Item information from the Item-Catalog */
|
||||
/*---------------------------------------------------------------------*/
|
||||
/* Get the evoking task occurrence{{{SINGLE-QUOTE}}}s list of Duplicate ITEMS/CLASSES */
|
||||
(cat_dup_item_name_list,
|
||||
cat_dup_item_guid_list,
|
||||
cat_class_name_list,
|
||||
cat_class_value_list,
|
||||
cat_message_type_list,
|
||||
cat_message_list) := read
|
||||
{"SELECT DuplicateItemName, DuplicateItemGUID, ClassTypeCode, "
|
||||
|| " ClassValue, MessageType, MessageText "
|
||||
|| " FROM CV3CatalogTaskDuplicate "
|
||||
|| " WHERE CatalogItemTaskGUID = "||SQL(task_catalog_item_guid)
|
||||
|| " AND Active = 1 "};
|
||||
|
||||
/*----------------------------------------------------------------------*/
|
||||
/* Get the items from Item-Catalog that have a matching Duplicate CLASS */
|
||||
/*----------------------------------------------------------------------*/
|
||||
/* If there are any classes associated with the evoking task occurrence, */
|
||||
/* then get the GUIDs of the items */
|
||||
// Select same kind of task (primary or follow-up)
|
||||
if is_primary_task
|
||||
then
|
||||
AND_match_task_sequence_number := " AND t.TaskSeqNum = 0";
|
||||
else
|
||||
AND_match_task_sequence_number := " AND t.TaskSeqNum <> 0";
|
||||
endif;
|
||||
|
||||
If exist cat_class_value_list
|
||||
then
|
||||
other_class_guid_list:= ();
|
||||
other_class_type_list:= ();
|
||||
other_class_value_list:= ();
|
||||
other_class_msg_type_list:= ();
|
||||
other_class_msg_text_list:= ();
|
||||
|
||||
index1_list := 1 seqto (count cat_class_value_list);
|
||||
for I in index1_list do
|
||||
single_class_value := last(first I from cat_class_value_list);
|
||||
single_class_type:= last(first I from cat_class_name_list);
|
||||
single_class_msg_type:= last(first I from cat_message_type_list);
|
||||
single_class_message:= last(first I from cat_message_list);
|
||||
|
||||
If exist single_class_value
|
||||
and exist single_class_type
|
||||
and exist task_catalog_item_guid
|
||||
then
|
||||
|
||||
(temp_catalog_GUID_db,
|
||||
temp_class_type_db,
|
||||
temp_class_value_db):= read
|
||||
{"SELECT t.OrderCatalogMasterItemGUID, "
|
||||
|| " d.ClassTypeCode, d.ClassValue "
|
||||
|| " FROM CV3CatalogTaskDuplicate as d"
|
||||
|| " JOIN CV3CatalogItemTask as t"
|
||||
|| " ON d.CatalogItemTaskGUID = t.GUID"
|
||||
|| " WHERE "
|
||||
|| " d.ClassTypeCode = " || SQL(single_class_type)
|
||||
|| " AND d.ClassValue = " || SQL(single_class_value)
|
||||
|| AND_match_task_sequence_number
|
||||
|| " AND d.CatalogItemTaskGUID <> "
|
||||
|| SQL(task_catalog_item_guid)} ;
|
||||
|
||||
If exist temp_catalog_GUID_db
|
||||
then
|
||||
other_class_guid_list:= other_class_guid_list,
|
||||
temp_catalog_GUID_db;
|
||||
other_class_type_list:= other_class_type_list,
|
||||
temp_class_type_db;
|
||||
other_class_value_list:= other_class_value_list,
|
||||
temp_class_value_db;
|
||||
|
||||
/* Add the MessageType and MessageText */
|
||||
/* Create the same number of instances as */
|
||||
/* the temp_catalog_GUID_db list */
|
||||
for each_catalog_guid in temp_catalog_GUID_db do
|
||||
other_class_msg_type_list:=
|
||||
other_class_msg_type_list,
|
||||
single_class_msg_type;
|
||||
other_class_msg_text_list:=
|
||||
other_class_msg_text_list,
|
||||
single_class_message;
|
||||
enddo; /* for each_catalog_guid */
|
||||
|
||||
endif; /* if exist temp_catalog_GUID_db */
|
||||
endif; /* if exist single_class_value */
|
||||
enddo; /* for I */
|
||||
endif; /* if exist cat_class_value_list */
|
||||
|
||||
|
||||
/*-------------------------------------------------*/
|
||||
/* Retrieve the task occurrences from the DATABASE */
|
||||
/*-------------------------------------------------*/
|
||||
(latest_scheduled_dtm_list,
|
||||
master_GUID_list,
|
||||
order_name_list,
|
||||
order_type_code_list,
|
||||
performed_to_dtm_list,
|
||||
process_type_list,
|
||||
schedule_type_code_list,
|
||||
significant_date_list,
|
||||
task_name_list,
|
||||
task_status_code_list ):= call func_task_retrieval with
|
||||
(client_guid,
|
||||
chart_guid,
|
||||
client_visit_guid,
|
||||
task_occurrence_guid,
|
||||
task_name,
|
||||
task_scope,
|
||||
is_primary_task,
|
||||
originating_order_guid,
|
||||
past_time,
|
||||
future_time,
|
||||
tasks_to_be_canceled_string,
|
||||
schedule_type_code,
|
||||
order_task_guid );
|
||||
|
||||
endif; /* if has_time_interval */
|
||||
endif; /* if any loc_group_found and not loc_is_excluded */
|
||||
endif; /* if exist duplicate_policy_guid */
|
||||
;;
|
||||
evoke:
|
||||
;;
|
||||
logic:
|
||||
|
||||
/*-----------------------*/
|
||||
/* Initializes Variables */
|
||||
/*-----------------------*/
|
||||
matching_guid_list:= ();
|
||||
matching_task_name_list:= ();
|
||||
matching_significant_date_list:= ();
|
||||
matching_msg_type_list:= ();
|
||||
matching_msg_text_list:= ();
|
||||
matching_time_msg_list:= ();
|
||||
matching_class_list:= ();
|
||||
matching_latest_scheduled_dtm_list:= ();
|
||||
matching_order_name_list:= ();
|
||||
matching_order_type_code_list:= ();
|
||||
matching_performed_to_dtm_list:= ();
|
||||
matching_process_type_list:= ();
|
||||
matching_schedule_type_code_list:= ();
|
||||
matching_task_status_code_list:= ();
|
||||
|
||||
|
||||
/*--------------------------------------------------------*/
|
||||
/* Create the DUP_ITEM_GUID_LIST and its associated lists */
|
||||
/*--------------------------------------------------------*/
|
||||
/* These lists are created from the item-catalog information associated */
|
||||
/* with the Evoking OrderTaskOccurrence object. */
|
||||
/* The DUP_ITEM_GUID_LIST contains the OrderCatalogMasterItemGUIDs */
|
||||
/* that are potential duplicates of the EvokingObject */
|
||||
/* The other lists contain information about the MessageType, MessageText, */
|
||||
/* etc. which are used to construct the alert message */
|
||||
|
||||
/* Step 1: Initialize the lists with the individual ITEMs */
|
||||
/* The individual ITEMs will have OrderCatalogMasterItemGUIDs in */
|
||||
/* the cat_dup_item_guid_list */
|
||||
cat_data_found := cat_dup_item_guid_list is not null;
|
||||
dup_item_guid_list:= cat_dup_item_guid_list where cat_data_found;
|
||||
class_name_list:= cat_class_name_list where cat_data_found;
|
||||
class_value_list:= cat_class_value_list where cat_data_found;
|
||||
message_type_list:= cat_message_type_list where cat_data_found;
|
||||
message_list:= cat_message_list where cat_data_found;
|
||||
|
||||
|
||||
/* Step 2: A task is always a duplicate of itself. */
|
||||
/* Add the evoking object{{{SINGLE-QUOTE}}}s OrderCatalogMasterItemGUID */
|
||||
/* to the front of the following lists, if the information from the */
|
||||
/* item-catalog--duplicate checking panel does not include it. */
|
||||
If item_catalog_guid is not in dup_item_guid_list
|
||||
then
|
||||
dup_item_guid_list:= item_catalog_guid, dup_item_guid_list;
|
||||
class_name_list:= null, class_name_list;
|
||||
class_value_list:= null, class_value_list;
|
||||
message_type_list:= same_item_type, message_type_list;
|
||||
message_list:= null, message_list;
|
||||
endif; /* if item_catalog_guid is not in... */
|
||||
|
||||
|
||||
/* Step 3: Add the OrderCatalogMasterItemGUIDs for the CLASSES */
|
||||
/* and the other associated data to the lists */
|
||||
If exist other_class_guid_list
|
||||
then
|
||||
dup_item_guid_list:= dup_item_guid_list, other_class_guid_list;
|
||||
class_name_list:= class_name_list, other_class_type_list;
|
||||
class_value_list:= class_value_list, other_class_value_list;
|
||||
message_type_list:= message_type_list, other_class_msg_type_list;
|
||||
message_list:= message_list, other_class_msg_text_list;
|
||||
endif; /* if exist other_class_guid_list */
|
||||
|
||||
|
||||
/*---------------------------------------------------------------*/
|
||||
/* Finds all possible duplicates among the ITEMS and the CLASSES */
|
||||
/*---------------------------------------------------------------*/
|
||||
If any(dup_item_guid_list is in master_guid_list)
|
||||
then
|
||||
/* The matching is done on the OrderCatalogMasterItemGUIDs */
|
||||
/* Process each GUID one-at-a-time to find a match between the following */
|
||||
/* Dup_item_guid_list, which are item-catalogs{{{SINGLE-QUOTE}}} OrderCatalogMasterItemGUIDs. */
|
||||
/* Master_guid_list, which are task occurrences{{{SINGLE-QUOTE}}} OrderCatalogMasterItemGUIDs. */
|
||||
|
||||
index2_list := 1 seqto (count dup_item_guid_list);
|
||||
for J in index2_list do
|
||||
|
||||
item_master_guid := last(first J from dup_item_guid_list);
|
||||
if item_master_guid is in master_guid_list
|
||||
then
|
||||
master_guid_found:= item_master_guid = master_guid_list;
|
||||
|
||||
temp_guid:= master_guid_list where master_guid_found;
|
||||
temp_task_name:= task_name_list where master_guid_found;
|
||||
temp_signif:= significant_date_list where master_guid_found;
|
||||
temp_latest_scheduled_dtm:= latest_scheduled_dtm_list
|
||||
where master_guid_found;
|
||||
temp_order_name:= order_name_list where master_guid_found;
|
||||
temp_order_type:= order_type_code_list where master_guid_found;
|
||||
temp_performed_to_dtm:= performed_to_dtm_list where master_guid_found;
|
||||
temp_process_type:= process_type_list where master_guid_found;
|
||||
temp_schedule_type:= schedule_type_code_list where master_guid_found;
|
||||
temp_status:= task_status_code_list where master_guid_found;
|
||||
matching_guid_list:=
|
||||
matching_guid_list, temp_guid;
|
||||
matching_task_name_list:=
|
||||
matching_task_name_list, temp_task_name;
|
||||
matching_significant_date_list:=
|
||||
matching_significant_date_list, temp_signif;
|
||||
matching_latest_scheduled_dtm_list:=
|
||||
matching_latest_scheduled_dtm_list, temp_latest_scheduled_dtm;
|
||||
matching_order_name_list:=
|
||||
matching_order_name_list, temp_order_name;
|
||||
matching_order_type_code_list:=
|
||||
matching_order_type_code_list, temp_order_type;
|
||||
matching_performed_to_dtm_list:=
|
||||
matching_performed_to_dtm_list, temp_performed_to_dtm;
|
||||
matching_process_type_list:=
|
||||
matching_process_type_list, temp_process_type;
|
||||
matching_schedule_type_code_list:=
|
||||
matching_schedule_type_code_list, temp_schedule_type;
|
||||
matching_task_status_code_list:=
|
||||
matching_task_status_code_list, temp_status;
|
||||
|
||||
|
||||
/* Find the associated MessageType and MessageText */
|
||||
For each_guid in temp_guid do
|
||||
temp_class_value := last(first J from class_value_list);
|
||||
temp_msg_type := last(first J from message_type_list);
|
||||
temp_msg_text := last(first J from message_list);
|
||||
|
||||
matching_msg_type_list:= matching_msg_type_list, temp_msg_type;
|
||||
matching_msg_text_list:= matching_msg_text_list, temp_msg_text;
|
||||
matching_class_list:= matching_class_list, temp_class_value;
|
||||
|
||||
/* Set the time messages */
|
||||
task_time:= time of each_guid;
|
||||
relative_date:= now;
|
||||
|
||||
If task_time >= exact_low_time AND task_time <= exact_high_time
|
||||
then correct_msg:= exact_msg;
|
||||
elseif task_time < relative_date
|
||||
then correct_msg:= performed_msg;
|
||||
elseif task_time > relative_date
|
||||
then correct_msg:= scheduled_msg;
|
||||
else correct_msg:= null;
|
||||
endif; /* if task_time */
|
||||
matching_time_msg_list:= matching_time_msg_list, correct_msg;
|
||||
enddo; /* for each_guid */
|
||||
endif; /* if item_master_guid is in master_guid_list */
|
||||
enddo; /* for J */
|
||||
endif; /* if any(dup_item_guid_list...*/
|
||||
|
||||
|
||||
/* All remaining, matched task occurrences are considered duplicates */
|
||||
/* Concludes true to return data to the calling MLM */
|
||||
conclude true;
|
||||
|
||||
;;
|
||||
action:
|
||||
return( has_time_interval,
|
||||
has_unknown_frequency,
|
||||
exact_msg,
|
||||
performed_msg,
|
||||
scheduled_msg,
|
||||
same_item_type,
|
||||
same_therapeutic_class_type,
|
||||
similar_task_type,
|
||||
conflict_type,
|
||||
possible_conflict_type,
|
||||
no_std_message_type,
|
||||
duplicate_policy_guid,
|
||||
matching_task_name_list,
|
||||
matching_significant_date_list,
|
||||
matching_msg_type_list,
|
||||
matching_msg_text_list,
|
||||
matching_time_msg_list,
|
||||
matching_class_list,
|
||||
matching_latest_scheduled_dtm_list,
|
||||
matching_order_name_list,
|
||||
matching_order_type_code_list,
|
||||
matching_performed_to_dtm_list,
|
||||
matching_process_type_list,
|
||||
matching_schedule_type_code_list,
|
||||
matching_task_status_code_list );
|
||||
;;
|
||||
end:
|
||||
531
MLMStripper/bin/Debug/STD/STD_FUNC_TOTAL_DAILY_DOSE_CAT.mlm
Normal file
531
MLMStripper/bin/Debug/STD/STD_FUNC_TOTAL_DAILY_DOSE_CAT.mlm
Normal file
@@ -0,0 +1,531 @@
|
||||
maintenance:
|
||||
|
||||
title: Extraction of Dosage Range Criteria;;
|
||||
mlmname: STD_FUNC_TOTAL_DAILY_DOSE_CAT;;
|
||||
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: Finds the appropriate dose-range criteria from the order{{{SINGLE-QUOTE}}}s item-catalog and
|
||||
returns the information to the calling MLM.
|
||||
;;
|
||||
explanation: This MLM assists the STD_TOTAL_DAILY_Dose_Exceeded MLM with dose-range checking.
|
||||
A large list of arguments is passed to this MLM, and they are used to find
|
||||
the most appropriate dose-range criteria (AGE, BSA, or WEIGHT)
|
||||
for the patient.
|
||||
|
||||
If the ORDERED-DOSE is being checking and the "PER WT OR M2" field has a
|
||||
valid uom (kg,lb,oz,g,m2), then the upper and lower dose-ranges will be
|
||||
(1) multiplied by the patient{{{SINGLE-QUOTE}}}s weight or BSA and
|
||||
(2) rounded using the rules found in the SYS_round_dosage MLM,
|
||||
if there is a valid route.
|
||||
|
||||
If the DOSE-PER is being checking and the "PER WT OR M2" field has a
|
||||
valid uom (kg,lb,oz,g,m2), then the upper and lower dose-ranges will NOT be
|
||||
multiplied or rounded.
|
||||
|
||||
The dose-ranges and other pertinent information are returned to the calling MLM.
|
||||
See the STD_TOTAL_DAILY_Dose_Exceeded MLM for further information.
|
||||
;;
|
||||
|
||||
keywords: single dose; average daily dose; total daily dose; dosage range
|
||||
;;
|
||||
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:
|
||||
|
||||
(age_string,
|
||||
birthday,
|
||||
birthmonthnum,
|
||||
BSA_number_rounded,
|
||||
BSA_string,
|
||||
catalog_item_obj,
|
||||
day_string,
|
||||
drug_name,
|
||||
gm_string,
|
||||
kg_string,
|
||||
lb_string,
|
||||
m2_string,
|
||||
month_string,
|
||||
order_med_per_uom,
|
||||
order_med_route,
|
||||
order_med_significant_date,
|
||||
order_med_units,
|
||||
ounce_string,
|
||||
intl_patient_gender,
|
||||
uom_facility_code,
|
||||
uom_sys_code,
|
||||
week_string,
|
||||
weight_string,
|
||||
wt_kg,
|
||||
year_string):= ARGUMENT;
|
||||
|
||||
// Set to true if logging is needed.
|
||||
log_execution_info := false;
|
||||
|
||||
|
||||
/* Declare the MLMs that can be called */
|
||||
round_dose_func := MLM {{{SINGLE-QUOTE}}}SYS_round_dosage{{{SINGLE-QUOTE}}};
|
||||
|
||||
|
||||
/* Get the reference to the CatalogItemDosage object */
|
||||
order_catalog_item_dosage_obj:= read last
|
||||
{OrderCatalogMasterItem: CatalogItemDosage
|
||||
REFERENCING catalog_item_obj };
|
||||
|
||||
|
||||
/* Get the Dosage range data from the catalog item when the routes */
|
||||
/* Match to the order. */
|
||||
(facility_gender_codes,
|
||||
gender_codes,
|
||||
criteria_type_codes,
|
||||
criteria_type_high_codes,
|
||||
criteria_type_low_codes,
|
||||
criteria_type_facility_uoms,
|
||||
routes,
|
||||
range_low_codes,
|
||||
range_high_codes,
|
||||
range_uoms,
|
||||
range_per_facility_uoms) := read
|
||||
{ CatalogItemDosage: GenderCode, GenderTypeIntlCode, CriteriaTypeCode,
|
||||
CriteriaTypeHigh, CriteriaTypeLow, CriteriaTypeUom, RouteCode,
|
||||
RangeLow, RangeHigh, RangeUom, RangePerUom
|
||||
REFERENCING order_catalog_item_dosage_obj
|
||||
WHERE RouteCode = order_med_route
|
||||
and RangeUom = order_med_units
|
||||
and (CriteriaTypeCode = age_string
|
||||
or CriteriaTypeCode = bsa_string
|
||||
or CriteriaTypeCode = weight_string) };
|
||||
|
||||
;;
|
||||
evoke:
|
||||
;;
|
||||
logic:
|
||||
/* Intializes variables */
|
||||
criteria_type_uoms:= ();
|
||||
dose_per_string:= "Dose Per";
|
||||
dose_reg_string:= "Dose Reg";
|
||||
found_criteria:= false;
|
||||
range_per_uoms:= ();
|
||||
|
||||
/*-----------------------------------------------------------------------------*/
|
||||
/* Check and flag existence of any criteria for BSA, wt, age, or Average Daily */
|
||||
/*-----------------------------------------------------------------------------*/
|
||||
If any (criteria_type_codes = age_string) then
|
||||
found_age_criteria := TRUE;
|
||||
else
|
||||
found_age_criteria := FALSE;
|
||||
endif;
|
||||
|
||||
If any (criteria_type_codes = bsa_string) then
|
||||
found_BSA_criteria := TRUE;
|
||||
else
|
||||
found_BSA_criteria := FALSE;
|
||||
endif;
|
||||
|
||||
If any (criteria_type_codes = weight_string) then
|
||||
found_weight_criteria := TRUE;
|
||||
else
|
||||
found_weight_criteria := FALSE;
|
||||
endif;
|
||||
|
||||
If any (range_per_facility_uoms = m2_string) then
|
||||
found_PER_M2_criteria := TRUE;
|
||||
else
|
||||
found_PER_M2_criteria := FALSE;
|
||||
endif;
|
||||
|
||||
|
||||
if ANY (range_per_facility_uoms = kg_string)
|
||||
OR ANY (range_per_facility_uoms = gm_string)
|
||||
OR ANY (range_per_facility_uoms = lb_string)
|
||||
OR ANY (range_per_facility_uoms = ounce_string)
|
||||
then
|
||||
found_PER_WT_criteria := TRUE;
|
||||
else
|
||||
found_PER_WT_criteria := FALSE;
|
||||
endif;
|
||||
|
||||
If any (facility_gender_codes is NOT NULL)
|
||||
then
|
||||
found_gender_code_criteria := TRUE;
|
||||
else
|
||||
found_gender_code_criteria := FALSE;
|
||||
endif;
|
||||
|
||||
|
||||
/*------------------------------*/
|
||||
/* Checks if the MLM should run */
|
||||
/*------------------------------*/
|
||||
If exist(range_high_codes) and any(range_high_codes > 0)
|
||||
then
|
||||
|
||||
/* Convert patient weight to grams */
|
||||
if wt_kg is number
|
||||
and wt_kg > 0
|
||||
then wt_gm:= wt_kg * 1000;
|
||||
endif; /* if wt_kg is number and and wt_kg > 0 */
|
||||
|
||||
/* Converts facility-defined UOM codes to the System{{{SINGLE-QUOTE}}}s CoreUOM codes */
|
||||
/* CV3CatalogItemDosage.CriteriaTypeUom and */
|
||||
/* CV3CatalogItemDosage.RangePerUom are replaced with CoreUOM codes. */
|
||||
/* The MLM will continue to use the facility-defined */
|
||||
/* CV3CatalogItemDosage.RangeUom */
|
||||
|
||||
temp_numbers:= 1 seqto count(criteria_type_facility_uoms);
|
||||
for k in temp_numbers do
|
||||
found_k:= temp_numbers = k;
|
||||
temp_criteria_type_uoms:= last (criteria_type_facility_uoms
|
||||
where found_k);
|
||||
temp_range_per_uoms:= last (range_per_facility_uoms where found_k);
|
||||
criteria_type_uoms:= criteria_type_uoms,
|
||||
last (uom_sys_code
|
||||
where (uom_facility_code = temp_criteria_type_uoms));
|
||||
range_per_uoms:= range_per_uoms,
|
||||
last (uom_sys_code where (uom_facility_code = temp_range_per_uoms));
|
||||
enddo; /* for k */
|
||||
|
||||
|
||||
/*-------------------------*/
|
||||
/* BSA (Body Surface Area) */
|
||||
/*-------------------------*/
|
||||
/* Checks the Dosage-range for the patient{{{SINGLE-QUOTE}}}s current BSA (body surface area) */
|
||||
if not found_criteria
|
||||
and exist BSA_number_rounded
|
||||
then
|
||||
type_name:= BSA_string;
|
||||
value:= BSA_number_rounded;
|
||||
|
||||
/* Determines which records are applicable--we will use the first one */
|
||||
temp_found_dosage_record :=
|
||||
((gender_codes = intl_patient_gender) or
|
||||
(facility_gender_codes = "" ) or
|
||||
(facility_gender_codes is null)) and
|
||||
(criteria_type_codes = type_name) and
|
||||
(value >= criteria_type_low_codes) and
|
||||
(value < criteria_type_high_codes) and
|
||||
(order_med_units = range_uoms) and
|
||||
(M2_string = criteria_type_uoms);
|
||||
|
||||
/* Determine if there is a match for DOSE-PER */
|
||||
found_per_dose_record:=
|
||||
temp_found_dosage_record and
|
||||
(order_med_per_uom = range_per_uoms);
|
||||
|
||||
/* Set the Dose Calculation Method and the Found Dosage Record */
|
||||
if any (found_per_dose_record)
|
||||
then
|
||||
found_dosage_record:= found_per_dose_record;
|
||||
dose_calc_method:= dose_per_string;
|
||||
elseif any (temp_found_dosage_record)
|
||||
then
|
||||
found_dosage_record:= temp_found_dosage_record;
|
||||
dose_calc_method:= dose_reg_string;
|
||||
endif; /* if any (found_per_dose_record) */
|
||||
|
||||
lower_dose := first (range_low_codes where found_dosage_record);
|
||||
upper_dose := first (range_high_codes where found_dosage_record);
|
||||
units:= first (range_uoms where found_dosage_record);
|
||||
per_units:= first (range_per_uoms where found_dosage_record);
|
||||
|
||||
/* Checks if a match was found by checking if the doses are numbers */
|
||||
/* Stops looking after finding the first match */
|
||||
If lower_dose is number and upper_dose is number
|
||||
then found_criteria:= true;
|
||||
endif;
|
||||
endif; /* if not found_criteria and exist BSA_number_rounded */
|
||||
|
||||
|
||||
/*--------*/
|
||||
/* WEIGHT */
|
||||
/*--------*/
|
||||
/* Checks the Dosage-range for the patient{{{SINGLE-QUOTE}}}s current WEIGHT, */
|
||||
/* when BSA is unavailable */
|
||||
|
||||
if not found_criteria
|
||||
and wt_gm is number
|
||||
and wt_gm > 0
|
||||
then
|
||||
type_name := weight_string;
|
||||
|
||||
/* Finds all the rows that apply to WEIGHT and */
|
||||
/* Eliminates duplicates weight-units and */
|
||||
/* Creates an unique list of sorted weight-units by ascending size */
|
||||
temp_wt_unit_list:= (criteria_type_uoms
|
||||
where weight_string = criteria_type_codes);
|
||||
wt_unit_list:= (gm_string, ounce_string, lb_string, kg_string )
|
||||
where it is in temp_wt_unit_list;
|
||||
|
||||
/* Processes all possible kinds of WEIGHT to find a match */
|
||||
for some_wt_unit in wt_unit_list do
|
||||
if not found_criteria
|
||||
then
|
||||
/* Saves the weight unit */
|
||||
wt_unit:= some_wt_unit;
|
||||
|
||||
/* Converts the patient{{{SINGLE-QUOTE}}}s weight into the expects units */
|
||||
if wt_unit = kg_string then value:= wt_gm/1000; /* kilogram */
|
||||
elseif wt_unit = gm_string then value:= wt_gm; /* gram */
|
||||
elseif wt_unit = lb_string then value := wt_gm/453.6; /* pound */
|
||||
elseif wt_unit = ounce_string then value:= wt_gm/28.35; /* ounce */
|
||||
endif;
|
||||
|
||||
/* Determines which records are applicable-MLM uses the first one*/
|
||||
temp_found_dosage_record :=
|
||||
((gender_codes = intl_patient_gender) or
|
||||
(facility_gender_codes = "" ) or
|
||||
(facility_gender_codes is null )) and
|
||||
(criteria_type_codes = type_name) and
|
||||
(value >= criteria_type_low_codes) and
|
||||
(value < criteria_type_high_codes) and
|
||||
(order_med_units = range_uoms) and
|
||||
(wt_unit = criteria_type_uoms);
|
||||
|
||||
/* Determine if there is a match for DOSE-PER */
|
||||
found_per_dose_record:=
|
||||
temp_found_dosage_record and
|
||||
(order_med_per_uom = range_per_uoms);
|
||||
|
||||
/* Set the Dosa Calculation Method and the Found Dosage Record */
|
||||
if any (found_per_dose_record)
|
||||
then
|
||||
found_dosage_record:= found_per_dose_record;
|
||||
dose_calc_method:= dose_per_string;
|
||||
elseif any (temp_found_dosage_record)
|
||||
then
|
||||
found_dosage_record:= temp_found_dosage_record;
|
||||
dose_calc_method:= dose_reg_string;
|
||||
endif; /* if any (found_per_dose_record) */
|
||||
|
||||
|
||||
/* Extracts the data that will be used for Dosage range checking */
|
||||
lower_dose:= first (range_low_codes where found_dosage_record);
|
||||
upper_dose:= first (range_high_codes where found_dosage_record);
|
||||
units:= first (range_uoms where found_dosage_record);
|
||||
per_units:= first (range_per_uoms where found_dosage_record);
|
||||
|
||||
/* Checks if a match was found by checking if the doses are numbers */
|
||||
/* Stops looking after finding the first match */
|
||||
If lower_dose is number and upper_dose is number
|
||||
then found_criteria:= true;
|
||||
endif;
|
||||
endif; /* if not found_criteria */
|
||||
enddo; /* for some_wt_unit */
|
||||
endif; /* if not found_criteria and wt_gm is number ... */
|
||||
|
||||
/*-----*/
|
||||
/* AGE */
|
||||
/*-----*/
|
||||
/* Checks the Dosage-range for the patient{{{SINGLE-QUOTE}}}s current AGE, */
|
||||
/* when BSA and Weight are unavailable. */
|
||||
|
||||
/* A valid birthday is required for the appropriate age calculation */
|
||||
/* The age of adults and older children can be calculated with the birth-year */
|
||||
/* when the month and day are not available. */
|
||||
/* However, the age of an infant can be over-estimated based solely */
|
||||
/* on the birth-year. Therefore infant must have */
|
||||
/* a valid birth-month and birth-year before an age calculation is attempted. */
|
||||
/* If the patient{{{SINGLE-QUOTE}}}s birth month is 0, */
|
||||
/* then only the birth-year is available for the age calculation. */
|
||||
/* In this case, don{{{SINGLE-QUOTE}}}t use the age-based dosage range data for */
|
||||
/* infants or children under age 3 years. */
|
||||
|
||||
if birthday is time then
|
||||
has_valid_birthdate:= true;
|
||||
if birthMonthNum = 0 then
|
||||
age_value:= (order_med_significant_date-birthday)/(1 year);
|
||||
if age_value <= 3 then
|
||||
has_valid_birthdate:= false;
|
||||
endif;
|
||||
endif;
|
||||
endif; /* if birthday is time */
|
||||
|
||||
|
||||
/* Check the age-based dosage range data when there is a valid birthdate */
|
||||
if not found_criteria
|
||||
and has_valid_birthdate
|
||||
then
|
||||
|
||||
type_name:= age_string;
|
||||
|
||||
/* Finds all the rows that apply to AGE and */
|
||||
/* Eliminates duplicates weight-units and */
|
||||
/* Creates an unique list of sorted age-units by ascending age */
|
||||
temp_age_unit_list:= (criteria_type_uoms
|
||||
where age_string = criteria_type_codes);
|
||||
age_unit_list:= (day_string, week_string, month_string, year_string)
|
||||
where it is in temp_age_unit_list;
|
||||
|
||||
|
||||
/* Processes all possible kinds of AGE to find a match */
|
||||
for some_age_unit in age_unit_list do
|
||||
if not found_criteria
|
||||
then
|
||||
/* Saves age unit */
|
||||
age_unit:= some_age_unit;
|
||||
|
||||
/* Converts the patient{{{SINGLE-QUOTE}}}s AGE into the expected units */
|
||||
if age_unit = year_string
|
||||
then value:= (order_med_significant_date - birthday)/(1 year);
|
||||
elseif age_unit= month_string
|
||||
then value:= (order_med_significant_date - birthday)/(1 month);
|
||||
elseif age_unit = week_string
|
||||
then value:= (order_med_significant_date - birthday)/(1 week);
|
||||
elseif age_unit = day_string
|
||||
then value:= (order_med_significant_date - birthday)/(1 day);
|
||||
endif; /* if age_unit */
|
||||
|
||||
/* Determines which records are applicable--MLM uses the first one */
|
||||
temp_found_dosage_record :=
|
||||
((gender_codes = intl_patient_gender) or
|
||||
(facility_gender_codes = "" ) or
|
||||
(facility_gender_codes is null )) and
|
||||
(criteria_type_codes = type_name) and
|
||||
(value >= criteria_type_low_codes) and
|
||||
(value < criteria_type_high_codes) and
|
||||
(order_med_units = range_uoms) and
|
||||
(age_unit = criteria_type_uoms);
|
||||
|
||||
|
||||
/* Determine if there is a match for DOSE-PER */
|
||||
found_per_dose_record:=
|
||||
temp_found_dosage_record and
|
||||
(order_med_per_uom = range_per_uoms);
|
||||
|
||||
/* Set the Dosa Calculation Method and the Found Dosage Record */
|
||||
if any (found_per_dose_record)
|
||||
then
|
||||
found_dosage_record:= found_per_dose_record;
|
||||
dose_calc_method:= dose_per_string;
|
||||
elseif any (temp_found_dosage_record)
|
||||
then
|
||||
found_dosage_record:= temp_found_dosage_record;
|
||||
dose_calc_method:= dose_reg_string;
|
||||
endif; /* if any (found_per_dose_record) */
|
||||
|
||||
|
||||
/* Extracts the data that will be used for Dosage range checking */
|
||||
lower_dose:= first (range_low_codes where found_dosage_record);
|
||||
upper_dose:= first (range_high_codes where found_dosage_record);
|
||||
units:= first (range_uoms where found_dosage_record);
|
||||
per_units:= first (range_per_uoms where found_dosage_record);
|
||||
|
||||
/* Checks if a match was found by checking if the doses are numbers */
|
||||
/* Stops looking after finding the first match */
|
||||
If lower_dose is number and upper_dose is number
|
||||
then found_criteria:= true;
|
||||
endif; /* If lower_dose is number ... */
|
||||
endif; /* if not found_criteria */
|
||||
enddo; /* for some_age_unit */
|
||||
endif; /* if not found_criteria */
|
||||
|
||||
|
||||
/*-------------------------*/
|
||||
/* PER WT OR M2 CONVERSION */
|
||||
/*-------------------------*/
|
||||
/* Converts doses based on the patient{{{SINGLE-QUOTE}}}s weight whenever there is a: */
|
||||
/* (1) {{{SINGLE-QUOTE}}}per unit{{{SINGLE-QUOTE}}} of body weight (PER WT OR M2), (2) weight for the patient, */
|
||||
/* and (3) regular dose calculation */
|
||||
if found_criteria
|
||||
and exists per_units
|
||||
and dose_calc_method = dose_reg_string
|
||||
then
|
||||
if per_units is in (kg_string, gm_string, lb_string, ounce_string)
|
||||
then
|
||||
if wt_gm > 0
|
||||
then
|
||||
If per_units = kg_string
|
||||
then lower_dose:= lower_dose * wt_gm/1000;
|
||||
upper_dose:= upper_dose * wt_gm/1000;
|
||||
elseif per_units = gm_string
|
||||
then lower_dose:= lower_dose * wt_gm;
|
||||
upper_dose:= upper_dose * wt_gm;
|
||||
elseif per_units = lb_string
|
||||
then lower_dose:=lower_dose * wt_gm/453.6;
|
||||
upper_dose:= upper_dose * wt_gm/453.6;
|
||||
elseif per_units = ounce_string
|
||||
then lower_dose:=lower_dose * wt_gm/28.35;
|
||||
upper_dose:= upper_dose * wt_gm/28.35;
|
||||
endif; /* if per_units = */
|
||||
else
|
||||
/* Stops MLM when there are valid weight units (per_units) */
|
||||
/* and invalid body weight (wt_gm) */
|
||||
found_criteria:= false;
|
||||
endif; /* wt_gm > 0 */
|
||||
|
||||
elseif per_units = m2_string
|
||||
then
|
||||
if BSA_number_rounded is number
|
||||
and BSA_number_rounded > 0
|
||||
then
|
||||
lower_dose:= lower_dose * BSA_number_rounded;
|
||||
upper_dose:= upper_dose * BSA_number_rounded;
|
||||
else
|
||||
/* Stops MLM when there is a valid M2 and invalid BSA number */
|
||||
found_criteria:= false;
|
||||
endif; /* if BSA_number_rounded is number */
|
||||
endif; /* if per_units */
|
||||
|
||||
/* ROUND the dose generated by the PER WT OR M2 */
|
||||
/* When there is a route */
|
||||
/* And save the original unrounded doses */
|
||||
if (exist lower_dose or exist upper_dose)
|
||||
and exist order_med_route
|
||||
then
|
||||
unrounded_lower_dose:= lower_dose;
|
||||
unrounded_upper_dose:= upper_dose;
|
||||
(rounding_error_msg, lower_dose):=
|
||||
call round_dose_func with lower_dose, order_med_route ;
|
||||
(rounding_error_msg, upper_dose):=
|
||||
call round_dose_func with upper_dose, order_med_route ;
|
||||
endif; /* if exist lower_dose or exist upper_dose */
|
||||
endif; /* if found_criteria and exists per_units... */
|
||||
else
|
||||
xxx_debug_check:= "Medication does not have Dosage-range checking";
|
||||
endif; /* If exist(range_high_codes)... */
|
||||
|
||||
/* Set the UOM according to the Dosage Calculation Method */
|
||||
if dose_calc_method = dose_per_string
|
||||
then corrected_uom:= units || "/" || order_med_per_uom;
|
||||
else corrected_uom:= units;
|
||||
endif; /* if dose_calc_method */
|
||||
|
||||
/* Always conclude true to return variables to calling MLM */
|
||||
CONCLUDE TRUE;
|
||||
|
||||
;;
|
||||
action:
|
||||
return (found_criteria, dose_calc_method, lower_dose, upper_dose,
|
||||
corrected_uom, per_units, type_name,
|
||||
found_age_criteria, found_BSA_criteria, found_weight_criteria,
|
||||
found_gender_code_criteria,found_PER_WT_criteria,found_PER_M2_criteria);
|
||||
;;
|
||||
end:
|
||||
@@ -0,0 +1,114 @@
|
||||
maintenance:
|
||||
|
||||
title: Validate and format numeric data in text field;;
|
||||
mlmname: STD_FUNC_VALIDATE_AND_FORMAT_TEXT_AS_NUMERIC;;
|
||||
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: Checks that a given string contains only numeric characters
|
||||
(May also contain a decimal point). It also formats that string
|
||||
based on the strFormatString that is passed from the calling MLM.
|
||||
;;
|
||||
explanation: This MLM will check that all of the characters in strTextToValidateAndFormat
|
||||
are numeric values or a decimal point. If bAllowDecimals = true, then the
|
||||
MLM will also consider a decimal point to be a valid character. Otherwise,
|
||||
only standard numeric characters (0-9) will be considered valid.
|
||||
If strTextToValidate is a valid numeric string, the MLM will format the
|
||||
string based on the strFormatString format specification. For further
|
||||
information on acceptable format specifications, please refer to the
|
||||
Arden syntax guide. NOTE: If you wish to validate the data but do not wish
|
||||
to format it, set strFormatString := null;
|
||||
|
||||
;;
|
||||
keywords: validate; format numeric data ;;
|
||||
|
||||
knowledge:
|
||||
type: data-driven;;
|
||||
data:
|
||||
|
||||
/* List Arguments passed by the calling MLM */
|
||||
(strTextToValidateAndFormat, //the numeric string to be validated
|
||||
strFormatString, //Arden syntax format specification (ie "%.2f") or null
|
||||
bAllowDecimals //whether or not this field allows decimal values
|
||||
):= ARGUMENT;
|
||||
|
||||
|
||||
/***************Make Changes To Spelling And Flags In This Section**************/
|
||||
|
||||
/* Set to true if logging is needed.*/
|
||||
log_execution_info := false;
|
||||
|
||||
/*******************************************************************************/
|
||||
|
||||
ValidNumericValues := ("1","2","3","4","5","6","7","8","9","0");
|
||||
|
||||
|
||||
;;
|
||||
evoke: ;;
|
||||
|
||||
logic:
|
||||
characterList := extract characters strTextToValidateAndFormat;
|
||||
cnt := count (characterList);
|
||||
indexList := 1 SEQTO cnt;
|
||||
bDecimalFound := false;
|
||||
|
||||
IsValid := true;
|
||||
|
||||
//Parses the string into individual characters and checks that each character
|
||||
//is either numeric or a decimal. It also makes sure that there is only one
|
||||
//decimal.
|
||||
for X in indexList do
|
||||
ch := characterList[X];
|
||||
if ch IS NOT IN ValidNumericValues then
|
||||
if bAllowDecimals = true then
|
||||
//check if ch is a decimal but make sure there is only one...
|
||||
if (string(ch) = string(".")) AND bDecimalFound = false then
|
||||
bDecimalFound := true;
|
||||
else
|
||||
IsValid := false;
|
||||
endif;
|
||||
else
|
||||
IsValid := false;
|
||||
endif;
|
||||
endif;
|
||||
enddo;
|
||||
|
||||
|
||||
If IsValid = true then
|
||||
if strFormatString IS NOT NULL then
|
||||
strFormattedString := (strTextToValidateAndFormat as number)
|
||||
formatted with strFormatString;
|
||||
else
|
||||
strFormattedString := strTextToValidateAndFormat;
|
||||
endif;
|
||||
|
||||
endif;
|
||||
|
||||
conclude true;
|
||||
|
||||
;;
|
||||
action:
|
||||
return (IsValid, strFormattedString);
|
||||
;;
|
||||
end:
|
||||
144
MLMStripper/bin/Debug/STD/STD_FUNC_VENIPUNCTURE_ACTIONS.mlm
Normal file
144
MLMStripper/bin/Debug/STD/STD_FUNC_VENIPUNCTURE_ACTIONS.mlm
Normal file
@@ -0,0 +1,144 @@
|
||||
maintenance:
|
||||
|
||||
title: Set the Actions for Venipuncture Alerts;;
|
||||
mlmname: STD_FUNC_VENIPUNCTURE_ACTIONS;;
|
||||
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: This MLM is used by the Venipuncture checking MLMs to call another
|
||||
MLM to create the AlertAction object and to populate them with data.
|
||||
;;
|
||||
explanation: This MLM will do the following:
|
||||
1. Call the STD_Func_Create_Alert_Action_Object MLM to create an instance
|
||||
of the AlertAction object.
|
||||
2. Process the data that was sent to it and populate each AlertAction object.
|
||||
3. Create a list of the objects and return it to the call program.
|
||||
;;
|
||||
keywords:
|
||||
;;
|
||||
knowledge:
|
||||
type: data-driven;;
|
||||
data:
|
||||
|
||||
/***************Make Changes To Spelling And Flags In This Section***************/
|
||||
/* Set to true if logging is needed.*/
|
||||
log_execution_info := false;
|
||||
|
||||
/********************************************************************************/
|
||||
|
||||
// Instantiate the variables associated with the Arguments
|
||||
(order_guid, //GUID of the Evoking Object
|
||||
matching_action_item_status_list, //List of STRINGs for the ActionItemStatus
|
||||
matching_order_guid_list, //List of GUIDs for the ActionItemID
|
||||
matching_name_list, //List of STRINGs for the ActionItemName
|
||||
matching_master_guid_list, //List of GUIDs for ActionEnterpriseItemID
|
||||
matching_short_message_list, //List of STRINGs for the ShortMessage
|
||||
matching_is_suspended_list ) //List of Booleans for Suspended Orders
|
||||
:= ARGUMENT;
|
||||
|
||||
// Declare the MLM that can be called by this MLM
|
||||
func_create_alert_action_object := MLM {{{SINGLE-QUOTE}}}STD_Func_Create_Alert_Action_Object{{{SINGLE-QUOTE}}};
|
||||
|
||||
// Execute only when this MLM is called by the editor
|
||||
if called_by_editor then
|
||||
obj := read last
|
||||
{ Order: THIS
|
||||
WHERE GUID = order_guid };
|
||||
EvokingObject := obj;
|
||||
endif;
|
||||
|
||||
//---------------------------------------------
|
||||
// Call the MLM to Create AlertAction Objects
|
||||
//---------------------------------------------
|
||||
|
||||
// Get data from the Evoking Object
|
||||
(evoking_catalog_item_guid,
|
||||
evoking_object_name):= read last
|
||||
{Order: OrderCatalogMasterItemGUID, Name
|
||||
REFERENCING EvokingObject };
|
||||
|
||||
|
||||
// Set Values for AlertAction data
|
||||
evoking_object_table := "CV3Order";
|
||||
action_item_table := "CV3Order";
|
||||
mlm_name := "STD_VENIPUNCTURE";
|
||||
alert_action_object_list := ();
|
||||
counter_list := 1 seqto (count matching_order_guid_list );
|
||||
|
||||
for JJ in counter_list do
|
||||
// Process Through the Lists
|
||||
// to Set Variables that will populate the AlertAction object
|
||||
action_item_name := matching_name_list[JJ];
|
||||
action_item_catalog_item_guid := matching_master_guid_list[JJ];
|
||||
action_item_guid := matching_order_guid_list[JJ];
|
||||
action_item_status := matching_action_item_status_list [JJ];
|
||||
is_suspended := matching_is_suspended_list[JJ];
|
||||
short_message := matching_short_message_list[JJ];
|
||||
|
||||
// Create the correct action_event_list for EXISTING and UNSUBMITTED orders
|
||||
if action_item_status = "Existing"
|
||||
then
|
||||
//Do NOT suspend an order that is already suspended.
|
||||
if is_suspended
|
||||
then action_event_list := "DC-Cancel", "Modify";
|
||||
else action_event_list := "DC-Cancel", "Modify", "Suspend";
|
||||
endif; //if is_suspended
|
||||
elseif action_item_status = "Unsubmitted"
|
||||
then action_event_list := "Delete", "Modify";
|
||||
endif;
|
||||
|
||||
for action_event in action_event_list do
|
||||
|
||||
// Create the AlertAction Object
|
||||
alert_action_obj:= call func_create_alert_action_object with
|
||||
(evoking_object_table,
|
||||
action_item_table) ;
|
||||
|
||||
// Set the Shared Values for a Single Instance of the AlertAction Object
|
||||
alert_action_obj.EvokingEnterpriseItemID := evoking_catalog_item_guid;
|
||||
alert_action_obj.EvokingObjectID := order_guid;
|
||||
alert_action_obj.EvokingObjectName := evoking_object_name;
|
||||
alert_action_obj.ActionEvent := action_event;
|
||||
alert_action_obj.ActionItemStatus := action_item_status;
|
||||
alert_action_obj.ActionItemID := action_item_guid;
|
||||
alert_action_obj.ActionItemName := action_item_name;
|
||||
alert_action_obj.ActionEnterpriseItemID := action_item_catalog_item_guid;
|
||||
alert_action_obj.MLMName := mlm_name;
|
||||
alert_action_obj.ShortMessage := short_message;
|
||||
|
||||
// Add AlertAction object to a list
|
||||
alert_action_object_list := alert_action_object_list, alert_action_obj;
|
||||
|
||||
enddo; //for action_event
|
||||
enddo; //for JJ
|
||||
;;
|
||||
evoke:
|
||||
;;
|
||||
logic:
|
||||
conclude true;
|
||||
;;
|
||||
action:
|
||||
return alert_action_object_list;
|
||||
;;
|
||||
end:
|
||||
67
MLMStripper/bin/Debug/STD/STD_INCLUDE_LIBS.mlm
Normal file
67
MLMStripper/bin/Debug/STD/STD_INCLUDE_LIBS.mlm
Normal file
@@ -0,0 +1,67 @@
|
||||
maintenance:
|
||||
|
||||
title: Standard assemblies and namespaces;;
|
||||
mlmname: std_include_libs;;
|
||||
arden: version 2.5;;
|
||||
version: 18.4;;
|
||||
institution: Allscripts Corporation, 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: The purpose of this MLM is to include the .NET Assemblies and
|
||||
namespaces required by most ObjectPlus MLMs
|
||||
;;
|
||||
explanation: Include this MLM at the start of any MLM that will
|
||||
be making any .NET calls standard System and ObjectPlus
|
||||
assemblies
|
||||
Example:
|
||||
standard_libs := MLM {{{SINGLE-QUOTE}}}std_include_libs{{{SINGLE-QUOTE}}};
|
||||
include standard_libs;
|
||||
;;
|
||||
keywords:
|
||||
;;
|
||||
knowledge:
|
||||
type: data-driven;;
|
||||
data:
|
||||
using "mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089";
|
||||
using "System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089";
|
||||
using "ObjectsPlusXA.SCM";
|
||||
using "Sunrise.Tasking.ServiceContracts";
|
||||
|
||||
using namespace "System";
|
||||
using namespace "System.Exception";
|
||||
using namespace "System.Windows.Forms";
|
||||
using namespace "ObjectsPlusXA.SunriseClinicalManager";
|
||||
using namespace "Sunrise.Tasking.ServiceContracts";
|
||||
using namespace "Sunrise.Tasking.ServiceContracts.Enums";
|
||||
|
||||
;;
|
||||
priority: 50
|
||||
;;
|
||||
evoke:
|
||||
;;
|
||||
logic:
|
||||
;;
|
||||
action:
|
||||
;;
|
||||
Urgency: 50;;
|
||||
|
||||
end:
|
||||
2401
MLMStripper/bin/Debug/STD/STD_PREGNANCY_AND_LACTATION.mlm
Normal file
2401
MLMStripper/bin/Debug/STD/STD_PREGNANCY_AND_LACTATION.mlm
Normal file
File diff suppressed because it is too large
Load Diff
835
MLMStripper/bin/Debug/STD/STD_TOTAL_DAILY_DOSE_EXCEEDED.mlm
Normal file
835
MLMStripper/bin/Debug/STD/STD_TOTAL_DAILY_DOSE_EXCEEDED.mlm
Normal file
@@ -0,0 +1,835 @@
|
||||
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:
|
||||
947
MLMStripper/bin/Debug/STD/STD_VENIPUNCTURE.mlm
Normal file
947
MLMStripper/bin/Debug/STD/STD_VENIPUNCTURE.mlm
Normal file
@@ -0,0 +1,947 @@
|
||||
maintenance:
|
||||
|
||||
title: Venipuncture Consolidation;;
|
||||
mlmname: STD_VENIPUNCTURE;;
|
||||
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: Recommends consolidation of blood collections to improve patient comfort by
|
||||
avoiding duplicate venipunctures and to avoid inefficient blood draws.
|
||||
Provides Actions on Alerts with each recommendation.
|
||||
;;
|
||||
explanation: An Evoking-Order is considered a candidate for venipuncture consolidation
|
||||
of Other-Orders when all of the criteria listed below are met:
|
||||
a. The Evoking-Order is one of the following events: new order, released from hold,
|
||||
activated from a conditional order, unsuspended, verified, or an order that
|
||||
has a modified significant-date.
|
||||
b. The evoking-order has a Type Code of "Diagnostic." "Medication" and "Other" are
|
||||
excluded, unless the order name is listed in the event clause.
|
||||
c. A flag, check_for_unsubmitted_orders, in the MLM determines which Other-Orders
|
||||
are checked. FALSE=only orders stored in the database. TRUE=unsubmitted orders
|
||||
and orders stored in the database. The default setting is TRUE.
|
||||
d. The orders (Evoking-Order and the Other-Orders) have order status level numbers
|
||||
between 0-50 (AWPA-AUA10, inclusive), excluding 15 = HOLD.
|
||||
e. CONDITIONAL, PRN, and Suspended orders are excluded.
|
||||
f. Master Repeat Orders are excluded.
|
||||
g. The orders have been designated for venipuncture consolidation checking with
|
||||
an "HVC-Venipuncture" "Yes" in their item-catalog-Ordering Information 2 panel.
|
||||
h. The location of the patient is not excluded from venipuncture checking in
|
||||
the HVC-Venipuncture Policy. The patient{{{SINGLE-QUOTE}}}s location is based on
|
||||
the location-business-rules established by the facility for other parts of
|
||||
Sunrise Clinical Manager.
|
||||
i. The Other-Orders are within the scoping rules for the patient location listed
|
||||
in the HVC-Venipuncture Policy.
|
||||
j. The Other-Orders are within the consolidation period specified in
|
||||
HVC-Venipuncture Policy, and are NOT in the past (ie. less than NOW, adjusted
|
||||
by the EXACT MATCH time criteria in the HVC-Venipuncture Policy).
|
||||
k. STAT orders cannot be consolidated.
|
||||
Routine (RTN) orders can be moved to a time critical (TIMEC) collection time,
|
||||
but a TIMEC order cannot be moved to a RTN collection time.
|
||||
Two RTN orders can be moved to the others collection times.
|
||||
l. Exception---If another order requiring a venipuncture is already scheduled for
|
||||
the same time slot as the evoking order, then a venipuncture alert is not needed,
|
||||
since it is already consolidated.
|
||||
|
||||
The GENERATE_ACTIONS_ON_ALERTS variable indicates whether to generate
|
||||
Actions on Alerts. The values are:
|
||||
* TRUE = Generate Actions on Alerts
|
||||
* FALSE = Do NOT generate Actions on Alerts
|
||||
|
||||
Master orders (ComplexOrderType of 1,3,5) existing in the database from Complex and
|
||||
Multiple Frequencies Orders are not checked.
|
||||
The following ComplexOrderType values define the type of order:
|
||||
0 or NULL - regular order
|
||||
1 - Sequential Complex Dose Master
|
||||
2 - Sequential Complex Dose Child Order
|
||||
3 - Concurrent Complex Dose Master
|
||||
4 - Concurrent Complex Dose Child Order
|
||||
5 - Multiple Frequencies Master
|
||||
6 - Multiple Frequencies Child Order
|
||||
|
||||
Change history
|
||||
|
||||
12.27.2010 DW Added site customization to 5.5 version
|
||||
02.26.2013 JML Added logic to not display venipuncture alert for AM Round orders
|
||||
07.15.2015 TMS Added site customization to 15.1 version. CSR 33555
|
||||
11.14.2016 TMS Added site customization to 16.3 version. CSR 35130
|
||||
03.21.2019 TMS Added site customization to 18.4 version. CSR 37676
|
||||
|
||||
|
||||
;;
|
||||
keywords: Venipuncture;
|
||||
;;
|
||||
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 logging is needed.*/
|
||||
log_execution_info := false;
|
||||
|
||||
/* If UNSUBMITTED orders need to be checked for venipuncture consolidation */
|
||||
/* Set the flag below to TRUE */
|
||||
check_for_unsubmitted_orders:= TRUE;
|
||||
|
||||
/* Set a flag indicating whether or not Actions on Alerts should be generated */
|
||||
generate_actions_on_alerts := TRUE;
|
||||
|
||||
/* Change the message within the quotes if a different short-message is needed.*/
|
||||
venipuncture_alert:= destination { Alert: warning,
|
||||
"Venipuncture Consolidation", low, chart,
|
||||
"HVC Activity Consolidations", 1005 };
|
||||
|
||||
/* Change the spelling within the quotes to match the order item-catalog.*/
|
||||
/* If Non-diagnostic (Medication or Other) orders need to be screened, */
|
||||
/* change the string "Order_Name#" to the name of the non-diagnostic order. */
|
||||
/* If there are more than 3 of these, add more ORs to the where clause */
|
||||
|
||||
any_new_order:= event {OrderEnter User Order:
|
||||
WHERE OrderStatusLevelNum >= 0
|
||||
AND OrderStatusLevelNum <= 50
|
||||
AND OrderStatusCode <> "HOLD"
|
||||
AND IsConditional = FALSE
|
||||
AND IsPRN = FALSE
|
||||
AND IsSuspended = FALSE
|
||||
AND SystemOrderPriorityCode <> "STAT"
|
||||
AND (TypeCode = "Diagnostic"
|
||||
OR Name = "Order_Name1"
|
||||
OR Name = "Order_Name2"
|
||||
OR Name = "Order_Name3" )};
|
||||
|
||||
any_new_patient_group_order:= event {OrderEnter Batch Order:
|
||||
WHERE OrderStatusLevelNum >= 0
|
||||
AND OrderStatusLevelNum <= 50
|
||||
AND OrderStatusCode <> "HOLD"
|
||||
AND IsConditional = FALSE
|
||||
AND IsPRN = FALSE
|
||||
AND IsSuspended = FALSE
|
||||
AND SystemOrderPriorityCode <> "STAT"
|
||||
AND (TypeCode = "Diagnostic"
|
||||
OR Name = "Order_Name1"
|
||||
OR Name = "Order_Name2"
|
||||
OR Name = "Order_Name3" )
|
||||
AND IsCreatedFromPatientGroupOrderTemplate = TRUE};
|
||||
|
||||
any_modified_order:= event {OrderModify User Order:
|
||||
WHERE OrderStatusLevelNum >= 0
|
||||
AND OrderStatusLevelNum <= 50
|
||||
AND OrderStatusCode <> "HOLD"
|
||||
AND IsConditional = FALSE
|
||||
|
||||
AND IsPRN = FALSE
|
||||
AND IsSuspended = FALSE
|
||||
AND SystemOrderPriorityCode <> "STAT"
|
||||
AND (TypeCode = "Diagnostic"
|
||||
OR Name = "Order_Name1"
|
||||
OR Name = "Order_Name2"
|
||||
OR Name = "Order_Name3" )};
|
||||
|
||||
|
||||
any_released_order:= event {OrderRelease User Order:
|
||||
WHERE OrderStatusLevelNum >= 0
|
||||
AND OrderStatusLevelNum <= 50
|
||||
AND OrderStatusCode <> "HOLD"
|
||||
AND IsConditional = FALSE
|
||||
AND IsPRN = FALSE
|
||||
AND IsSuspended = FALSE
|
||||
AND SystemOrderPriorityCode <> "STAT"
|
||||
AND (TypeCode = "Diagnostic"
|
||||
OR Name = "Order_Name1"
|
||||
OR Name = "Order_Name2"
|
||||
OR Name = "Order_Name3" )};
|
||||
|
||||
|
||||
any_unsuspended_order:= event {OrderUnsuspend User Order:
|
||||
WHERE OrderStatusLevelNum >= 0
|
||||
AND OrderStatusLevelNum <= 50
|
||||
AND OrderStatusCode <> "HOLD"
|
||||
AND IsConditional = FALSE
|
||||
AND IsPRN = FALSE
|
||||
AND IsSuspended = FALSE
|
||||
AND SystemOrderPriorityCode <> "STAT"
|
||||
AND (TypeCode = "Diagnostic"
|
||||
OR Name = "Order_Name1"
|
||||
OR Name = "Order_Name2"
|
||||
OR Name = "Order_Name3" )};
|
||||
|
||||
|
||||
any_verified_order:= event {OrderVerify User Order:
|
||||
WHERE OrderStatusLevelNum >= 0
|
||||
AND OrderStatusLevelNum <= 50
|
||||
AND OrderStatusCode <> "HOLD"
|
||||
AND IsConditional = FALSE
|
||||
AND IsPRN = FALSE
|
||||
AND IsSuspended = FALSE
|
||||
AND SystemOrderPriorityCode <> "STAT"
|
||||
AND (TypeCode = "Diagnostic"
|
||||
OR Name = "Order_Name1"
|
||||
OR Name = "Order_Name2"
|
||||
OR Name = "Order_Name3" )};
|
||||
|
||||
|
||||
/***************** Do not change these Internal Representations *****************/
|
||||
|
||||
hold_code:= "HOLD";
|
||||
stat_code:= "STAT";
|
||||
routine_code:= "RTN";
|
||||
time_critical_code:= "TIMEC";
|
||||
lowest_level:= 0;
|
||||
highest_level:= 50;
|
||||
|
||||
/* Set the master order types */
|
||||
complex_master_order_type := (1,3,5);
|
||||
|
||||
continue_checking_order := true;
|
||||
|
||||
/********************************************************************************/
|
||||
|
||||
/* Executes only when this MLM is called by the editor */
|
||||
if called_by_editor then
|
||||
order_obj:= read last
|
||||
{Order: This
|
||||
WHERE Name = "cbc"
|
||||
// AND complexordertype is not in (2,4,6)
|
||||
// AND ORDERSTATUSLEVELNUM <=50
|
||||
};
|
||||
EvokingObject:= order_obj;
|
||||
endif;
|
||||
|
||||
/* Declares MLMs which can be called */
|
||||
calc_duration:= MLM {{{SINGLE-QUOTE}}}std_func_dup_duration{{{SINGLE-QUOTE}}};
|
||||
func_venipuncture_actions := MLM {{{SINGLE-QUOTE}}}std_func_venipuncture_actions{{{SINGLE-QUOTE}}};
|
||||
|
||||
/* Gets the Client GUID */
|
||||
client_guid := read last {ClientInfo: GUID};
|
||||
|
||||
/* Gets the TimeZone of current evoking order */
|
||||
visit_tz := read last {ClientVisit: TimeZone};
|
||||
|
||||
/* Gets information from the evoking Order */
|
||||
(order_name,
|
||||
order_guid,
|
||||
order_status_code,
|
||||
order_level_num,
|
||||
order_summary_line,
|
||||
item_catalog_guid,
|
||||
chart_guid,
|
||||
client_visit_guid,
|
||||
order_significant_date,
|
||||
order_stop_date,
|
||||
order_sys_priority,
|
||||
order_user_priority,
|
||||
order_is_conditional,
|
||||
order_complex_type,
|
||||
order_variable_component_obj,
|
||||
back_up_obj) := read last
|
||||
{Order: Name, GUID, OrderStatusCode, OrderStatusLevelNum, SummaryLine,
|
||||
OrderCatalogMasterItemGUID, ChartGUID, ClientVisitGUID, SignificantDtm, StopDtm
|
||||
SystemOrderPriorityCode, OrderPriorityCode, IsConditional, ComplexOrderType,
|
||||
OrderVariableComponent, BackUp
|
||||
REFERENCING EvokingObject};
|
||||
|
||||
|
||||
|
||||
|
||||
/* Check to see if this is a master order and if so whether children exist */
|
||||
if exists order_complex_type
|
||||
and order_complex_type IS IN complex_master_order_type
|
||||
then
|
||||
|
||||
/* Gets information from the order variable components */
|
||||
(component_child_order_guid_list) := read
|
||||
{OrderVariableComponent: ChildOrderGUID
|
||||
REFERENCING order_variable_component_obj};
|
||||
|
||||
/* Check to see if children exist */
|
||||
if exists component_child_order_guid_list
|
||||
then
|
||||
child_orders_generated := true;
|
||||
|
||||
/* If children exist, this MLM should not run on Master order on modify or unsuspend */
|
||||
If EvokingEventType = any_modified_order.type
|
||||
OR EvokingEventType = any_unsuspended_order.type
|
||||
then
|
||||
|
||||
continue_checking_order := false;
|
||||
endif; //If EvokingEventType = any_modified_order.type
|
||||
|
||||
/* This is a master order without children*/
|
||||
else
|
||||
continue_checking_order := true;
|
||||
endif; //if exists component_child_order_guid_list
|
||||
|
||||
endif; //if exists order_complex_type
|
||||
|
||||
|
||||
/* Determines if a modified order should be checked for duplicates */
|
||||
If EvokingEventType = any_modified_order.type
|
||||
and continue_checking_order
|
||||
then
|
||||
|
||||
if exist back_up_obj
|
||||
then
|
||||
back_up_obj_date:= read last
|
||||
{Order: SignificantDtm
|
||||
REFERENCING back_up_obj};
|
||||
|
||||
if (back_up_obj_signif_date <> order_significant_date)
|
||||
OR
|
||||
(back_up_obj_stop_date <> order_stop_date)
|
||||
OR
|
||||
(back_up_obj_stop_date is null and order_stop_date is time)
|
||||
OR
|
||||
(back_up_obj_stop_date is time and order_stop_date is null)
|
||||
then continue_checking_order:= true;
|
||||
endif; /* back_up_obj_signif_date... */
|
||||
else
|
||||
continue_checking_order:= false;
|
||||
endif; /* if exist back_up_obj */
|
||||
endif; /* If EvokingEventType = any_modified_order.type */
|
||||
|
||||
// St.Clair Hospital Customization after this //
|
||||
|
||||
/* Get User Info */
|
||||
|
||||
no_fire_on_User := ("gfino","chughes","mvennero");
|
||||
|
||||
user_id := read last {UserInfo: idcode};
|
||||
userinlist := user_id in no_fire_on_User;
|
||||
|
||||
if userinlist = True
|
||||
then
|
||||
continue_checking_order := False;
|
||||
endif;
|
||||
|
||||
//CSR 25233: AM Rounds change
|
||||
if (order_user_priority = "AM Rounds") then
|
||||
continue_checking_order := false;
|
||||
endif;
|
||||
|
||||
// St.Clair Hospital Customization before this //
|
||||
|
||||
If continue_checking_order
|
||||
then
|
||||
|
||||
/* Gets the Item-Catalog GUIDs that have HVC-Venipuncture YES associated with it */
|
||||
(venipuncture_catalog_GUID_list,
|
||||
veni_value,
|
||||
veni_code):= read
|
||||
{"SELECT CV3CatalogClassTypeValue.CatalogMasterGUID,"
|
||||
||" CV3CatalogClassTypeValue.Value, CV3ClassType.Code "
|
||||
||" FROM CV3ClassType JOIN CV3CatalogClassTypeValue "
|
||||
||" ON CV3ClassType.GUID = CV3CatalogClassTypeValue.ClassTypeGUID "
|
||||
||" WHERE CV3ClassType.Code = {{{SINGLE-QUOTE}}}HVC-Venipuncture{{{SINGLE-QUOTE}}} "
|
||||
||" AND CV3CatalogClassTypeValue.Value = {{{SINGLE-QUOTE}}}Yes{{{SINGLE-QUOTE}}} "
|
||||
||" AND CV3CatalogClassTypeValue.Active = 1 " };
|
||||
|
||||
|
||||
/* Continue if the Item-Catalog is marked with a HVC-Venipuncture YES */
|
||||
If item_catalog_GUID is in venipuncture_catalog_GUID_list
|
||||
then
|
||||
/* Gets the patient{{{SINGLE-QUOTE}}}s location group */
|
||||
If called_by_editor
|
||||
Then
|
||||
/* Since the patient has many visits, we must get the one from the Evoking Object */
|
||||
patient_loc_group:= read last
|
||||
{ ClientVisit: BusinessRuleLocationGUID
|
||||
where GUID = client_visit_guid};
|
||||
Else
|
||||
patient_loc_group:= read last
|
||||
{ ClientVisit: BusinessRuleLocationGUID};
|
||||
Endif;
|
||||
|
||||
/* Gets the HVC-Venipuncture Policy information */
|
||||
(venpuncture_policy_name,
|
||||
policy_loc_group_guid_list,
|
||||
policy_scope_list,
|
||||
policy_performed_time_list,
|
||||
policy_performed_unit_list,
|
||||
policy_exact_time_list,
|
||||
policy_exact_unit_list,
|
||||
policy_scheduled_time_list,
|
||||
policy_scheduled_unit_list,
|
||||
policy_loc_is_excluded_list) := read
|
||||
{"SELECT Name, LocationGroupGUID, SearchScope, PastTime, PastTimeUnits,"
|
||||
|| " ExactTime, ExactTimeUnits, FutureTime, FutureTimeUnits, IsExcluded"
|
||||
|| " FROM CV3OrderDuplicatePolicy JOIN CV3OrderDuplicatePolicyDtl "
|
||||
|| " ON CV3OrderDuplicatePolicyDtl.OrderDuplicatePolicyGUID = "
|
||||
|| " CV3OrderDuplicatePolicy.GUID "
|
||||
|| " WHERE CV3OrderDuplicatePolicy.Name = {{{SINGLE-QUOTE}}}HVC-Venipuncture Policy{{{SINGLE-QUOTE}}} "
|
||||
|| " AND LocationGroupGUID IN (0, " || SQL(patient_loc_group) || " )"
|
||||
|| " AND CV3OrderDuplicatePolicy.Active = 1 "
|
||||
|| " AND CV3OrderDuplicatePolicyDtl.Active = 1 "};
|
||||
|
||||
/* Matches patient{{{SINGLE-QUOTE}}}s location group to the item-catalog{{{SINGLE-QUOTE}}}s location group and */
|
||||
/* Determines if the match excludes the location from duplicate checking */
|
||||
If exist policy_scope_list
|
||||
then
|
||||
If any (patient_loc_group = policy_loc_group_guid_list)
|
||||
then
|
||||
loc_group_found := patient_loc_group = policy_loc_group_guid_list;
|
||||
else
|
||||
loc_group_found := policy_loc_group_guid_list is null;
|
||||
endif;
|
||||
loc_is_excluded := last (policy_loc_is_excluded_list where loc_group_found);
|
||||
endif; /* if exist policy_loc_group_guid_list */
|
||||
|
||||
|
||||
/* Continue if there is a location group match or a default location group */
|
||||
/* and the location is not excluded from duplicate checking */
|
||||
If any loc_group_found and not loc_is_excluded
|
||||
then
|
||||
/*--------------------------------------------------*/
|
||||
/* Finds the scope and times for the location group */
|
||||
/*--------------------------------------------------*/
|
||||
policy_loc_grp := last (policy_loc_group_guid_list where loc_group_found);
|
||||
policy_scope := last (policy_scope_list where loc_group_found);
|
||||
policy_performed_time := last (policy_performed_time_list where loc_group_found);
|
||||
policy_performed_unit := last (policy_performed_unit_list where loc_group_found);
|
||||
policy_exact_time := last (policy_exact_time_list where loc_group_found);
|
||||
policy_exact_unit := last (policy_exact_unit_list where loc_group_found);
|
||||
policy_scheduled_time := last (policy_scheduled_time_list where loc_group_found);
|
||||
policy_scheduled_unit := last (policy_scheduled_unit_list where loc_group_found);
|
||||
|
||||
|
||||
/*-------------------------------------*/
|
||||
/* Converts EXACT TIME into Arden Time */
|
||||
/*-------------------------------------*/
|
||||
If policy_exact_time > 0 and policy_exact_unit is string
|
||||
then
|
||||
exact_duration:= call calc_duration with
|
||||
(policy_exact_time, policy_exact_unit);
|
||||
If policy_exact_unit = "days"
|
||||
then exact_low_time:= (day floor of order_significant_date)
|
||||
- exact_duration ;
|
||||
exact_high_time:= (day floor of order_significant_date)
|
||||
+ exact_duration + (1 day) - (1 second);
|
||||
else exact_low_time:= order_significant_date - exact_duration;
|
||||
exact_high_time:= order_significant_date + exact_duration;
|
||||
endif; /* if policy_exact_unit = */
|
||||
else
|
||||
exact_low_time:= order_significant_date;
|
||||
exact_high_time:= order_significant_date;
|
||||
endif; /* if policy_exact_time > 0...*/
|
||||
|
||||
|
||||
/*-----------------------------------------*/
|
||||
/* Converts PERFORMED TIME into Arden Time */
|
||||
/*-----------------------------------------*/
|
||||
If policy_performed_time > 0 and policy_performed_unit is string
|
||||
then
|
||||
performed_duration:= call calc_duration with
|
||||
(policy_performed_time, policy_performed_unit);
|
||||
If policy_performed_unit = "days"
|
||||
then past_time:= (day floor of order_significant_date)
|
||||
- performed_duration;
|
||||
else past_time:= order_significant_date - performed_duration;
|
||||
endif; /* if policy_performed_unit = */
|
||||
else
|
||||
past_time:= exact_low_time;
|
||||
endif; /* if policy_performed_time > 0...*/
|
||||
|
||||
/* Reset the time to NOW - EXACT MATCH time criteria, */
|
||||
/* when past_time is less than now */
|
||||
If past_time < now
|
||||
then
|
||||
visit_now := now AS Time visit_tz;
|
||||
If policy_exact_unit = "days"
|
||||
then past_time:= (day floor of visit_now ) - exact_duration ;
|
||||
else past_time:= visit_now - exact_duration;
|
||||
endif; /* If policy_exact_unit */
|
||||
endif; /* If past_time < now */
|
||||
|
||||
/*-----------------------------------------*/
|
||||
/* Converts SCHEDULED TIME into Arden Time */
|
||||
/*-----------------------------------------*/
|
||||
If policy_scheduled_time > 0 and policy_scheduled_unit is string
|
||||
then
|
||||
scheduled_duration:= call calc_duration with
|
||||
(policy_scheduled_time, policy_scheduled_unit);
|
||||
If policy_scheduled_unit = "days"
|
||||
then future_time:= (day floor of order_significant_date)
|
||||
+ scheduled_duration + (1 day) - (1 second);
|
||||
else future_time:= order_significant_date + scheduled_duration;
|
||||
endif; /* if policy_scheduled_unit = */
|
||||
else
|
||||
future_time:= exact_high_time;
|
||||
endif; /* if policy_scheduled_time > 0...*/
|
||||
|
||||
/* Reset the time to NOW + EXACT MATCH time criteria, */
|
||||
/* when future_time is less than now */
|
||||
If future_time < now
|
||||
then
|
||||
visit_now := now AS Time visit_tz;
|
||||
if policy_exact_unit = "days"
|
||||
then
|
||||
future_time:= (day floor of visit_now )
|
||||
+ exact_duration + (1 day) - (1 second);
|
||||
else
|
||||
future_time:= visit_now + exact_duration;
|
||||
endif; /* if policy_exact_unit ... */
|
||||
endif; /* If future_time < now */
|
||||
|
||||
/*-----------------------------------------------------*/
|
||||
/* Sets the SCOPE to retrieve orders from the database */
|
||||
/*-----------------------------------------------------*/
|
||||
If policy_scope = "This Chart"
|
||||
then
|
||||
ID_equals_patient_GUID := "CV3Order.ClientGUID = " || SQL(client_guid)
|
||||
|| " AND CV3Order.ChartGUID = " || SQL(chart_guid);
|
||||
elseif policy_scope = "This Visit"
|
||||
then
|
||||
ID_equals_patient_GUID := "CV3Order.ClientGUID = " || SQL(client_guid)
|
||||
|| " AND CV3Order.ChartGUID = " || SQL(chart_guid)
|
||||
|| " AND CV3Order.ClientVisitGUID = " || SQL(client_visit_guid);
|
||||
else
|
||||
ID_equals_patient_GUID := "CV3Order.ClientGUID = " || SQL(client_guid);
|
||||
endif; /* policy_scope */
|
||||
|
||||
/*---------------------------------------------*/
|
||||
/* Get the GUIDs of ALL the Unsubmitted Orders */
|
||||
/*---------------------------------------------*/
|
||||
/* So we do not retrieve them from the database */
|
||||
(all_unsub_intended_action,
|
||||
all_unsub_order_name_list,
|
||||
all_unsub_order_guid_list) := read
|
||||
{UnsubmittedOrders: IntendedAction, Name, GUID
|
||||
WHERE GUID <> order_guid};
|
||||
|
||||
/*----------------------------------*/
|
||||
/* Only get some UNSUBMITTED ORDERS */
|
||||
/*----------------------------------*/
|
||||
/* 1. They are New or Modifed unsubmitted orders */
|
||||
/* 2. The check_for_unsubmitted_orders flag is true */
|
||||
|
||||
If check_for_unsubmitted_orders
|
||||
then
|
||||
(unsub_order_name_list,
|
||||
unsub_order_guid_list,
|
||||
unsub_significant_date_list,
|
||||
unsub_sys_priority_list,
|
||||
unsub_user_priority_list,
|
||||
unsub_is_conditional_list,
|
||||
unsub_is_suspended_list,
|
||||
unsub_order_status_code_list,
|
||||
unsub_order_status_level_list,
|
||||
unsub_summary_list,
|
||||
unsub_master_GUID_list ):= read
|
||||
{UnsubmittedOrders: Name, GUID, SignificantDtm,
|
||||
SystemOrderPriorityCode, OrderPriorityCode,
|
||||
IsConditional, IsSuspended, OrderStatusCode,
|
||||
OrderStatusLevelNum, SummaryLine, OrderCatalogMasterItemGUID
|
||||
WHERE SignificantDtm >= past_time
|
||||
AND SignificantDtm <= future_time
|
||||
AND IsConditional = FALSE
|
||||
AND IsPRN = FALSE
|
||||
AND IsSuspended = FALSE
|
||||
AND SystemOrderPriorityCode <> stat_code
|
||||
AND OrderStatusLevelNum >= lowest_level
|
||||
AND OrderStatusLevelNum <= highest_level
|
||||
AND OrderStatusCode <> HOLD_code
|
||||
AND RepeatOrder <> 1
|
||||
AND GUID <> order_guid
|
||||
AND (IntendedAction is NULL
|
||||
OR IntendedAction is in ("Add New","Modify","Modified"))};
|
||||
|
||||
endif; /* if check_for_unsubmitted_orders */
|
||||
|
||||
/* Get ALL the UNSUBMITTED ORDERS */
|
||||
|
||||
|
||||
/*------------------------------------------------------------------------------*/
|
||||
/* Create a fragment of the SQL code that avoids retrieving the same orders */
|
||||
/* from the database that are in the unsubmitted list. */
|
||||
/* This is needed when the CDS Trigger is one of the order maintenance triggers */
|
||||
/* and the user is performing a multi-order function */
|
||||
/*------------------------------------------------------------------------------*/
|
||||
|
||||
/* Initialize variable to empty string */
|
||||
AND_avoid_these_unsubmitted_order_guids := "";
|
||||
|
||||
/* Concatenate a fragment of the SQL code to the initalized variable */
|
||||
if exist all_unsub_order_guid_list
|
||||
then
|
||||
if (count(all_unsub_order_guid_list) = 1)
|
||||
then
|
||||
//Set up to exclude this single order item
|
||||
single_unsub_order_guid := last of (all_unsub_order_guid_list);
|
||||
AND_avoid_these_unsubmitted_order_guids := AND_avoid_these_unsubmitted_order_guids
|
||||
|| " AND (CV3Order.GUID <> " || SQL(single_unsub_order_guid)||")";
|
||||
|
||||
else
|
||||
//Set up to exclude the these order guids
|
||||
AND_avoid_these_unsubmitted_order_guids := AND_avoid_these_unsubmitted_order_guids
|
||||
|| " AND (CV3Order.GUID NOT IN (" || SQL(all_unsub_order_guid_list)||"))";
|
||||
endif;
|
||||
else
|
||||
AND_avoid_these_unsubmitted_order_guids :="";
|
||||
endif;
|
||||
|
||||
/* Create 2 tables temporary result sets of potential orders within the range of maximum time zone difference */
|
||||
/* These results will then be filtered by the datetime range based on the Duplicate Policy */
|
||||
FROM_common_columns := " Name, CV3Order.GUID, "
|
||||
|| " ConvSignificantDtm.TimeValue as SignificantDtmOffset, "
|
||||
|| " SystemOrderPriorityCode, "
|
||||
|| " OrderPriorityCode, IsConditional,IsSuspended, "
|
||||
|| " OrderStatusCode, OrderStatusLevelNum, "
|
||||
|| " SummaryLine, OrderCatalogMasterItemGUID "
|
||||
|| " FROM CV3Order "
|
||||
|| " INNER JOIN CV3ClientVisit v on v.GUID = CV3Order.ClientVisitGUID"
|
||||
|| " CROSS APPLY dbo.SXADBConvertLocalToOffsetTblFn(v.TimeZone, SignificantDtm) AS ConvSignificantDtm ";
|
||||
|
||||
max_hours_differece_between_time_zones := 26 as number;
|
||||
WHERE_conditions_common := " WHERE " || ID_equals_patient_GUID
|
||||
|| " AND CV3Order.SignificantDtm >= dateadd( hour, -" || SQLEX(max_hours_differece_between_time_zones)
|
||||
|| ", " || SQL(past_time) || " )" // filter out potential orders based on unconverted datetime
|
||||
|| " AND CV3Order.SignificantDtm <= dateadd( hour, " || SQLEX(max_hours_differece_between_time_zones)
|
||||
|| ", " || SQL(future_time) || " )" // filter out potential orders based on unconverted datetime;
|
||||
|| " AND CV3Order.OrderStatusLevelNum >= " || SQLEX(lowest_level)
|
||||
|| " AND CV3Order.OrderStatusLevelNum <= " || SQLEX(highest_level)
|
||||
|| " AND CV3Order.IsConditional = 0 "
|
||||
|| " AND CV3Order.IsPRN = 0 "
|
||||
|| " AND CV3Order.IsSuspended = 0 "
|
||||
|| " AND CV3Order.Active = 1"
|
||||
|| " AND CV3Order.SystemOrderPriorityCode <> " ||SQLEX(stat_code)
|
||||
|| " AND CV3Order.RepeatOrder <> 1 "
|
||||
|| " AND CV3Order.GUID <> " || SQLEX(order_guid)
|
||||
|| " AND CV3Order.OrderStatusCode <> " || SQLEX(HOLD_code);
|
||||
|
||||
|
||||
FROM_result_columns := " Name, GUID, SignificantDtmOffset, SystemOrderPriorityCode, OrderPriorityCode, IsConditional,IsSuspended, "
|
||||
|| " OrderStatusCode, OrderStatusLevelNum, "
|
||||
|| " SummaryLine, OrderCatalogMasterItemGUID ";
|
||||
|
||||
Filter_by_policy_datetime_range := " SignificantDtmOffset >= " || SQLEX(past_time)
|
||||
|| " AND SignificantDtmOffset <= " || SQLEX(future_time);
|
||||
|
||||
/*----------------------------------*/
|
||||
/* Gets the list of DATABASE ORDERS */
|
||||
/*----------------------------------*/
|
||||
(db_order_name_list,
|
||||
db_order_guid_list,
|
||||
db_significant_date_list,
|
||||
db_sys_priority_list,
|
||||
db_user_priority_list,
|
||||
db_is_conditional_list,
|
||||
db_is_suspended_list,
|
||||
db_order_status_code_list,
|
||||
db_order_status_level_list,
|
||||
db_summary_list,
|
||||
db_master_GUID_list ):= read
|
||||
{ ";With CteAllOrders AS ( "
|
||||
|| "SELECT " || FROM_common_columns
|
||||
|| WHERE_conditions_common
|
||||
|| " AND CV3Order.ComplexOrderType NOT IN (" || complex_master_order_type|| ")"
|
||||
|| " ), "
|
||||
|| " CteAllOrdersComp AS ( "
|
||||
|| "SELECT DISTINCT " || FROM_common_columns
|
||||
|| " INNER JOIN CV3OrderVariableComponent"
|
||||
|| " ON CV3Order.GUID = CV3OrderVariableComponent.OrderGUID "
|
||||
|| WHERE_conditions_common
|
||||
|| AND_avoid_these_unsubmitted_order_guids
|
||||
|| " AND CV3Order.ComplexOrderType IN (" || complex_master_order_type|| ")"
|
||||
|| " AND ChildOrderGUID is NULL "
|
||||
|| " ) "
|
||||
|| "SELECT " || FROM_result_columns
|
||||
|| " FROM CteAllOrdersComp"
|
||||
|| " WHERE " || Filter_by_policy_datetime_range
|
||||
|| " UNION "
|
||||
|| "SELECT DISTINCT " || FROM_result_columns
|
||||
|| " FROM CteAllOrders"
|
||||
|| " WHERE " || Filter_by_policy_datetime_range
|
||||
, PrimaryTime = SignificantDtmOffset};
|
||||
|
||||
endif; /* if any loc_group_found and not loc_is_excluded */
|
||||
endif; /* if item_catalog_GUID is in venipuncture_catalog_GUID_list */
|
||||
endif; /* If continue_checking_order */
|
||||
;;
|
||||
evoke: any_new_order
|
||||
OR any_new_patient_group_order
|
||||
OR any_modified_order
|
||||
OR any_released_order
|
||||
OR any_unsuspended_order
|
||||
OR any_verified_order ;
|
||||
;;
|
||||
logic:
|
||||
If item_catalog_GUID is NOT in venipuncture_catalog_GUID_list
|
||||
OR NOT continue_checking_order
|
||||
OR NOT (any loc_group_found)
|
||||
OR loc_is_excluded
|
||||
then conclude false;
|
||||
endif;
|
||||
|
||||
/*-----------------------------------------------------------------*/
|
||||
/* Concatenates information on "unsubmitted" and "database" orders */
|
||||
/* and avoids concatenating NULL lists */
|
||||
/*-----------------------------------------------------------------*/
|
||||
If (exist unsub_master_guid_list) and (exist db_master_guid_list)
|
||||
then
|
||||
master_guid_list:= (unsub_master_guid_list, db_master_guid_list);
|
||||
order_name_list:= (unsub_order_name_list, db_order_name_list);
|
||||
significant_date_list:= (unsub_significant_date_list, db_significant_date_list);
|
||||
sys_priority_list:= (unsub_sys_priority_list, db_sys_priority_list);
|
||||
user_priority_list:= (unsub_user_priority_list, db_user_priority_list);
|
||||
summary_list:= (unsub_summary_list, db_summary_list);
|
||||
order_status_code_list:= (unsub_order_status_code_list, db_order_status_code_list);
|
||||
order_guid_list := (unsub_order_guid_list,db_order_guid_list);
|
||||
is_suspended_list := (unsub_is_suspended_list,db_is_suspended_list);
|
||||
elseif (not exist unsub_master_guid_list) and (exist db_master_guid_list)
|
||||
then
|
||||
master_guid_list:= db_master_guid_list;
|
||||
order_name_list:= db_order_name_list;
|
||||
significant_date_list:= db_significant_date_list;
|
||||
sys_priority_list:= db_sys_priority_list;
|
||||
user_priority_list:= db_user_priority_list;
|
||||
summary_list:= db_summary_list;
|
||||
order_status_code_list:= db_order_status_code_list;
|
||||
order_guid_list := db_order_guid_list;
|
||||
is_suspended_list := db_is_suspended_list;
|
||||
elseif (exist unsub_master_guid_list) and (not exist db_master_guid_list)
|
||||
then
|
||||
master_guid_list:= unsub_master_guid_list;
|
||||
order_name_list:= unsub_order_name_list;
|
||||
significant_date_list:= unsub_significant_date_list;
|
||||
sys_priority_list:= unsub_sys_priority_list;
|
||||
user_priority_list:= unsub_user_priority_list;
|
||||
summary_list:= unsub_summary_list;
|
||||
order_status_code_list:= unsub_order_status_code_list;
|
||||
order_guid_list := unsub_order_guid_list;
|
||||
is_suspended_list := unsub_is_suspended_list;
|
||||
endif; /* If (exist unsub_master_guid_list)... */
|
||||
|
||||
/*-------------------------------------------------*/
|
||||
/* Create List of Unsubmitted and Existing Strings */
|
||||
/*-------------------------------------------------*/
|
||||
action_item_status_list:= ();
|
||||
for AA in unsub_order_name_list do
|
||||
action_item_status_list := action_item_status_list, "Unsubmitted";
|
||||
enddo; //for AA
|
||||
|
||||
for BB in db_order_name_list do
|
||||
action_item_status_list := action_item_status_list, "Existing";
|
||||
enddo; //for BB
|
||||
|
||||
|
||||
/*-----------------------*/
|
||||
/* Initializes Variables */
|
||||
/*-----------------------*/
|
||||
matching_master_guid_list:= ();
|
||||
matching_name_list:= ();
|
||||
matching_significant_date_list:= ();
|
||||
matching_sys_priority_list:= ();
|
||||
matching_user_priority_list:= ();
|
||||
matching_summary_list:= ();
|
||||
matching_order_status_code:= ();
|
||||
matching_order_guid_list:= ();
|
||||
matching_is_suspended_list:= ();
|
||||
matching_action_item_status_list := ();
|
||||
already_consolidated:= false;
|
||||
|
||||
/*------------------------------------------------*/
|
||||
/* Finds all possible venipuncture consolidations */
|
||||
/*------------------------------------------------*/
|
||||
If any(venipuncture_catalog_GUID_list is in master_guid_list)
|
||||
then
|
||||
for item_master_guid in venipuncture_catalog_GUID_list do
|
||||
master_guid_found:= item_master_guid = master_guid_list;
|
||||
temp_sys_priority:= sys_priority_list where master_guid_found;
|
||||
temp_user_priority:= user_priority_list where master_guid_found;
|
||||
temp_guid:= master_guid_list where master_guid_found;
|
||||
temp_name:= order_name_list where master_guid_found;
|
||||
temp_signif:= significant_date_list where master_guid_found;
|
||||
temp_summary:= summary_list where master_guid_found;
|
||||
temp_status:= order_status_code_list where master_guid_found;
|
||||
temp_order_guid:= order_guid_list where master_guid_found;
|
||||
temp_is_suspended := is_suspended_list where master_guid_found;
|
||||
temp_action_status := action_item_status_list where master_guid_found;
|
||||
matching_sys_priority_list:= matching_sys_priority_list, temp_sys_priority;
|
||||
matching_user_priority_list:= matching_user_priority_list, temp_user_priority;
|
||||
matching_master_guid_list:= matching_master_guid_list, temp_guid;
|
||||
matching_name_list:= matching_name_list, temp_name;
|
||||
matching_significant_date_list:= matching_significant_date_list, temp_signif;
|
||||
matching_summary_list:= matching_summary_list, temp_summary;
|
||||
matching_order_status_code:= matching_order_status_code, temp_status;
|
||||
matching_order_guid_list:= matching_order_guid_list, temp_order_guid;
|
||||
matching_is_suspended_list:= matching_is_suspended_list, temp_is_suspended;
|
||||
matching_action_item_status_list:=
|
||||
matching_action_item_status_list, temp_action_status;
|
||||
enddo; /* for item_master_guid...*/
|
||||
|
||||
|
||||
/* If there is another order within the exact-match time interval */
|
||||
/* that requires a venipuncture, */
|
||||
/* then the current order{{{SINGLE-QUOTE}}}s blood collection time does not have be be changed */
|
||||
/* and there is no need for an venipunture consolidation alert */
|
||||
if any(matching_significant_date_list>= exact_low_time
|
||||
AND matching_significant_date_list <= exact_high_time)
|
||||
then
|
||||
already_consolidated:= true;
|
||||
else
|
||||
/* Removes TIMEC orders, only keeps RTN orders */
|
||||
If order_sys_priority = time_critical_code
|
||||
AND (time_critical_code is in matching_sys_priority_list)
|
||||
then
|
||||
RTN_found:= matching_sys_priority_list = routine_code;
|
||||
matching_sys_priority_list:= matching_sys_priority_list where RTN_found;
|
||||
matching_user_priority_list:= matching_user_priority_list where RTN_found;
|
||||
matching_master_guid_list:= matching_master_guid_list where RTN_found;
|
||||
matching_name_list:= matching_name_list where RTN_found;
|
||||
matching_significant_date_list:=
|
||||
matching_significant_date_list where RTN_found;
|
||||
matching_summary_list:= matching_summary_list where RTN_found;
|
||||
matching_order_status_code:= matching_order_status_code where RTN_found;
|
||||
matching_order_guid_list:= matching_order_guid_list where RTN_found;
|
||||
matching_is_suspended_list:= matching_is_suspended_list where RTN_found;
|
||||
matching_action_item_status_list:=
|
||||
matching_action_item_status_list where RTN_found;
|
||||
endif; /* if order_sys_priority */
|
||||
endif; /* if any(matching_significant_date_list>= exact_low_time */
|
||||
endif; /* if any(venipuncture_catalog_GUID_list...*/
|
||||
|
||||
|
||||
/*----------------------*/
|
||||
/* Format Alert Message */
|
||||
/*----------------------*/
|
||||
if NOT already_consolidated
|
||||
then
|
||||
matching_short_message_list := ();
|
||||
alert_message:= "";
|
||||
order_index:= 1 seqto count(matching_name_list);
|
||||
|
||||
for I in order_index do
|
||||
index_found:= I = order_index;
|
||||
temp_name:= first(matching_name_list where index_found);
|
||||
temp_signif:= first(matching_significant_date_list where index_found);
|
||||
temp_sys_priority:= first(matching_sys_priority_list where index_found);
|
||||
temp_user_priority:= first(matching_user_priority_list where index_found);
|
||||
|
||||
/* Format dates, removing milliseconds */
|
||||
If exist temp_signif then
|
||||
temp_signif_formatted := temp_signif formatted with "%.4t";
|
||||
endif;
|
||||
If exist order_significant_date then
|
||||
temp_order_significant_date_formatted :=
|
||||
order_significant_date formatted with "%.4t";
|
||||
endif;
|
||||
|
||||
first_sentence:= "A " || temp_user_priority
|
||||
|| " blood collection for this patient is currently scheduled at "
|
||||
|| temp_signif_formatted || " for " || temp_name ||".";
|
||||
|
||||
If order_sys_priority = routine_code
|
||||
AND temp_sys_priority = routine_code
|
||||
then
|
||||
temp_msg_list:= first_sentence
|
||||
|| " Consider consolidating one of the collection times to"
|
||||
|| " the other collection time";
|
||||
elseif order_sys_priority = time_critical_code
|
||||
AND temp_sys_priority = routine_code
|
||||
then
|
||||
temp_msg_list:= first_sentence
|
||||
|| " Consider consolidating the collection time of the "
|
||||
|| temp_user_priority || " order "
|
||||
|| "to the collection time of the " || order_user_priority
|
||||
||" order";
|
||||
elseif order_sys_priority = routine_code
|
||||
AND temp_sys_priority = time_critical_code
|
||||
then
|
||||
temp_msg_list:= first_sentence
|
||||
|| " Consider consolidating the collection time of the "
|
||||
|| order_user_priority || " order "
|
||||
|| "to the collection time of the " || temp_user_priority
|
||||
||" order.";
|
||||
endif; /* if order_sys_priority... */
|
||||
|
||||
/* Append or Concatenate alert messages */
|
||||
matching_short_message_list:= matching_short_message_list, temp_msg_list;
|
||||
alert_message := alert_message ||temp_msg_list || "\n\n";
|
||||
enddo; /* for I */
|
||||
endif; /* if NOT already_consolidated */
|
||||
|
||||
/*------------------------------*/
|
||||
/* Create the Actions on Alerts */
|
||||
/*------------------------------*/
|
||||
// Only create actions for alerts when the flag, generate_actions_on_alerts, is TRUE
|
||||
// And there are alerts
|
||||
// And the EvokingEventType is a new order or the MLM is running the the MLM Editor
|
||||
|
||||
If generate_actions_on_alerts
|
||||
and exist matching_name_list
|
||||
and NOT already_consolidated
|
||||
and (EvokingEventType = any_new_order.type
|
||||
OR EvokingEventType = any_new_patient_group_order.type
|
||||
OR EvokingEventType = "OrderEnterNoIVAdditives"
|
||||
OR EvokingEventType = "OrderEnterWithIVAdditives"
|
||||
or Called_By_Editor)
|
||||
then
|
||||
|
||||
|
||||
/* Call the MLM to create and populate actions */
|
||||
alert_action_list := call func_venipuncture_actions WITH
|
||||
order_guid,
|
||||
matching_action_item_status_list,
|
||||
matching_order_guid_list,
|
||||
matching_name_list,
|
||||
matching_master_guid_list,
|
||||
matching_short_message_list,
|
||||
matching_is_suspended_list ;
|
||||
|
||||
if exist alert_action_list
|
||||
then alert_actions_exist := true;
|
||||
else alert_actions_exist := false;
|
||||
endif; //if exist alert_action_list
|
||||
|
||||
endif; //generate_actions_on_alerts
|
||||
|
||||
|
||||
|
||||
/*---------------*/
|
||||
/* Clinical Rule */
|
||||
/*---------------*/
|
||||
If exist matching_name_list
|
||||
and NOT already_consolidated
|
||||
then conclude true;
|
||||
endif;
|
||||
;;
|
||||
action:
|
||||
Write "Current Order: " ||order_user_priority || " " || order_name || "---"
|
||||
|| temp_order_significant_date_formatted || "\n\n"
|
||||
|| alert_message
|
||||
at venipuncture_alert;
|
||||
|
||||
/* Only attach actions, when they exist */
|
||||
if alert_actions_exist
|
||||
then
|
||||
attach alert_action_list to venipuncture_alert;
|
||||
endif; //if generate_actions_on_alerts
|
||||
;;
|
||||
Urgency: 50;;
|
||||
end:
|
||||
102
MLMStripper/bin/Debug/STD/STD_VR_CHART_PACKAGE_PRINT.mlm
Normal file
102
MLMStripper/bin/Debug/STD/STD_VR_CHART_PACKAGE_PRINT.mlm
Normal file
@@ -0,0 +1,102 @@
|
||||
maintenance:
|
||||
|
||||
title: Visit Record Package at Print;;
|
||||
mlmname: STD_VR_CHART_PACKAGE_PRINT;;
|
||||
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) 2016 - 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: If all components are configured, this MLM generates an external file of the Visit Record when it is printed from the application. The file
|
||||
is encrypted. It will have the same content and formatting as if it were printed.
|
||||
;;
|
||||
explanation: Several settings must be configured this MLM to be evoked.
|
||||
1. Site must have an SFTP server.
|
||||
2. A package definition must be defined in the Visit Record Configuration tool (Chart Packaging Definition).
|
||||
3. In Visit Record Definition, the package definition name must be selected from the Package at Print area.
|
||||
See the Visit Record Installation and Configuration Guide for more details.
|
||||
;;
|
||||
keywords: Visit Record;Chart Package;Package
|
||||
;;
|
||||
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}}: 2017-04-21
|
||||
;;
|
||||
knowledge:
|
||||
type: data-driven;;
|
||||
data:
|
||||
standard_libs := MLM {{{SINGLE-QUOTE}}}std_include_libs{{{SINGLE-QUOTE}}};
|
||||
include standard_libs;
|
||||
|
||||
//*** calling the package Logic ***//
|
||||
//
|
||||
// Specify which .NET assemblies need to be loaded for ObjectsPlus
|
||||
|
||||
//Defines the alert in case of error
|
||||
Error_occurred := false;
|
||||
error_destination := destination { Alert } with [
|
||||
alert_type := "Warning",
|
||||
short_message := "Chart Packaging at Print Error from MLM",
|
||||
priority := "low",
|
||||
scope := "chart",
|
||||
Rule_group := "Chart Packaging at Print Error from MLM",
|
||||
Rule_number := 1003,
|
||||
Rule_subgroup := "",
|
||||
Send_with_order := "",
|
||||
Alert_dialog_settings := "",
|
||||
Display_alert := true ];
|
||||
|
||||
//***********************************************************************************************
|
||||
clientVisitObject := read last { ClientVisit: this };
|
||||
stateInfoObject := read last { StateInfo: this};
|
||||
|
||||
//Call Chart Packaging at Printing here
|
||||
using "Sunrise.ChartPackaging.Processor";
|
||||
using namespace "Sunrise.ChartPackaging.Processor";
|
||||
try
|
||||
PackagingClass := NEW NET_Object {{{SINGLE-QUOTE}}}Packaging{{{SINGLE-QUOTE}}};
|
||||
ApplicationName := "Emergency Care";
|
||||
void := call PackagingClass.CreatePackageFromPrintJob with (clientVisitObject.GUID);
|
||||
endtry;
|
||||
catch exception ex0
|
||||
Error_occurred := true;
|
||||
error_message := ex0.Message;
|
||||
endcatch;
|
||||
|
||||
|
||||
;;
|
||||
priority: 50
|
||||
;;
|
||||
evoke:
|
||||
;;
|
||||
logic:
|
||||
conclude true;
|
||||
;;
|
||||
action:
|
||||
if (Error_occurred) then
|
||||
write error_message AT error_destination;
|
||||
endif;
|
||||
;;
|
||||
Urgency: 50;;
|
||||
end:
|
||||
Reference in New Issue
Block a user