Contacts Related to Multiple Accounts
It is not uncommon to run into situations where a single contact may deal with multiple accounts. Perhaps there is a company with subsidiaries is represented by multiple accounts in Dataverse. Or maybe a subcontracts works for multiple organizations.
By default, Dataverse doesn’t really handle this situation very well. The out-of-the-box parent relationship only allows you to select a single account (or contact). So what can we do to handle this situation?
Generally we have to create our own relationship. A simple answer is to create a many-to-many relationship between the Account and Contact tables, and use that. This makes it simple in Power Pages as well – build all of your Table Permissions off of this new relationship. However, the user will see all of the data for all accounts at the same time. Often we get the requirement that the user should be able to select which account they want view, one at a time.
Account Switcher
When we run into that type of requirement, our solution is often to provide a simple “account switcher” functionality. This allows the user to change, in real time, their parent account.
In this case, we base all of the Power Pages permissions on their parent account. Then, as they switch their parent account, the site is changed to reflect the data for whichever parent account they’ve just chosen.
We still need a custom many-to-many relationship between Account and Contact, however this relationship is used solely to determine which accounts a contact is able to switch between. All of the other permissions, for example, cases or opportunities related to their accounts, are all based on their parent account.
With that new relationship defined, we can build out a simple interface that lists the user’s available accounts, and let’s them change to a different one.
Drop Down of Accounts
While you can build a fancy interface, in this example we are just going to create a simple drop down of the available accounts. To do this, we are going to use Liquid and the <select> element. It looks something like:
{% fetchxml relatedAccounts %}
<fetch>
<entity name="account">
<attribute name="name" />
<attribute name="accountid" />
<link-entity name="nh_contact_account" from="accountid" to="accountid" link-type="inner" intersect="true">
<filter>
<condition attribute="contactid" operator="eq" value="{{user.contactid}}" />
</filter>
</link-entity>
</entity>
</fetch>
{% endfetchxml %}
<select id="accountSwitcher">
{% for acc in relatedAccounts.results.entities %}
<option {% if acc.accountid == user.parentcustomerid.id} -%}selected{% endif %} value="{{acc.accountid}}">{{acc.name}}</option>
{% endfor %}
</select>
In this case, my custom many-to-many relationship is named nh_contact_account. First, I use Liquid to query all of the accounts related to the currently logged in contact by that relationship. Then I use a simple Liquid for loop to create the options in the select element. As an added bonus, I check to see which account is currently set as the parent customer, in order to ensure that it is selected by default.
With this in place, you should get a drop down of all of the related accounts.
Code to Update Parent Account
Now, all we need to do is handle the situation where the user chooses a different option from the drop down. That could look something like:
<script>
$(document).ready(function() {
$('#accountSwitcher').on('change', function() {
var record = {};
record["parentcustomerid_account@odata.bind"] = "/accounts(" + $(this).val() + ")";
webapi.safeAjax({
type: "PATCH",
contentType: "application/json",
url: "/_api/contacts({{user.contactid}})",
data: JSON.stringify(record),
success: function (data, textStatus, xhr) {
console.log("Record updated");
window.location.reload();
},
error: function (xhr, textStatus, errorThrown) {
console.log(xhr);
}
});
});
});
</script>
Note that this code uses the webapi.safeAjax wrapper available here.
This code binds to the change event of our select element. It performs a simple PATCH operation to update the parent account of the contact, and then reloads the page.
The great news is that, since the Web API is hooked into the same caching as the rest of the site, the change to the parent account is reflected immediately after the page reloads.
Don’t Forget!
In order for this all to work, don’t forget that you need to:
- Enable the Web API for the Contact table, and ensure the parentcustomerid_account field is enabled
- Enable Table Permissions to allow contacts to read the accounts related via the new many-to-many relationship
- Enable Table Permissions to allow a contact to update their parent account
This is obviously a very basic implementation. There lots of ways to improve the user experience and interface, but hopefully this is enough to get you started!