+ Start a Discussion
Guru 91Guru 91 

Getting multi level Parent Id's (No Limit) in hierarchy in trigger?

Hi,
My below code is giving only the immediate parent ID of an account but I need to fetch multi level parents means his parent then his parent then his parent till the parentid for an account in heirarchy is null. Please help me out. And then I need to update all parent Account.

set<id> ParentIds = new set<id>(); 
For(Account acc: Trigger.New){
                    if(acc.ParentId!=null){
                   ParentIds.add(acc.ParentId);
              }
}

 
NagendraNagendra (Salesforce Developers) 
Hi Guru,

Faced a similar issue in the past and below is the use case.

There is a field on Account called Account.Ultimate_Parent__c. I want to update(through trigger) this field with correct value whenever Account. Parent field is Changed.

Although Ultimate Parent could be at any level up in the hierarchy which seems not possible to find using SOQL in a loop otherwise it will reach apex governor limit. Also accessing field in a query like parent.parent.parent will limit no of levels we can go up to find the Ultimate Parent.

Somehow we can pull all the records in the Map and then find out Ultimate Parent? Because after updating the account with its Ultimate Parent, we have to update all of its child accounts down in the hierarchy to have a correct Ultimate Parent.

As shown in the following diagram that all child accounts have the same Ultimate Parent i.e 'A1'
User-added image The solution will really depend on how many levels you need to be able to support.

For instance, if you can rely on only going 10 levels deep then you can just use a formula field as per this post https://salesforce.stackexchange.com/questions/95617/need-a-custom-field-grand-parent-account-which-has-highest-level-of-account-heir/113611#113611 to Need a custom field Grandparent Account which has highest level of account hierarchy.

Another alternative is to use a text field to maintain the hierarchy. It would essentially store the path from the current node to the ultimate parent.

E.g. Using the above identifiers. In reality you would use the 18 character record IDs and a suitable delimiter.
  • For B4 it would be A1|B1|B2
  • For B3 A1|B1
Then if there is ever a modification to a non-leaf node's parent you can perform a SOQL search to find all the affected nodes that need to be updated. Potentially doing so via a batch process to correct their parent relationship.

Hope this helps.

Kindly mark this as solved if the reply was helpful.

Thanks,
Nagendra
 
Ajay K DubediAjay K Dubedi
Hi Guru,

Below Sample code can fullfill your requirements. Hope this will work for you.

trigger childAccountRollupTrigger on Account (after insert,after update,after delete){

if(checkRecursive.runOnce()){

Set<Id> setParentAccId = new Set<Id>();

if(Trigger.isInsert || Trigger.isUpdate){
for(Account acc: Trigger.new) {
if(acc.ParentId!=null)
setParentAccId.add(acc.ParentId);
}
}

if(Trigger.isDelete){
for(Account acc_Old : Trigger.old){
if(acc_Old.ParentId!=null)
setParentAccId.add(acc_Old.ParentId);
}
}

Map<Id,Double> mapChildTotalAmount = new Map<Id,Double>();
for(AggregateResult agg: [Select ParentId, SUM(Child_Total_Amount__c) from Account where ParentId IN : setParentAccId group by ParentId ]){
mapChildTotalAmount .put((Id)agg.get(‘ParentId’),(Double)agg.get(‘expr0’));
}

List<Account> ParentListUpdate = new List<Account>();
for(Account acc : [Select Id, Child_Total_Amount__c from Account where Id IN :setParentAccId]){
Double TotalSummaryAmount = mapChildTotalAmount .get(acc.Id);
acc.Child_Total_Amount__c = TotalSummaryAmount ;
ParentListUpdate .add(acc);

}
if(ParentListUpdate !=null && ParentListUpdate.size()>0)
update ParentListUpdate ;
}
}


Please mark this as best answer if this solves your problem.

Thank you
Ajay Dubedi