maintenance: title: SCH_UNSIGNED_ORDERS2;; mlmname: SCH_UNSIGNED_ORDERS2;; arden: version 2;; version: 4.00;; institution: St Clair Memorial Hospital;; author: Robert Spence;; specialist: ;; date: 2009-11-23;; validation: testing;; library: purpose: ;; explanation: Change history 12.23.2010 DW Altered for 5.5. Change event UserLogon to ActivateApplication 12.29.2012 DW HD ticket #154600 Doctors forced to sign "incomplete" Orders Reconciliation Documents 06.13.2019 KR Add 3M ChartFact support ;; keywords: ;; knowledge: type: data-driven;; data: //Logging level of execution information log_execution_info:=FALSE; using "LaunchSignMan"; using namespace "LaunchSignMan"; standard_libs := mlm {{{SINGLE-QUOTE}}}std_include_libs{{{SINGLE-QUOTE}}}; include standard_libs; using "ObjectsPlusXA.SCM.Forms"; using namespace "ObjectsPlusXA.SunriseClinicalManager.Forms"; //The evoking event for this MLM is OrderInit evoking_event_order:= EVENT { ActivateApplication User UserInfo: WHERE CareProvider is NOT NULL And OrderRoleType Matches Pattern "%Physician%"}; RunSignMan:= new net_object {{{SINGLE-QUOTE}}}LaunchSignMan.SigManGateWay{{{SINGLE-QUOTE}}}; userguid,idcode :=read last {UserInfo: guid,idcode}; //Physician Alert - 20190808 - kwr using "ACS_Phys_Alert"; // name of your .DLL file in client Directory using namespace "ACS_Phys_Alert"; //NAMESPACE in your program error_occurred := false; try get_val := NEW NET_Object {{{SINGLE-QUOTE}}}PhysicianAlert{{{SINGLE-QUOTE}}}; //name of the CLASS in your program // now, call the FUNCTION or SUBROUTINE in defined in your class // rtnval := call get_val.buildmlmform with my_val as string; //get_val.Visible := true as {{{SINGLE-QUOTE}}}Boolean{{{SINGLE-QUOTE}}}; rtnval := call get_val.AlertPhysician ; endtry; catch exception ex error_occurred := true; msg := msg || "\nError: \n" || ex; endcatch; //END Physician Alert //Check for 3M Deficiencies - 20190613 - kwr using "ACS_ViewLincLib"; // name of your .DLL file in client Directory using namespace "SCMViewLinc"; //NAMESPACE in your program error_occurred := false; trigger3M := false; try get_val := NEW NET_Object {{{SINGLE-QUOTE}}}SCMViewLinc{{{SINGLE-QUOTE}}}; //name of the CLASS in your program // now, call the FUNCTION or SUBROUTINE in defined in your class // rtnval := call get_val.buildmlmform with my_val as string; //get_val.Visible := true as {{{SINGLE-QUOTE}}}Boolean{{{SINGLE-QUOTE}}}; rtnval := call get_val.GetDeficiencyCount ; RunSignMan.MMMParams.Text := rtnval; if rtnval <> "0" then trigger3M := true; endif; endtry; catch exception ex error_occurred := true; msg := msg || "\nError: \n" || ex; endcatch; //End 3M // userguid := "12312312"; rettype := read last {" select typecode " || " from cv3careprovider with (nolock) " || " where guid = " || SQL(userguid) || " and typecode not like {{{SINGLE-QUOTE}}}Non Staff%{{{SINGLE-QUOTE}}} " || " and typecode like {{{SINGLE-QUOTE}}}%Physician%{{{SINGLE-QUOTE}}} " // || " and DisplayName not like {{{SINGLE-QUOTE}}}Cedar, Mark A{{{SINGLE-QUOTE}}} " || " and signorderflag = 1" }; if (rettype is null) or (not (exists rettype )) then triggerme := false; else triggerme := true; endif; OverRideOn5s:= false; if triggerme = true then excludedocuments := read last { " select count(value) " || " from CV3UserDictionaryValue with (nolock) " || " WHERE UserDictionaryCode = {{{SINGLE-QUOTE}}}SignManUsersExcDocuments{{{SINGLE-QUOTE}}} AND Active = 1 " || " and value = " || sql(idcode) } ; if excludedocuments >0 // only 1{{{SINGLE-QUOTE}}}s then filtertype := " (1) "; else filtertype := " (1,3) "; endif; RunSignMan.SignTypes.Text := filtertype; ICanLaunchGroup := false; mygroup := (); groupstring := ""; mygroup := read {" select distinct(sgpf.careproviderguid) " || " from cv3signaturegrpproviderxref as sgpf with (nolock) " || " join cv3signaturegroup as sg with (nolock) " || " on sg.guid = sgpf.signaturegroupparentguid " || " and sg.active = 1 " || " and sg.code not in ({{{SINGLE-QUOTE}}}BLA{{{SINGLE-QUOTE}}},{{{SINGLE-QUOTE}}}GCC{{{SINGLE-QUOTE}}},{{{SINGLE-QUOTE}}}AYG{{{SINGLE-QUOTE}}},{{{SINGLE-QUOTE}}}HOA{{{SINGLE-QUOTE}}},{{{SINGLE-QUOTE}}}MLG{{{SINGLE-QUOTE}}},{{{SINGLE-QUOTE}}}SHC{{{SINGLE-QUOTE}}},{{{SINGLE-QUOTE}}}SEN{{{SINGLE-QUOTE}}},{{{SINGLE-QUOTE}}}SPA{{{SINGLE-QUOTE}}},{{{SINGLE-QUOTE}}}SOG{{{SINGLE-QUOTE}}},{{{SINGLE-QUOTE}}}TOG{{{SINGLE-QUOTE}}},{{{SINGLE-QUOTE}}}UHV{{{SINGLE-QUOTE}}}) " || " where sgpf.signaturegroupparentguid in (select usgx.signaturegroupguid " || " from cv3usersignaturegroupxref as usgx with (nolock) " || " where usgx.userguid = " || SQL(userguid) || " and (usgx.ExpiryDtm >= getdate() or usgx.ExpiryDtm is null) " || " and usgx.active = 1 " || ") " || " and sgpf.active = 1 " }; if count mygroup > 1 then if userguid not in mygroup then mygroup := mygroup , userguid; endif; ICanLaunchGroup:=true; for k in (1 seqto (count mygroup )) do if k = 1 then groupstring := "({{{SINGLE-QUOTE}}}" || mygroup[k]; elseif k <> (count mygroup) then groupstring := groupstring || "{{{SINGLE-QUOTE}}},{{{SINGLE-QUOTE}}}" || mygroup[k]; elseif k = (count mygroup) then groupstring := groupstring || "{{{SINGLE-QUOTE}}},{{{SINGLE-QUOTE}}}" || mygroup[k] || "{{{SINGLE-QUOTE}}})"; endif; enddo; else ICanLaunchGroup := false; endif; //Determine the number of unsigned orders for the provider group // if userguid = "7000001175119001" then ICanLaunchGroup := false; endif; // if userguid = "7000002033119001" then ICanLaunchGroup := false; endif; /*Peggy*/ // if userguid = "1000002185119001" then ICanLaunchGroup := false; endif; /*Cedar copied from Peggy*/ // if userguid = "8000001103119001" then ICanLaunchGroup := false; endif; /*Dr. Lisa Ann Oliva*/ // if userguid = "3000001019119001" then ICanLaunchGroup := false; endif; /*Dr. Mark A. Cedar*/ num_unsign_prov := 0; secondarySQL :=""; if ICanLaunchGroup = true then RunSignMan.fromMLM.text := groupstring; num_unsign_prov := read last {" SELECT count(SM.CompletionObjectID) " ||" FROM SXACMPCompletionObject SM with (nolock) " ||" left join cv3clientdocument cd with (nolock) on cd.guid = sm.objectguid " ||" Where SM.CareProviderGUID in " || groupstring ||" AND SM.CompletionStep = {{{SINGLE-QUOTE}}}Sign{{{SINGLE-QUOTE}}} " ||" AND SM.CompletionStatus = {{{SINGLE-QUOTE}}}Active{{{SINGLE-QUOTE}}} " ||" and sm.createdwhen <= (dateadd(hour, -12, getdate())) " ||" and (cd.isincomplete is null or cd.isincomplete = 0) " ||" and sm.objecttypeid in " || filtertype }; secondarySQL := " SM.CareProviderGUID In " || groupstring || " "; else num_unsign_prov:=read last {"SELECT count(SM.CompletionObjectID) " ||" FROM SXACMPCompletionObject SM with (nolock) " ||" left join cv3clientdocument cd with (nolock) on cd.guid = sm.objectguid " ||" Where SM.CareProviderGUID = " || SQL(userguid) ||" AND SM.CompletionStep = {{{SINGLE-QUOTE}}}Sign{{{SINGLE-QUOTE}}} " ||" AND SM.CompletionStatus = {{{SINGLE-QUOTE}}}Active{{{SINGLE-QUOTE}}} " ||" and sm.createdwhen <= (dateadd(hour, -12, getdate())) " ||" and (cd.isincomplete is null or cd.isincomplete = 0) " ||" and sm.objecttypeid in " || filtertype }; secondarySQL := " SM.CareProviderGUID = " || SQL(userguid) || " "; endif; // Now do the 5AM / 5PM logic as requested in 03/2010 PRISM Meeting if num_unsign_prov = 0 then currtime := now ; yesterday := currtime - 1 day; ss := extract second currtime; if ss <10 then ss := "0" || ss;endif; mi := extract minute currtime; if mi <10 then mi := "0" || mi; endif; hr := extract hour currtime; if hr < 10 then hr := "0" || hr; endif; yr := extract year currtime; mn := extract month currtime; if mn < 10 then mn := "0" || mn; endif; dd := extract day currtime; if dd < 10 then dd := "0" || dd; endif; yyr := extract year yesterday; ymn := extract month yesterday; if ymn < 10 then ymn := "0" || ymn; endif; ydd := extract day yesterday; if ydd < 10 then ydd := "0" || ydd; endif; Endtime := yr || "-" || mn || "-" || dd || " " || hr || ":" || mi || ":" || ss; SQLyesterday := yyr || "-" || ymn || "-" || ydd || " "; SQLtoday := yr || "-" || mn || "-" || dd || " "; SQLstart := ""; hrnum := hr as number; Messagetest := ""; if (hrnum < 5) then SQLStart := SQLyesterday || "17:00:00.000"; elseif (hrnum >=5) and (hrnum < 17) then SQLStart := SQLtoday || "05:00:00.000"; elseif (hrnum >= 17) then SQLStart := SQLtoday || "17:00:00.000"; endif; MessageTest := "Start " || SQLStart || "\n" || "END " || Endtime ; RobertSays := "Testing"; hrtest := hr as number; // so now we have our starting and ending ranges (both in SQL format). // if the provider has deficiencies between these two date / time ranges and has not signed any thing in the same range: // Launch signature manager as a reminder that new orders / documents are available to sign. DidISignAny := read last {"select count(*) from SXACMPCompletionObject as sm with (nolock) " ||" left join cv3clientdocument cd with (nolock) on cd.guid = sm.objectguid " || " where " || secondarySQL || " and sm.completionuserguid = " || SQL(userguid) || " and sm.completionStatus = {{{SINGLE-QUOTE}}}Complete{{{SINGLE-QUOTE}}} " || " and sm.completiondtm >= {{{SINGLE-QUOTE}}}" || SQLStart || "{{{SINGLE-QUOTE}}}" || " and sm.completiondtm <= {{{SINGLE-QUOTE}}}" || Endtime || "{{{SINGLE-QUOTE}}}" || " and (cd.isincomplete is null or cd.isincomplete = 0) " || " and sm.objecttypeid in " || filtertype }; // Only If I didn{{{SINGLE-QUOTE}}}t sign any and there are orders etc out there for my group should SM fire if (DidISignAny =0) then numcurrently := read last {" SELECT count(SM.CompletionObjectID) " ||" FROM SXACMPCompletionObject SM with (nolock) " ||" left join cv3clientdocument cd with (nolock) on cd.guid = sm.objectguid " ||" Where " || secondarySQL ||" AND SM.CompletionStep = {{{SINGLE-QUOTE}}}Sign{{{SINGLE-QUOTE}}} " ||" AND SM.CompletionStatus = {{{SINGLE-QUOTE}}}Active{{{SINGLE-QUOTE}}} " ||" and (cd.isincomplete is null or cd.isincomplete = 0) " ||" and sm.objecttypeid in " || filtertype }; endif; if (DidISignAny = 0) and (numcurrently >0) then if idcode in ("radams","dsacco","rspence") then OverRideOn5s:= true; endif; MessageText := "Override firing on the 5s no signature for " || idcode || ": Between " || SQLStart || " and " || Endtime || ": Current Unsigned = " || numcurrently ; TestDBWrite:= read last {" insert into schsignmanalertrecords " || " (Login,CreatedWhen,Comment) " || " values (" || sql(idcode) || " ,getdate()," || sql(MessageText) || ")" }; else OverRideOn5s:= false; endif; // dialogResult := call {{{SINGLE-QUOTE}}}MessageBox{{{SINGLE-QUOTE}}}.Show with "Time Reference Is " || currtime || "\n\n" || MessageTest, // "Tester","OK" as {{{SINGLE-QUOTE}}}MessageBoxButtons{{{SINGLE-QUOTE}}}; endif; endif; // trigger me. if (triggerme = true and (num_unsign_prov>0 or OverRideOn5s = true)) then RunSignMan.SMParams.Text := "LaunchSM"; endif; ;; evoke: evoking_event_order; ;; logic: //provider list for the pilot /* prov_list:= ("7000001175119001",//Spence, Robert "6000001149119001", "4000001091119001", "9000002364101190", "1000001064119001", "7000001272119001", "1000001032119001", "3000001032119001", "4000001244119001", "6000001208119001"); */ // This can be used to enable a doctor with a corrupted record to bypass signature manager upon login // if (triggerme = true and userguid not in ("5000001012119001","8000001055119001","9000001055119001","9000115581901190","7000001049119001","2000001826119001") and if (triggerme = true and (num_unsign_prov>0 or OverRideOn5s = true)) or (trigger3M = true) then oeUnsigned:=CALL RunSignMan.ShowDialog; conclude true; else conclude false; endif; ;; action: //all of the action is done by the call to the FFI ;; Urgency: 50;; end: