function readOnly(count){ }
Starting November 20, the site will be set to read-only. On December 4, 2023,
forum discussions will move to the Trailblazer Community.
+ Start a Discussion
faceroy123faceroy123 

Trigger new Opportunity Contact Role based on opportunity custom field

Hi,

 

I have a custom field on the opportunity object named 'contact__c'. This is a simple lookup field.

If populated I want a trigger that creates an Opportunity contact role for that same contact.

 

Any ideas?

 

I can update the contact__c field based on the primary contact role but I need this work the other way round.

 

Any ideas?

 

Thanks

 

 

Best Answer chosen by Admin (Salesforce Developers) 
UVUV

May be this trigger can help you-

 

trigger addContactRole on Opportunity (after Insert, after update) {

    

    List<OpportunityContactRole> newContactRoleList=new List<OpportunityContactRole>();

    List<OpportunityContactRole> oldContactRoleList=new List<OpportunityContactRole>();

    Set<Id> OppId=new Set<Id>();

    Set<Id> ContactId=new Set<Id>();

   

    for(Opportunity oppObj: Trigger.new)

    {

        //Insert condition    

        if(Trigger.isInsert)

        {

            if(oppObj.Contact__c!=null)

            {

                //Creating new contact role

                newContactRoleList.add(new OpportunityContactRole (ContactId=oppObj.Contact__c,OpportunityId=oppObj.Id, Role=null));

                                                                                         

            }

        }

        else

        {   

       

                if(oppObj.Contact__c==null && Trigger.oldMap.get(oppObj.Id).Contact__c!=null)

                {

                    //Getting the contact and oppty Id from old values and adding this in set               

                     Opportunity OldoppObj=Trigger.oldMap.get(oppObj.Id);        

                     OppId.add(OldoppObj.id);

                     ContactId.add(OldoppObj.Contact__c);

                    

                }

                else if(oppObj.Contact__c!=null)

                {

                    //Creating new contact role

                    newContactRoleList.add(new OpportunityContactRole (ContactId=oppObj.Contact__c, OpportunityId=oppObj.Id, Role='Business User'));

                }

        }                    

    }

   

   

    try

    {

        //inserting new Contact Roles

        if(newContactRoleList.size()>0) insert newContactRoleList;

       

        //Selecting old Selecting old contact roles

        if (OppId.size()>0) oldContactRoleList=[Select Id from OpportunityContactRole where ContactId in : ContactId  and OpportunityId in : OppId];

       

        //Deleting old contact roles

        if (oldContactRoleList.size()>0) delete oldContactRoleList;

    }

    catch(Exception e)

    {

        System.debug(e);

        trigger.new[0].addError('Technical error occurred. Please contact to your system administrator or try after some time.');

       

    }

   

   

   

   

}

All Answers

UVUV

May be this trigger can help you-

 

trigger addContactRole on Opportunity (after Insert, after update) {

    

    List<OpportunityContactRole> newContactRoleList=new List<OpportunityContactRole>();

    List<OpportunityContactRole> oldContactRoleList=new List<OpportunityContactRole>();

    Set<Id> OppId=new Set<Id>();

    Set<Id> ContactId=new Set<Id>();

   

    for(Opportunity oppObj: Trigger.new)

    {

        //Insert condition    

        if(Trigger.isInsert)

        {

            if(oppObj.Contact__c!=null)

            {

                //Creating new contact role

                newContactRoleList.add(new OpportunityContactRole (ContactId=oppObj.Contact__c,OpportunityId=oppObj.Id, Role=null));

                                                                                         

            }

        }

        else

        {   

       

                if(oppObj.Contact__c==null && Trigger.oldMap.get(oppObj.Id).Contact__c!=null)

                {

                    //Getting the contact and oppty Id from old values and adding this in set               

                     Opportunity OldoppObj=Trigger.oldMap.get(oppObj.Id);        

                     OppId.add(OldoppObj.id);

                     ContactId.add(OldoppObj.Contact__c);

                    

                }

                else if(oppObj.Contact__c!=null)

                {

                    //Creating new contact role

                    newContactRoleList.add(new OpportunityContactRole (ContactId=oppObj.Contact__c, OpportunityId=oppObj.Id, Role='Business User'));

                }

        }                    

    }

   

   

    try

    {

        //inserting new Contact Roles

        if(newContactRoleList.size()>0) insert newContactRoleList;

       

        //Selecting old Selecting old contact roles

        if (OppId.size()>0) oldContactRoleList=[Select Id from OpportunityContactRole where ContactId in : ContactId  and OpportunityId in : OppId];

       

        //Deleting old contact roles

        if (oldContactRoleList.size()>0) delete oldContactRoleList;

    }

    catch(Exception e)

    {

        System.debug(e);

        trigger.new[0].addError('Technical error occurred. Please contact to your system administrator or try after some time.');

       

    }

   

   

   

   

}

