function readOnly(count){ }
Starting November 20, the site will be set to read-only. On December 4, 2023,
forum discussions will move to the Trailblazer Community.
+ Start a Discussion
Deepika Gupta 26Deepika Gupta 26 

Not able to associate contact in Account Hierarchy

Hi All,
Need help on an urgent issue.Requirement is to create a hierarchy of Parent Account its child and its corresponding contact.
Controller Class--->

public without sharing class HierarchyTree {

    public static String currentId {get; set;}

    private static Account currentAccount {
        get {
            if (currentAccount == null) {
                currentAccount = [select Name, ParentId, UltimateParent__c From Account where Id = :currentId];
            }
            return currentAccount;
        }
        private set;
    }

    private static Account ultimateParentAccount {
        get {
            if (ultimateParentAccount == null) {
                if (currentAccount.UltimateParent__c != null) {
                    ultimateParentAccount = [select Name, ParentId, UltimateParent__c from Account where Id = :currentAccount.UltimateParent__c];
                } else {
                    ultimateParentAccount = currentAccount;
                }
                currentAccount = [select Name, ParentId, UltimateParent__c From Account where Id = :currentId];
            }
            return currentAccount;
        }
        private set;
    }
    
    /**
     * @description This methos is used to generate JSON data for jsTree component
     */
    public static String getJsonTree() {
        List<JSTreeNode> listItems = new List<JSTreeNode>();
        listItems.add(
            new JSTreeNode(
                ultimateParentAccount.Id,
                '#',
                ultimateParentAccount.Name,
                new JSTreeNodeState(true, false, false),
                new JSTreeNodeAAttr(String.valueOf(ultimateParentAccount.Id) == currentId ? 'font-weight:bold' : '')
                
            )
        );
        for (Account acc : AccountHierarchyServices.getAllChildren(new List<Account>{ultimateParentAccount})) {
            listItems.add(
                new JSTreeNode(
                    acc.Id,
                    acc.ParentId,
                    acc.Name,
                    new JSTreeNodeState(true, false, false),
                    new JSTreeNodeAAttr(String.valueOf(acc.Id) == currentId ? 'font-weight:bold' : '')
                )
            );
        }
        return JSON.serialize(listItems);
    }

    /**
     * This class is used to generate jsTree node
     */
    @TestVisible private class JSTreeNode {
        public String id; //required
        public String parent; //required
        public String text; // node text
        public String icon; // string for custom icon
        public JSTreeNodeState state; // instance of JSTreeNodeState
        public Object li_attr; // attributes for the generated LI node
        public JSTreeNodeAAttr a_attr; // attributes for the generated A node
        
        public JSTreeNode(String id, String parent, String text, JSTreeNodeState state, JSTreeNodeAAttr a_attr) {
            this.id = id;
            this.parent = parent;
            this.text = text;
            this.state = state;
            this.a_attr = a_attr;
        }
    }

    @TestVisible private class JSTreeNodeState {
        public Boolean opened; // is the node open
        public Boolean disabled; // is the node disabled
        public Boolean selected; // is the node selected

        public JSTreeNodeState(Boolean opened, Boolean disabled, Boolean selected) {
            this.opened = opened;
            this.disabled = disabled;
            this.selected = selected;
        }
    }

    @TestVisible private class JSTreeNodeAAttr {
        public String style; // style of current node

        public JSTreeNodeAAttr(String style) {
            this.style = style;
        }
    }
    
}
 
Visualforce Component --->

<apex:component controller="HierarchyTree">
	
	<apex:attribute name="currId" description="This is the Account Id for displaying Acccount Hierarchy" type="String" required="true" assignTo="{!currentId}"/>

	<apex:outputPanel rendered="{! currId == null}" layout="none">
		<span style="font-size:16px; font-weight:bold; padding-top: 15px; display: inline-block;">{!$Label.AccountIdIsRequired}</span>
	</apex:outputPanel>

	<apex:outputPanel rendered="{! currId != null}" layout="none">

		<apex:stylesheet value="{!URLFOR($Resource.jsTree, 'dist/themes/default/style.min.css')}"/>
		<apex:includeScript value="{!URLFOR($Resource.jquery_1_11_3)}"/>
		<apex:includeScript value="{!URLFOR($Resource.jsTree, 'dist/jstree.min.js')}"/>

		<script>
			var j$ = jQuery.noConflict();

			j$(function(){

				j$('#jstree')
				// listen for event
				.on('changed.jstree', function (e, data) {
			        if( (typeof sforce != 'undefined') && sforce && (!!sforce.one) ) {
			            // Salesforce1 navigation
			            sforce.one.navigateToSObject('' + data.selected);
			        } else {
			        	// Set the window's parent URL using a javascript expression
			            window.top.location.href = '/' + data.selected;
			        }
				})
				// create the instance
				.jstree({
					'core' : {
						'data' : {!JsonTree}
					}
				});

			});
			
		</script>

		<div id="jstree"></div>

	</apex:outputPanel>

