+ Start a Discussion
Jon KeenerJon Keener 

Determining in trigger for before delete (or before update) whether Merge is the cause

Is there anyway to determine in a before delete trigger if the reason that a delete is because a user is attempting to merge a record, and the record being deleted is the losing record in the merge?  The reason I'm asking, is I would like to show a different error message, depending on the context. (merging, vs. clickling the delete button on the account.)
Also, I was thinking about whether there might be value in have "before merge" and "after merge" triggers.  These might be useful, for example, being able to look at something like trigger.old.1.name, trigger.old.2.name, trigger.old.3.name, and trigger.new.name. 
Rules could be put in place to not allow certain types of field merges from certain types of records.  For example:
1.  I want to allow users to merge prospect recordtype accounts to customer recordtype accounts, but not the reverse.
2.  I do not want to allow customer recordtypes to be merged with other customer recordtypes.  (In our case, we have an integration with SAP, and we want SAP to have full control over this)
3.  When merging a prospect recordtype to a customer recordtype, I do not want certain fields from prospect records to ever merge to a customer recordtype.  These would typically be fields that are prepopulated on the customer recordtype from our SAP system.
In the Spring '07 release the MasterRecordId field will be set on the object in a delete event that was the result of a merge operation. That will be the indicator you need for the loser(s).

As for your use cases, are your rules actually different in a merge event, i.e you allow prospect to customer change when it's a merge event but not an update? Unless there is a difference then your rules should apply as expected in the Update trigger on the winner.

If SAP is the master, won't the values get written back over? Sounds like you want those fields to be readonly in salesforce no matter what, again either in a merge or a direct update, right?

We've debated whether to have triggers for merge events but so far we've been able to justify use of the existing delete/update events that result - which also means fewer trigger states for developers to worry about.

If you have different logic you'd enforce on the update based on the operation being a merge please include them here.

Jon KeenerJon Keener
The MasterRecordId field in the Spring '07 release will definitely help with showing appropriate error messages in a before delete trigger. 
Your mostly correct on the SAP information, that we have most of those fields as read only.  Where this becomes a little bit challenging though, is that there are some fields, currently some custom address fields, that have field level security set to allow editing, and it is the customer page layout that stops our users from editing these fields on a customer recordtype.  One thing that we've found, is that reporting and dashboards get to be a bit more challenging when you're showing prospects and customers, but you are storing filter criteria information in two different fields, depending on recordtype.  (This also applies to Mail Merges, etc.)  In this case, a before update trigger could definitely be set up to not allow these updates, so this doesn't justify the before merge/after merge triggers.
Thinking about the above, there would definitely be some specific coding in most triggers to allow certain user ids/roles/profiles through, while blocking others.  It might not be a bad thing to expose more "current user" information directly in the trigger regarding their role and profile, to save on coding.  Another thought would be to allow for custom fields on both the role and profile objects.  For example, on the profiles that I want to be able to perform a delete of a customer record, I add a custom checkbox field to the profile object called "Allow Customer Deletions" and I make sure it's checked on the appropriate profiles.
One use case for before merge and after merge events would be more specific error handling in the merge interface.  For my before delete tests, I see that the message shows up at the top of the screen, vs. near to non-master record in the merge selection area.  If I was merging 3 records, I wouldn't know which column it was referring to.  Also, I just tested an update trigger via merge, and it did not appear to function with the merge.  I was testing with the following trigger, (I picked the website field at random for testing), and it works perfectly if I go to an account and I try to edit and save it. However, if I merge two records, and choose the website record from the losing record to update on the master record, the merge allows this to occur.  I would have expected the trigger below to stop the update.  (I would also expect the field error message to show up in the correct column, at the correct field on the merge edit screen)
trigger ChangeWebSiteCheck on Account(before update) {

  if (Trigger.old.WebSite != Trigger.new.WebSite)
       Trigger.new.WebSite.addError('Web Sites can not be changed on a customer record.');

 As for different logic between a merge and an update, I haven't thought of any specific scenarios, that couldn't be handled via the standard update/delete triggers, assuming they are working appropriately.  One that I need to think about a little more is recordtype changes, during a merge.
The only thing beyond the more specific error handling I mentioned above, would be specific merge rules to disallow certain merges at all between different recordtypes.  For example, If someone is trying to merge two/three account records that are both Customer recordtypes, I would like to stop this from happening.  It actually might not be bad to have a merge trigger fire when the "Next" button is clicked, and before the actual screen that allows you to choose the field sources shows up.  (To make it even more fun, the trigger could control some of the defaults as to which fields are auto selected, force one to be the master, etc)  At this point, you could save the end user a lot of time in the above scenario.  I might have rules like the following:
Prospect + Prospect (master) = Allow Merge to continue
Prospect + Customer (master) = Allow Merge to continue
Customer + Customer (master) = Never Allow Merge
Vendor + Customer = Never Allow Merge (doesn't matter which would be master)
Plant + Vendor = Never Allow Merge (doesn't matter which would be master)
Jon Keener