This was selected as the best answer
faceroy123faceroy123

Thanks Umesh! :-)

faceroy123faceroy123

Umesh,

 

would you know how to modify this so that upon lead conversion the contact__c lookup field is also populated with the contact created upon conversion?

 

Thanks for your help

 

ArunaAruna

Hi,

 

 when i click on converted to lead  opportunity and The opportunitycontactrole is created but   The opportunitycontactrole is not creating when i create a new opportunity.

 

Could you please post the solution i need to create a opportunity contactrole when the lead is converted and when the new opportunity is created.

 

sample code is appreciated.

 

Thank you

DavidNorman.ax1639DavidNorman.ax1639

Hi, 

 

I'd really like to use this appex trigger on a project I'm working on. Do you happen to have the unit test for this trigger available?

 

Thank You!

Friend of JimFriend of Jim

This trigger is excellent - thank you for posting!

 

I have however found one issue with the trigger: duplicates Contact Roles are created whenever the opportunity is modified. I've tried altering the trigger in a number of ways, including adding a SOQL query to the 'inserting new contacts' section:

 

[select count() from OpportunityContactRole where IsPrimary=true]==0

 

I've also tried using oldMap to compare the new value to the old value for 'Creating new contact role' - No luck.

 

if(oppObj.Contact__c!=null && Trigger.oldMap.get(oppObj.Id).Contact__c==null)

 

Any suggestions on preventing creation of duplicate contact roles?

Friend of JimFriend of Jim

For anybody experiencing duplicate contact roles (this messed with our reporting) - here is what I used for updated code. Seemed to solve the problem with no adverse effects.

 

Simple alteration - this adds an oldMap clause for when Contact__c != null.

 

trigger addContactRole on Opportunity (after Insert, after update) {

List<OpportunityContactRole> newContactRoleList=new List<OpportunityContactRole>();
List<OpportunityContactRole> oldContactRoleList=new List<OpportunityContactRole>();
Set<Id> OppId=new Set<Id>();
Set<Id> ContactId=new Set<Id>();

for(Opportunity oppObj: Trigger.new)
{
//Insert condition
if(Trigger.isInsert)
{
if(oppObj.Contact__c!=null && Trigger.oldMap.get(oppObj.Id).Contact__c==null)
{
//Creating new contact role
newContactRoleList.add(new OpportunityContactRole (ContactId=oppObj.Contact__c,OpportunityId=oppObj.Id, Role='Decision Maker', IsPrimary = true));

}
}
else
{

if(oppObj.Contact__c==null && Trigger.oldMap.get(oppObj.Id).Contact__c!=null)
{
//Getting the contact and oppty Id from old values and adding this in set
Opportunity OldoppObj=Trigger.oldMap.get(oppObj.Id);
OppId.add(OldoppObj.id);
ContactId.add(OldoppObj.Contact__c);

}
else if(oppObj.Contact__c!=null && Trigger.oldMap.get(oppObj.Id).Contact__c==null)
{
//Creating new contact role
newContactRoleList.add(new OpportunityContactRole (ContactId=oppObj.Contact__c, OpportunityId=oppObj.Id, Role='Decision Maker', IsPrimary = true));
}
}
}


try
{
//inserting new Contacts
if(newContactRoleList.size()>0) insert newContactRoleList;

//Selecting old contact roles
if (OppId.size()>0) oldContactRoleList=[Select Id from OpportunityContactRole where ContactId in : ContactId and OpportunityId in : OppId];

//Deleting old contact roles
if (oldContactRoleList.size()>0) delete oldContactRoleList;
}
catch(Exception e)
{
System.debug(e);
trigger.new[0].addError('Technical error occurred. Please contact to your system administrator or try after some time.');

}




}

