0

I'm new to salesforce and I'm trying to learn more. Currently I'm stuck at a point where I don't know what to do further. Kindly point me in the right direction. Any help is appreciated. So what im trying to do is to compare lastnames to find duplicates when the record is being created and if a duplicate is found then instead of creating it as a new record it should be merged with existing record.

So to achieve the task I have wrote the following trigger handler:

public class LeadTriggerHandler {

    public static void duplicateMerge(){
        
        List<Lead> leadList = [SELECT Id,Name, Email, Phone, FirstName, LastName FROM Lead];
        List<Lead> leadTrigger = Trigger.new;
        
        
        for(Lead leadVarTrigger : leadTrigger){
            
            for(Lead leadVar : leadList){
                //System.debug(leadVar.LastName + '==' + leadVarTrigger.LastName);
                if(leadVarTrigger.LastName == leadVar.LastName)
                {
                    //System.debug(leadVar.LastName + '==' + leadVarTrigger.LastName);
                    
                    //leadVarTrigger.addError('This is a duplicate record');
                    Database.merge(leadVar, leadVarTrigger);
                    System.debug('Trigger Successful');
                    
                }
            }
        }
    }
}

the following is my trigger:

trigger LeadTrigger on Lead (after insert) {
    
    if(Trigger.isafter && Trigger.isInsert)
    {
       LeadTriggerHandler.duplicateMerge(); 
    }

}

And when I try with after insert i get the following error:

LeadTrigger: execution of AfterInsert caused by: System.DmlException: Merge failed. First exception on row 0 with id 00Q5j00000ENUGVEA5; first error: INVALID_FIELD_FOR_INSERT_UPDATE, Unable to create/update fields: Name. Please check the security settings of this field and verify that it is read/write for your profile or permission set.: [Name] Class.LeadTriggerHandler.duplicateMerge: line 18, column 1 Trigger.LeadTrigger: line 5, column 1

And if i try with before trigger i get the following error for the same code:

LeadTrigger: execution of BeforeInsert caused by: System.StringException: Invalid id at index 0: null External entry point Trigger.LeadTrigger: line 5, column 1

James Z
  • 12,209
  • 10
  • 24
  • 44

1 Answers1

0

Actually, according to your code, you are allowing the record to be created and saved to the database by using after insert. Your before insert failed because your handler class is referencing an Id, however, if you use before logic, the record isn't saved to the database yet, meaning it doesn't have an Id. With that being said, let's try the following. :)

The Trigger (Best practice is to have one trigger with all events):

trigger TestTrigger on Lead (before insert, before update, before delete, after insert, after update, after delete, after undelete) {
    if(Trigger.isafter && Trigger.isInsert)
    {
       //Can't conduct DML operations with trigger.new or trigger.old
       //So we will create a set and send this to our handler class
       Set<Id> leadIds = Trigger.newMap.keySet();
       LeadTriggerHandler.duplicateMerge(leadIds); 
    }
}

The Handler Class:

public class LeadTriggerHandler {
    public static void duplicateMerge(Set<Id> idsFromTrigger){
        //Querying the database for the records created during the trigger
        List<Lead> leadTrigger = [SELECT Id, LastName FROM Lead WHERE Id IN: idsFromTrigger];
        List<String> lastNames = new List<String>();
        //This set is important as it prevents duplicates in our dml call later on
        Set<Lead> deDupedLeads = new Set<Lead>();
        List<Lead> leadsToDelete = new List<Lead>();
        
        for (Lead l : leadTrigger){
            //getting all of the Last Names of the records from the trigger
            lastNames.add(l.lastName);
        }
        //We are querying the database for records that have the same last name as 
        //the records that were created during our trigger
        List<Lead> leadList = [SELECT Id, Name, Email, Phone, FirstName, LastName FROM Lead WHERE LastName IN: lastNames];
        
        for(Lead leadInTrigger : leadTrigger){   
            for(Lead leadInList : leadList){
                if(leadInTrigger.LastName == leadInList.LastName){
                    //if the lead from the trigger has the same last name as a lead that
                    //already exists, add it to our set
                    deDupedLeads.add(leadInTrigger);
                }
            }
        }
        //add all duplicate leads from our set to our list and delete them
        leadsToDelete.addAll(deDupedLeads);
        delete leadsToDelete;
    }
}

This handler has been bulkified in two ways, we removed the DML operation out of the loop and the code is able to process a scenario where someone mass inserts 1000s of leads at a time. Plus, rather than querying every lead record in your database, we only query for records that have the same last name as the records created during the insert operation. We advise using something more unique than LastName like Email or Phone as many people/leads can have the same Last Name. Hope this helps and have a blessed one.

coderunner
  • 13
  • 2