</apex:component>
 
Visualforce Page--->


<apex:page standardController="Account" > <apex:form >

<c:HierarchyTree currId="{!Account.id}" />


  <apex:outputLink value="https://bd2--cgkt.cs87.my.salesforce.com/001/o"><h1><b>Back to Account List</b></h1>!</apex:outputLink> 
<a href="?#"><font style="color:blue;">Exclude Contact</font></a> | <a href="?#"><font style="color:blue;">Include Contact</font></a>

</apex:form>

</apex:page>

Its Working fine and showing me the hierarchy of Account : 

Now my concern is i am not able to associate contact in the HierarchyTree first my thought was that i can make sub query or may be its call nested query like this in Hierarchy Tree Methods :

private static Account currentAccount {
        get {
            if (currentAccount == null) {
                currentAccount = [select Name, ParentId, UltimateParent__c,(select id,name from contacts) From Account where Id = :currentId];
            }
            return currentAccount;
        }
        private set;
    }

But its not returning me any row.then one suggestion i got is that i should use map for account and contact like 

 public Map<Id,Contact> contactsMap {
        get {
            if (contactsMap == null) {
                contactsMap = new Map<Id,Contact>();
                for (Account acc : [select Id, (select Id, FirstName, LastName from Contacts) from Account where Id = :currentId]) {
                    for (Contact c : acc.Contacts) {
                        contactsMap.put(c.Id, c);
                    }
                }
            }
            return contactsMap;
        }
        private set;
    }

But i am not sure how acutully i need to use map to get associate contact because that variable current account is also used in the another method to get parent account.Could someone suggeste me a proper way to associate contact in my current code.and how can i render this map to get hierarchy form in VF page means which method should i use to get contact and how i can use this method in <repeat> to get child in tree form.Please suggest its on Priority and not getting proper solution to show it in required format for contact. 
 
Mahesh DMahesh D
Hi Deepika,

Here 2 things I would like to mention.

(1) You are getting the currentAccount in 2 places one is at line 10 and other one is at line 25.

Make sure that both the places you are using the below query:

 
currentAccount = [select Name, ParentId, UltimateParent__c,(select id,name from contacts) From Account where Id = :currentId];

This will give you the Current Account along with list of Contacts.

(2) Another way is, if you use below code:
 
public Map<Id,Contact> contactsMap {
	get {
		if (contactsMap == null) {
			contactsMap = new Map<Id,List<Contact>>();
			for (Account acc : [select Id, (select Id, FirstName, LastName from Contacts) from Account where Id = :currentId]) {
				for (Contact c : acc.Contacts) {
					contactsMap.get(acc.Id).add(c);
				}
			}
		}
		return contactsMap;
	}
	private set;
}
you will get a Map which contains the list of Contacts for the given account id.

Please do let me know if it helps you.

Regards,
Mahesh

 
Deepika Gupta 26Deepika Gupta 26
Yaa Thats what i want that this map i wanted to show in VF Page : i have written a code like this in vf Page 
 
<apex:page standardController="Account" "> <apex:form >

<c:HierarchyTree currId="{!Account.id}" />
<apex:repeat value="{!contactsMap}" var="conMap">

        <apex:outputText value="{!conMap}" /> --

        <apex:outputText value="{!contactsMap[conMap]}" /><br/>

</apex:repeat>



  <apex:outputLink value="https://bd2--cgkt.cs87.my.salesforce.com/001/o"><h1><b>Back to Account List</b></h1>!</apex:outputLink> 
<a href="?#"><font style="color:blue;">Exclude Contact</font></a> | <a href="?#"><font style="color:blue;">Include Contact</font></a>

</apex:form>

</apex:page>

But its showing me the error that Visualforce Page: Hierarchy_Clone ~ Salesforce - Unlimited EditionError: Unknown property 'AccountStandardController.contactsMap' not sure why and how to solve it to show account and its corresponding contact hierarchy on VF page