Salesforce accounts can be grouped together in something called an account hierarchy. Each account can have a parent account, and then that parent can have a parent, and so on. In this way you can create a tree structure for a set of related accounts.
In Salesforce Lightning you can view the account hierarchy by clicking on a button next to the account name. Unfortunately, this button is displayed on all accounts, even ones that don’t have a parent or children. The only way to tell if the account is a part of a hierarchy is by clicking on the button and viewing the hierarchy page.
I wanted to replace the hierarchy button with a Lightning Component that would only display if the account was part of a hierarchy. And – since this would be a component and I’d have a bit more real estate to work with (compared to a button) – I wanted to indicate if the account had a parent or children (and how many).
With that in mind I created the Account Hierarchy Lightning Component. It looks like this:
With all of that out of the way, here’s all of the code you’ll need to create your own account hierarchy component for Salesforce Lightning:
AccountHierarchy.cmp (Component):
<aura:component implements="flexipage:availableForRecordHome,force:hasRecordId" controller="AccountHierarchyController">
<!-- Atributes-->
<aura:attribute name="hasParent" type="boolean" default="false"/>
<aura:attribute name="numChildren" type="integer" default="0" />
<aura:attribute name="childOrChildren" type="string" default="children" />
<aura:attribute name="headerTitle" type="Aura.Component[]">
<h2>
<b>This account is part of a hierarchy.</b>
</h2>
</aura:attribute>
<!-- Handlers -->
<aura:handler name="init" value="{!this}" action="{!c.init}" />
<aura:if isTrue="{!or(v.hasParent, v.numChildren > 0)}">
<lightning:card title="{!v.headerTitle}" iconName="standard:hierarchy" class="slds-card_boundary">
<div class="slds-card__body_inner">
This account has
<aura:if isTrue="{!and(v.hasParent, v.numChildren > 0)}">
a parent and {!v.numChildren} {!v.childOrChildren}.
<aura:set attribute="else">
<aura:if isTrue="{!v.hasParent}">a parent. </aura:if>
<aura:if isTrue="{!v.numChildren > 0}">{!v.numChildren} {!v.childOrChildren}. </aura:if>
</aura:set>
</aura:if>
<a onclick="{!c.navigateToAccountHierarchy}">View the Account Hierarchy</a>.
</div>
</lightning:card>
</aura:if>
</aura:component>
AccountHierarchyController.js (Controller):
({
init : function(component, event, helper) {
helper.checkForParent(component, event, helper);
helper.checkForChildren(component, event, helper);
},
navigateToAccountHierarchy: function(component, event, helper) {
var acctId = component.get('v.recordId');
var evt = $A.get("e.force:navigateToComponent");
evt.setParams({
componentDef: "sfa:hierarchyFullView",
componentAttributes: {
recordId: acctId,
sObjectName: "Account"
}
});
evt.fire();
}
})
AccountHierarchyHelper.js (Helper):
({
checkForParent : function(component, event, helper) {
var action = component.get("c.hasParent");
var acctId = component.get('v.recordId');
action.setParams({"accountId": acctId});
action.setCallback(this, function(response) {
var state = response.getState();
if (state === "SUCCESS") {
var result = response.getReturnValue();
component.set("v.hasParent", result);
}
});
$A.enqueueAction(action);
},
checkForChildren : function(component, event, helper) {
var action = component.get("c.numChildren");
var acctId = component.get('v.recordId');
action.setParams({"accountId": acctId});
action.setCallback(this, function(response) {
var state = response.getState();
if (state === "SUCCESS") {
var result = response.getReturnValue();
component.set("v.numChildren", result);
if(result == 1) {
component.set("v.childOrChildren", "child");
} else {
component.set("v.childOrChildren", "children");
}
}
});
$A.enqueueAction(action);
}
})
AccountHierarchyController.apxc:
public class AccountHierarchyController {
@AuraEnabled
public static Boolean hasParent(String accountId) {
List<Account> listAccounts = [SELECT ParentId FROM Account WHERE Id = :accountId LIMIT 1];
Account acct = listAccounts[0];
return acct.ParentId != null;
}
@AuraEnabled
public static Integer numChildren(String accountId) {
List<Account> listAccounts = [SELECT Id FROM Account WHERE ParentId = :accountId];
return listAccounts.size();
}
}
AccountHierarchyControllerTest.apxc:
@isTest
public class AccountHierarchyControllerTest {
static testMethod void testHasParent() {
Account acct = new Account(Name='Test');
insert acct;
Account acct2 = new Account(Name='Test2');
acct2.ParentId = acct.Id;
insert acct2;
System.assertEquals(AccountHierarchyController.hasParent(acct.Id), False);
System.assertEquals(AccountHierarchyController.hasParent(acct2.Id), True);
}
static testMethod void testNumChildren() {
Account acct = new Account(Name='Test');
insert acct;
Account acct2 = new Account(Name='Test2');
acct2.ParentId = acct.Id;
insert acct2;
System.assertEquals(AccountHierarchyController.numChildren(acct.Id), 1);
System.assertEquals(AccountHierarchyController.numChildren(acct2.Id), 0);
}
}
You may also want to disable Salesforce’s default account hierarchy button. After all, if you have the component, you don’t need a second way to get to the hierarchy page.
Thankfully Salesforce provides a way to turn it off. Here’s what you need to do:
- Click on the gear icon in the upper right and choose Setup
- In the Quick Find box, type in: Account Settings
- On the Account Settings page click on the Edit button
- Click on the checkbox next to: Show View Hierarchy link on account pages
(to be clear: you want the checkbox to be unchecked) - Click on the Save button
Success! No more account hierarchy button. And you now have a fancy new component to use.