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
Dharmesh MaheshwariDharmesh Maheshwari 

I want to update unique contact name under account on the basis of comma separated values. Actually these are the names which I want to update on contact name. If the value is remove from this field then that name of contact should be deleted.

Here is my code. It perfectly run on insert, it also update contact name and it also delete the contact if i remove tha name but it updates by duplicate name. there is field on contact i.e. No_of_Occurences. If I update t
public class CommaSeparatedContact 
{
    String strFirstName;
    String strLastName;
    String strName;
    List<Contact> lstContact;
    Map<String,Contact> mapUniqueContact = new Map<String,Contact>();
    List<Contact> lstContactToDelete = new List<Contact>();
    Map<String,List<Contact>> mapContactComparison = new Map<String,List<Contact>>();
    Set<Id> setAccId= new Set<Id>();   
    
    public void onInsert(List<Account> lstAccountTrigger)
    {   
        List<String> lstString = new List<String>();
        for(Account objAccountCon : lstAccountTrigger)
        {
            lstContact = new List<Contact>();
            if(objAccountCon.Comma_Separated_Values__c != null)
                lstString =  objAccountCon.Comma_Separated_Values__c.split(',');
            for(Integer i=0; i<lstString.size(); i++)
            {
                Contact objContact = new Contact();
                if(lstString[i].contains(' '))
                {
                    strFirstName = lstString[i].substringBefore(' ');
                    strLastName = lstString[i].substringAfter(' ');
                }
                else
                {
                    strFirstName = '';
                    strLastName = lstString[i];
                }
                objContact.No_of_Occurrence__c = 1;
                objContact.LastName = strLastName;
                objContact.FirstName = strFirstName;
                strname = objContact.FirstName+' '+ objContact.LastName;
                objContact.AccountId = objAccountCon.Id;
                
                if(mapUniqueContact.containsKey(strname))
                {
                    Contact objc = mapUniqueContact.get(strname);
                    objc.No_of_Occurrence__c +=1;  
                }
                else
                {
                    mapUniqueContact.put(strname,objContact);
                }
            }
        }
        
        for(String objCont : mapUniqueContact.keySet())
        {
            lstContact.add(mapUniqueContact.get(objCont));
        }
        if(lstContact.size()>0)
        {
            insert lstContact;
        }
    }
    
