function readOnly(count){ }
Starting November 20, the site will be set to read-only. On December 4, 2023,
forum discussions will move to the Trailblazer Community.
+ Start a Discussion
kirankumarreddy punurukirankumarreddy punuru 

trigger to check for duplicate last name in leads and if found duplicates performs checkbox as checked

Hi ,
 I need to write a trigger which checks all the leads and if any lead had duplicate lastname then in that i have to mark checkbox via trigger,for that i have written a trigger but it is not working can anyone help me..
my trigger is:
trigger LeadDuplicatePreventer on Lead (before insert ,after update) 
{
List<Lead> lead1 = new List<Lead>();
List<Lead> lead2 = new List<Lead>();
for (Lead L1 :trigger.new)
{
  for(Lead L2:trigger.new)
  {
   if(L1.LastName == L2.LastName)
   
    L1.Duplicate_Lastname1__c = true;
    exit();
   }
   
 } 
}
 
but is showing an error method does not exist exit();
Neetu_BansalNeetu_Bansal
Hi Kiran,

Is exit() any custom method in trigger, because there is not such native method in Apex. Although I have updated the trigger code. You can use this code:
trigger LeadDuplicatePreventer on Lead( before insert, before update ) 
{
	Set<String> lastNames = new Set<String>();
	for( Lead l : trigger.new )
	{
		if( trigger.isInsert
			|| ( trigger.isUpdate && trigger.oldMap.get( l.Id ).LastName != l.LastName ))
		{
			lastNames.add( l.LastName );
		}
	}
	
	Set<String> alreadyInsertedLastNames = new Set<String>();
    for( Lead l : [ Select Id, LastName from Lead where LastName IN: lastNames ])
    {
        alreadyInsertedLastNames.add( l.LastName );
    }
    
    for( Lead l : trigger.new )
	{
		if( trigger.isInsert
			|| ( trigger.isUpdate && trigger.oldMap.get( l.Id ).LastName != l.LastName ))
		{
            if( alreadyInsertedLastNames.contains( l.LastName ))
            {
                l.Duplicate_Lastname1__c = true;
            }
            else
            {
                alreadyInsertedLastNames.add( l.LastName );
            }
        }
    }
}
Let me know, if you need any other help.

Thanks,
Neetu
William TranWilliam Tran
To exit a loop in Salesforce use the break command so:

replace 
          exit();
with
          break;
Thx
 
Łukasz BieniawskiŁukasz Bieniawski
trigger LeadDuplicatePreventer on Lead (before insert, before update) {
    stampDuplicates(Trigger.new);
}

// Stamp duplicated records -> checking all db records LastNames, Case Insensitive
private void stampDuplicates(List<Lead> leadScope){        
    Map<String, List<Lead>> namesToLeadMap = new Map<String, List<Lead>>();
    for (Lead L1 : leadScope) {
        if (String.isBlank(L1.LastName)){
            continue;
        }
        String leadLastName = L1.LastName.toUpperCase();
        if (!namesToLeadMap.containsKey(leadLastName)){            
            namesToLeadMap.put(leadLastName, new List<Lead>());
        } 
        namesToLeadMap.get(leadLastName).add(L1);
    }
    if (namesToLeadMap.size() == 0){
        return;
    }

    // 2. Collecting Lead LastNames set from existing database records
    Set<String> dbLastNames = new Set<String>();
    // Not optimal, if we have a lot of records we can achieve a query 50k records limit, we should add some more conditions here to the query
    for (Lead dbLead : [Select LastName from Lead Where LastName In :namesToLeadMap.keyset()]){
        dbLastNames.add(dbLead.LastName.toUpperCase());
    }
    if (dbLastNames.size() == 0){
        return;
    }

    // 3. Stamping scoped (inserted or updated) Lead records
    for (String leadNameFromScope : namesToLeadMap.keySet()){
        if (dbLastNames.contains(leadNameFromScope)){
            for (Lead scopedLead : namesToLeadMap.get(leadNameFromScope)){
                scopedLead.Duplicate_Lastname1__c = true;
            }
        }
    }
}
Code very similar to Neetu's example, including case-insensitive comparision.

Greetings,
Lukasz
kirankumarreddy punurukirankumarreddy punuru
Hi Lukasz,
              If need to update the checkbox automatically for duplicate lastnames then the above trigger works?? 
thanks
kiran
kirankumarreddy punurukirankumarreddy punuru
Hi,
    Let suppose i am having two leads records with name kiran punuru and kirankumar punuru where punuru as lastname then when i go that record and if i update any value it is not making the check box as checked why ? any reason for that..

 Like this above example as mentioned there are many leads with duplicate lastnames ,instead of going to each and every record does it make the checkbox as true for existing records? 

Thanks  Neetu,Lukasz 
 
Neetu_BansalNeetu_Bansal
Hi Kiran,

Try my code and it will work for all the use cases. Let me know if there is any issue or you need any other help.

Thanks,
Neetu
kirankumarreddy punurukirankumarreddy punuru
Hi Neetu,
 Your Code is working when iam  creating a new lead with duplicate last name when iam updating the record it is no changing the checkbox.

Thanks
kiran
Neetu_BansalNeetu_Bansal
Hi Kiran,

