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
ankur khattriankur khattri 

send emai funtionalityl not working

public with sharing class ChildCloneHandler implements ITrigger
{       
    Map<Id,Account> accountMap = new Map<Id,Account>();
    Map<Id,list<Contact>> lstMap = new Map<Id,list<Contact>>();
    list<Account> lstAccount = new list<Account>();
    set<Id> acctIds = new set<Id>();
    Set<Id> tobeReverted = new Set<Id>();
    public string errString;
    //list<id> lstAccountId = new  list<id>();
    //list<Account> accToInsert = new list<Account>();
    //list<Contact> conToInsert = new list<Contact>();
    //list<Contact> cont = new list<Contact>();
    
    public ChildCloneHandler()
    {
         
    }
    public void beforeUpdate(SObject oldSo, SObject so)  
    {
        
    }
    public void bulkBefore()
    {
        
    }
    public void bulkAfter()
    {
        //checkin if it is update
        if(Trigger.new != null)
        {
        if(Trigger.IsUpdate)
        {
            system.debug('----chhh-----');
            Set<id> setid = new Set<id>();
            //iterating over Account
            for(SObject Item:Trigger.new)
            {
                Account acc = (Account) Item;
                if(Trigger.oldMap.containsKey(acc.Id))
                {
                    Account oldAcc = (Account) Trigger.oldMap.get(acc.Id);
                    //if field is updated or not if yes then we will collect the id for further process
                    if(oldAcc.ChildClone__c == false && acc.ChildClone__c == true)
                    {
                        setid.add(acc.id);
                    }
                }
            }
            //retriving field that is updated ChildClone__c
            lstAccount = [select id,Name, Description,Type, Phone, Fax,
            AccountNumber,BillingAddress,Industry,(select LastName,
            Title,Department,Birthdate,MailingAddress,Languages__c,Level__c
            from Contacts) from Account where id IN: setid];
            
            for(Account a : lstAccount)
            {
                if(a.Contacts != null && a.Contacts.size()>0)
                {
                    //storing value in map for id and contact
                    lstMap.put(a.id, a.Contacts);
                }
            }
        }
        }
    }
    public void beforeInsert(SObject so)
    {
        
    }   
    public void beforeDelete(SObject so)
    {
        
    }
    public void afterInsert(SObject so)
    {
    
    }
    public void afterUpdate(SObject oldSo, SObject so)
    {
         Account OrderRecOld = (Account) oldSo;
         Account OrderRecNew = (Account) so;
         //checking if ChildClone__c was false and is true after update
         if(OrderRecOld.ChildClone__c == false && OrderRecNew.ChildClone__c == true)
         {
            //clonning account and contacts
            Account clonedAcc = OrderRecNew.clone(false);
            clonedAcc.ChildClone__c = false;
            //accToInsert.add(clonedAcc);
            //link old account and new account to compare their child(contacts)
            accountMap.put(OrderRecNew.id, clonedAcc);  
            
         }
    }
    public void afterDelete(SObject so)
    {
        
    }
    public void andFinally()
    {
        //insert accToInsert;
        //cloned account to be inserted
        if(accountMap.values().size()>0 )
        {   
            //result of an insert or update DML operation is returned by a Database method.
            Database.SaveResult[] srList1 = Database.insert(accountMap.values(), false);
            Integer i = 0;
            for(Id id : accountMap.KeySet())
            {
                // Returns a Boolean that is set to true if the DML operation was successful for this object, false otherwise.
                if (srList1[i].isSuccess() == false)
                {
                    // Operation was successful, so get the ID of the record that was processed
                    //System.debug('Successfully inserted account. Account ID: ' + id.getId());
                    errString += 'Error with record '+id+': '+srList1[i].getErrors()[0].getMessage()+'</br>';
                    //To remove elements while iterating a list, create a new list, then copy the elements you wish to keep. Alternatively, add the elements you wish to remove to a temporary list and remove them after you finish iterating the collection.
                    accountMap.remove(id);
                    //To add elements while iterating a list, set or map, keep the new elements in a temporary list, set, or map and add them to the original after you finish iterating the collection.
                    tobeReverted.add(id);
                }
                //loop for the contacts
                 i++;
            }
            //list for the contacts to be inserted
            list<Contact> conListToBeInserted = new list<Contact>();
            // (keyset)Returns a set that contains all of the keys in the map.
            //When executing loop,the Apex runtime engine assigns variable to each element in list_or_set, and runs the code_block for each value.
            for(id i1 : accountMap.keySet())
            {
                //clonedAcc
                Account clonedAcc = accountMap.get(i1);
                system.debug('----aba-----'+clonedAcc.id);
                // retrieve items.....storing value in map for id and contact    
                list<Contact> toBeClonedCon = lstMap.get(i1);
                for(Contact c : toBeClonedCon)
                {
                    Contact conToClone = new Contact();
                    // false to deep clone
                    conToClone = c.clone(false);
                    conToClone.AccountId = clonedAcc.id;
                    conListToBeInserted.add(conToClone);
                }
            }
            system.debug('----aba1-----'+conListToBeInserted);
            if(conListToBeInserted != null && conListToBeInserted.size()>0)
            {
                
                //insert contacts;
                //insert conListToBeInserted;
                Database.SaveResult[] srList = Database.insert(conListToBeInserted, false);
                // Iterate through each returned result
                for (Database.SaveResult sr : srList)
                {
                    if (sr.isSuccess())
                    {
                        // Operation was successful, so get the ID of the record that was processed
                        System.debug('Successfully inserted account. Account ID: ' + sr.getId());
                    }
                    else
                    {
                        // Operation failed, so get all errors                
                        for(Database.Error err : sr.getErrors())
                        {
                            System.debug('The following error has occurred.');                    
                            System.debug(err.getStatusCode() + ': ' + err.getMessage());
                            System.debug('Account fields that affected this error: ' + err.getFields());
                        }
                    }
                }
            }
            
            if(errString != '')
            {
                system.debug('----asasasa---'+accountMap);
                //reverting  Orginal Accounts updates when exception occurs while cloning them
                HelperClass.updateAccount(tobeReverted);
                //deleting Cloned Accounts when their Product has exception while creation
                If(accountMap != null && accountMap.values().size() > 0)
                delete accountMap.values();
                Messaging.SingleEmailMessage mail = new Messaging.SingleEmailMessage();
                String[] toAddresses = new String[] {'ankur.khattri@cynoteck.com'};
                mail.setToAddresses(toAddresses);
                //mail.setBccSender(false);
                mail.setSubject('subject');
                mail.setHtmlBody(errString);
                Messaging.SendEmailResult [] r = Messaging.sendEmail(new Messaging.SingleEmailMessage[] {mail});
            }
        }
    }
}
Mahesh DMahesh D
Hi Ankur,

