EncompDEV
LoanDebugger2

Macro Exec Plugin

Click here to download EMPKG     Click here to download Project Source

MacroExecPlugin allows you to execute Macro Actions and Epass services from Field Triggers via Advanced Coding.

Advanced coding is very limited to just a few loan functions like fields and a few standard functions like MsgBox. You cannot call Macro functions from Field Trigger advanced code same way you would inside an Input Form event handler. MacroExecPlugin solves this limitation via a global plugin that monitors changes to [CX.MACRO.ACTION] and [CX.MACRO.SIGNATURE] fields and then calling Macro.ExeciAction() and Macro.ExecSignature() functions.

In case when your field trigger often occurs in the middle of a loan recalculation or a chain of field updates, optional parameter [CX.MACRO.DELAYMS] can be set to delay execution by a number of milliseconds enough for calculations to finish.

Following is an example how MacroExecPlugin can be used to popup MI dialog "mipff" action inside a field trigger for LTV:


If you need to test or debug when MacroExecPlugin executes, you can use standard Encompass Debug registry flag HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Ellie Mae\Encompass\"Debug"="1". A log file will be created in C:\Users\USERID\AppData\LocalLow\Apps\Ellie Mae\xIHR5EqGa7zPnRG0YpD5z4TPAB0=\EncompassData\Settings\Logs\

An Admin Test form is provided for your convinience. You can test each Action / Signature and you can open the log file directly from this form. Screenshot below:


You can find the list of standard actions in Appendix B of Encompass360 Input Form Builder User’s Guide. Standard actions are: 1stmor addregistration altlender baseincome cashflow ccprog cityfee cityfeeca condlist copyaddr detailrequest editcheck fhamaxloan geocode hazins hud1a hudsetup importliab income investor loanprog loanprog2 manageborrowers mersmin mipff mortg mtginsprem mtginspremca mtginsreserv orderappraisal ordercredit orderflood ordertitle other otherf plancode presenthe productandpricing ratespread resetrequestform retaxes selecttemplate statefee statefeeca subfin subfin2 syncbrw taxes taxesreserv transferto trusteedb userfee1 userfee1ca userfee2 userfee2ca userfee3 userfee3ca viewcredit vod voe vol vom vor zoomarm.

There are also few nonstandard actions to run various services and popup various forms. For example: accesslenders getindex getpricing exportulddfannie exportulddfreddie 203kws allotherpay basecost cashavailable cashflow closingcosts edithudgfe1203 edithudgfe801 edithudgfe802 editpuradvintcal editregistration enerfyimprove escrowtable feedetails gotosection32 hmda...

ExecSignature allows you to execute EPASS services to select vendors or from specific vendors. You can contact Ellie Mae to get a list of EPASS Signatures for the services you need.

Examples of generic services EPASS Signatures where Vendor will be selected from the list:
Appraisal: _EPASS_SIGNATURE;EPASSAI;2;Appraisal
Credit Report: _EPASS_SIGNATURE;EPASSAI;2;Credit+Report
Mortgage Insurance: _EPASS_SIGNATURE;EPASSAI;2;Mortgage+Insurance

Examples of specific vendor EPASS Signatures:
Equifax: _EPASS_SIGNATURE;EQUIFAX_CRI;2;EQUIFAXREQ;2101
Credco: _EPASS_SIGNATURE;CREDCO_CRI;2;FACREDCOREQ;CoreLogic%20Credco;1601;ShowCC
United Guarantee: _EPASS_SIGNATURE;UNITEDG_MI;2;UNITEDG_MIREQ
MGIC: _EPASS_SIGNATURE;MGIC_MI;2;MGIC_MIREQ

Source Code

EncompassPlugin.cs - Plugin main entry point
using System;
using System.Collections.Generic;
using System.Text;
using System.IO;
using System.Threading;
using System.Windows.Forms;

using System.Reflection;

using EllieMae.Encompass.ComponentModel;

