Supporting Person Accounts in Your ISV Solution

Mar 27, 2018

by Jaswinder Rattanpal

Wondering how to support Person and Business Accounts in a single package? In this blog, we will talk about Person Accounts, considerations when adding Person Account in managed packages and suggestions on how to include Person and Business Account support in a single managed package without adding a dependency on Person Account.

Overview of the two-part series
  • Supporting Person Accounts in Your ISV Solution
    • Person Accounts considerations when adding Person Account in managed packages and suggestions on how to safely include Person and Business Account support in a single managed package.
  • Building a Managed Package for Person Account
    • How to create a managed package that will support Person Accounts in Financial Services Cloud . This package will be available for orgs with and without Person Account functionality.
What is Person Account?
Salesforce is best known for its leadership position in B2B, but it also offers powerful solutions in B2C and for our customers who sell to individuals. The core feature for using Salesforce to manage B2C relationships is the “Person Account.” This feature has been around for quite a while, and thousands of organizations are using it as a vital part of their customer relationship management strategy.

While standard Accounts are used to store information about companies or organizations, Person Accounts are designed to store the same types of information in situations where the customer target is an individual person. You can think of a Person Account as a hybrid object within your Salesforce Organization that can either behave like an Account or a Contact depending on the situation. When you use Person Accounts, the Account and Contact objects are essentially “married” to represent a B2C customer, allowing you the flexibility to use that record as an account or contact .

Person Account is a enabled as a record type for Account object. Creating a Person or Business Account is as simple as users selecting a record type when creating new account:

User-added image

Let's see how a Person Account is different from a Business Account:

User-added image

Person Account support in Financial Services Cloud and Health Cloud

Salesforce is “all in” to support our customers who sell to individuals. We recognize how important the Person Account feature is, and to that end, with Spring'18, Person Account support has been added to Financial Services Cloud and Health Cloud. Person accounts bring together fields from Account and Contact in a single record to provide a completely streamlined, customizable and simplified user experience. Person Accounts inherits many capabilities, such as
  • Duplicate Management
  • Chatter Follow (single step)
  • Record sharing (single step)
  • Community user creation from UI
Why ISVs Should Embrace Person Accounts
Here the top reasons why ISVs should embrace Person Accounts
  1. Person Account is ideally suited for certain industries which are B2C centric like retail banking, insurance, & healthcare (to name a few- all of which are areas that Salesforce is targeting in their vertical strategy)
  2. Person Account is entrenched in the Salesforce's product DNA. Salesforce continues to invest in augmenting this functionality
  3. Customers can continue to use Person Accounts or stop using them at any point based on their business choice
  4. Financial Services Cloud and Health Cloud now fully support Person Account and encourage use of Person Accounts
  5. You can elegantly design for both Person Account and Business Account potentially increasing your marketability
Read: Myth Busting: Five Common Misconceptions about Person Accounts

What happens when Person Account is enabled?
You can use the following code to test whether Person Accounts are enabled in the org or not.

public Boolean PersonAccountsEnabled()
{
    //Check to see if the Account table contains the field 'isPersonAccount'
    return Schema.sObjectType.Account.fields.getMap().containsKey( 'isPersonAccount' );
}

//OR

public Boolean PersonAccountsEnabled()
{
    //Check to see if the Record Type table contains any Person Account record types
    return Schema.sObjectType.RecordType.fields.getMap().containsKey( 'isPersonType' );
}

When the Person Account feature is enabled, some extra fields are added to the Account object. After you have tested whether Person Account has been enabled, you can check for Account.IsPersonAccount on a record. If true, then this is a Person Account and those fields can be modified. However, if the IsPersonAccount field has the value “false”, then the current record is not a Person Account, and those additional fields have a null value and can't be modified. See this page for more information on which fields are added when the Person Account feature is enabled.

This is how other objects relate to Person Account. This means, if an account is Business Account then these objects will connect separately to Account and Contact as needed. But if an account is Person Account then all these objects will relate to only 1 object as all the information is now in 1 record rather than split across 2 records.

User-added image

Ok, now that we have talked about Person Account, busted some myths, and new fields added when Person Account is enabled, let's talk about how to add support for Person Account in managed packages.

Adding Person Account support in Managed Package
Salesforce partners use managed packages to bundle their application's components together for distribution on the on the AppExchange.

Let's take a quick look at how a developer can add functionality for Person Account in their Apex class.

public with sharing class MyController {
    public PersonAccount getAccount(Id PersonAccountID) {
        //Add CRUD/FLS Check
        return [Select ID, IsPersonAccount, FirstName, LastName from Account where ID=:PersonAccountID];
    }
}

