Our current sales process has a lead converted to an opportunity. There is a custom lookup field on the Opportunity to identify the primary point of contact. Once that lookup field is populated, we have a custom field to populate the email address of that contact in order to have an email alert set up. Question here is, if that lookup field is populated with the contact, is there a way we can also leverage some automation to assign it as primary and add them under Contact Roles related list in the Opportunity?
[SalesForce] How to populate contact roles based on a custom lookup field in Opportunities for the Primary Contact
Related Solutions
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;
}
It seems that the code snippet you provieded is correct. I just copy-pasted it to my dev org and it works perfectly - the first contact is populated as primary. It's either I do your business process incorrectly or the problem isn't in that trigger. I would suggest you to test this trigger on a clean dev org and check if the first contact is not populated as primary. If so, write several debug logs to understand better code execution. If in dev org this trigger will work perfectly - you need to dig deeper into debug logs and understand what else affects Contact Roles
Best Answer
In addition, to using a Process Builder and a Flow based solution, an alternative could be to use an after update Apex Trigger.
Refer the following sample Apex Trigger code and build upon this.
Although I would recommend using the ProcessBuilder and Flow based approach stated above since, that will save you the overhead of writing test code.