3

I have a phone list of users and have each department titled. If it's a sales department, the sales manager name is listed next to the department name (see picture).

I want the sales manager to show up under their own department. The logic I have now is grouping people under their sales managers. So if Bob Smith is a manager but Bob Smith's manager is John Doe, then Bob Smith will end up under John Doe's list. I need Bob Smith in his own list as well.

I have tried a number of variations of adding the managers in the list for a second time, but I get stuck because when I do this it adds the manager to everyone's list. I can't use JavaScript conditionals because it will be a PDF.

I need some logic that states: add the department manager's name back into their own list. Any advice on how to write the conditional? I am unsure how to add the name back in only by department.

What the list looks like now:

What the list looks like now

Controller:

public Map<String, User[]> allPeople {
    get {
        Map<String, User[]> tmp = new Map<String, User[]>();
        //looping through list
        for (User u : [SELECT Name, Title, Department, Extension, Phone, Manager_for_Reports__c FROM User WHERE UserType != 'Partner' AND UserType != 'Power Partner' AND IsActive = true AND Title != null ORDER BY Department ASC, Name ASC]) {
            //checking only in sales departments
            if (u.Department == 'Sales' && u.Manager_for_Reports__c != null) {
                //getting all of the Manager names in the SOQL query and adding the string 'Sales Team' to the front of it
                //saving this data into array uList
                User[] uList = tmp.get('Sales Team ' + u.Manager_for_Reports__c);
                system.debug('this is the uList:' + uList);
                //checking to see if uList is empty
                if (uList == null) {
                    //if it is empty- create a new user array
                    uList = new User[]{};
                    //add to the uList array all of the data in the u SOQL query
                    uList.add(u);
                    //creating another list of managers and adding it back into the uList 
                    for (User nm : [SELECT Name, Title, Department, Extension, Phone, Manager_for_Reports__c FROM User WHERE UserType != 'Partner' AND UserType != 'Power Partner'AND IsActive = true AND Title != null AND Sales_Leadership__c = true AND Department = 'Sales' ORDER BY Name ASC]){ 
                    //adding the sales manager back into their own list only
                    *****if(tmp.get(u.Manager_For_Reports__c) == u.Name)*****{
                            //I can't just add nm into uList again, if I do this it will add the names to every department. I need to only add it to specific departments
                            uList.add(nm);
                            system.debug('this is the value of the uList:' + uList);
                        }
                    }
                    tmp.put('Sales Team ' + u.Manager_for_Reports__c, uList);
                    system.debug('this is the tmp:' + tmp);
                }
                else {
                    uList.add(u);
                    system.debug('this is the value of u: ' + u);
                    tmp.put('Sales Team ' + u.Manager_for_Reports__c, uList);
                }
            }
            else {
                User[] uList = tmp.get(u.Department);
                if (uList == null) {
                    uList = New User[]{};
                    uList.add(u);
                    tmp.put(u.Department, uList);
                }
                else {
                    uList.add(u);
                    tmp.put(u.Department, uList);
                }
            }
        }
        return tmp;
    } set;}

Visualforce:

<table>
    <tbody>
    <thead>
    <tr>
        <th>Name</th>
        <th>Title</th>
        <th>Ext.</th>
        <th>Phone</th>
    </tr>
    </thead>
        <apex:repeat value="{!allPeople}" var="depts">
            <th colspan="5" id="department">{!depts}</th>
            <apex:repeat value="{!allPeople[depts]}" var="person">
                <tr>
                    <td>{!person.Name}</td>
                    <td>{!person.Title}</td>
                    <td>{!person.Extension}</td>
                    <td>{!person.Phone}</td>
                </tr>
            </apex:repeat>
        </apex:repeat>
    </tbody>
 </table>

UPDATE:

This is what I want the list to look like:

What I want the new list to look like

UPDATE2: Is there a way to do a .contains() in the key of a map? I was thinking something like this might work as well...