Developers can then use getAccount() to retrieve a Person Account using specified ID. This code will work and can be used in any solution. This solution can be packaged and we can distribute it to customers

However, there are some issues with this approach. Let's talk about these.

Note: A managed package is required to pass the Salesforce security review before it can be distributed on AppExchange. But that is beyond the scope of this article.

Issues? What Issues?
When you add references to Person Account-specific fields in a managed package, that creates a dependency on Person Account.

Therefore, if you try to install your package in an org where Person Account is not enabled then your package will fail to install. Since not all orgs will have Person Account enabled, this is something that might impact who can use your package.

How do we get around this installation dependency?
There are methods to get around this issue that will allow you to support orgs that have both Person and standard Accounts. Some possible solution to this are below:

1. Extension Packages
You can create a base package that will support standard Account object and can be installed in any org. To support Person Account, you can create an extension package that relies on your base package. Any org, where Person Account is enabled, you can install your base and extension packages.

Some advantages to using extension packages are:
  • Be able to use standard SOQL
  • Keep your business logic separate for both features
  • Add more features to Person Account as it grows without impacting base package
  • Include declarative elements (workflows etc) in extension package
Some disadvantages to using extension packages are:
  • You have to go through Security Review for each package
  • You will need to manage both packages separately
2. Dynamic SOQL / Dynamic DML / Dynamic SOSL
Let's assume that you want to process some data based on information in Account/Contact records. You can create separate Apex classes to handle logic for Person and Business Account and use Dynamic SOQL/DML/SOSL based on IsPersonAccount field to decide which Apex class to execute. This will allow you to add logic to support both Business and Person Accounts in the same package.

If you use Dynamic SOQL to query Person Account fields then it will not add a dependency on Person Accounts. You can also use Dynamic DML to manipulate and Dynamic SOSL to search data on Person Account specific fields. This is because Dynamic SOQL/DML/SOSL are not pre-compiled and there is no way to know which object, fields etc are referenced hence no dependency is added

Some advantages to using Dynamic SOQL/DML are:
  • Can use same package to add support for Person and Business Accounts
  • You avoid the separate security review that would be required for an extension package although Dynamic SOQL/DML should be properly tested for SOQL injection
Some disadvantages to using Dynamic SOQL/DML are:
  • Dynamic SOQL and DML are limited to Apex code, so there is no way to create dynamic declarative components like workflows, process builder etc
  • As the package grows, it might become hard to support all Person Account related features in one package without adding dependency
  • Using Dynamic SOQL has a negative impact on performance because these cannot be pre-compiled
How do Financial Services Cloud and Health Cloud support Person Accounts?
When building Person Account support, Financial Services Cloud and Health Cloud follow below architecture in addition to using Dynamic SOQL/SOSL/DML mentioned above:
  • Any declarative features, such as record types or page layouts that refer to Person Accounts, are not packaged, nor are referred to in packaged code. Instead setup of these features are included in the Administrator Guide
  • All if/else conditions in Apex code will check for “Use Person Account” custom setting (which is part of Financial Services Cloud and Health Cloud packages) and Account.IsPersonAccount field
    • Both conditions must be true for Financial Services Cloud and Health Cloud to use the Person Account specific logic in Apex classes, triggers etc
  • No reference is made to any Person Account field (__pc) on the Account object directly in the package
The following is a pseudocode example showing how to test for Person Account in Financial Services Cloud and Health Cloud:

If (Use Person Account is enabled)
    Then if (Account.IsPersonAccount is true)
          Do Person account logic
    Else do business account logic
Else go through individual/business account flows as normal

How do we test our account for Person Account dependency?
Ok, we have discussed Person Accounts, and how to avoid making our package dependent on them. But how can we confirm that we were successful, and didn't inadvertently require our customers to enable Person Accounts before installing our package?

The easiest way is to upload your package in the “Managed-Beta” state, and then try to install it in an org where Person Accounts are not enabled. If you can successfully install your package, then you can be confident that it's not dependent on Person Accounts.

Conclusion
You should build your package to support both Person and Business Accounts. To add support for Person Accounts, you can either use Dynamic SOQL, DML or SOSL in a single package, or you can develop an extension package and move Person Account support to that package. There are advantages and disadvantages to each approach. Evaluate different solutions and pick the ones suitable for your needs as long as you avoid adding a dependency in your base package.

Continue to Part 2 of Supporting Person Accounts in Your ISV Solution

Resources #blog #news