EncompDEV
CodeWizard

Alert Counter Field Plugin

Click here to download this plugin with source code    

This plugin sets two custom fields [CX.ALERT.CNT] and [CX.ALERT.SUMMARY] to total alert count and alert summary when loan is opened & saved. This will allow you to have these as fields in reports as well as sort pipeline by alert types (i.e. eConsent / Disclosures).

Screenshots with Loan Monitor showing field updates at Loan Open / Save:


Code used for this plugin:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows.Forms;

using EllieMae.Encompass.ComponentModel;
using EllieMae.Encompass.Automation;
using EllieMae.Encompass.BusinessObjects;
using EllieMae.Encompass.BusinessObjects.Loans;
using EllieMae.Encompass.Reporting;
using EllieMae.Encompass.Query;

namespace AlertCounterFieldPlugin
{
    [Plugin]
    public class EncompassPlugin
    {
        const string FIELD_ALERT_COUNTER = "CX.ALERT.CNT";
        const string FIELD_ALERT_SUMMARY = "CX.ALERT.SUMMARY";

        // don't process alert fields when saving loan internally
        bool bInternalLoanSaveIgnoreCommitedEvent = false;

        // Constructor - wait for Login event
        public EncompassPlugin()
        {
            EncompassApplication.Login += new EventHandler(Application_Login);
        }

        // Login - handle Loan Open and Loan Closing events
        private void Application_Login(object sender, EventArgs e)
        {
            EncompassApplication.LoanOpened += new EventHandler(LoanOpenedEvent);
            EncompassApplication.LoanClosing += new EventHandler(LoanClosingEvent);
        }

        // Loan Opened event - start monitoring Commited event
        private void LoanOpenedEvent(object sender, EventArgs e)
        {
            Loan loan = EncompassApplication.CurrentLoan;
            // start listning to loan saves
            loan.Committed += new PersistentObjectEventHandler(Loan_Committed);
            // update alert fields on loan open
            UpdateAlertFields(loan);
        }

        // Loan Closing event - stop monitoring Commited event
        private void LoanClosingEvent(object sender, EventArgs e)
        {
            Loan loan = EncompassApplication.CurrentLoan;
            // stop listning to loan saves
            loan.Committed -= new PersistentObjectEventHandler(Loan_Committed);
        }

        // check alert fields after loan is saved
        private void Loan_Committed(object sender, PersistentObjectEventArgs e)
        {
            if (!this.bInternalLoanSaveIgnoreCommitedEvent)
            {
                Loan loan = EncompassApplication.CurrentLoan;
                try
                {
                    this.bInternalLoanSaveIgnoreCommitedEvent = true;

                    // if alerts changed - resave loan again
                    if (UpdateAlertFields(loan))
                    {
                        loan.Commit();
                    }
                }
                catch (Exception ex)
                {
                    MsgBox_Err("AlertCounterFieldPlugin: Cannot save loan: " + ex.Message);
                }
                finally
                {
                    this.bInternalLoanSaveIgnoreCommitedEvent = false;
                }
            }
        }

        // find loan pipeline data and update fields from that data
        // return TRUE if fields were changed
        private bool UpdateAlertFields(Loan loan)
        {
            try
            {
                // find pipeline data for this loan & update loan fields
                StringFieldCriterion this_loan = new StringFieldCriterion("Loan.Guid", loan.Guid, 
                    StringFieldMatchType.CaseInsensitive, true);
                using (PipelineCursor pc = loan.Session.Loans.QueryPipeline(this_loan, PipelineSortOrder.None))
                {
                    // our pipeline cursor should only have ONE result for this loan
                    foreach (PipelineData data in pc)
                    {
                        return UpdateAlertFieldsFromPipelineData(loan, data);
                    }
                }
            }
            catch (Exception ex)
            {
                MsgBox_Err("AlertCounterFieldPlugin: Cannot update fields: " + ex.Message);
            }
            // fallthrough - return false
            return false;
        }

        // set fields, return TRUE if fields were changed
        private bool UpdateAlertFieldsFromPipelineData(Loan loan, PipelineData data)
        {
            // 1. count
            string sCount = data.Alerts.Count.ToString();
            bool bUpdated1 = UpdateFieldIfDifferent(loan, FIELD_ALERT_COUNTER, sCount);

            // 2. summary
            string sSummary = data.Alerts.ToString();
            bool bUpdated2 = UpdateFieldIfDifferent(loan, FIELD_ALERT_SUMMARY, sSummary);

            // 3. return TRUE if something changed
            return bUpdated1 | bUpdated2;
        }

        private bool UpdateFieldIfDifferent(Loan loan, string sFieldID, string sValue)
        {
            // compare string in alpha-numeric only mode (ignore extra spaces or other chars)
            string s1 = AlphaNumericOnly(sValue);
            string s2 = AlphaNumericOnly(loan.Fields[sFieldID].UnformattedValue);
            if (!s1.Equals(s2))
            {
                Macro.SetFieldNoRules(sFieldID, sValue);
                return true;
            }
            else
            {
                return false;
            }
        }

        private static string AlphaNumericOnly(string s)
        {
            string sOut = "";
            foreach (char ch in s)
            {
                if ((ch >= '0' && ch <= '9') ||
                    (ch >= 'a' && ch <= 'z') ||
                    (ch >= 'A' && ch <= 'Z'))
                {
                    // valid letter or digit
                    sOut += ch;
                }
            }
            return sOut;
        }

        private static void MsgBox_Err(string s)
        {
            MessageBox.Show(s, "Error",
                MessageBoxButtons.OK,
                MessageBoxIcon.Exclamation);
        }

    }
}