Files
St.Clair/MLMStripper/bin/Debug/SCH/SCH_CREATE_RECON_RQMT_MAIN.mlm

563 lines
22 KiB
Plaintext

maintenance:
title: Create Order Reconcile Requirement Main MLM;;
mlmname: SCH_CREATE_RECON_RQMT_MAIN;;
arden: version 2.5;;
version: 5.00;; // SP1
institution: Eclipsys, Standard MLM;;
author: Eclipsys Corporation;;
specialist: ;;
date: 2008-04-23;;
validation: testing;;
library:
purpose:
This MLM creates Requirements for Order Reconciliation based on site defined policies.
;;
explanation:
This MLM creates Order Reconciliation Requirements based on site policies that the site
defines in the functional MLMs called by this MLM. Once created these Requirements are
used to set a flag on the Patient List to indicate whether Order Reconciliation is due
or overdue.
When Orders are reconciled, the Reconciliation is linked to the Requirement.
Note : the Order Reconciliation can occur before the Requirement is created. If this is
the case, the application links the Requirement to the Order Reconciliation
using the data stored for each requirement created by the MLM.
The CDS Trigger Events where this MLM will be evoked are as follows:
. Admit a patient to a specific Facility, Location Function Group or a particular
Location Group
. Transfer patient from a specific Facility, Location Function Group or a particular
Location Group to a specific Facility, Location Function Group or a
particular Location Group
. Transfer patient to a specific VisitType\Care Level\Service
. Transfer patient to a specific Provider on particular units
. Discharge a patient from a specific Facility, Location Function Group or a
particular Location Group
. Enter a ?discharge? order from a specific Facility, Location Function Group or
a particular Location Group
. Enter a ?transfer? order from a specific Facility, Location Function Group or a
particular Location Group to a specific Facility, Location Function Group or
a particular Location Group
This MLM writes to the Destination only when the MLM
concludes TRUE to ensure that the Requirement is only created when the user has
proceeded beyond any possible Alerts to save the data to the database.
Based on ?rules? defined in this MLM, the logic will determine:
. When a Reconciliation Requirement is to be created
. What type of Reconciliation can be linked to the Requirement being created
. What the time frame is used for linking an Order Reconciliation to a Requirement
. When the Reconciliation is to be considered overdue
. The locations, Location Function Groups, and Facilities that use a given rule
. The various VisitType/CareLevel/Service changes that use a given rule
. The various Provider Type and Role changes that use a given rule
. Various Orders for transfer and discharge that use a given rule bases on the
class associated with the item in the Item Catalog
To support their own site policies for when Order Reconciliation should be performed,
sites must code their preferences for these {{{SINGLE-QUOTE}}}rules{{{SINGLE-QUOTE}}} in the supporting Functional MLMs.
The order - class associations must be configured in the Item Catalog.
The MLM will create the Requirement using these site policy definitions.
In order to populate the Reconciliation Requirement, the MLM will pass the following
information to the Eclipsys function.
. The ClientGUID
. The ChartGUID
. The ClientVisitGUID from the Evoking Object
. Type of the reconciliation requirement. Seven types are supported:
- Admission,
- Location Change
- Care Provider Change,
- Visit Type\Care Level\Service Change
- Discharge
- Transfer
- Transfer Order
- Discharge Order
. List of facility defined Reconciliation types.
. Precedence for this Requirement.
. Timeframe in which this Requirement should be linked.
. DateTime after which the Requirement becomes inactive.
. Timeframe in which the Requirement and a previous Order Reconciliation can be
auto-linked.
. DateTime after which the requirement will become overdue.
. GUID of the Order that was for a Transfer or Discharge
. FromGUID1 and ToGUID1
- For Location Change or Transfer Order, this is the LOcationGUID from the
backup ClientVisit and the LocationGUID for the Current
ClientVisit.
- For Care Provider Change, this is the backup CareProviderVisitRoleGUID
and the current CareProviderVisitRoleGUID
- For Visit Type/Care Level/Service Change, this is the GUID of the
VisitType\Care Level\Service for the backup Clientvisit
and the GUID of the VisitType\Care Level\Service for the
current ClientVisit.
;;
keywords: Order Reconciliation; Policy
;;
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;
/***************Make Changes To Spelling And Flags In This Section*******************/
// Set to true if logging is needed.
log_execution_info := false;
// ----------------------------------------------------------------------------------
// Event Statements
// ---------------------------------------------------------------------------------
// To enhance efficiency add filtering clauses where ever possible. For example add a
// WHERE clause limiting the Event to match the data configured in the supporting
// MLM policy definitions.
//Transfer - add the locations defined in the transfer policy to enhance efficiency
//Visit Type, Care Level or Service - add various VistTypes to enhance efficiency
client_visit_modify_event := EVENT { ClientVisitModify Any ClientVisit};
//WHERE TypeCode in ( "Inpatient" )};
//Discharge - add locations that are defined in the discharge policy.
client_visit_discharge_event := EVENT { ClientVisitDischarge Any ClientVisit};
//WHERE TypeCode in ( "Inpatient" )};
order_enter_event := EVENT {OrderEnter Any Order:
WHERE first of ( OrderCatalogMasterItem.CatalogClassTypeValue.Records__
WHERE
OrderCatalogMasterItem.CatalogClassTypeValue.Records__.Code ="ECLP-Reconciliation Order Type" AND
OrderCatalogMasterItem.CatalogClassTypeValue.Records__.Value = "Discharge Order"
) is not null
};
order_modify_event := EVENT {OrderModify Any Order:
WHERE first of ( OrderCatalogMasterItem.CatalogClassTypeValue.Records__
WHERE
OrderCatalogMasterItem.CatalogClassTypeValue.Records__.Code ="ECLP-Reconciliation Order Type" AND
OrderCatalogMasterItem.CatalogClassTypeValue.Records__.Value = "Discharge Order"
) is not null
};
using "ObjectsPlusXA.SCM.Forms";
using namespace "ObjectsPlusXA.SunriseClinicalManager.Forms";
// Flag on how to handle multiple occurences of the same provider role type
// (This flag is only applicable when SCMCareProviderRoleType is configured to allow multiple)
// (If SCMCareProviderRoleType does not allow multiple, check for valid policy always happen)
// If TRUE - check for valid policy for first occurrence only
// If FALSE - check for valid policy for all occurrences
handle_first_multi_provider_occurrence_flag := TRUE;
// Error message text can be editted as needed
error_destination := destination { Alert: reminder,
"Error in order reconciliation", medium, chart };
/**************************Do not make changes below this Section**********************/
//A variable used to check if a policy record is found
policy_record_found := false;
//A variable used to store order reconciliation requirement
my_req := Null;
my_req_list := ();
//A variable used to store policy definition
policy_def := null;
policydef_list := ();
// Used when running from the editor
if called_by_editor then
EvokingObject := read last { ClientVisit: This};
//EvokingEvent := client_visit_enter_event; // Admission Event
//EvokingEvent := client_visit_modify_event; // Transfer Event, Service Change Event
//EvokingEvent := client_visit_discharge_event; // Discharge Event
//EvokingObject := read last { Order: This};
//EvokingEvent := order_enter_event; // Order Transfer, Order Discharge Event
//EvokingEvent := order_modify_event; // Order Transfer, Order Discharge Event
//EvokingEvent := order_enter_no_iv_additives_event; // Order Transfer Event
//EvokingEvent := order_init_event; // Order Discharge Event
//EvokingObject := read last { CareProviderVisitRole: This};
//EvokingEvent := provider_enter_event; // Care Provider Change
endif; // if called_by_editor
// Declare policy specific MLMs that can be called
AdmissionPolicy_MLM := MLM {{{SINGLE-QUOTE}}}STD_FUNC_CREATE_RECON_RQMT_ADMISSIONPOLICY{{{SINGLE-QUOTE}}};
// TransferPolicy_MLM := MLM {{{SINGLE-QUOTE}}}STD_FUNC_CREATE_RECON_RQMT_TRANSFERPOLICY{{{SINGLE-QUOTE}}};
// DischargePolicy_MLM := MLM {{{SINGLE-QUOTE}}}STD_FUNC_CREATE_RECON_RQMT_DISCHARGEPOLICY{{{SINGLE-QUOTE}}};
// CareProviderChangePolicy_MLM
// := MLM {{{SINGLE-QUOTE}}}STD_FUNC_CREATE_RECON_RQMT_CAREPROVIDERCHANGEPOLICY{{{SINGLE-QUOTE}}};
OrderDischargePolicy_MLM := MLM {{{SINGLE-QUOTE}}}STD_FUNC_CREATE_RECON_RQMT_ORDERDISCHARGEPOLICY{{{SINGLE-QUOTE}}};
// OrderTransferPolicy_MLM := MLM {{{SINGLE-QUOTE}}}STD_FUNC_CREATE_RECON_RQMT_ORDERTRANSFERPOLICY{{{SINGLE-QUOTE}}};
// VisitTypeCareLevelServicePolicy_MLM := MLM {{{SINGLE-QUOTE}}}STD_FUNC_CREATE_RECON_RQMT_VISITTYPECARELEVELSERVICEPOLICY{{{SINGLE-QUOTE}}};
SelectPatientLocPolicy_MLM := MLM {{{SINGLE-QUOTE}}}STD_FUNC_CREATE_RECON_RQMT_SelectPatientLocPolicy{{{SINGLE-QUOTE}}};
// SelectTransferPolicy_MLM := MLM {{{SINGLE-QUOTE}}}STD_FUNC_CREATE_RECON_RQMT_SelectTransferPolicy{{{SINGLE-QUOTE}}};
// SelectCareProviderPolicy_MLM := MLM {{{SINGLE-QUOTE}}}STD_FUNC_CREATE_RECON_RQMT_SelectCareProviderPolicy{{{SINGLE-QUOTE}}};
// SelectServicePolicy_MLM := MLM {{{SINGLE-QUOTE}}}STD_FUNC_CREATE_RECON_RQMT_SelectServicePolicy{{{SINGLE-QUOTE}}};
SetDefault_MLM := MLM {{{SINGLE-QUOTE}}}STD_FUNC_CREATE_RECON_RQMT_SET_POLICY_DEFAULT{{{SINGLE-QUOTE}}};
error_occured := false;
overridebyloc := false;
//Determine the type of event and perform logic for that event
// dialogResult := call {{{SINGLE-QUOTE}}}MessageBox{{{SINGLE-QUOTE}}}.Show with "Marker 1"
// ,"Tester","Ok" as {{{SINGLE-QUOTE}}}MessageBoxButtons{{{SINGLE-QUOTE}}};
//**************************//
// //
// Admission Event SCH changed to transfer from ER Major only //
// //
//**************************//
if EvokingEvent = client_visit_modify_event
then
// RS 05/10/2010 Added to find previous location
(backup_obj) := read last {ClientVisit: Backup REFERENCING EvokingObject};
(Bk_Loc_Name, Bk_Loc_GUID, Bk_VisitStatus,Bk_TypeCode,Bk_TemporaryLocation) :=
read last {ClientVisit: CurrentLocation,CurrentLocationGUID,VisitStatus,TypeCode, TemporaryLocation REFERENCING backup_obj};
// RS 05/10/2010 end of addition
//Get Required parameters from the evoking object
( visit_client_guid,
visit_guid,
visit_chart_guid,
visit_location_guid,
alternate_visit_location_guid,
visit_loc_name) := read last
{ClientVisit: ClientGUID, GUID, ChartGUID,
BusinessRuleLocationGUID, CurrentLocationGUID, currentlocation
REFERENCING EvokingObject} ;
// RS added to insure that to location is an inpatient bed
counter := 0;
// dialogResult := call {{{SINGLE-QUOTE}}}MessageBox{{{SINGLE-QUOTE}}}.Show with "From Location " || Bk_Loc_Name || "\n\n To Location " || visit_loc_name
// ,"Tester","Ok" as {{{SINGLE-QUOTE}}}MessageBoxButtons{{{SINGLE-QUOTE}}};
counter := read last {" select count(*) from Cv3Location with (nolock) "
|| " where locngrpguid = " || alternate_visit_location_guid
|| " and name = " || sql(visit_loc_name)
|| " and typecode = {{{SINGLE-QUOTE}}}Bed{{{SINGLE-QUOTE}}} "
|| " and active = 1 "
};
// dialogResult := call {{{SINGLE-QUOTE}}}MessageBox{{{SINGLE-QUOTE}}}.Show with "Marker 2"
// ,"Tester","Ok" as {{{SINGLE-QUOTE}}}MessageBoxButtons{{{SINGLE-QUOTE}}};
if ((Bk_Loc_Name <> "ER Major") or (counter =0)) then
overridebyloc := true;
// dialogResult := call {{{SINGLE-QUOTE}}}MessageBox{{{SINGLE-QUOTE}}}.Show with "I should not create a flag as from loc is " || Bk_Loc_Name || "\n\n and to bed is " || counter
// ,"Tester","YesNo" as {{{SINGLE-QUOTE}}}MessageBoxButtons{{{SINGLE-QUOTE}}};
else
// dialogResult := call {{{SINGLE-QUOTE}}}MessageBox{{{SINGLE-QUOTE}}}.Show with "Marker 3"
// ,"Tester","Ok" as {{{SINGLE-QUOTE}}}MessageBoxButtons{{{SINGLE-QUOTE}}};
// dialogResult := call {{{SINGLE-QUOTE}}}MessageBox{{{SINGLE-QUOTE}}}.Show with "I should create a flag as from loc is " || Bk_Loc_Name || "\n\n and to bed is " || counter
// ,"Tester","Ok" as {{{SINGLE-QUOTE}}}MessageBoxButtons{{{SINGLE-QUOTE}}};
// RS 05/10/2010 added to here, note the extra if above
// Will only fire if coming from ER Major and going to a bed
//Ensure location guid value is filled in, if not, use alternate value
if (visit_location_guid is NULL)
then
visit_location_guid := alternate_visit_location_guid;
endif;
//Check for existing policy definition
(AdmissionPolicyListDef, AdmissionPolicyDefaults):= call AdmissionPolicy_MLM;
// dialogResult := call {{{SINGLE-QUOTE}}}MessageBox{{{SINGLE-QUOTE}}}.Show with "Marker 4"
// ,"Tester","Ok" as {{{SINGLE-QUOTE}}}MessageBoxButtons{{{SINGLE-QUOTE}}};
//When a patient is admitted, determine if
//order reconciliation requirement needs to be created.
policy_def := call SelectPatientLocPolicy_MLM with
visit_location_guid,
AdmissionPolicyListDef;
//check for default values
policy_def:= call SetDefault_MLM with
policy_def,AdmissionPolicyDefaults;
// dialogResult := call {{{SINGLE-QUOTE}}}MessageBox{{{SINGLE-QUOTE}}}.Show with "Marker 5"
// ,"Tester","Ok" as {{{SINGLE-QUOTE}}}MessageBoxButtons{{{SINGLE-QUOTE}}};
//Intentionally left for support purposes
//eventName:= "Admission";
//break;
if (policy_def is NOT NULL)
then
policy_record_found := true;
try
reconcileList := policy_def.ReconcileType;
reconcileTypeColl:= new net_object {{{SINGLE-QUOTE}}}ReconcileTypeCollection{{{SINGLE-QUOTE}}};
//dialogResult := call {{{SINGLE-QUOTE}}}MessageBox{{{SINGLE-QUOTE}}}.Show with "Marker 6"
// ,"Tester","Ok" as {{{SINGLE-QUOTE}}}MessageBoxButtons{{{SINGLE-QUOTE}}};
index_list := 1 seqto (count reconcileList);
for ind in index_list do
void := call reconcileTypeColl.Add with ( reconcileList[ind] as {{{SINGLE-QUOTE}}}String{{{SINGLE-QUOTE}}});
enddo; //ind in index_list do
//dialogResult := call {{{SINGLE-QUOTE}}}MessageBox{{{SINGLE-QUOTE}}}.Show with "Marker 7"
// ,"Tester","Ok" as {{{SINGLE-QUOTE}}}MessageBoxButtons{{{SINGLE-QUOTE}}};
// create ObjectsPlus OrderReconciliationRequirement object
my_req := call
{{{SINGLE-QUOTE}}}OrderReconciliationRequirement{{{SINGLE-QUOTE}}}.CreateAdmissionRequirement
with ((visit_client_guid as number) as {{{SINGLE-QUOTE}}}Int64{{{SINGLE-QUOTE}}}),
((visit_chart_guid as number) as {{{SINGLE-QUOTE}}}Int64{{{SINGLE-QUOTE}}}),
((visit_guid as number) as {{{SINGLE-QUOTE}}}Int64{{{SINGLE-QUOTE}}}),
reconcileTypeColl;
// dialogResult := call {{{SINGLE-QUOTE}}}MessageBox{{{SINGLE-QUOTE}}}.Show with "Marker 8"
// ,"Tester","Ok" as {{{SINGLE-QUOTE}}}MessageBoxButtons{{{SINGLE-QUOTE}}};
my_req_list := my_req,my_req_list;
policydef_list := policy_def,policydef_list;
endtry;
catch exception ex
my_exception := ex;
error_occured := True;
endcatch;
endif; // override location change
endif; // if(policy_def is NOT NULL)
//**************************//
// //
// Discharge Order Event //
// //
//**************************//
elseif ( (EvokingEvent = order_enter_event)
OR (EvokingEvent = order_modify_event)
)
then
//Gets information from the evoking Order
(visit_guid,
order_guid,
Ord) := read last
{Order: ClientVisitGUID,
GUID,
This
REFERENCING EvokingObject};
transfer_to_location := Ord.OrderAdditionalInfo.TransferToLocnGUID;
//Get Required parameters from the ClientVisitObject object
( type_code) := read last
{ClientVisit: TypeCode
Where GUID = visit_guid } ;
( visit_client_guid,
visit_chart_guid,
visit_location_guid,
alternate_visit_location_guid,
new_visit_location_guid) := read last
{ClientVisit: ClientGUID, ChartGUID,
BusinessRuleLocationGUID, CurrentLocationGUID,
NextLocnGrpGUID,
Where GUID = visit_guid } ;
//Ensure location guid value is filled in, if not, use alternate value
if (visit_location_guid is NULL)
then
visit_location_guid := alternate_visit_location_guid;
endif;
//Get Order Class Type
ocmi := Read last {Order: OrderCatalogMasterItem referencing Ord};
orderRecCatalogClassTypeValue := first of (ocmi.CatalogClassTypeValue.Records__ where ocmi.CatalogClassTypeValue.Records__.code = "ECLP-Reconciliation Order Type" );
classTypeValue := orderRecCatalogClassTypeValue.value;
if (classTypeValue="Discharge Order")
then
//Check for existing policy definition
(OrderDischargePolicyListDef, OrderDischargePolicyDefaults):= call OrderDischargePolicy_MLM;
//When a discharge order is placed, determine if
//order reconciliation requirement needs to be created.
policy_def := call SelectPatientLocPolicy_MLM with
visit_location_guid,
OrderDischargePolicyListDef;
//check for default values
policy_def:= call SetDefault_MLM with
policy_def,OrderDischargePolicyDefaults;
//Intentionally left for support purposes
//eventName:= "Order Discharge";
//break;
endif;
if (policy_def is NOT NULL)
then
policy_record_found := true;
try
// get current client visit object
client_visit := call
{{{SINGLE-QUOTE}}}ClientVisit{{{SINGLE-QUOTE}}}.FindByPrimaryKey
with ((visit_guid as number) as {{{SINGLE-QUOTE}}}Int64{{{SINGLE-QUOTE}}});
reconcileTypeColl:= new net_object {{{SINGLE-QUOTE}}}ReconcileTypeCollection{{{SINGLE-QUOTE}}};
reconcileList := policy_def.ReconcileType;
index_list := 1 seqto (count reconcileList);
for ind in index_list do
void := call reconcileTypeColl.Add with ( reconcileList[ind] as {{{SINGLE-QUOTE}}}String{{{SINGLE-QUOTE}}});
enddo; //ind in index_list do
if (classTypeValue = "Transfer Order")
then
my_req := call {{{SINGLE-QUOTE}}}OrderReconciliationRequirement{{{SINGLE-QUOTE}}}.CreateTransferOrderRequirement
with client_visit,
reconcileTypeColl,
((order_guid as number) as {{{SINGLE-QUOTE}}}Int64{{{SINGLE-QUOTE}}}),
((visit_location_guid as number) as {{{SINGLE-QUOTE}}}Int64{{{SINGLE-QUOTE}}}),
((transfer_to_location as number) as {{{SINGLE-QUOTE}}}Int64{{{SINGLE-QUOTE}}});
elseif (classTypeValue="Discharge Order")
then
my_req := call {{{SINGLE-QUOTE}}}OrderReconciliationRequirement{{{SINGLE-QUOTE}}}.CreateDischargeOrderRequirement
with client_visit,
reconcileTypeColl,
((order_guid as number) as {{{SINGLE-QUOTE}}}Int64{{{SINGLE-QUOTE}}});
endif;
if ( client_visit is NOT NULL ) then
void:= call client_visit.Dispose;
client_visit:= null;
endif;
my_req_list := my_req,my_req_list;
policydef_list := policy_def,policydef_list;
endtry;
catch exception ex
my_exception := ex;
if ( client_visit is NOT NULL ) then
void:= call client_visit.Dispose;
client_visit:= null;
endif;
index_list := 1 seqto (count my_req_list);
for ind in index_list do
req_obj := my_req_list[ind];
if ( req_obj is NOT NULL ) then
void:= call req_obj.Dispose;
req_obj:= null;
endif;
enddo;
endcatch;
endif; // if(policy_def is NOT NULL)
endif; //if EvokingEvent = client_visit_enter_event
//******************************//
// //
// Populate Requirement //
// //
//******************************//
//populate order reconciliation requirement with values
if (policy_record_found)
then
index_list := 1 seqto count(my_req_list);
for ind in index_list do
req := my_req_list[ind];
def := policydef_list[ind];
if (def.AutoLinkTimeFrame is not Null)
then
req.AutoLinkTimeframeHours := def.AutoLinkTimeFrame as {{{SINGLE-QUOTE}}}System.Int32{{{SINGLE-QUOTE}}};
endif;
if (def.RequirementPrecedence is not Null)
then
req.Precedence := def.RequirementPrecedence as {{{SINGLE-QUOTE}}}System.Int32{{{SINGLE-QUOTE}}};
endif;
if (def.RequirementPrecedenceTime is not Null)
then
req.PrecedenceTimeframeHours := def.RequirementPrecedenceTime
as {{{SINGLE-QUOTE}}}System.Int32{{{SINGLE-QUOTE}}};
endif;
if (def.OverDueDtmHours is not Null)
then
req.OverdueAfter := (NOW + (def.OverDueDtmHours hours))
as {{{SINGLE-QUOTE}}}System.DateTime{{{SINGLE-QUOTE}}};
endif;
if (def.RequirementCleanupDtmHours is not Null)
then
req.InactivateAfter := (NOW + (def.RequirementCleanupDtmHours hours))
as {{{SINGLE-QUOTE}}}System.DateTime{{{SINGLE-QUOTE}}};
endif;
//Define the XA Object Destination for Requirement
Reqt_Destination:= destination { XAObject } with [xaobject := req];
enddo; // ind in index_list do
endif; //if(policy_record_found)
;;
evoke:
// client_visit_modify_event OR
//client_visit_discharge_event OR
order_enter_event OR
order_modify_event
;;
logic:
if (policy_record_found) and (overridebyloc = false)
then
conclude TRUE;
else
conclude FALSE;
endif //(policy_record_found)
;;
action:
if (error_occured)
then
write my_exception at error_destination;
else
Write true at Reqt_Destination ;
endif; //(error_occured)
;;
Urgency: 50;;
end: