Opportunity Contact Roles with Process Builder and Flow
Lookup fields and related lists can get a bit tricky, especially if you have a complex business process where you capture several lookups from one object to another. In this case, we are tackling several lookups on Opportunity to the Contact object, each of which has its own purpose. If we continue to add lookups, we continue to have related lists, which can have negative side effects. Imagine a scenario where we have 3 contact lookups on Opportunity, and thus our contact page layouts have 3 separate opportunity related lists… no bueno.
Opportunity Contact Roles is a great object to leverage, and it helps consolidate to a single related list when viewing a Contact, but we need to push the data into this object. To assist with usability, we can use a combination of Process Builder and Flow to create, update, or delete records that appear in OpportunityContactRoles based on contact lookup fields changing on the Opportunity record.
This is a variation from Judi Sohn's blog post in April, which outlines a use case for pushing data from Opportunity to OpportunityContactRole, and from OpportunityContactRole to Opportunity. The examples shown for the former case do not handle a use case where the lookup field changes from A to B, and then back to A, as this can create multiple OpportunityContactRole records for the same contact and opportunity pair.
Process Builder
Our first step is to create a new process that runs on the Opportunity object whenever it is created or edited. For this example, we want to have the Decision Maker lookup field create or update a contact role with Primary = True, and Role = Decision Maker.
Our criteria step will check to see that the Opportunity Decision Maker field does not equal a global constant, and that global constant's value is null. Below are screenshots of the object and criteria steps.
Flow
Our first step is to check whether there is an existing contact role, as it prevents us from creating duplicate data that links a contact to the opportunity. This step requires us to assign the OpportunityId and ContactId to variables. Creating these variables is relatively simple, as we click on the down arrow for the fields appearing in the Value column, select Create New > Variable. Our variables have a Data Type of Text, and Input/Output Type as Input and Output.
We will also want to assign the Id field of the OpportunityContactRole record to a variable (same types as above), and check "Assign null values...", as we'll use this to determine whether a record exists in our decision step. After saving this step, hover over the small green icon in the top right to set this as the start of our flow.
Our decision step has a single "editable outcome" and a default outcome, where the former is the case where the OpportunityContactRole's ID variable is null (i.e. we didn't find a record for that combination of Contact, Opportunity, and the role of Decision Maker).
For our "null" condition, where an OpportunityContactRole does not exist, we will want to use a Record Create step to create a new record. We can map the contact ID and opportunity ID variables that we used in our first step to accomplish this.
For our "not null" condition, where an OpportunityContactRole does exist already, we will want to use a Record Update step. This record update will find the record based on the contact ID and opportunity ID, and then set the IsPrimary field to true (the checkbox that we see on the related list).
You will need to save and close the flow we created, and click on the Activate link that appears next to your version.
Back to Process Builder
Process Builder can call our flow as an immediate action. We'll add this action with a type of Flows, and select the auto-launched flow that we just created. If the flow does not appear, it is likely because the flow has not been activated. We'll set two of our flow variables to the contact lookup field and the opportunity's ID, and activate our process.
Testing and Deploying
To test this effectively, create a new opportunity with the Decision Maker field populated, and another opportunity with the field not populated. Ensure that you can change the field from one contact to another contact, and that the Contact Roles list changes appropriately based on your actions. Also try editing the opportunity and nulling the field, ensuring that no errors occur. Alternatively, you can write test classes to assert that the various results that occur are expected, something that was suggested by Luke Cushanick at a recent NYC Dev User Group.
Have you made a similar process, or used a combination of Process Builder and Flow that you’d like to share? We’d love to hear about it @RogerMitchell, or in a comment on our Facebook page or on the Success Community.