namespace MacroExecPlugin
{
    [Plugin]
    [ObfuscationAttribute(Exclude = true, ApplyToMembers = true)]
    public class EncompassPlugin
    {
        EncompassPluginHandler ph = null; 

        public EncompassPlugin()
        {
            ph = new EncompassPluginHandler();
        }
    }
}

EncompassPluginHandler.cs - Loan Open / Close event handlers
using System;
using System.Collections.Generic;
using System.Text;
using System.IO;
using System.Threading;
using System.Windows.Forms;

using EllieMae.Encompass.Automation;
using EllieMae.Encompass.BusinessObjects.Loans;


namespace MacroExecPlugin
{
    public class EncompassPluginHandler
    {
        private volatile FieldMonitor_MacroExec field_monitor = null;

        public EncompassPluginHandler()
        {
            EncompassApplication.Login += new EventHandler(EncompassApplication_Login);
        }

        private void EncompassApplication_Login(object sender, EventArgs e)
        {
            EncompassApplication.LoanOpened += new EventHandler(Application_LoanOpened);
            EncompassApplication.LoanClosing += new EventHandler(Application_LoanClosing);
        }

        private void Application_LoanOpened(object sender, EventArgs e)
        {
            StartMonitor();
        }

        private void Application_LoanClosing(object sender, EventArgs e)
        {
            StopMonitor();
        }

        private void StartMonitor()
        {
            lock (this)
            {
                try
                {
                    StopMonitor();
                    Loan loan = EncompassApplication.CurrentLoan;
                    if (loan != null)
                    {
                        Utils2.AddToLog("Start Monitor");
                        field_monitor = new FieldMonitor_MacroExec(loan);
                        field_monitor.Start();
                    }
                }
                catch (Exception ex)
                {
                    Utils2.AddToLog("StartMonitor Exception: " + ex.Message);
                    Utils2.MsgBox_ErrorOK("StartMonitor Exception: " + ex.Message);
                }
            }
        }

        private void StopMonitor()
        {
            lock (this)
            {
                try
                {
                    if (field_monitor != null)
                    {
                        Utils2.AddToLog("Stop Monitor");
                        field_monitor.Stop();
                        field_monitor = null;
                    }
                }
                catch (Exception ex)
                {
                    Utils2.AddToLog("StopMonitor Exception: " + ex.Message);
                    Utils2.MsgBox_ErrorOK("StopMonitor Exception: " + ex.Message);
                }
            }
        }

    }
}

FieldMonitor_MacroExec.cs - FieldChange Event Handler
using System;
using System.Collections.Generic;
using System.Text;

using EllieMae.Encompass.BusinessObjects.Loans;

namespace MacroExecPlugin
{
    public class FieldMonitor_MacroExec
    {
        private Loan LOAN = null;

        // timer for delayed execution
        private volatile System.Timers.Timer timer_delayed_exec = null;

        // values we read from custom field trigger and need for delayed triggering
        private string TriggerFieldId = "";
        private string TriggerFieldValue = "";
        private int DelayMilliSec = 0;

        public FieldMonitor_MacroExec(Loan loan)
        {
            this.LOAN = loan;
        }

        public void Start()
        {
            LOAN.FieldChange += Loan_FieldChange;
        }

        public void Stop()
        {
            LOAN.FieldChange -= Loan_FieldChange;
            StopTimer_DelayedExec();
        }

        // don't throw
        private void Loan_FieldChange(object source, FieldChangeEventArgs e)
        {
            try
            {
                string sFieldID = e.FieldID;
                if (String.Equals(sFieldID, "CX.MACRO.ACTION", StringComparison.OrdinalIgnoreCase) ||
                    String.Equals(sFieldID, "CX.MACRO.SIGNATURE", StringComparison.OrdinalIgnoreCase))
                {
                    Utils2.AddToLog("FieldChange Start");

                    if (e.NewValue.Length > 0)
                    {
                        // 1. params
                        this.TriggerFieldId = e.FieldID;
                        this.TriggerFieldValue = e.NewValue;
                        this.DelayMilliSec = LOAN.Fields["CX.MACRO.DELAYMS"].ToInt();

                        // 2. clear fields
                        LOAN.Fields["CX.MACRO.ACTION"].Value = "";
                        LOAN.Fields["CX.MACRO.SIGNATURE"].Value = "";
                        LOAN.Fields["CX.MACRO.DELAYMS"].Value = "";

                        // 3. exec action or signature
                        HandleImmediateOrDelayedExec();
                    }

                    Utils2.AddToLog("FieldChange End");
                }
            }
            catch (Exception ex)
            {
                Utils2.AddToLog("FieldChange Exception: " + ex.Message);
            }
        }