for (User nm : [SELECT Name, Title, Department, Extension, Phone, Manager_for_Reports__c FROM User WHERE UserType != 'Partner' AND UserType != 'Power Partner'AND IsActive = true AND Title != null AND Sales_Leadership__c = true AND Department = 'Sales' ORDER BY Name ASC]){ 
if(tmp.get('Sales Team ' + u.Manager_for_Reports__c).contains(nm.name)){
    uList.add(nm);
}
2
  • 1
    Can you please provide a pictorial example of this line: "So if Bob Smith is a manager but Bob Smith's manager is John Doe, then Bob Smith will end up under John Doe's list. I need Bob Smith in his own list as well". what exactly you want.. Jan 2, 2017 at 0:45
  • @SantanuBoral please see updated picture
    – Olivia
    Jan 3, 2017 at 16:50

2 Answers 2

2

Try replacing your allPeople getter with code below and let me know if it works. There are comments in the code that explain the logic.

public Map<String, User[]> allPeople {
    get {
        Map<String, User[]> teams = new Map<String, User[]>();
        List<User> users = [SELECT Name, Title, Department, Extension, Phone, Manager_for_Reports__c FROM User WHERE UserType != 'Partner' AND UserType != 'Power Partner' AND IsActive = true AND Title != null ORDER BY Department ASC, Name ASC];

        //Since `Manager_For_Reports__c` is a picklist, and not a lookup,
        //you need to map the user name to its user record 
        //(which could generally cause problems when there are users with same names, 
        //but it shouldn't be an issue in your current use case)
        Map<String, User> nameToUserMap= new Map<String, User>();
        for(User u : users){
            nameToUserMap.put(u.Name, u);
        }

        for(User u : users){
            if(u.Manager_For_Reports__c == null){
                //doesn't have a manager, so just add it to his own department
                if(teams.containsKey(u.Department)){
                    teams.get(u.Department).add(u);
                }else{
                    teams.put(u.Department, new User[]{u});
                }
            }else{
                //has a manager, so add him to his manager's team
                User manager = nameToUserMap.get(u.Manager_For_Reports__c);
                String teamName = u.Department + ' Team ' +  manager.Name;

                if(teams.containsKey(teamName)){
                    teams.get(teamName).add(u);
                }else{
                    //if the manager's team doesn't exist you need to create it 
                    //and add the manager to that team as well
                    teams.put(teamName, new User[]{manager, u});
                }
            }
       }
       return teams;
   } 
   set;
}

Note that this will create manager teams for all departments if they exist, and not just for the Sales department like your original code did.

BTW, I coded this directly here, so there could be some errors I missed. Let me know if the code doesn't work.


My original solution back when I thought Manager_For_Reports__c was a lookup:

public Map<String, User[]> allPeople {
    get {
        Map<String, User[]> teams = new Map<String, User[]>();
        Map<Id, User> users = new Map<Id, User>([SELECT Name, Title, Department, Extension, Phone, Manager_for_Reports__c FROM User WHERE UserType != 'Partner' AND UserType != 'Power Partner' AND IsActive = true AND Title != null ORDER BY Department ASC, Name ASC]);

        for(Id userKey : users.keySet()){
            User u = users.get(userKey);

            if(u.Manager_For_Reports__c == null){
                //doesn't have a manager, so just add it to his own department
                if(teams.containsKey(u.Department)){
                    teams.get(u.Department).add(u);
                }else{
                    teams.put(u.Department, new User[]{u});
                }
            }else{
                //has a manager, so add him to his manager's team
                User manager = users.get(u.Manager_For_Reports__c);
                String teamName = u.Department + ' Team ' +  manager.Name;

                if(teams.containsKey(teamName)){
                    teams.get(teamName).add(u);
                }else{
                    //if the manager's team doesn't exist you need to create it 
                    //and add the manager to that team as well
                    teams.put(teamName, new User[]{manager, u});
                }
            }
       }
       return teams;
   } 
   set;
}

I kept my original code here that would work if the Manager_For_Reports__c field was a lookup field. I'm sure that it won't be straightforward, but I strongly recommend to recreate this field as a lookup, instead of a picklist.

6
  • @smujov, thank you, this is a good idea as well...I am getting an error though, it is pulling in the Manager Name as the key which is giving the error: Invalid id: Carlos Smith
    – Olivia
    Jan 3, 2017 at 18:26
  • 1
    @Olivia So the Manager_For_Reports__c field isn't a lookup field? What's the type of that field?
    – smukov
    Jan 3, 2017 at 18:28
  • ohh jeeze. My bad, I just double checked and it is actually a picklist.
    – Olivia
    Jan 3, 2017 at 18:30
  • @Olivia Try with my updated code, please.
    – smukov
    Jan 3, 2017 at 18:38
  • @smukv, this worked perfectly. I wanted to go through it and make sure I understood what you were doing and was a little confused about this line: teams.put(teamName, new User[]{manager, u}); I understand you are putting into the map the teamName (aka the department + sales manager name), but the second half I am unsure about. The value that is tied to the teamName key is a new User list that contains the manager as well as the u list. How does this comma between the two values add them together? Is that what is happening here? You are adding manager and u together?
    – Olivia
    Jan 3, 2017 at 19:20
1

I think I understand what you are going for, but let me know if it's wrong. I think this will be easier if you use the manager as a key and then construct the department name in Visualforce.

Map<User, User[]> tmp = new Map<User, User[]>();
Map<ID, User> people = new Map<ID, User>([SELECT Name, Title, Department, Extension, Phone, Manager_for_Reports__c FROM User WHERE UserType != 'Partner' AND UserType != 'Power Partner' AND IsActive = true AND Title != null ORDER BY Department ASC, Name ASC]);

for (User u : people.values()) {
    if (u.Manager_For_Reports != null){
        User manager = people.get(u.Manager_For_Reports__c);
        if (!tmp.containsKey(manager){
            tmp.put(manager, new List<User>());
        }
        tmp.get(manager).add(u);
    }
}

I will note this assumes that any person who manages a team has someone with Manager_For_Reports__c pointing to them, and that anyone who has a null value for Manager_For_Reports__c is a manager.

6
  • @IlluvsuveBrian, unfortunately the department name has to be generated dynamically without JavaScript, so constructing the department name in Visualforce is not going to work.
    – Olivia
    Jan 3, 2017 at 16:52
  • @Olivia I said in Visualforce, not in Javascript. You can do something like <th>{!depts.Department + IF(ISBLANK(depts.Manager_For_Reports__c), '', ' Sales Team')}</th>. However, I just noticed that Manager_For_Reports__c is a text field rather than a user lookup, so this answer needs to be changed a bit. Jan 3, 2017 at 16:57
  • the Manager_For_Reports__c actually is a lookup fields so this could work. Let me dig into this and I will get back to you. I also updated my question with another possibility of checking the key values and comparing them to the values of a list...I am not sure if you can do a .contains on a key though....
    – Olivia
    Jan 3, 2017 at 17:16
  • @Olivia Do you mean it's a lookup formula, e.g. Manager__c.Name? If so, you'll need to change it to whatever the actual lookup field is so you can use the ID - finding a manager by their name requires more work and you may run into issues if you ever have two users with the same name. Jan 3, 2017 at 18:30
  • I apologize, I just double checked and the Manager_For_Reports__c field is actually a picklist. :(
    – Olivia
    Jan 3, 2017 at 18:30

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .