maintenance: title: Maintain Advanced Visit List Potential Heart Failure;; mlmname: SCH_AVL_POTENTIAL_HEART_FAILURE;; arden: version 2.5;; version: 5.50;; institution: Eclipsys, Sample MLM;; author: Eclipsys Corporation;; specialist: ;; date: 2011-06-01;; validation: Testing;; library: purpose: Maintains Potential Heart Failure Advanced Visit List data ;; explanation: This MLM maintains the Potential Heart Failure Advanced Visit List ;; keywords: ObjectsPlus, Advanced Visit List Data, Potential Heart Failure ;; knowledge: type: data-driven;; data: //****************Make Changes To Spelling And Flags In This Section**************** // Advanced Visit List Item Names AVL_Name := "Potential Heart Failure"; AVL_External_ID := "001"; AVL_HI_GUID_Coded := "HealthIssue_GUID_Coded"; AVL_HI_OnsetDate := "HealthIssue_OnsetDate"; AVL_HI_GUID_Patient:= "HealthIssue_GUID_Patient"; AVL_Result := "ResultValue" ; // Triggers clientvisit_enter_event := Event {ClientVisitEnter ANY ClientVisit: where typecode = "Inpatient" or typecode = "Observation"}; clientvisit_modify_event := Event {ClientVisitModify BATCH ClientVisit: where typecode = "Inpatient" or typecode = "Observation"}; bnp_result_enter_event:= EVENT {ObservationEnter ANY Observation: WHERE Itemname matches pattern "%BNP%"}; health_issue_enter_event:= event { HealthIssueEnter Any HealthIssue: where typecode = "Admitting DX" and (ShortName matches pattern ("%CHF%") or ShortName matches pattern ("%Heart%") or text matches pattern ("%CHF%") or text matches pattern ("%Heart%")) or typecode <> "Admitting DX" and (ShortName matches pattern ("%CHF%") or ShortName matches pattern ("%Heart Failure%"))}; health_issue_modify_event:= event { HealthIssueModify Any HealthIssue: where typecode = "Admitting DX" and (ShortName matches pattern ("%CHF%") or ShortName matches pattern ("%Heart%") or text matches pattern ("%CHF%") or text matches pattern ("%Heart%")) or typecode <> "Admitting DX" and (ShortName matches pattern ("%CHF%") or ShortName matches pattern ("%Heart Failure%"))}; health_issue_delete_event:= event { HealthIssueDelete Any HealthIssue: where typecode = "Admitting DX" and (ShortName matches pattern ("%CHF%") or ShortName matches pattern ("%Heart%") or text matches pattern ("%CHF%") or text matches pattern ("%Heart%")) or typecode <> "Admitting DX" and (ShortName matches pattern ("%CHF%") or ShortName matches pattern ("%Heart Failure%"))}; health_issue_discontinue_event:= event { HealthIssueDiscontinue Any HealthIssue: where typecode = "Admitting DX" and (ShortName matches pattern ("%CHF%") or ShortName matches pattern ("%Heart%") or text matches pattern ("%CHF%") or text matches pattern ("%Heart%")) or typecode <> "Admitting DX" and (ShortName matches pattern ("%CHF%") or ShortName matches pattern ("%Heart Failure%"))}; // Destinations objects_plus_destination := destination { ObjectsPlus } with [ alert_type := "Warning", short_message := "Object created by MLM", priority := "low", scope := "chart", rule_group := "Advanced Visit List Data Object", rule_number := 2010]; send_alert := "DoNotSend"; alert_dest := destination { Alert: warning, "Order Session Type", high, chart, "Order Session Type", 15042, send_alert, "No Override Allowed" }; //******************Do Not Make Changes Below This Section******************* // Specify which .NET assemblies need to be loaded for ObjectsPlus standard_libs := MLM {{{SINGLE-QUOTE}}}std_include_libs{{{SINGLE-QUOTE}}}; include standard_libs; if called_by_editor then EvokingObject := read last {HealthIssue: THIS }; endif; // DETERMINE IF PROCESSING SHOULD CONTINUE SECTION If EvokingEventType = bnp_result_enter_event.type then evokevent := "BNP Event"; (VisitGUID, ChartGUID, ClientGUID) := read last { Observation: ClientVisitGUID, ChartGUID, ClientGUID REFERENCING EvokingObject }; endif; If EvokingEventType = health_issue_enter_event.type then evokevent := "Health Issue Enter Event"; (VisitGUID, ChartGUID, ClientGUID) := read last { HealthIssue: ClientVisitGUID, ChartGUID, ClientGUID REFERENCING EvokingObject }; endif; If EvokingEventType = health_issue_modify_event.type then evokevent := "Health Issue Modify Event"; (VisitGUID, ChartGUID, ClientGUID) := read last { HealthIssue: ClientVisitGUID, ChartGUID, ClientGUID REFERENCING EvokingObject }; endif; If EvokingEventType = health_issue_delete_event.type then evokevent := "Health Issue Delete Event"; (VisitGUID, ChartGUID, ClientGUID) := read last { HealthIssue: ClientVisitGUID, ChartGUID, ClientGUID REFERENCING EvokingObject }; endif; If EvokingEventType = health_issue_discontinue_event.type then evokevent := "Health Issue Discontinue Event"; (VisitGUID, ChartGUID, ClientGUID) := read last { HealthIssue: ClientVisitGUID, ChartGUID, ClientGUID REFERENCING EvokingObject }; endif; IF EvokingEventType = clientvisit_enter_event.type then evokevent := "New Visit Event"; (VisitGUID, ChartGUID, ClientGUID) := read last {ClientVisit: GUID, ChartGUID, ClientGUID REFERENCING EvokingObject}; endif; IF EvokingEventType = clientvisit_modify_event.type then evokevent := "Change to Inpatient Event"; (VisitGUID, ChartGUID, ClientGUID) := read last {ClientVisit: GUID, ChartGUID, ClientGUID REFERENCING EvokingObject}; endif; PatientType := read last {"select typecode from CV3ClientVisit with (nolock) where typecode in ({{{SINGLE-QUOTE}}}inpatient{{{SINGLE-QUOTE}}}, {{{SINGLE-QUOTE}}}observation{{{SINGLE-QUOTE}}}) and ClientGUID = " || ClientGUID || " and ChartGUID = " || ChartGUID || " and guid = " || VisitGUID || " "}; NonCHFAdmittingDx := read last {"Select description from CV3HealthIssueDeclaration with (nolock) where TypeCode = {{{SINGLE-QUOTE}}}admitting dx{{{SINGLE-QUOTE}}} and Active = 1 and ShortName not like {{{SINGLE-QUOTE}}}%CHF%{{{SINGLE-QUOTE}}} and ShortName not like {{{SINGLE-QUOTE}}}%Heart%{{{SINGLE-QUOTE}}} and text not like {{{SINGLE-QUOTE}}}%CHF%{{{SINGLE-QUOTE}}} and text not like {{{SINGLE-QUOTE}}}%Heart%{{{SINGLE-QUOTE}}} and ClientGuid = " || ClientGuid || " and ChartGuid = " || ChartGuid || " and ClientVisitGUID = " || VisitGUID}; PastCHFAdmittingDx := read last {"Select description from CV3HealthIssueDeclaration with (nolock) where Active = 1 and typecode <> {{{SINGLE-QUOTE}}}Admitting DX{{{SINGLE-QUOTE}}} and (ShortName like ({{{SINGLE-QUOTE}}}%CHF%{{{SINGLE-QUOTE}}}) or ShortName like({{{SINGLE-QUOTE}}}%Heart Failure%{{{SINGLE-QUOTE}}})) and ClientGuid = " || ClientGuid}; WasBeddedPriorToModify := read last {"Select l.shortname from cv3clientvisitlocation cvl with (nolock) join cv3location l with (nolock) on l.guid = cvl.locationguid where l.typecode = {{{SINGLE-QUOTE}}}bed{{{SINGLE-QUOTE}}} and cvl.status <> {{{SINGLE-QUOTE}}}cur{{{SINGLE-QUOTE}}} and cvl.clientguid = " || ClientGuid || " and cvl.clientvisitguid = " || VisitGUID}; (BNP_Value, abnormalitycode, ArrivalDtm) := read last {"select bo.value, bo.abnormalitycode, convert(varchar(10), bo.ArrivalDtm,101) from cv3order o with (nolock) join cv3basicobservation as bo with (nolock) on bo.ClientGUID = o.ClientGUID and bo.ChartGUID = o.ChartGUID and bo.clientvisitguid = o.clientvisitguid and bo.orderguid = o.guid and bo.ishistory = 0 where o.ClientGUID = " || ClientGUID || " and o.ChartGUID = " || ChartGUID || " and o.clientvisitguid = " || VisitGUID || " and o.name like {{{SINGLE-QUOTE}}}%NT Pro BNP%{{{SINGLE-QUOTE}}}"}; If ((EvokingEventType = bnp_result_enter_event.type or EvokingEventType = health_issue_enter_event.type or EvokingEventType = health_issue_modify_event.type or EvokingEventType = health_issue_delete_event.type or EvokingEventType = health_issue_discontinue_event.type ) and PatientType is not null) or ((EvokingEventType = clientvisit_modify_event.type or clientvisit_enter_event.type) and (not exists NonCHFAdmittingDx and not exists WasBeddedPriorToModify and (exists PastCHFAdmittingDx or exists BNP_Value) ) ) then // INPATIENT/OBSERVATION PATIENT PROCEED SECTION // BNP EVENT SECTION If EvokingEventType = bnp_result_enter_event.type then BNPValue, abnormalitycode, ArrivalDtm := read last { Observation: value, abnormalitycode, ArrivalDtm REFERENCING EvokingObject }; ResultMonth:= EXTRACT Month ArrivalDtm; if ResultMonth < 10 then ResultMonth:= "0" || ResultMonth; endif; ResultDay:= EXTRACT Day ArrivalDtm; if ResultDay < 10 then ResultDay:= "0" || ResultDay; endif; ResultDate := ResultMonth || "/" || ResultDay || "/" || EXTRACT YEAR ArrivalDtm; if abnormalitycode = "H" then BNP_Value := BNPValue || " (H) " || ResultDate; else BNP_Value := BNPValue || " " || ResultDate; endif; // Attain patient{{{SINGLE-QUOTE}}}s existing Advanced Visit List Data for re-entry (onset_date,current_coded_health_issue_id,ObjectGUID2Text, current_health_issue_id,ObjectGUID1Text,ClientVisitGUID) := read last{"select Date2, ObjectGUID2, ObjectGUID2Text, ObjectGUID1, ObjectGUID1Text,ClientVisitGUID from CV3AdvancedVisitListData with (nolock) where externalid = " || AVL_External_ID || " and ClientVisitGUID = " || VisitGUID || " "}; // Attain the patient{{{SINGLE-QUOTE}}}s admitting dx guid for use as patient health issue guid when there is no existing relavent health issue (current_health_issue_id_admitting) := read last{" select guid from CV3HealthIssueDeclaration with (nolock) where TypeCode = {{{SINGLE-QUOTE}}}Admitting Dx{{{SINGLE-QUOTE}}} and ClientVisitGUID = " || VisitGUID || " "}; if not exists current_health_issue_id then current_health_issue_id := current_health_issue_id_admitting; endif; // VISIT EVENT SECTION ElseIf (EvokingEventType = clientvisit_enter_event.type or EvokingEventType = clientvisit_modify_event.type) then // Populate BNP data found in the patient record if exists BNP_Value then if abnormalitycode = "H" then BNP_Value := BNP_Value || " (H) " || ArrivalDtm ; else BNP_Value := BNP_Value || " " || ArrivalDtm ; endif; else BNP_Value := " "; endif; // Attain the patient{{{SINGLE-QUOTE}}}s admitting dx guid for use as patient health issue guid current_health_issue_id := read last{" select guid from CV3HealthIssueDeclaration with (nolock) where TypeCode = {{{SINGLE-QUOTE}}}Admitting Dx{{{SINGLE-QUOTE}}} and ClientVisitGUID = " || VisitGuid || " "}; // HEALTH ISSUE EVENT SECTION else // Get data from the evoking Health Issue (current_coded_health_issue_id, current_onset_day_num, current_onset_month_num, current_onset_year_num, current_health_issue_id, current_status, existing_health_issue_obj) := read last { HealthIssue: CodedHealthIssueGUID, OnsetDayNum, OnsetMonthNum, OnsetYearNum, GUID, Status, Backup REFERENCING EvokingObject }; // Populate BNP data found in the patient record if exists BNP_Value then if abnormalitycode = "H" then BNP_Value := BNP_Value || " (H) " || ArrivalDtm ; else BNP_Value := BNP_Value || " " || ArrivalDtm ; endif; else BNP_Value := " "; endif; endif; // If BNP or Patient Type or Health Issue event error_occurred := false; error_message := ""; continue_processing:= true; log_execution_info := false; is_closed := false; is_active := false; // HEALTH HEALTH ISSUE MODIFY SECTION if( EvokingEventType = health_issue_modify_event.type ) then if(existing_health_issue_obj is not null) then health_issue_onset_date_obj:= existing_health_issue_data_obj.OnsetDate; // processing only continues if status or onset date changes if( existing_health_issue_data_obj.Status = current_status AND ( health_issue_onset_date_obj.Day = current_onset_day_num AND health_issue_onset_date_obj.Month = current_onset_month_num AND health_issue_onset_date_obj.Year = current_onset_year_num ) ) then continue_processing:= false; elseif (existing_health_issue_data_obj.Status <> current_status ) then ( is_closed, is_active ) := read { "EXEC SCMGetHealthIssueStatusSelPr " || SQL(current_status) }; endif; endif; endif; // CONTINUE PROCESSING (except for Health Issue Modify event where something other than status or onset date changed) if continue_processing then try client_visit_obj := call {{{SINGLE-QUOTE}}}ClientVisit{{{SINGLE-QUOTE}}}.FindByPrimaryKey with ((VisitGUID as number) as {{{SINGLE-QUOTE}}}Int64{{{SINGLE-QUOTE}}}) ; // Create the AdvancedVisitListData object. advanced_visit_list_data_obj := call {{{SINGLE-QUOTE}}}AdvancedVisitListData{{{SINGLE-QUOTE}}}.CreateAdvancedVisitListData with (client_visit_obj, AVL_Name, AVL_External_ID) ; // with (client_visit_obj, AVL_Name, current_health_issue_id) ; /*permits mult of each patient on this list */ endtry; catch Exception ex error_occurred := true; error_message := "{{+R}}Error Message:{{-R}}\n" || ex.Message || "\n\n"; if ( advanced_visit_list_data_obj is NOT NULL ) then void:= call advanced_visit_list_data_obj.Dispose; advanced_visit_list_data_obj:= null; endif; if ( client_visit_obj is NOT NULL ) then void:= call client_visit_obj.Dispose; client_visit_obj:= null; endif; endcatch; endif; // End of INPATIENT/OBSERVATION PATIENT PROCEED SECTION else // DO NOT PROCEED SECTION continue_processing:= false; endif; // If PatientType ;; priority: 50 ;; evoke: 1 minutes after time of bnp_result_enter_event; 1 minutes after time of clientvisit_enter_event; 1 minutes after time of clientvisit_modify_event; 0 minutes after time of health_issue_enter_event; 0 minutes after time of health_issue_modify_event; 0 minutes after time of health_issue_delete_event; 0 minutes after time of health_issue_discontinue_event; ;; logic: if( EvokingObject is null or continue_processing = false ) then conclude false; endif; try if( is_closed AND is_active ) then void := call advanced_visit_list_data_obj.Deactivate; // don{{{SINGLE-QUOTE}}}t conclude false as we still need to return true to OP destination continue_processing:= false; endif; if( continue_processing ) then // BNP Enter or HEALTH ISSUE ENTER OR HEALTH ISSUE MODIFY SECTION // BNP Enter Event If EvokingEventType = bnp_result_enter_event.type then void := call advanced_visit_list_data_obj.{{{SINGLE-QUOTE}}}SetValue>{{{SINGLE-QUOTE}}} with (AVL_HI_GUID_Patient, (current_health_issue_id as number) as {{{SINGLE-QUOTE}}}Int64{{{SINGLE-QUOTE}}}); void := call advanced_visit_list_data_obj.{{{SINGLE-QUOTE}}}SetValue>{{{SINGLE-QUOTE}}} with (AVL_HI_GUID_Coded,(current_coded_health_issue_id as number) as {{{SINGLE-QUOTE}}}Int64{{{SINGLE-QUOTE}}}); void := call advanced_visit_list_data_obj.{{{SINGLE-QUOTE}}}SetValue{{{SINGLE-QUOTE}}} with AVL_Result , BNP_Value ; void := call advanced_visit_list_data_obj.{{{SINGLE-QUOTE}}}SetValue>{{{SINGLE-QUOTE}}} with (AVL_HI_OnsetDate, onset_date as {{{SINGLE-QUOTE}}}System.DateTime{{{SINGLE-QUOTE}}}); objects_plus_destination.ObjectsPlus := advanced_visit_list_data_obj; // Client Visit Event elseif (EvokingEventType = clientvisit_enter_event.type or EvokingEventType = clientvisit_modify_event.type)then void := call advanced_visit_list_data_obj.{{{SINGLE-QUOTE}}}SetValue>{{{SINGLE-QUOTE}}} with (AVL_HI_GUID_Patient, (current_health_issue_id as number) as {{{SINGLE-QUOTE}}}Int64{{{SINGLE-QUOTE}}}); void := call advanced_visit_list_data_obj.{{{SINGLE-QUOTE}}}SetValue{{{SINGLE-QUOTE}}} with AVL_Result , BNP_Value ; objects_plus_destination.ObjectsPlus := advanced_visit_list_data_obj; else // Health Issue Enter or Modify Event if( EvokingEventType = health_issue_enter_event.type or EvokingEventType = health_issue_modify_event.type) then // Set the Patient Health Issue GUID. void := call advanced_visit_list_data_obj.{{{SINGLE-QUOTE}}}SetValue>{{{SINGLE-QUOTE}}} with (AVL_HI_GUID_Patient, (current_health_issue_id as number) as {{{SINGLE-QUOTE}}}Int64{{{SINGLE-QUOTE}}}); // Set the Coded Health Issue. void := call advanced_visit_list_data_obj.{{{SINGLE-QUOTE}}}SetValue>{{{SINGLE-QUOTE}}} with (AVL_HI_GUID_Coded,(current_coded_health_issue_id as number) as {{{SINGLE-QUOTE}}}Int64{{{SINGLE-QUOTE}}}); // Set the BNP Value. void := call advanced_visit_list_data_obj.{{{SINGLE-QUOTE}}}SetValue{{{SINGLE-QUOTE}}} with AVL_Result , BNP_Value ; // Set the Onset Date if available. if( current_onset_year_num is not null and current_onset_year_num > 0 ) then if( current_onset_month_num is null or current_onset_month_num <= 0 ) then current_onset_month_num:= 1; else if ( current_onset_day_num is null or current_onset_day_num <= 0 ) then current_onset_day_num:= 1; endif; endif; onset_date_string := (current_onset_year_num as String) || "-" || (current_onset_month_num as String) || "-" || (current_onset_day_num as String); onset_date := onset_date_string as time; void := call advanced_visit_list_data_obj.{{{SINGLE-QUOTE}}}SetValue>{{{SINGLE-QUOTE}}} with (AVL_HI_OnsetDate, onset_date as {{{SINGLE-QUOTE}}}System.DateTime{{{SINGLE-QUOTE}}}); endif; // HEALTH ISSUE DELETE SECTION // Deactivate then delete the Advanced Visit List Data elseif ( EvokingEventType = health_issue_delete_event.type ) then void := call advanced_visit_list_data_obj.Deactivate; void := call advanced_visit_list_data_obj.Purge; // HEALTH ISSUE DISCONTINUE SECTION // Deactivate the Advanced Visit List Data elseif ( EvokingEventType = health_issue_discontinue_event.type ) then void := call advanced_visit_list_data_obj.Deactivate; // note: since Deactivate and Delete both permenantly remove the HI from the list, we will treat them the same and purge the row void := call advanced_visit_list_data_obj.Purge; endif; // if( EvokingEventType = health_issue_enter_event.type or health_issue_modify_event.type ) objects_plus_destination.ObjectsPlus := advanced_visit_list_data_obj; endif; // If BNP Result/Health Issue Enter etc... endif; // if( continue_processing ) endtry; catch Exception ex error_occurred := true; error_message := "{{+R}}Error Message:{{-R}}\n" || ex.Message || "\n\n"; if ( advanced_visit_list_data_obj is NOT NULL ) then void:= call advanced_visit_list_data_obj.Dispose; advanced_visit_list_data_obj:= null; endif; if ( client_visit_obj is NOT NULL ) then void:= call client_visit_obj.Dispose; client_visit_obj:= null; endif; endcatch; if ( client_visit_obj is NOT NULL ) then void:= call client_visit_obj.Dispose; client_visit_obj:= null; endif; conclude true; ;; action: if error_occurred then write "An error has occured in the MLM " || "{{+B}}MLM SC_AVL_POTENTIAL_HEART_FAILURE {{-B}} " || "Please notify your System Administrators that an error message has " || "occurred for this patient. They will review the following error " || "message: \n" at alert_dest; write error_message at alert_dest; endif; if exists objects_plus_destination then write true at objects_plus_destination; endif; write " Messages " || " List Name.: " || AVL_Name || " Evoking Event: " || evokevent || " ObjectGUID1: " || current_health_issue_id || " ObjectGUID1Text: " || ObjectGUID1Text || " ObjectGUID2: " || current_coded_health_issue_id || " ObjectGUID2Text: " || ObjectGUID1Text || " onset_date: " || onset_date || " BNP Value: " || BNP_Value || " ClientVisitGUID: " || ClientVisitGUID || " PatientType: " || PatientType || " NonCHFAdmittingDx: " || NonCHFAdmittingDx || " PastCHFAdmittingDx: " || PastCHFAdmittingDx || " WasBeddedPriorToModify: " || WasBeddedPriorToModify || " continue_processing : " || continue_processing at alert_dest; ;; urgency: 50;; end: