+ Start a Discussion
ChickenOrBeefChickenOrBeef 

How to update ALL sub accounts (sub accounts of sub accounts, etc)?

Hey everyone,

When a certain account field is updated, I need all the sub accounts to be updated to have that same value. And I'm not just talking about the immediate sub accounts, but the subs of those subs, the subs of those subs, and so on.

What is the simpliest way to query/update all those sub accounts?

Thanks!
-Greg
Best Answer chosen by ChickenOrBeef
ChickenOrBeefChickenOrBeef
Hey Ramu,

One of the commenters under that question you posted said that SOQL queries can go five levels deep, so I decided to just go with this, which should be good enough:

public class ClassManagedAccountTrickle {
    
    public void updateChildren(List<Account> accounts){
        
        Set<String> accountsInTrigger = new Set<String>();
        List<Account> accountsToUpdate = new List<Account>();
        List<Account> accountsToBypass = new List<Account>();
        
        FOR(Account a : accounts){
            
            accountsInTrigger.add(a.Id);
            
        }
        
        List<Account> subAccounts = [SELECT
                                    	Id,Social_Goals__c,Offerpop_Products__c,
                                     	Parent.Social_Goals__c,Parent.Offerpop_Products__c,
                                     	Parent.Parent.Social_Goals__c,Parent.Parent.Offerpop_Products__c,
                                     	Parent.Parent.Parent.Social_Goals__c,Parent.Parent.Parent.Offerpop_Products__c,
                                     	Parent.Parent.Parent.Parent.Social_Goals__c,Parent.Parent.Parent.Parent.Offerpop_Products__c,
                                     	Parent.Parent.Parent.Parent.Parent.Social_Goals__c,Parent.Parent.Parent.Parent.Parent.Offerpop_Products__c
                                     FROM
                                    	Account
                                     WHERE
                                    	ParentId In :accountsInTrigger
                                     OR
                                    	Parent.ParentId In :accountsInTrigger
                                     OR
                                    	Parent.Parent.ParentId In :accountsInTrigger
                                     OR
                                    	Parent.Parent.Parent.ParentId In :accountsInTrigger
                                     OR
                                    	Parent.Parent.Parent.Parent.ParentId In :accountsInTrigger];
        
        
        
        FOR(Account sab : subAccounts){
            sab.Managed_Account_Trickle_Bypass__c = TRUE;
            accountsToBypass.add(sab);
        }
        
        UPDATE accountsToBypass;
        
        FOR(Account sa : subAccounts){
            
            IF(accountsInTrigger.contains(sa.ParentId)){
                sa.Social_Goals__c = sa.Parent.Social_Goals__c;
                sa.Offerpop_Products__c = sa.Parent.Offerpop_Products__c;
            }
            ELSE IF(accountsInTrigger.contains(sa.Parent.ParentId)){
                sa.Social_Goals__c = sa.Parent.Parent.Social_Goals__c;
                sa.Offerpop_Products__c = sa.Parent.Parent.Offerpop_Products__c;
            }
            ELSE IF(accountsInTrigger.contains(sa.Parent.Parent.ParentId)){
                sa.Social_Goals__c = sa.Parent.Parent.Parent.Social_Goals__c;
                sa.Offerpop_Products__c = sa.Parent.Parent.Parent.Offerpop_Products__c;
            }
            ELSE IF(accountsInTrigger.contains(sa.Parent.Parent.Parent.ParentId)){
                sa.Social_Goals__c = sa.Parent.Parent.Parent.Parent.Social_Goals__c;
                sa.Offerpop_Products__c = sa.Parent.Parent.Parent.Parent.Offerpop_Products__c;
            }
            ELSE IF(accountsInTrigger.contains(sa.Parent.Parent.Parent.Parent.ParentId)){
                sa.Social_Goals__c = sa.Parent.Parent.Parent.Parent.Parent.Social_Goals__c;
                sa.Offerpop_Products__c = sa.Parent.Parent.Parent.Parent.Parent.Offerpop_Products__c;
            }
            
            accountsToUpdate.add(sa);
            
        }
        
        UPDATE accountsToUpdate;
        
    }

}

