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);
}
  • 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.. – Santanu Boral Jan 2 '17 at 0:45
  • @SantanuBoral please see updated picture – Olivia Jan 3 '17 at 16:50
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.

  • @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 '17 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 '17 at 18:28
  • ohh jeeze. My bad, I just double checked and it is actually a picklist. – Olivia Jan 3 '17 at 18:30
  • @Olivia Try with my updated code, please. – smukov Jan 3 '17 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 '17 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.

  • @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 '17 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. – IllusiveBrian Jan 3 '17 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 '17 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. – IllusiveBrian Jan 3 '17 at 18:30
  • I apologize, I just double checked and the Manager_For_Reports__c field is actually a picklist. :( – Olivia Jan 3 '17 at 18:30

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.