    public void onUpdate(List<Account> lstAccountTrigger, Map<Id,Account> mapOldAccount)
    {  
        List<Contact> lstContactToUpdate = new List<Contact>();
        for(Account objConAcc : lstAccountTrigger)
        {
            if(objConAcc.Comma_Separated_Values__c != mapOldAccount.get(objConAcc.id).Comma_Separated_Values__c)
            {
                setAccId.add(objConAcc.id);
            }
        }
        
        for(Contact objCon : [Select Id, Name, AccountId, FirstName, LastName, Phone, Email, Description From Contact Where AccountId in : setAccId])
        {
            if(mapContactComparison!=null && mapContactComparison.containsKey(objCon.AccountId))
            {
                List<Contact> conList = mapContactComparison.get(objCon.AccountId);
                conList.add(objCon);
                mapContactComparison.put(objCon.AccountId, conList);
            }
            else
                mapContactComparison.put(objCon.AccountId, new List<Contact>{objCon});
        System.debug('>>>>>>>>81'+mapContactComparison.get(objCon.AccountId));
        }
        System.debug('>>>>>>>>83'+mapContactComparison.keySet());
        List<String> lstString = new List<String>();
        
        for(Account objAccountCon : lstAccountTrigger)
        {  
            Integer i =0;
            lstContact = new List<Contact>();
            if(objAccountCon.Comma_Separated_Values__c != null)
                lstString =  objAccountCon.Comma_Separated_Values__c.split(',');
            if(mapContactComparison != null && mapContactComparison.containsKey(objAccountCon.Id))
            {
                for(Contact objCon : mapContactComparison.get(objAccountCon.id))
                { 
                    if(lstString.size() == 0)
                    {
                       if(mapContactComparison.containsKey(objCon.AccountId))
                            mapUniqueContact.put(objCon.Name,objCon); 
                    }
                    if(lstString.size()>i)
                    {
                        System.debug('>>>103'+lstString[i]);
                        System.debug('Name Contains : '+lstString[i].contains(' ')); 
                        if(lstString[i].contains(' '))
                        {
                            strFirstName = lstString[i].substringBefore(' ');
                            strLastName = lstString[i].substringAfter(' ');
                        }
                        else
                        {
                            strFirstName = '';
                            strLastName = lstString[i];
                        }
                        
                        objCon.LastName = strLastName;
                        objCon.FirstName = strFirstName;
                        strName = objCon.FirstName+' '+ objCon.LastName;
                        lstContact.add(objCon);
                        System.debug('>>>>>>>119'+lstContact);
                        System.debug('>>>>>>>120'+mapContactComparison.get(objCon.AccountId));
                        if(mapContactComparison.containsKey(objCon.AccountId))
                            mapUniqueContact.put(strname,objCon);
                        System.debug('>>>>>>>>122'+mapUniqueContact.get(strname));
                        System.debug('>>>>>>>>123'+mapUniqueContact.keySet());
                    }
                    i+=1;
                }
            }
        }
        System.debug('>>>>>>>>1325'+lstContact);
        for(String objCont : mapUniqueContact.keySet())
        {
            System.debug('>>>>>>>>>>>>>131'+objCont);
            System.debug('>>>>>>>>>132'+lstContact.contains(mapUniqueContact.get(objCont)));
            if(!lstContact.contains(mapUniqueContact.get(objCont)))
                lstContact.add(mapUniqueContact.get(objCont));
        }
        System.debug('List of Contact Under An Account'+lstContact);
        if(lstContact.size()>0)
        {
            update lstContact;
        }
        for(Contact objConToDelete : lstContact)
        {
            System.debug('>>>>>>>>>143'+objConToDelete.Name);
            if(!lstString.contains(objConToDelete.Name))
            {  
                if(!lstContactToDelete.contains(objConToDelete))
                { 
                    System.debug('>>>>>>>>>>>>>148'+objConToDelete.Name);
                    lstContactToDelete.add(objConToDelete);
                }    
            }
        }
        if(lstContactToDelete.size()==0 && lstContact.size()==0)
        {
            System.debug('>>>>>>>>>>55');
            for(Contact str : mapUniqueContact.values())
            {
                System.debug('>>>>>>>>>>158');
                lstContactToDelete.add(str);
            }
        }
        if(lstContactToDelete.size()>0)
        {
            System.debug('delete List'+lstContactToDelete);
            delete lstContactToDelete;
        }
    }
}

he account  comma separated field with same values then the total number of time the values are come is update on Contact field i.e. Number of Occurences. Please Help

On update please Insert following values on account comma separated field: Amit,Dharmesh,Amit,Ankit,Amit. and test.

So the no of occurrence contains on Amit Contact is 3 and if I update the value with Amit,Dharmesh,Amit,Amit,Amit then the Ankit name of contact will be deleted and under Amit account there is no of occurences field value updated by 3 to 4 and only 2 accounts will remains i.e. Amit and Dharmesh.
Leon ThanikalLeon Thanikal
Hello Dharmesh,

I don't understand if you are using a trigger or not, but I believe that this is best done using a trigger. You would use the following trigger events in order to do the logic that you want: after insert, after update, after delete, and after undelete. (It is always preferred to use an after trigger when updating another related object.) So the code for the trigger is as follows:
 
trigger ContactTrigger on Contact (before insert, after insert, before update, after update, after delete, after undelete) {
    if(Trigger.isBefore){
        if(Trigger.isInsert){

        }
        if(Trigger.isUpdate){

        }
    }
    if(Trigger.isAfter){
        if(Trigger.isInsert){
            ContactTriggerHandler.concatenateContacts(Trigger.New, null, false);
        }
        if(Trigger.isUpdate){
            ContactTriggerHandler.concatenateContacts(Trigger.New, null, false);
        }
        if(Trigger.isDelete){
            ContactTriggerHandler.concatenateContacts(null, Trigger.Old, true);
        }
        if(Trigger.isUndelete){
            ContactTriggerHandler.concatenateContacts(Trigger.New, null, false);
        }
    }
}