Does that look like a good idea? It seems to work.

Thanks!
-Greg

All Answers

Ramu_SFDCRamu_SFDC
This seems way to complex. I came across this post few days back and hope it might be of some help

http://salesforce.stackexchange.com/questions/14324/recursive-functions-apex
ChickenOrBeefChickenOrBeef
Hey Ramu,

One of the commenters under that question you posted said that SOQL queries can go five levels deep, so I decided to just go with this, which should be good enough:

public class ClassManagedAccountTrickle {
    
    public void updateChildren(List<Account> accounts){
        
        Set<String> accountsInTrigger = new Set<String>();
        List<Account> accountsToUpdate = new List<Account>();
        List<Account> accountsToBypass = new List<Account>();
        
        FOR(Account a : accounts){
            
            accountsInTrigger.add(a.Id);
            
        }
        
        List<Account> subAccounts = [SELECT
                                    	Id,Social_Goals__c,Offerpop_Products__c,
                                     	Parent.Social_Goals__c,Parent.Offerpop_Products__c,
                                     	Parent.Parent.Social_Goals__c,Parent.Parent.Offerpop_Products__c,
                                     	Parent.Parent.Parent.Social_Goals__c,Parent.Parent.Parent.Offerpop_Products__c,
                                     	Parent.Parent.Parent.Parent.Social_Goals__c,Parent.Parent.Parent.Parent.Offerpop_Products__c,
                                     	Parent.Parent.Parent.Parent.Parent.Social_Goals__c,Parent.Parent.Parent.Parent.Parent.Offerpop_Products__c
                                     FROM
                                    	Account
                                     WHERE
                                    	ParentId In :accountsInTrigger
                                     OR
                                    	Parent.ParentId In :accountsInTrigger
                                     OR
                                    	Parent.Parent.ParentId In :accountsInTrigger
                                     OR
                                    	Parent.Parent.Parent.ParentId In :accountsInTrigger
                                     OR
                                    	Parent.Parent.Parent.Parent.ParentId In :accountsInTrigger];
        
        
        
        FOR(Account sab : subAccounts){
            sab.Managed_Account_Trickle_Bypass__c = TRUE;
            accountsToBypass.add(sab);
        }
        
        UPDATE accountsToBypass;
        
        FOR(Account sa : subAccounts){
            
            IF(accountsInTrigger.contains(sa.ParentId)){
                sa.Social_Goals__c = sa.Parent.Social_Goals__c;
                sa.Offerpop_Products__c = sa.Parent.Offerpop_Products__c;
            }
            ELSE IF(accountsInTrigger.contains(sa.Parent.ParentId)){
                sa.Social_Goals__c = sa.Parent.Parent.Social_Goals__c;
                sa.Offerpop_Products__c = sa.Parent.Parent.Offerpop_Products__c;
            }
            ELSE IF(accountsInTrigger.contains(sa.Parent.Parent.ParentId)){
                sa.Social_Goals__c = sa.Parent.Parent.Parent.Social_Goals__c;
                sa.Offerpop_Products__c = sa.Parent.Parent.Parent.Offerpop_Products__c;
            }
            ELSE IF(accountsInTrigger.contains(sa.Parent.Parent.Parent.ParentId)){
                sa.Social_Goals__c = sa.Parent.Parent.Parent.Parent.Social_Goals__c;
                sa.Offerpop_Products__c = sa.Parent.Parent.Parent.Parent.Offerpop_Products__c;
            }
            ELSE IF(accountsInTrigger.contains(sa.Parent.Parent.Parent.Parent.ParentId)){
                sa.Social_Goals__c = sa.Parent.Parent.Parent.Parent.Parent.Social_Goals__c;
                sa.Offerpop_Products__c = sa.Parent.Parent.Parent.Parent.Parent.Offerpop_Products__c;
            }
            
            accountsToUpdate.add(sa);
            
        }
        
        UPDATE accountsToUpdate;
        
    }

}

Does that look like a good idea? It seems to work.

Thanks!
-Greg
This was selected as the best answer