0

我在地图中有一个角色层次结构及其子角色。我想获取每个角色下的所有用户并拥有该用户下的所有用户。

例如

角色:市场总监

子角色:RM东

子角色:RM West

子角色:RM North

子角色:RM South

我有这个 Map<id, set<id>>

如果 Phil 是营销总监,我希望所有用户都向 Phil 报告,并且在这些用户下也有用户向 RM 报告。每个角色下可能有多个用户,我需要帮助才能找到在某些集合中捕获这些用户的方法。

Phil - Director Marketing
      Kevin - RM South   
           Clara - TM
           Joe   - TM
      Robin - RM North
           Rita  - TM
           John  - TM

我不知道该怎么做。

谢谢

4

1 回答 1

3

我写了一个帮助类来解决这个确切的问题。

public with sharing class GroupsHelper {
    private static final String userPrefix = User.SObjectType.getDescribe().getKeyPrefix();

    public Map<Id, Set<Id>> roleUsers { get; private set; }
    public Map<Id, Set<Id>> roleSubordinateUsers { get; private set; }
    public Map<Id, Set<Id>> groupsUsers { get; private set; }
    public Map<Id, Set<Id>> usersGroups { get; private set; }
    public Map<Id, Set<Id>> usersQueues { get; private set; }

    public GroupsHelper() {
        this.roleUsers = new Map<Id, Set<Id>>();
        this.roleSubordinateUsers = new Map<Id, Set<Id>>();
        this.groupsUsers = new Map<Id, Set<Id>>();
        this.usersGroups = new Map<Id, Set<Id>>();
        this.usersQueues = new Map<Id, Set<Id>>();
        refresh(true, true);
    }

    public void refresh(Boolean refreshRoles, Boolean refreshGroups) {
        if(refreshRoles) {
            refreshRoles();
        }
        if(refreshGroups) {
            refreshGroups();
        }
    }

    public void refreshRoles() {
        roleUsers.clear();
        roleSubordinateUsers.clear();
        //Populate a Map with the role Id and all the users
        Map<Id, UserRole> roles = new Map<Id, UserRole>([
            SELECT
                Id,
                Name,
                ParentRoleId,
                (
                    SELECT
                        Id,
                        Name
                    FROM
                        Users
                )
            FROM
                UserRole]);
        Set<Id> userIds;
        Id subordinateId;
        for(UserRole role : roles.values()) {
            //Add the User Ids of the current role
            roleUsers.put(role.Id, (new Map<Id, User>(role.Users)).keySet());
            //Loop throuh and populate the role and subordinate Map
            subordinateId = null;
            while(role != null) {
                if(!roleSubordinateUsers.containsKey(role.Id)) {
                    roleSubordinateUsers.put(role.Id, new Set<Id>());
                }
                userIds = roleSubordinateUsers.get(role.Id);
                if(roleSubordinateUsers.containsKey(subordinateId)) {
                    userIds.addAll(roleSubordinateUsers.get(subordinateId));
                }
                for(User user : role.Users) {
                    userIds.add(user.Id);
                }
                subordinateId = role.Id;
                role = roles.get(role.ParentRoleId);
            }
        }
    }

    public void refreshGroups() {
        groupsUsers.clear();
        usersGroups.clear();
        Map<Id, Group> groups = new Map<Id, Group>([
            SELECT
                Id,
                Name,
                Type,
                        RelatedId,
                (
                    SELECT
                        UserOrGroupId
                    FROM
                        GroupMembers
                ),
                (
                    SELECT
                        Id,
                        SobjectType
                    FROM
                        QueueSobjects
                )
            FROM
                Group]);

        List<Id> stack;
        Set<Id> userIds, queueIds;
        Group groop;
        for(Id groupId : groups.keySet()) {
            stack = new List<Id> { groupId };
            userIds = new Set<Id>();
            do {
                groop = groups.get(stack.remove(0));
                //This is extra cautious, it should not be possible to get a null value
                if(groop != null) {
                    if(groop.RelatedId != null) {
                        if(groop.Type == 'Role') {
                            userIds.addAll(roleUsers.get(groop.RelatedId));
                        } else if(groop.Type == 'RoleAndSubordinates') {
                            userIds.addAll(roleSubordinateUsers.get(groop.RelatedId));
                        }
                    } else {
                        for(GroupMember member : groop.GroupMembers) {
                            if(isPrefix(member.UserOrGroupId, userPrefix)) {
                                userIds.add(member.UserOrGroupId);
                            } else {
                                //When the Id is not a user Id it is reliably a group Id, that we can add to the stack for processing
                                stack.add(member.UserOrGroupId);
                            }
                        }
                    }
                }
            } while(!stack.isEmpty());
            if(userIds.size() > 0) {
                groupsUsers.put(groupId, userIds);
                for(Id userId : userIds) {
                    if(!usersGroups.containsKey(userId)) {
                        usersGroups.put(userId, new Set<Id>());
                    }
                    usersGroups.get(userId).add(groupId);
                }
            }
        }
        for(Id userId : usersGroups.keySet()) {
            if(!usersQueues.containsKey(userId)) {
                usersQueues.put(userId, new Set<Id>());
            }
            for(Id groupId : usersGroups.get(userId)) {
                groop = groups.get(groupId);
                if(groop.Type == 'Queue' && groop.QueueSobjects.size() > 0) {
                    usersQueues.get(userId).addAll((new Map<Id, QueueSobject>(groop.QueueSobjects)).keySet());
                }
            }
        }
    }

    public static Boolean isPrefix(Id sfdcId, String prefix) {
        if(sfdcId == null || prefix == null || prefix.length() != 3) {
            return false;
        } else {
            return String.valueOf(sfdcId).startsWith(prefix);
        }
    }

    private static testMethod void testGroupsHelper() {
        GroupsHelper helper = new GroupsHelper();

        Integer rolesCount = [SELECT Id FROM UserRole].size();
        System.assertEquals(rolesCount, helper.roleUsers.size());
        System.assertEquals(rolesCount, helper.roleSubordinateUsers.size());

        if(helper.usersQueues.size() > 0) {
        Integer queueCount = [SELECT Id FROM QueueSobject].size();
            Id userId = new List<Id>(helper.usersQueues.keySet())[0];
            System.assertEquals(queueCount, helper.usersQueues.get(userId).size());
        }

        //Can't test the size of the groups and users Maps because they only
        //contain a key if there are child values to add.
    }
}
于 2012-06-14T03:34:53.487 回答