ElenaTeguiElenaTegui

This is AMAZING! I´m really not familiar with trigger yet. Does this need a Test class? It appear as 0%cover and I can´t install it in production. 

arunadeveloperarunadeveloper
Yes. Triggrr/apex class required at least 75. Percent coverage to deploye. Into production.
.
kevin.chileskevin.chiles

Hello!

 

 

I have found this very usefull but was not able to get my code coverage up over 73 percent, does anyone have the test class I could use for this post?

Swapnil PatneSwapnil Patne

Hi,

I have a similar requirement and I used the code above and it works to a point it adds contacts as a contact role, however for some reasons it's adding contact twice. Not sure what's the issue.. can someone help?

Thanks,
Swapnil
Swapnil PatneSwapnil Patne
Also, can someone help with the Test class for this apex trigger?
Swapnil PatneSwapnil Patne
Hi Friend of Jim,

I used the code you mentioned in your comment above but I get this error:

Error: Invalid Data. 
Review all error messages below to correct your data.
Apex trigger addContactRole caused an unexpected exception, contact your administrator: addContactRole: execution of AfterInsert caused by: System.NullPointerException: Attempt to de-reference a null object: Trigger.addContactRole: line 13, column 1

Can you please help me?

Thanks,
swapnil
Swapnil PatneSwapnil Patne
Hi All, can anyone please help me on this ??
Kevin Chiles 930Kevin Chiles 930
Hello @Swapril,  I think the error you are getting is because the field you are using the in the trigger is blank.  If has to be populated for the trigger to work on the insert.  However, if the field is blank you will get the error.  I am running into the same issue.  Not sure why, I am currently debugging the issue
Swapnil PatneSwapnil Patne
Hi Kevin, thanks for picking up the issue and for your reply, I hope you are able to debug and resolve it. Keeping my hopes alive ;) thanks. 
Swapnil 
Joe ReyesJoe Reyes
Hi All,

 This is great.  Does anyone have the unit test for this trigger?

Thanks in advanced.

Joe
Kevin Chiles 930Kevin Chiles 930
Hello!

I am writing a test class for this item but I am only getting 66% coverage!  Can anyone help!?
 
p@isTest(SeeAllData=true)

public class YourTriggerTestClass{
    static testMethod void yourTestMethod(){
    
        //fill all the required field and make sure your data passes the validation rules.
        //insert account
        account acc = new account(
        Name='test account');
        
        insert acc;
        
        //insert contact
        contact ct2 = new Contact(
        LastName='Tester',
        AccountId=acc.id);
        
        insert ct2;
        
        contact ct = new Contact(
        LastName='Tester',
        AccountId=acc.id);
        
        insert ct;
        
        //insert propert
        Property__c p = new Property__c(
        Name='test');
        
        insert p;
        
        //insert campaign
        Campaign camp = new Campaign(
        Name='test camp',
        IsActive=True,
        Property__c=p.Id);
        
        insert camp;
        
        
        //Insert Opportunity
        opportunity opp = new opportunity(
        Name = 'Test oppty',
        
        CampaignId=camp.id,
        StageName='Prospecting',
        CloseDate=system.today(),
        AccountId=acc.id,
        Investor__r=ct);
        
        insert opp;
        
       // opp.Investor__r=ct2;
        
       // update opp;
        
        OpportunityContactRole ocr = new OpportunityContactRole(
        ContactId=ct.id,
        OpportunityId=opp.id,
        Role='Decision Maker',
        IsPrimary=True);
        
        insert ocr;
        
        }
        }
Kevin Chiles 930Kevin Chiles 930
Ok Guys!  I cracked this one.

For the Trigger with no error on record creation:
 
