Blog

Auto-update Opportunity Contact Role Trigger(s)

2

I recently wrote a couple of triggers that I hope others may find useful. The purpose was to automatically update the list of contact roles against an opportunity, based on the tasks/activity created against it. We found that our sales users were generally good at logging activities against the opportunity but often forgot to update the opportunity contact roles.

Here’s where the triggers come in. This first variant was written to ensure that there is at least one primary contact against the opportunity, and if not it will add the first contact (related to a task on the opp) as the primary – with the role set to ‘Decision Maker’:

trigger TaskOppCPR on Task (after insert) {
	if (Trigger.new.size() == 1) { // only fires on single insert through UI        
		if (string.valueOf(Trigger.new[0].WhatId).startsWith('006') && Trigger.new[0].WhoId != null) { 
                  // if no primary contact, set this contact as primary            
		if ([select count() from OpportunityContactRole where OpportunityId =:Trigger.new[0].WhatId and IsPrimary=true] == 0) {  
			OpportunityContactRole ocr = new OpportunityContactRole();                
			ocr.OpportunityId = Trigger.new[0].WhatId;                
			ocr.ContactId = Trigger.new[0].WhoId;                
			ocr.IsPrimary = true;                
			ocr.Role = 'Decision Maker';                
			insert ocr;            
		}
	}
}}

The next variant ignores the ‘primary’ element of the contact role and will update the list with any contact against a related task on the opportunity (unless it already exists as a contact role). This time it will set the role to ‘Other’:

trigger TaskOppCR on Task (after insert) {
	if (Trigger.new.size() == 1) { // only fires on single insert through UI        
		if (string.valueOf(Trigger.new[0].WhatId).startsWith('006') && Trigger.new[0].WhoId != null) { 
			// if this contact is not already in Contact Roles, add it   
			if ([select count() from OpportunityContactRole where OpportunityId =:Trigger.new[0].WhatId and ContactId =:Trigger.new[0].WhoId] == 0) {
				OpportunityContactRole ocr = new OpportunityContactRole();
				ocr.OpportunityId = Trigger.new[0].WhatId;                
				ocr.ContactId = Trigger.new[0].WhoId;
				ocr.Role = 'Other';                
			insert ocr;            
		}
	}
}}

Notes:
1) Both of these triggers have been set to fire only when the size is 1 in order to avoid governor limits. They will only run when used through the user interface
2) The ‘default’ contact role can easily be changed from ‘Other’ or ‘Decision Maker’ to something more suitable
3) These examples are for tasks only, however a similar approach could be used for events (may prove interesting/difficult with large numbers of invitees)
4) Please contribute by posting your own variants in comments

  • Kyle

    Looks like your code examples are slight mixed up. you are setting the role to other in the first screen shot and Decision maker in the second.

    As far as second trigger goes, how do you accomplish "update the list with any contact against a related task on the opportunity (unless it already exists as a contact role)"

    Is is just SFDC functionality that is blocking the addition of that contact if it already exists? I don't see any code that checks for it.

  • forcedotcom

    Hi Kyle,

    Thanks for pointing that out – I had make some changes when editing the post but didn't update that. I believe it's in order now.

    As for the second trigger the SOQL query does a check to see if the contact is already a contact role on this opportunity and if not it will be added… see line 5