Please provide us the exact error so that it will be easy to help you.

Regards,
Mahesh
ankur khattriankur khattri
Error:Apex trigger ChildClone caused an unexpected exception, contact your administrator: ChildClone: execution of AfterUpdate caused by: System.EmailException: SendEmail failed. First exception on row 0; first error: REQUIRED_FIELD_MISSING, Either the plain text body or html body must be supplied.: []: Class.ChildCloneHandler.andFinally: line 185, column 1
 
Mahesh DMahesh D
Hi Ankur,

Please take the below code. 

My changes are having a comment like below:

//MD -- Modified
 
public with sharing class ChildCloneHandler implements ITrigger
{       
    Map<Id,Account> accountMap = new Map<Id,Account>();
    Map<Id,list<Contact>> lstMap = new Map<Id,list<Contact>>();
    list<Account> lstAccount = new list<Account>();
    set<Id> acctIds = new set<Id>();
    Set<Id> tobeReverted = new Set<Id>();
    public string errString = ''; //MD -- Modified
    //list<id> lstAccountId = new  list<id>();
    //list<Account> accToInsert = new list<Account>();
    //list<Contact> conToInsert = new list<Contact>();
    //list<Contact> cont = new list<Contact>();
    
    public ChildCloneHandler()
    {
         
    }
    public void beforeUpdate(SObject oldSo, SObject so)  
    {
        
    }
    public void bulkBefore()
    {
        
    }
    public void bulkAfter()
    {
        //checkin if it is update
        if(Trigger.new != null)
        {
        if(Trigger.IsUpdate)
        {
            system.debug('----chhh-----');
            Set<id> setid = new Set<id>();
            //iterating over Account
            for(SObject Item:Trigger.new)
            {
                Account acc = (Account) Item;
                if(Trigger.oldMap.containsKey(acc.Id))
                {
                    Account oldAcc = (Account) Trigger.oldMap.get(acc.Id);
                    //if field is updated or not if yes then we will collect the id for further process
                    if(oldAcc.ChildClone__c == false && acc.ChildClone__c == true)
                    {
                        setid.add(acc.id);
                    }
                }
            }
            //retriving field that is updated ChildClone__c
            lstAccount = [select id,Name, Description,Type, Phone, Fax,
            AccountNumber,BillingAddress,Industry,(select LastName,
            Title,Department,Birthdate,MailingAddress,Languages__c,Level__c
            from Contacts) from Account where id IN: setid];
            
            for(Account a : lstAccount)
            {
                if(a.Contacts != null && a.Contacts.size()>0)
                {
                    //storing value in map for id and contact
                    lstMap.put(a.id, a.Contacts);
                }
            }
        }
        }
    }
    public void beforeInsert(SObject so)
    {
        
    }   
    public void beforeDelete(SObject so)
    {
        
    }
    public void afterInsert(SObject so)
    {
    
    }
    public void afterUpdate(SObject oldSo, SObject so)
    {
         Account OrderRecOld = (Account) oldSo;
         Account OrderRecNew = (Account) so;
         //checking if ChildClone__c was false and is true after update
         if(OrderRecOld.ChildClone__c == false && OrderRecNew.ChildClone__c == true)
         {
            //clonning account and contacts
            Account clonedAcc = OrderRecNew.clone(false);
            clonedAcc.ChildClone__c = false;
            //accToInsert.add(clonedAcc);
            //link old account and new account to compare their child(contacts)
            accountMap.put(OrderRecNew.id, clonedAcc);  
            
         }
    }
    public void afterDelete(SObject so)
    {
        
    }
    public void andFinally()
    {
        //insert accToInsert;
        //cloned account to be inserted
        if(accountMap.values().size()>0 )
        {   
            //result of an insert or update DML operation is returned by a Database method.
            Database.SaveResult[] srList1 = Database.insert(accountMap.values(), false);
            Integer i = 0;
            for(Id id : accountMap.KeySet())
            {
                // Returns a Boolean that is set to true if the DML operation was successful for this object, false otherwise.
                if (srList1[i].isSuccess() == false)
                {
                    // Operation was successful, so get the ID of the record that was processed
                    //System.debug('Successfully inserted account. Account ID: ' + id.getId());
                    errString += 'Error with record '+id+': '+srList1[i].getErrors()[0].getMessage()+'</br>';
                    //To remove elements while iterating a list, create a new list, then copy the elements you wish to keep. Alternatively, add the elements you wish to remove to a temporary list and remove them after you finish iterating the collection.
                    accountMap.remove(id);
                    //To add elements while iterating a list, set or map, keep the new elements in a temporary list, set, or map and add them to the original after you finish iterating the collection.
                    tobeReverted.add(id);
                }
                //loop for the contacts
                 i++;
            }
            //list for the contacts to be inserted
            list<Contact> conListToBeInserted = new list<Contact>();
            // (keyset)Returns a set that contains all of the keys in the map.
            //When executing loop,the Apex runtime engine assigns variable to each element in list_or_set, and runs the code_block for each value.
            for(id i1 : accountMap.keySet())
            {
                //clonedAcc
                Account clonedAcc = accountMap.get(i1);
                system.debug('----aba-----'+clonedAcc.id);
                // retrieve items.....storing value in map for id and contact    
                list<Contact> toBeClonedCon = lstMap.get(i1);
                for(Contact c : toBeClonedCon)
                {
                    Contact conToClone = new Contact();
                    // false to deep clone
                    conToClone = c.clone(false);
                    conToClone.AccountId = clonedAcc.id;
                    conListToBeInserted.add(conToClone);
                }
            }
            system.debug('----aba1-----'+conListToBeInserted);
            if(conListToBeInserted != null && conListToBeInserted.size()>0)
            {
                
                //insert contacts;
                //insert conListToBeInserted;
                Database.SaveResult[] srList = Database.insert(conListToBeInserted, false);
                // Iterate through each returned result
                for (Database.SaveResult sr : srList)
                {
                    if (sr.isSuccess())
                    {
                        // Operation was successful, so get the ID of the record that was processed
                        System.debug('Successfully inserted account. Account ID: ' + sr.getId());
                    }
                    else
                    {
                        // Operation failed, so get all errors                
                        for(Database.Error err : sr.getErrors())
                        {
                            System.debug('The following error has occurred.');                    
                            System.debug(err.getStatusCode() + ': ' + err.getMessage());
                            System.debug('Account fields that affected this error: ' + err.getFields());
                        }
                    }
                }
            }
            
            if(errString != '' )
            {
                system.debug('----asasasa---'+accountMap);
                //reverting  Orginal Accounts updates when exception occurs while cloning them
                HelperClass.updateAccount(tobeReverted);
                //deleting Cloned Accounts when their Product has exception while creation
                If(accountMap != null && accountMap.values().size() > 0)
                delete accountMap.values();
                Messaging.SingleEmailMessage mail = new Messaging.SingleEmailMessage();
                String[] toAddresses = new String[] {'ankur.khattri@cynoteck.com'};
                mail.setToAddresses(toAddresses);
                //mail.setBccSender(false);
                mail.setSubject('subject');
                mail.setHtmlBody(errString);
				mail.setPlainTextBody(errString); //MD -- Modified
                Messaging.SendEmailResult [] r = Messaging.sendEmail(new Messaging.SingleEmailMessage[] {mail});
            }
        }
    }
}

Please do let me know if it helps you.

Regards,
Mahesh