[SalesForce] Apex Trigger to create Opportunity Contact Role based on Contact Lookup field

I have created the following Apex trigger that will create, update and delete Opportunity Contact Roles based on a Contact Lookup field placed on the Opportunity. Everything works great currently.

I am just trying to figure out one final scenario. If John Doe already has a Contact Role but is not the Primary Contact Role and I want him to be. I want to be able to change my look up field to him and then have that check him as the primary.

Currently it just creates a new one and checks them both as primary. So what I need to do is check the current Contact Roles and if there is already one with the same name as in the Lookup field then just check that one as primary, but if there isn't then create a new one.

Below is the code. Please let me know if you need further description.

Thanks,

trigger CreateContactRole 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>();

if(Trigger.isInsert) {
    for(Opportunity opp : Trigger.new) {
      if(opp.Primary_Contact__c != null) {
          //Creating new Contact Role
          newContactRoleList.add(new OpportunityContactRole(ContactId=opp.Primary_Contact__c,OpportunityId=opp.Id,Role='Decision Maker',IsPrimary=true));
      }
  }
}

if(Trigger.isUpdate) {      
  for(Opportunity opp : Trigger.new) {
      if(opp.Primary_Contact__c != null && Trigger.oldMap.get(opp.Id).Primary_Contact__c == null) {
            //Creating new Contact Role
          newContactRoleList.add(new OpportunityContactRole(ContactId=opp.Primary_Contact__c,OpportunityId=opp.Id,Role='Decision Maker',IsPrimary=true));
      }
        else if(opp.Primary_Contact__c != null && Trigger.oldMap.get(opp.Id).Primary_Contact__c != null) {
            //Create New Contact Role make new CR Primary over the old CR
            Opportunity OldOpp = Trigger.oldMap.get(opp.Id);
            OppId.add(OldOpp.id);
            ContactId.add(OldOpp.Primary_Contact__c);
            newContactRoleList.add(new OpportunityContactRole(ContactId=opp.Primary_Contact__c,OpportunityId=opp.Id,Role='Decision Maker',IsPrimary=true));
        }
      else if(opp.Primary_Contact__c == null && Trigger.oldMap.get(opp.Id).Primary_Contact__c != null) {
            Opportunity OldOpp = Trigger.oldMap.get(opp.Id);
            OppId.add(OldOpp.id);
            ContactId.add(OldOpp.Primary_Contact__c);
            try {
            //Deleting old Contact Roles
            if(oldContactRoleList.size()>0) delete oldContactRoleList;
            }
            catch(Exception e) {
                System.debug(e);
                trigger.new[0].addError('An error has occurred. Please contact your system administrator.');
            }
      }
  }
}

try {
    //inserting new contact roles
    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];        

}
catch(Exception e) {
    System.debug(e);
    trigger.new[0].addError('An error has occurred. Please contact your system administrator.');
}
}

Best Answer

Here's some modifications to your trigger that should point you in the right direction. Basically you want to use maps to do what you attempting. Your code was a bit unclear around your delete method. You don't want to do that inside your for loop one record at a time. Collect them all and do it all in a single operation.

If you want to do error handling, adjust the code to get DML save results and use your maps to equate them to the proper opportunity. Be sure to do the Delete operation FIRST since you don't want to have two primary OCR's on the same Opp record!

map<Id,Id>OpOldOcR = new map<Id,Id>();
map<Id,Id>OpNewOcR = new map<Id,Id>();

if(Trigger.isUpdate) {

  for(Opportunity opp : Trigger.new) {
      if(opp.Primary_Contact__c != null && Trigger.oldMap.get(opp.Id).Primary_Contact__c == null) {
            //Creating new Contact Role
          OpNewOcR.put(opp.Id,opp.Primary_Contact__c);
      }
        else if(opp.Primary_Contact__c != null && Trigger.oldMap.get(opp.Id).Primary_Contact__c != null) {
            //Create New Contact Role make new CR Primary over the old CR
            OpNewOcR.put(opp.Id,opp.Primary_Contact__c);
            OpOldOcR.put(opp.Id,Trigger.oldMap.get(opp.Id).Primary_Contact__c)

        }
      else if(opp.Primary_Contact__c == null && Trigger.oldMap.get(opp.Id).Primary_Contact__c != null) {
            OpOldOcR.put(opp.Id,Trigger.oldMap.get(opp.Id).Primary_Contact__c)
      }
  }

for(Id oId:OpNewOcR.keyset())
{
      newContactRoleList.add(new OpportunityContactRole(ContactId=OpNewOcR.get(oId),OpportunityId=oId,Role='Decision Maker',IsPrimary=true));
}

CtctIds.addALL(OpOldOcR.values());
list<OpportunityContactRole>toDelete = [SELECT Id, ContactId FROM OpportunityContactRole WHERE ContactId IN : CtctIds];

}

if(!toDelete.isEmpty()) delete toDelete;

if(!newContactRoleList.isEmpty()) insert newContactRoleList; 

}