As now, my code will run only if you have changed the LastName in case of update, but if this not your requirement. Use the below one:
trigger LeadDuplicatePreventer on Lead( before insert, before update ) 
{
	Set<String> lastNames = new Set<String>();
	for( Lead l : trigger.new )
	{
		lastNames.add( l.LastName );
	}
	
	Set<String> alreadyInsertedLastNames = new Set<String>();
    for( Lead l : [ Select Id, LastName from Lead where LastName IN: lastNames ])
    {
        alreadyInsertedLastNames.add( l.LastName );
    }
    
    for( Lead l : trigger.new )
	{
		if( alreadyInsertedLastNames.contains( l.LastName ))
		{
			l.Duplicate_Lastname1__c = true;
		}
		else
		{
			l.Duplicate_Lastname1__c = false;
			alreadyInsertedLastNames.add( l.LastName );
		}
    }
}
This will also helps you to uncheck the Duplicate checkbox, once you have updated the lastname with something which is not duplicate.

Thanks,
Neetu
kirankumarreddy punurukirankumarreddy punuru
can we update the checkbox from trigger after checking all the lead ids??
Neetu_BansalNeetu_Bansal
This is what we are doing right now. Have you even look at the code once?

If still you have any issue, you can contact me on my skype  id: neetu.bansal.5

Thanks,
Neetu
Łukasz BieniawskiŁukasz Bieniawski
I have done some modification. Please try this:

Trigger LeadDuplicatePreventer:
trigger LeadDuplicatePreventer on Lead (before insert, before update) {
    
    if (!LeadHelper.isInTrigger()){
    
        LeadHelper.setIsInTrigger(true);
        
        if (Trigger.isUpdate && Trigger.isBefore){
            LeadHelper.onBeforeTriggerUpdate(Trigger.new);
        } else if (Trigger.isInsert && Trigger.isBefore){
            LeadHelper.onBeforeTriggerInsert(Trigger.new);        
        }
        
        LeadHelper.setIsInTrigger(false);
    }
}
Helper Class LeadHelper:
public class LeadHelper {

    private static Boolean inTrigger = false;
    
    public static Boolean isInTrigger(){
        return inTrigger;
    }
    
    public static void setIsInTrigger(Boolean isInside){
        inTrigger = isInside;
    }
    
    public static void onBeforeTriggerUpdate(List<Lead> leadScope){
        updateDuplicates(leadScope, false);
    }
    
    public static void onBeforeTriggerInsert(List<Lead> leadScope){
        updateDuplicates(leadScope, true);    
    }
    
    private static void updateDuplicates(List<Lead> leadScope, Boolean isInsert){
        Map<String, List<Lead>> namesToLeadMap = new Map<String, List<Lead>>();
        for (Lead L1 : leadScope) {
            if (String.isBlank(L1.LastName)){
                continue;
            }
            String leadLastName = L1.LastName.toUpperCase();
            if (!namesToLeadMap.containsKey(leadLastName)){            
                namesToLeadMap.put(leadLastName, new List<Lead>());
            } 
            namesToLeadMap.get(leadLastName).add(L1);
        }   
        if (namesToLeadMap.size() == 0){
            return;
        }

        // 2. Collecting Lead LastNames set from existing database records
        Map<String, List<Lead>> dbLastNames = new Map<String, List<Lead>>();
        // Not optimal, if we have a lot of records we can achieve a query 50k records limit, we should add some more conditions here to the query
        for (Lead dbLead : isInsert ? [Select Id, LastName from Lead Where LastName In :namesToLeadMap.keyset()] : [Select Id, LastName from Lead Where LastName In :namesToLeadMap.keyset() AND Id Not In :leadScope]){
            String dbLastName = dbLead.LastName.toUpperCase();
            if (!dbLastNames.containsKey(dbLastName)){
                dbLastNames.put(dbLastName, new List<Lead>());
            }
            dbLastNames.get(dbLastName).add(dbLead);
        }
        if (dbLastNames.size() == 0){
            return;
        }
        
        List<Lead> existingRecordsToUpdate = new List<Lead>();
        // 3. Stamping scoped (inserted or updated) Lead records
        for (String leadNameFromScope : namesToLeadMap.keySet()){
            if (dbLastNames.containsKey(leadNameFromScope) || namesToLeadMap.get(leadNameFromScope).size() > 1){
                for (Lead scopedLead : namesToLeadMap.get(leadNameFromScope)){
                    scopedLead.Duplicate_Lastname1__c = true;
                }
                if (dbLastNames.containsKey(leadNameFromScope)){
                    for (Lead existingLead : dbLastNames.get(leadNameFromScope)){
                        existingLead.Duplicate_Lastname1__c = true;
                        existingRecordsToUpdate.add(existingLead);
                    }
                }
            }
        }
        if (existingRecordsToUpdate.size() > 0){
            update existingRecordsToUpdate;
        }
    }
}
I checked it and it works. New records and existing database records are stamped.

Hope this helps.
Lukasz
 
kirankumarreddy punurukirankumarreddy punuru
Hi Neetu,
 The trigger which u have mentioned above is updating the checkbox for non duplicate records also..

Thanks
kiran