I'm trying to create a trigger that updates a field on a contact whenever the contact changes ownership. The trigger saves without error, and my test class for the trigger gives a 100% code coverage result. However, when I test changing ownership on a contact, the field does not change. Here is my trigger:
trigger BusinessDivisionUpdateCont on Contact (before update)
{
Set<Id> relatedContactIdSet = new Set<Id>();
for (Contact cont : Trigger.new)
{
if (cont.OwnerId != null)
{
relatedContactIdSet.add(cont.OwnerId);
}
}
Map<Id, User> relatedContactsMap = new Map<Id, User>([
SELECT Id, Default_Business_Division__c
FROM User WHERE Id IN :relatedContactIdSet
]);
User ApiUser = [Select Id from User where Name = 'System'];
for (Contact newCont : Trigger.new)
{
Contact oldCont = Trigger.oldMap.get(newCont.Id);
if (oldCont.ownerId != null)
{
if ((oldCont.OwnerId != newCont.OwnerId)
&& (newCont.Owner != ApiUser)
&& (oldCont.OwnerId != null)
&& (newCont.OwnerId != null))
{
User newOwner = relatedContactsMap.get(newCont.OwnerId);
newCont.Business_Division__c = newOwner.Default_Business_Division__c;
}
}
}
}
Does the field not update because the ownership change isn't occurring on the contact level, but rather the account level? In other words, to change a contact's ownership, you have to change the ownership of the account that the contact belongs to. Changing the account automatically changes ownership of the contact to the new account owner. Even though this is the case, the trigger is still looking to see if the contact changed ownership, which it did. So I'm not sure why the field wouldn't update with the new information on the new owner. Any help would be awesome!
Attribution to: grimsvotn
Possible Suggestion/Solution #1
Have you considered using a Worfklow Rule or Formula Field to meet this requirement? It looks like you simply want the Business_Division__c field to be in sync with the owners Busines_Division__c field. To do that you could use a Workflow Rule / Field Update to copy Owner.Default_Business_Division__c into Contact.Business_Division__c.
The Formula Field would be on Contact, and its formula would be Owner.Business_Division__c. You could even add the check in the Formula or Field Update to ignore the API User.
Moving this to "Clicks not Code" via Workflow Rule or Formula Field will save you Apex Code, Unit Tests, and Deployment troubles. It is also best practice to use "Clicks" wherever possible.
Attribution to: CoryCowgill
Possible Suggestion/Solution #2
The reason your field is not being updated is because the IF statement will always be FALSE, for the reason that crop1645 notes in a comment above. newCont.Owner
is a null User object, since no related objects are available from trigger.new
. I created the following trigger on Contact to verify this.
trigger Contact_Trigger on Contact (before update)
{
Contact thisCon = Trigger.new[0];
User thisUser = [select Id, Name from User where Id = :trigger.new[0].OwnerId];
for (Integer i = 0; i < Trigger.new.size(); i++)
{
if (i == 0)
if (Trigger.new[i].Owner != thisUser)
Trigger.new[i].addError('Different: ' + Trigger.new[i].Owner + ' | ' + thisUser);
}
}
As crop1645 says, you need to compare the newCont.OwnerId
with ApiUser.Id
instead of newCont.Owner
and ApiUser
.
Attribution to: Jeremy Nottingham
This content is remixed from stackoverflow or stackexchange. Please visit https://salesforce.stackexchange.com/questions/34795