Then for the trigger handler class:
public class ContactTriggerHandler {
    public static void concatenateContacts(List<Contact> lstNew, List<Contact> lstOld, Boolean isDel){
        Set<ID> accountIds = new Set<ID>();
        List<Account> accounts = new List<Account>();

        if(!isDel){
            for(Contact c : lstNew){
                accountIds.add(c.AccountId);
            }
        }else if (isDel) {
            for(Contact c: lstOld){
                accountIds.add(c.AccountId);
            }
        }

        if(accountIds.isEmpty()) return;

        accounts = [Select Id, Name, (Select Id, Name from Contacts) from Account where id = :accountIds];

        for(Account a : accounts){
            if(a.Contacts.size() > 0){
                Set<String> contactName = new Set<String>();

                for(Contact ct : a.Contacts){
                    if(ct.Name != null) contactName.add(ct.Name);
                }

                if(!contactName.isEmpty()){
                    a.Contact_List__c = String.join(new List<String>(contactName), ' , ');
                }else {
                    a.Contact_List__c = null;
                }
            }else {
                a.Contact_List__c = null;
            }
        }

        if(accounts.size() > 0) update accounts;
    }
}

Before testing the code, make sure to change the relevant field names. For me to test it, I created a custom text(long) field in the Accounts called Contact_List__c. The code works for the aforementioned operations. Just a forewarning for the undelete, it will take some time for the changes to appear but it will appear after the page is refreshed a few times.

Hope this helps! ​​​​​​​
Leon ThanikalLeon Thanikal
Also on another note, a set automatically has only unique values hence why it is used in the code. However if you want to make sure that no duplicate contacts are being added then you can use the following trigger and trigger handler.

Trigger:
trigger ContactTrigger on Contact (before insert, after insert, before update, after update, after delete, after undelete) {
//*This is for filtering out which type of trigger and which event
    if(Trigger.isBefore){
        if(Trigger.isInsert){
            //todo Add code here whenever before insert
            ContactTriggerHandler.checkDuplicateContacts(Trigger.New, null, false);
        }
        if(Trigger.isUpdate){
            //todo Add code here whevener before update
            ContactTriggerHandler.checkDuplicateContacts(Trigger.New, null, false);
        }
    }
    
    if(Trigger.isAfter){
        if(Trigger.isInsert){
            ContactTriggerHandler.concatenateContacts(Trigger.New, null, false);
        }
        if(Trigger.isUpdate){
            ContactTriggerHandler.concatenateContacts(Trigger.New, null, false);
        }
        if(Trigger.isDelete){
            ContactTriggerHandler.concatenateContacts(null, Trigger.Old, true);
        }
        if(Trigger.isUndelete){
            ContactTriggerHandler.concatenateContacts(Trigger.New, null, false);
        }
    }
}
Note this includes the events from the previous trigger.

The method to add to the ContactTriggerHandler class:
//#This is for checking for duplicate contact names
    public static void checkDuplicateContacts(List<Contact> lstNew, List<Contact> lstOld, Boolean isDel){
        List<Contact> ct = lstNew;
        List<Contact> allCt = [Select Id, Name, AccountID from Contact];

        for(Contact c : allCt){
            for(Contact con : ct){
                if (c.Name.toUppercase() == (con.FirstName.toUppercase() + ' ' + con.LastName.toUppercase())) {
                    if(c.AccountId == con.AccountId){
                    	con.addError('This contact already exists!');                        
                    }
                }                
            }
        }
    }

Just an added function that you can  do with the trigger if you like. Food for thought!
Dharmesh MaheshwariDharmesh Maheshwari
I think you misunderstand the requirement. I want to update the contact on update of account. So the trigger is write upon account.
Leon ThanikalLeon Thanikal
Couple of questions then. So then this field in account will have a series of contacts that can: 
1. When a new unique name is added the a new contact is added.
2. If a duplicate name is added to the list, then another field on the contact will be updated to count the number of recurrances.
3. If a name is deleted or updated from the field, the field on the contact has to reflect this change or the contact has to be deleted.
4. If a new unique name is added to this field, then a resulting contact has to also be created.
Is this correct?

Second question is, what is the business logic behind this idea?
Dharmesh MaheshwariDharmesh Maheshwari
Absolutely, you are correct now. In 3rd point yes, if the value is deleted then contact is delete if the value is update then contact name will update (if unique otherwise delete) and changes reflect to contact field on reoccurence in delete case or create case. Like if the value is repeat 2 times then on contact field it is 2 and if value is not repeat then it is 1 time on occurence contact field. All these things are done on the account basis, like particular under that account in bulkify manner. Business logic is that Overcome to insert, update and delete multiple contact manually.