maintenance: title: SCH_AVL_COPD;; mlmname: SCH_AVL_COPD;; arden: version 2.5;; version: 5.50;; institution: St. Clair Hospital;; author: Juliet Law, Allscripts;; specialist: Dean Miklavic, Allscripts;; date: 2012-06-26;; validation: Testing;; library: purpose: Maintains COPD Advanced Visit List data ;; explanation: This MLM maintains the COPD 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 := "AVL Potential COPD Patients"; AVL_External_ID := "004"; AVL_HI_GUID_Coded := "HealthIssue_GUID_Coded"; AVL_HI_OnsetDate := "HealthIssue_OnsetDate"; AVL_HI_GUID_Patient := "HealthIssue_GUID_Patient"; // Triggers clientvisit_enter_event := Event {ClientVisitEnter ANY ClientVisit : WHERE TypeCode = "Inpatient" OR TypeCode = "Observation"}; clientvisit_modify_event := Event {ClientVisitModify ANY ClientVisit : WHERE TypeCode = "Inpatient" OR TypeCode = "Observation"}; healthissue_enter_event := Event {HealthIssueEnter ANY HealthIssue : WHERE TypeCode IN ("Admitting DX","AMB Med History","Problem-Chronic", "Problem-Proced","Problem-Visit") AND (ShortName matches pattern "%COPD%" OR Text matches pattern "%COPD%") }; healthissue_modify_event := Event {HealthIssueModify ANY HealthIssue : WHERE TypeCode IN ("Admitting DX","AMB Med History","Problem-Chronic", "Problem-Proced","Problem-Visit") AND (ShortName matches pattern "%COPD%" OR Text matches pattern "%COPD%") }; healthissue_delete_event := Event {HealthIssueDelete ANY HealthIssue : WHERE TypeCode IN ("Admitting DX","AMB Med History","Problem-Chronic", "Problem-Proced","Problem-Visit") AND (ShortName matches pattern "%COPD%" OR Text matches pattern "%COPD%") }; healthissue_discontinue_event := Event {HealthIssueDiscontinue ANY HealthIssue : WHERE TypeCode IN ("Admitting DX","AMB Med History","Problem-Chronic", "Problem_Proced","Problem-Visit") AND (ShortName matches pattern "%COPD%" OR Text matches pattern "%COPD%") }; //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 := 2011]; send_alert := "DoNotSend"; alert_dest := Destination { alert } WITH [alert_type := "warning", short_message := "Order Session Type", priority := "high", scope := "chart", rule_group := "Order Session Type", rule_number := 15042, send_with_order := send_alert, alert_dialog_settings := "No Override Allowed", display_alert := true]; //******************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 = healthissue_enter_event.type then evokevent := "Health Issue Enter Event"; (VisitGUID, ChartGUID, ClientGUID) := read last { HealthIssue: ClientVisitGUID, ChartGUID, ClientGUID REFERENCING EvokingObject }; endif; If EvokingEventType = healthissue_modify_event.type then evokevent := "Health Issue Modify Event"; (VisitGUID, ChartGUID, ClientGUID) := read last { HealthIssue: ClientVisitGUID, ChartGUID, ClientGUID REFERENCING EvokingObject }; endif; If EvokingEventType = healthissue_delete_event.type then evokevent := "Health Issue Delete Event"; (VisitGUID, ChartGUID, ClientGUID) := read last { HealthIssue: ClientVisitGUID, ChartGUID, ClientGUID REFERENCING EvokingObject }; endif; If EvokingEventType = healthissue_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 = " || Sql(ClientGUID) || " AND ChartGUID = " || Sql(ChartGUID) || " AND guid = " || Sql(VisitGUID) }; NonCOPDAdmittingDx := 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}}}%COPD%{{{SINGLE-QUOTE}}} " || " AND Text not like {{{SINGLE-QUOTE}}}%COPD%{{{SINGLE-QUOTE}}} " || " AND ClientGuid = " || Sql(ClientGuid) || " AND ChartGuid = " || Sql(ChartGuid) || " AND ClientVisitGUID = " || Sql(VisitGUID) }; PastCOPDAdmittingDx := read last {"SELECT Description " || " FROM CV3HealthIssueDeclaration with (nolock) " || " WHERE Active = 1 " || " AND TypeCode <> {{{SINGLE-QUOTE}}}Admitting DX{{{SINGLE-QUOTE}}} " || " AND ShortName like ({{{SINGLE-QUOTE}}}%COPD%{{{SINGLE-QUOTE}}}) " || " AND ClientGuid = " || Sql(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 = " || Sql(ClientGuid) || " AND cvl.clientvisitguid = " || Sql(VisitGUID) }; If ((EvokingEventType = healthissue_enter_event.type or EvokingEventType = healthissue_modify_event.type or EvokingEventType = healthissue_delete_event.type or EvokingEventType = healthissue_discontinue_event.type ) and PatientType is not null) or ((EvokingEventType = clientvisit_modify_event.type or clientvisit_enter_event.type) and (not exists NonCOPDAdmittingDx and not exists WasBeddedPriorToModify and (exists PastCOPDAdmittingDx) ) ) then //INPATIENT/OBSERVATION PATIENT PROCEED SECTION //VISIT EVENT SECTION If (EvokingEventType = clientvisit_enter_event.type or EvokingEventType = clientvisit_modify_event.type) then //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 = " || Sql(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 }; endif; // If 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 = healthissue_modify_event.type ) then if(existing_health_issue_obj is not null) then health_issue_onset_date_obj := existing_health_issue_obj.OnsetDate; // processing only continues if status or onset date changes if( existing_health_issue_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_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) ; 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 clientvisit_enter_event; 1 minutes after time of clientvisit_modify_event; 0 minutes after time of healthissue_enter_event; 0 minutes after time of healthissue_modify_event; 0 minutes after time of healthissue_delete_event; 0 minutes after time of healthissue_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 //HEALTH ISSUE ENTER OR HEALTH ISSUE MODIFY SECTION // Client Visit Event if (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}}}); objects_plus_destination.ObjectsPlus := advanced_visit_list_data_obj; else // Health Issue Enter or Modify Event if( EvokingEventType = healthissue_enter_event.type or EvokingEventType = healthissue_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 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 = healthissue_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 = healthissue_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 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_COPD {{-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 || " ObjectGUID2: " || current_coded_health_issue_id || " onset_date: " || onset_date || " ClientVisitGUID: " || VisitGUID || " PatientType: " || PatientType || " NonCHFAdmittingDx: " || NonCOPDAdmittingDx || " PastCHFAdmittingDx: " || PastCOPDAdmittingDx || " WasBeddedPriorToModify: " || WasBeddedPriorToModify || " continue_processing : " || continue_processing at alert_dest; */ ;; urgency: 50;; end: