Find users under a node in role hierarchy
I would get the UserRole
records you want first and then query the User
records.
Grouping UserRole Records by Parent
// public with sharing class RoleHierarchy
static Map<Id, List<UserRole>> hierarchy
{
get
{
if (hierarchy == null)
{
hierarchy = new Map<Id, List<UserRole>>();
for (UserRole role : [SELECT ParentRoleId FROM UserRole])
{
if (!hierarchy.containsKey(role.ParentRoleId))
hierarchy.put(role.ParentRoleId, new List<UserRole>());
hierarchy.get(role.ParentRoleId).add(role);
}
}
return hierarchy;
}
private set;
}
Getting Relevant UserRole Records
// public with sharing class RoleHierarchy
public static List<UserRole> getChildren(Id userRoleId)
{
return hierarchy.containsKey(userRoleId) ?
hierarchy.get(userRoleId) : new List<UserRole>();
}
// I would just use one of the below and name it getSubHierarchy
// Not entirely clear based on OP if top-level should be included
public static Set<Id> getSubHierarchyInclusive(Id userRoleId)
{
Set<Id> roleIds = new Set<Id> { userRoleId };
for (UserRole childRole : getChildren(userRoleId))
roleIds.addAll(getSubHierarchyInclusive(childRole.Id);
return roleIds;
}
public static Set<Id> getSubHierarchyExclusive(Id userRoleId)
{
Set<Id> roleIds = new Set<Id>();
for (UserRole childRole : getChildren(userRoleId))
{
roleIds.add(childRole.Id);
roleIds.addAll(getSubHierarchyExclusive(childRole.Id);
}
return roleIds;
}
Get Users
// public with sharing class RoleHierarchy
public static List<User> getUsersUnder(Id userRoleId)
{
return [
SELECT Id FROM User
WHERE UserRoleId IN :getSubHierarchy(userRoleId)
];
}
The above approach consumes a total of 2 SOQL
statements.