This question is really old, but still doesn't have an accepted answer, so I'll throw out a solution. I see two possible approaches here:
- You create some custom checkbox (example below has a checkbox called
Assigned_by_Trigger__c
) or hijack some other field that indicates that the Lead was assigned via your trigger and have a rule in your Lead Assignment rules that if it was assigned via a trigger, keep the owner the same. Make this the first condition.
- You let Lead Assignment Rules run and then delegate this to an asynchronous method, either
@future
or Queueable
Personally, I'd go for option 1, so that it's never in the hands of the "wrong" owner. Additionally, you'll want to take the logic out of your trigger and delegate it to an Apex class (read up on trigger frameworks). There's also no reason for this to process in the after
context, so I'd move this to before insert
and before update
. Lastly, you'll want to either make sure the User triggering this code has permission to update records with inactive owners and/or check to see that the Named Account owner is active.
Your code might look something like this:
trigger LeadTrigger on Lead (before insert, after insert, before update, after update, before delete, after delete) {
LeadHandler.handleEvents(trigger.isBefore, trigger.isAfter, trigger.isInsert, trigger.isUpdate, trigger.isDelete, trigger.new, trigger.old, trigger.newMap, trigger.oldMap);
}
And the handler class:
public class LeadHandler {
public static void handleEvents(Boolean isBefore, Boolean isAfter, Boolean isInsert, Boolean isUpdate, Boolean isDelete, List<Lead> newList, List<Lead> oldList, Map<Id,Lead> newMap, Map<Id,Lead> oldMap){
try{
if(isBefore && isInsert){
assignToNamedAccountOwner(newList);
}
if(isAfter && isInsert){
//do afterInsert
}
if(isBefore && isUpdate){
assignToNamedAccountOwner(newList);
}
if(isAfter && isUpdate){
//do afterUpdate
}
if(isBefore && isDelete){
//do beforeDelete
}
if(isAfter && isDelete){
//do afterDelete
}
}
catch(Exception e){
if(newList.size()>0){
newList[0].addError(e.getMessage());
}
}
}
public static void assignToNamedAccountOwner(List<Lead> newLeads){
Set<String> leadDomains = new Set<String>();
for(Lead l : newLeads){
if(l.email_domain__c != null){
leadDomains.add(l.email_domain__c);
}
}
Map<String,Account> domainAccMap = new Map<String,Account>();
for(Account a : [SELECT Id, OwnerId, Owner.isActive, email_domain__c
FROM Account
WHERE email_domain__c = :leadDomains
AND Named_Account__c = TRUE]){
domainAccMap.put(a.email_domain__c,a);
}
for(Lead l : newLeads){
if(l.email_domain__c != null){
Account a = domainAccMap.get(l.email_domain__c);
if(a != null && a.Owner.isActive){
l.OwnerId = a.OwnerId;
l.Assigned_by_Trigger__c = TRUE;
}
}
}
}
}
after insert/update trigger
? If yes, Lead Assignment rules will always run after the Lead 'after trigger' and to change the default assignments will require using an @future method.