0

I want to show in child accounts, the related contacts of the parents and other child accounts too. I almost solved this with a Visualforce Page and a Controller, but the related contacts are shown only on the parent account and the current account contacts.

How do I show the related contacts of the other parent/child accounts contacts on the child account too?

Example: I have parent account A, and child Account B and C. When I click on the Account C, i want the visual force page to show me the related contacts of the Account A and also the related contacts of child account B.

Thanks in advance for the help.

Here is my Controller:

public with sharing class AccountHierarchyController {
public Account acc { get; private set; }
public List<Account> accountList { get; private set; }
public ApexPages.StandardController controller { get; private set; }

public AccountHierarchyController(ApexPages.StandardController controller) {
    this.acc = (Account)controller.getRecord();
    this.accountList = new List<Account>();
    
    Account baseAccount = [SELECT Id, 
                           ParentId, 
                           Name,
                           Parent.Name,
                           (SELECT Id, Name, Phone, Email from Contacts),
                           (SELECT Id, Name FROM ChildAccounts)
                           FROM Account 
                           WHERE Id = :acc.id];
    accountList.add(baseAccount);
    
    Account currentAccount = baseAccount;

    // Traverse the hierarchy upwards.
    while (currentAccount.ParentId != null) {
        currentAccount = [Select id, Name, ParentId, Parent.Name, (Select Id, Name, Phone, Email from Contacts) from Account where Id = :currentAccount.ParentId];
        accountList.add(currentAccount);
    }
    
    // Traverse the hierarchy downwards
    Set<Id> accountsToQuery = new Map<Id, Account>(baseAccount.ChildAccounts).keySet();
    while (accountsToQuery.size() > 0) {
        List<Account> thisLevelAccounts = [SELECT Id, Name, Parent.Name,
                                           (Select Id, Name, Phone, Email from Contacts),
                                           (SELECT Id, Name FROM ChildAccounts)
                                           FROM Account
                                           WHERE Id IN :accountsToQuery];
        accountsToQuery = new Set<Id>();
        
        for (Account a : thisLevelAccounts) {
            // Add this Account (with its Contacts) to the list.
            accountList.add(a);
            
            // Add this Account's children to the query for the next level.
            for (Account child : a.ChildAccounts) {
                accountsToQuery.add(child.Id);
            }
        }
    }
}

}

and here is the VF page:

<apex:page title="Contact" standardController="Account" extensions="AccountHierarchyController">
    <apex:outputPanel id="cont">
        <apex:pageBlock title="Contacts">
            <apex:repeat value="{! accountList }" var="a">
                <apex:pageBlockSection title="{! a.Name + IF(NOT(ISBLANK(a.ParentId)), ' (child of ' + a.Parent.Name + ')', '') }">
                    <apex:pageBlockTable value="{! a.Contacts }" var="con" id="conlist" title="Contact">
                        <apex:column value="{!con.Name}"/>
                        <apex:column value="{!con.Phone}" />
                        <apex:column value="{!con.Email}" />
                    </apex:pageBlockTable>
                </apex:pageBlockSection>
            </apex:repeat>
        </apex:pageBlock>
    </apex:outputPanel>
</apex:page>

Thanks in advance for the help.

PS: I commented in the other old thread where I found this solution and I am hopping that the original commenter written again

1 Answer 1

0

Since you want to display all contacts for all accounts in hierarchy you can change your code to find the Account at the top and go downwards from there. This way you can find Accounts in other branches of Account Hierarchy.

Also be careful this code will run a lot of SOQL based on the depth of hierarchy.

public with sharing class AccountHierarchyController {
    public Account acc { get; private set; }
    public List<Account> accountList { get; private set; }
    public ApexPages.StandardController controller { get; private set; }
    
    public AccountHierarchyController(ApexPages.StandardController controller) {
        this.acc = (Account)controller.getRecord();
        this.accountList = new List<Account>();
        
        Account baseAccount = [SELECT Id, 
                               ParentId, 
                               Name,
                               Parent.Name,
                               (SELECT Id, Name, Phone, Email from Contacts),
                               (SELECT Id, Name FROM ChildAccounts)
                               FROM Account 
                               WHERE Id = :acc.id];
        
        Account currentAccount = baseAccount;
        
        
        
        Id topAccountId;
        // Find the top node(Account).
        while (currentAccount.ParentId != null) {
            currentAccount = [Select id, Name, ParentId, Parent.Name, (Select Id, Name, Phone, Email from Contacts) 
                              from Account 
                              where Id = :currentAccount.ParentId];
            if(currentAccount.ParentId == null) {
                topAccountId = currentAccount.Id;
            }
        }
        
        // Traverse the hierarchy downwards
        Set<Id> accountsToQuery = new Set<Id>();
        accountsToQuery.add(topAccountId);
        while (accountsToQuery.size() > 0) {
            List<Account> thisLevelAccounts = [SELECT Id, Name, Parent.Name,
                                               (Select Id, Name, Phone, Email from Contacts),
                                               (SELECT Id, Name FROM ChildAccounts)
                                               FROM Account
                                               WHERE Id IN :accountsToQuery];
            accountsToQuery = new Set<Id>();
            
            for (Account a : thisLevelAccounts) {
                // Add this Account (with its Contacts) to the list.
                accountList.add(a);
                
                // Add this Account's children to the query for the next level.
                for (Account child : a.ChildAccounts) {
                    accountsToQuery.add(child.Id);
                }
            }
        }
    }
}

You must log in to answer this question.

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