trigger addContactRole on Opportunity (after Insert, after update) {
    
    List<OpportunityContactRole> newContactRoleList=new List<OpportunityContactRole>();
    List<OpportunityContactRole> oldContactRoleList=new List<OpportunityContactRole>();
    Set<Id> OppId=new Set<Id>();
    Set<Id> ContactId=new Set<Id>();
   
    for(Opportunity oppObj: Trigger.new)
    {
        //Insert condition    
        if(Trigger.isInsert)
        {
            if(oppObj.Investor__c!=null)
            {
                //Creating new contact role
                newContactRoleList.add(new OpportunityContactRole (ContactId=oppObj.Investor__c,OpportunityId=oppObj.Id, Role='Decision Maker',IsPrimary=True));
                                                                                         
            }
        }
        else
        {   
       
                if(oppObj.Investor__c==null && Trigger.oldMap.get(oppObj.Id).Investor__c!=null)
                {
                    //Getting the contact and oppty Id from old values and adding this in set               
                     Opportunity OldoppObj=Trigger.oldMap.get(oppObj.Id);        
                     OppId.add(OldoppObj.id);
                     ContactId.add(OldoppObj.Investor__c);
                    
                }
                else if(oppObj.Investor__c!=null && Trigger.oldMap.get(oppObj.Id).Investor__c==null)
                {
                    //Creating new contact role
                    newContactRoleList.add(new OpportunityContactRole (ContactId=oppObj.Investor__c, OpportunityId=oppObj.Id, Role='Business User',IsPrimary=True));
                }
        }                    
    }
   
   
    try
    {
        //inserting new Contact Roles
        if(newContactRoleList.size()>0) insert newContactRoleList;
       
        //Selecting old Selecting old contact roles
        if ( OppId.size()>0) oldContactRoleList=[Select Id from OpportunityContactRole where ContactId in : ContactId  and OpportunityId in : OppId];
       
        //Deleting old contact roles
        if (oldContactRoleList.size()>0) delete oldContactRoleList;
    }
    catch(Exception e)
    {
        System.debug(e);
        trigger.new[0].addError('Technical error occurred. Please contact to your system administrator or try after some time.');
       
    }
   
   
   
   
}

For the Test Class:(modify for your required fields)
 
@isTest(SeeAllData=true)

public class YourTriggerTestClass{
    static testMethod void yourTestMethod(){
    
        //fill all the required field and make sure your data passes the validation rules.
        //insert account
        account acc = new account(
        Name='test account');
        
        insert acc;
        
        //insert contact
        contact ct2 = new Contact(
        LastName='Tester',
        AccountId=acc.id);
        
        insert ct2;
        
        contact ct = new Contact(
        LastName='Tester',
        AccountId=acc.id);
        
        insert ct;
        
        //insert propert
        Property__c p = new Property__c(
        Name='test');
        
        insert p;
        
        //insert campaign
        Campaign camp = new Campaign(
        Name='test camp',
        IsActive=True,
        Property__c=p.Id);
        
        insert camp;
        
        
        //Insert Opportunity
        opportunity opp = new opportunity(
        Name = 'Test oppty',
        
        CampaignId=camp.id,
        StageName='Prospecting',
        CloseDate=system.today(),
        AccountId=acc.id);
        opp.Investor__c=ct.Id
        ;
        
        insert opp;
        
                          
        
        //opp.Investor__c=ct2.id;
        
       // update opp;
        
        opp.Investor__c = null;

        update opp;
        
        }
        }



 
Kathleen LehnigkKathleen Lehnigk
@Kevin Chiles 930: Thanks for the adapted code.

Unfortunately I still get duplicate values when creating the opp via a contact. Anyone knows, what could be the issue here? Thank you
Kathleen LehnigkKathleen Lehnigk
Hi everyone, 

I've now fixed the issue myself. Now used a simple flow and a process (process builder). Got the initial info from http://judisohn.com/2015/04/06/using-salesforce-process-builder-flow-with-opportunity-contact-roles/ 

Just modified it so that it checks at the beginning if a contact role already exists or not. It works like a charm and now I don't have duplicate contact roles anymore. Also very easy to implement.
Chad MoutesChad Moutes
Hey everyone,

I know this post is older but I am looking for some help here. I am doing something very similar to this and I am having an issue. Lets say there is a contact role John Doe and he is not currently the primary contact role. But something has changed and now I want to make him the primary. So I change the custom field on the opportunity to his contact record and what happens is it create a second contact role and checks both of them as primary. How do I make it delete the old contact role for him and replace it with a new primary one?

Any help would be great.
Barry EdwardsBarry Edwards
What if my "Investor__c" field is actually a formula field that captures the contact ID from another object?

Any clues?  Deployment is returning the following error:

System.DmlException: Insert failed. First exception on row 0; first error: CANNOT_INSERT_UPDATE_ACTIVATE_ENTITY, addContactRole : execution of AfterInsert

caused by: System.StringException: Invalid id: null