When creating a new Opportunity the contact role is automatically populated when the opportunity is created from a contact record(standard functionality). In the case where users create an opportunity from a different record (e.g Account), the opportunity contact role is not automatically populated.
I have create an after insert trigger to automatically insert an opportunity contact role based on a custom field "Related_Contact__c". This works when the opp is created from any record besides a contact. But in the situation when the record is created from a contact record, the trigger is still firing and therefor the contact has two opportunity contact roles..
Am I overlooking something?
public static void populateOpportunityOcr(List<Opportunity> newOpportunityRecords){
set<Id> newOppId = new set<Id>();
set<Id> newOppRelatedContactId = new set<Id>();
for(Opportunity o: newOpportunityRecords){
newOppId.add(o.Id);
if(o.Related_Contact__c != NULL){
newOppRelatedContactId.add(o.Related_Contact__c);
}
}
List<OpportunityContactRole> oppsLst = [SELECT Id, ContactId, OpportunityId FROM OpportunityContactRole WHERE ID IN: newOppId AND ContactId IN :newOppRelatedContactId];
List<OpportunityContactRole> ocrToInsert = new List<OpportunityContactRole>();
if(oppsLst.isEmpty()){
for(Opportunity ops: newOpportunityRecords){
if(ops.Related_Contact__c != NULL){
ocrToInsert.add(new OpportunityContactRole(contactId = ops.Related_Contact__c,
OpportunityId = ops.Id,
Role = 'Business User',
isPrimary = FALSE
));
}
}
}
if(!ocrToInsert.isEmpty()){
Insert ocrToInsert;
}
}
Best Answer
Parent records are always created before their children. The OpportunityContactRole is created after the transaction completes. What you need is some asynchronous code. The easiest fix is to just use a Queueable.
And then...
Note: DML on an empty list is okay, there's no need to check for an empty list.
Also, this code demonstrates bulkification in the event that more than one record is created at once for some reason.