apex-enterprise-patterns / fflib-apex-common

Common Apex Library supporting Apex Enterprise Patterns and much more!
BSD 3-Clause "New" or "Revised" License
911 stars 517 forks source link

feat: add sobject hierarchy #389

Open codythomaszeitler opened 2 years ago

codythomaszeitler commented 2 years ago

This utility function was created for the following reason. Our team kept writing code snippets that looked like the following:

if ( acct.Parent.Parent.Parent.Parent.Parent != null ) {
         managingUser = new User( Id = acct.Parent.Parent.Parent.Parent.Parent.OwnerId  );
} else if (acct.Parent.Parent.Parent.Parent != null   ) {
         managingUser = new User( Id = acct.Parent.Parent.Parent.Parent.OwnerId );
} else if (  acct.Parent.Parent.Parent != null) {
    managingUser = new User( Id = acct.Parent.Parent.Parent.OwnerId );
} else if ( acct.Parent.Parent != null ) ) {
    managingUser = new User( Id = acct.Parent.Parent.OwnerId );
} else if ( acct.Parent != null  ) {
    managingUser = new User( Id =acct.Parent.OwnerId );
} else if (acct.OwnerId != null   ) {
    managingUser = new User( Id = acct.OwnerId );
} 

There were many places where people would query five lookup levels deep in order to get some information from a hierarchy. However, not only does this lead to awkward looking code as above, but it also does not handle the case where there are more than five levels of the hierarchy, leading to bugs.

This new functionality would handle the above case in the following manner:

fflib_SObjectHierarchy utility = new fflib_SObjectHierarchy(Account.SObjectType, Account.ParentId, new Set<SObjectField> {Account.OwnerId});
Map<Id, List<SObject> hierarchies = utility.getUntilTopOfHierarchy(new Set{account.Id});

List<SObject> hierarchy = hierarchies.get(account.Id);

SObject topOfHierarchy = hierarchy.get(hierarchy.size() - 1);
// Set the owner id here etc etc.
topOfHierarchy.get('OwnerId');

The utility function getUntilTopOfHierarchy returns a map of ids that were input into the function, with a list of sobjects that represent their hierarchy, from bottom to top. This will parse out the entire hierarchy, starting from the given record. It may use multiple SOQL statements to reach the top. More specifically, for every five levels of hierarchy, there must be one SOQL performed (since that is the salesforce max).

Thus, if you want to get the top of the hierarchy of the account, one only needs to get the last element of the list associated to the input id.

We believe that this greatly simplifies navigating hierarchies (which is something that our team kept doing again and again) and believe that this could be helpful functionality for other teams out there.


This change is Reviewable