Using IChangedState to track before/after values of an entity
Posted By: nicocrm on May 11th, 2009 in Uncategorized
No Gravatar

This is a very nifty feature of the new Saleslogix platform that addresses the very common scenario of detecting when the user edited a field.  In the legacy client we often had to either run a SQL or manually save the old value to a global on the form – this was a rather tedious and dirty if you had to check a lot of properties.  In this new platform the change tracking is built-in – there are a few steps to it so it does not necessarily save in terms of line of code but it is less messy.

The basics are documented in the Saleslogix Web Client FAQ:

private static String GetOldMainPhoneValue(IAccount account)
{
    IChangedState accountState = account as IChangedState;
    if (accountState != null)
    {
        ChangeSet changes = accountState.GetChangedState();
        PropertyChange mainPhoneChange = changes.FindPropertyChange("MainPhone");
        
        if (mainPhoneChange != null)
        {
            return (string) mainPhoneChange.OldValue;
        }
    }
    return null;
}

However there are a few pitfalls.

First of all and not really related, but I found out your business rules would not execute if you specified it as a “Pre-Execute” or “Post-Execute” target but did not have a primary step on the rule.

Secondly, you have to know when this update information is available.  As far as I can tell this is available on the form handlers, as well as on the “OnBeforeUpdate” entity events, but not once the entity has been saved (e.g. on the OnAfterUpdate event).

Another point is that there is a slightly different syntax depending on the type of change to be tracked.  If it is a simple property change the above code (FindPropertyChange) works.  However if the change is on a related entity… for example opportunity.AccountManager… you have to use this syntax:

ChangeSet changes = changeState.GetChangedState();
EntityPropertyChange change = changes.FindMemberChange<EntityPropertyChange>("AccountManager");
string newUserId = (String) change.NewEntity.EntityId;
string oldUserId = (String)change.OldEntity.EntityId;

Unfortunately this does not work with simple properties… so you have to know which property you are dealing with in order to know how to examine the changes.


Leave a Reply