        // throw on error
        private void HandleImmediateOrDelayedExec()
        {
            Utils2.AddToLog("Exec: Field=" + this.TriggerFieldId + " Value=" + this.TriggerFieldValue + " DelayMS=" + this.DelayMilliSec);
            if (this.DelayMilliSec < 1)
            {
                // immediate execution
                ExecuteNow();
            }
            else
            {
                // delayed execution
                StartTimer_DelayedExec();
            }
        }

        // throw on error
        private void StartTimer_DelayedExec()
        {
            lock (this)
            {
                // stop previous timer in case more than 1 delayed triggers
                StopTimer_DelayedExec(); 

                // delayed execution
                timer_delayed_exec = new System.Timers.Timer(this.DelayMilliSec);
                timer_delayed_exec.Elapsed += new System.Timers.ElapsedEventHandler(OnTimer_DelayedExec);
                timer_delayed_exec.AutoReset = false; // single-time
                // timer_delayed_exec.SynchronizingObject = frmMain; <- set this if there are cross-thread issues
                timer_delayed_exec.Enabled = true;
            }
        }

        // don't throw
        private void StopTimer_DelayedExec()
        {
            lock (this)
            {
                if (timer_delayed_exec != null)
                {
                    try
                    {
                        timer_delayed_exec.Enabled = false;
                        timer_delayed_exec.Dispose();
                    }
                    catch { } // ignore
                    timer_delayed_exec = null;
                }
            }
        }

        // don't throw
        private void OnTimer_DelayedExec(object sender, System.Timers.ElapsedEventArgs e)
        {
            lock (this)
            {
                try
                {
                    StopTimer_DelayedExec();
                    ExecuteNow();
                }
                catch (Exception ex)
                {
                    Utils2.AddToLog("DelayedTimer Exception: " + ex.Message);
                    Utils2.MsgBox_ErrorOK("DelayedTimer Exception: " + ex.Message);
                }
            }
        }

        // throw on error
        // Insnance Params: TriggerFieldId, TriggerFieldValue, DelayMilliSec
        private void ExecuteNow()
        {
            if (this.TriggerFieldId.IndexOf("ACTION", StringComparison.OrdinalIgnoreCase) >= 0)
            {
                // Exec Action
                Utils2.AddToLog("Exec Action: " + this.TriggerFieldValue);
                EllieMae.Encompass.Automation.Macro.ExecAction(this.TriggerFieldValue);
            }
            else if (this.TriggerFieldId.IndexOf("SIGNATURE", StringComparison.OrdinalIgnoreCase) >= 0)
            {
                // Exec Signature
                Utils2.AddToLog("Exec Signature: " + this.TriggerFieldValue);
                EllieMae.Encompass.Automation.Macro.ExecSignature(this.TriggerFieldValue);
            }
            else
            {
                throw new Exception ("Unexpected Exec field: " + this.TriggerFieldId);
            }
        }

    }
}

Utils2.cs - Various Utility Functions
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows.Forms;

namespace MacroExecPlugin
{
    class Utils2
    {
        public static void MsgBox_ErrorOK(string s)
        {
            // Form w = Form.ActiveForm; 
            MessageBox.Show("MacroExecPlugin - " + s, "Error", MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
        }

        public static void AddToLog(string s)
        {
            EllieMae.Encompass.Client.ApplicationLog.Write("MacroExecPlugin", s);
        }
    }
}