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
Hm_inviHm_invi 

trigger to check and uncheck parent checkbox field values based on child picklist values


Hi,
Iam new to apex. this is one of the trigger scenario bothering me.
Please help me with this.

I have a status checkbox field on accounts.
status picklist field with "open","closed" on contacts.
1) if status="closed" in all the related contacts then checkbox on account should be true.
2) if status="open" in any one of the related contacts then checkbox on account should be false.  
-------------------------------------------------------------------------------------------
Trigger:
trigger contactTrigg on contact(after insert, after update, after delete, after undelete){
    if(trigger.isInsert || trigger.isUpdate){
        accProgress.method1(trigger.new,trigger.old);
    }
}

-------
Handler:
public class accProgress{
    public static void method1(list<contact> newInsert, list<contact> oldInsert){
        
        set<id> conSet = new set<id>();
        
        for(contact con1 : newInsert){
            if(con1.Accountid != null){
                conSet.add(con1.accountid);
            }
        }
 for(contact con2 : oldInsert){
                conSet.add(con2.accountid);
        }

        List<account> accList =[SELECT id, progress_field__c,(SELECT id, progress_field_contacts__c FROM contacts) FROM account WHERE id IN :conSet];
        if(accList != null){
            for(account acc : accList){
                for(contact con : acc.contacts){
                    
                    if(con.progress_field_contacts__c == 'open' ){
                        acc.progress_field__c = false;
                    }
                    else{
                        acc.progress_field__c = true;
                    }
                }
            }
            update accList;
        }
    }
---------------------------------------------------------------------------------------------
1st one is working. i.e, whenever i make all related contacts "close" . the check box is getting checked(true).
2nd one is where iam failing. when i'm changing any contacts picklist values to open the account status checkbox is not unchecking(false).
please help me.
Best Answer chosen by Hm_invi
Abdul KhatriAbdul Khatri
Updated Code. You actually don't need to check anything in the trigger since you already place the trigger context you wanted to run this code for so simplify it like this unless in future something changes

Trigger change
trigger contactTrigg on contact(after insert, after update, after delete, after undelete) 
{ 
     accProgress.method1(trigger.new,trigger.old);  
}

Handlet Change:
  • Added newInsert == null, to handle the Delete 
public class accProgress{
    public static void method1(list<contact> newInsert, list<contact> oldInsert){     
        set<Id> idAcctSet = new set<Id>();
        
        for(Contact con1 : newInsert)
        {
            if(con1.AccountId == null) continue;
            
            if(oldInsert == null || newInsert == null || (oldInsert != null && oldInsert.get(con1.Id).Status != con1.Status)){
                idAcctSet.add(con1.AccountId);
            }
        }
        
        if(idAcctSet.isEmpty()) return;
 		
        List<Account> accList =[SELECT id, progress_field__c,
                                	(SELECT Id, progress_field_contacts__c FROM Contacts WHERE Status = 'open') 
                                	FROM Account WHERE id IN :idAcctSet];

        for(Account acc : accList)
        {
            if(acc.Contacts != null){
                acc.progress_field__c = false;
            } else {
                acc.progress_field__c = true;
            }
        }
        update accList;
    }
}

 

All Answers

Learn Salesforce 36Learn Salesforce 36
Try adding  break; after below line :

  acc.progress_field__c = false;

Like below : 
  acc.progress_field__c = false;
  break;
Abdul KhatriAbdul Khatri
Hi Krishna,

I little tweaked the code

This is the same
trigger contactTrigg on contact(after insert, after update, after delete, after undelete)
{
    if(trigger.isInsert || trigger.isUpdate){
        accProgress.method1(trigger.new,trigger.old);
    }
}
Made changes here
  • Change the variable name from conSet to idAcctSet as it contains AccountId's.
  • Trigger.old will not be available at after insert, so took care of it by checking oldInsert == null
  • Trigger.old available after update so making sure this only triggers if there is a status change you can further refine it by looking at the specific status but this will prevent re-occurance of the trigger
  • Took care of idAcctSet null, to prevent Null Pointer Exception
  • Added the filter in the Contact and use that in the further code. This simplifies the code
public class accProgress{
    public static void method1(list<contact> newInsert, list<contact> oldInsert){     
        set<Id> idAcctSet = new set<Id>();
        
        for(Contact con1 : newInsert)
        {
            if(con1.AccountId == null) continue;
            
            if(oldInsert == null || (oldInsert != null && oldInsert.get(con1.Id).Status != con1.Status)){
                idAcctSet.add(con1.AccountId);
            }
        }
        
        if(idAcctSet.isEmpty()) return;
 		
        List<Account> accList =[SELECT id, progress_field__c,
                                	(SELECT Id, progress_field_contacts__c FROM Contacts WHERE Status = 'open') 
                                	FROM Account WHERE id IN :idAcctSet];

        for(Account acc : accList)
        {
            if(acc.Contacts != null){
                acc.progress_field__c = false;
            } else {
                acc.progress_field__c = true;
            }
        }
        update accList;
    }
}

Let me know it helped
 
Hm_inviHm_invi
Try adding  break; after below line :

  acc.progress_field__c = false;

Like below : 
acc.progress_field__c = false;   
break;
the above correction works fine but it does not in the below case:
i have three related contacts.
for one of the contact picklist field,  progress_field_contacts__c = 'open' and this contact is deleted.
for the remaining 2 contacts, progress_field_contacts__c = 'close'.

now the account checkbox field, progress_box__c = 'false'. 
but it should be checked as 'true'.
how can i include this after delete event into the same class.
Learn Salesforce 36Learn Salesforce 36
Hi Krishna, 

You can add below condition in the if statement of your trigger like below for delete event: 

if(trigger.isInsert || trigger.isUpdate || trigger.isDelete){
Abdul KhatriAbdul Khatri
Updated Code. You actually don't need to check anything in the trigger since you already place the trigger context you wanted to run this code for so simplify it like this unless in future something changes

Trigger change
trigger contactTrigg on contact(after insert, after update, after delete, after undelete) 
{ 
     accProgress.method1(trigger.new,trigger.old);  
}

Handlet Change:
  • Added newInsert == null, to handle the Delete 
public class accProgress{
    public static void method1(list<contact> newInsert, list<contact> oldInsert){     
        set<Id> idAcctSet = new set<Id>();
        
        for(Contact con1 : newInsert)
        {
            if(con1.AccountId == null) continue;
            
            if(oldInsert == null || newInsert == null || (oldInsert != null && oldInsert.get(con1.Id).Status != con1.Status)){
                idAcctSet.add(con1.AccountId);
            }
        }
        
        if(idAcctSet.isEmpty()) return;
 		
        List<Account> accList =[SELECT id, progress_field__c,
                                	(SELECT Id, progress_field_contacts__c FROM Contacts WHERE Status = 'open') 
                                	FROM Account WHERE id IN :idAcctSet];

        for(Account acc : accList)
        {
            if(acc.Contacts != null){
                acc.progress_field__c = false;
            } else {
                acc.progress_field__c = true;
            }
        }
        update accList;
    }
}

 
This was selected as the best answer
Abdul KhatriAbdul Khatri
Hey Krishna,
Any Update?