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

487 lines
22 KiB
Plaintext

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: