I’m sure we’ve all fallen into this issue. When creating new users or updating users in Salesforce, we may or may not remember to add or remove users to certain other permissions in Salesforce, whether it’s assigning a user to a Call Center, permission set or permission set license assignment.
Rather than rely on humans to remember to take action accordingly, why not have Salesforce do it for us? You may be aware that you can automate the permission set assignment/removal from my previous blog postings. But, did you know that you can automate this process and have Salesforce do the work of assigning users to a Call Center, Sales Console User permission set license assignment and Sales Console permission set? How great is that?!
You can assign a user to the Call Center one of two ways, either via the Call Center itself or selecting the Call Center via the Call Center field on the user record. The value is stored in the CallCenterId field on the User record.
You can assign a user to a permission set license assignment via the User record, permission set license assignment related list. This creates a record in the PermissionSetLicenseAssign object with the AssigneeId (which is the userID) and the PermissionSetLicenseId.
You can assign a user to a permission set via the User record, permission set related list. This creates a record in the PermissionSetAssignment object with the AssigneeId (which is the userID) and the PermissionSetId.
While, I’m sure you can accomplish the same via a trigger, we are going to build this process declaratively using automation tools process builder, including an invocable process, and visual workflow.
Here are a few lessons learned from implementing this use case:
- Do not “hardcode” IDs in process builder or flow. If you need to update IDs to make them environment specific, do it outside process builder/flow so you don’t run the situation where you have different versions of the same process builder/flow in different environments.
- Provide descriptions, where provided, in Salesforce. This may be tedious step, I know, but your future self will thank you when you are trying to remember what you configured or assist other/future admins when troubleshooting or enhancing what was built. This includes noting the data stored in a custom field, providing the purpose of a process builder, etc.
Business Use Case: Addison Dogster is the system administrator at Universal Containers. Sally Sunshine is the Sales Manager. Sally mentioned to Addison that she often forgets to have Custom: Sales Profile users added to the Call Center and given the Sales Console when the users are created or transferred onto her team. When Addison reviews the list of users assigned to the Call Center, has the Sales Console User permission set license and the Sales Console permission set, she discovers that there are people assigned to the three that should not.
Solution: Being the #AwesomeAdmin that Addison is, she was able to solution this declaratively with the use of a custom user field to reference the user’s assigned profile, two process builders and a visual workflow to add/remove new and existing users from the Call Center, the Sales Console User permission set license and a permission set with the Sales Console system permission. (Note: You can automate the process to remove users from the Call Center, Sales Console user permission set license, Sales Console permission set via process builder/flow when a user becomes inactive. However, we will not be covering that in this use case solution.)
I broke the process into a “master” and invocable process to limit the number of criteria nodes in the “master” process. While we could have handled everything in the “master” process, I am thinking that this “master” process will grow in your org over time so let’s build it with performance in mind now. By invoking a process, we can consolidate two criteria nodes into one and introduce a simple second layer of if/then statements in an invocable process.
We need to be able to reference the user’s profile in the process, rather than the profileID.
Let me get on my soapbox for a sec or two.
It is worth pointing out that while we can easily “hardcode” ID references in process builder or flow, I do not consider that best practice. Configuration items when created bottom up, are different from sandbox to sandbox and in production. For this reason, every time you deploy the process builder or flow from sandbox to sandbox or to production, you will need to revise the ID in your process builder or flow. The only time all IDs would match (sandboxes and production) is if you refreshed the sandboxes after the process builder or flow is deployed to Production.
My preference is to reference something less likely to change, such as the profile name. However, in process builder, the profile name is not easily accessible. You need to go through the profile ID > name. If you try referencing the profile name when creating a new user, you will get a process builder error that it could not assign the profile name. As a workaround, we are going to create a custom user field with the type formula that will reference the user’s profile’s name.
Quick Steps:
Note: This configuration assumes that the Call Center and a Sales Console permission set have been configured for use in your org, and that there is only one Call Center in use.
1.Create a new custom user field called Profile Name. In Classic setup, navigate to Customize | Users | Fields. In Lightning setup, navigate to Objects and Fields | Object Manager | User | Fields.
Field Label: Profile Name
Data Type: Formula – text
Formula: Profile.Name
Description: Captures the user’s associated profile name
The end result looks like this…
Best practice tips:
- Don’t forget to provide a description so you and other/future admins know what this custom field is used for.
- Set the FLS (field level security) for each profile. Only make the field visible and editable for the profiles that need it. Do not just click the “Next” button when you are on the screen.
- Leave this field off the page layouts since this is a processing field. By default, new fields are added to the page layout.
2. [Precondition: Call Center is already configured in your org.] If there are no users assigned to the Call Center yet, assign one user in your org to the configured call center.
Then, using either Developer Console or Workbench or by performing an extract from the User object via Data Loader, perform the following query:
Select Id, FirstName, LastName, CallCenterId from User
Example: Using Developer Console as the tool to perform the above query, the value in the CallCenterId field is the ID we need to reference to assign users to the call center.
Rather than use hardcoded IDs and avoid having to modify the flow in every region, it’s better to create a custom label to hold the ID for the CallCenterId and you change that value outside of flow to match the CallCenterID in that sandbox or Production.
In Classic setup, go to Create | Custom Labels. In Lightning setup, go to User Interface | Custom Labels. Let’s create the custom label to store the CallCenterId that the flow will reference.
Click on the New button, provide the following information and save:
Short Description: CallCenterID
Categories: ID References (this is so you can organize your custom labels)
Value: <ID of the CallCenterId from your query that you performed>
The end result looks like this…
3. Now, we need to get the ID for the Sales Console User permission set license. Assign the Sales Console User- Permission Set License Assignment to a user.
This is done by selecting a user, go to the Permission Set License Assignments related list and click on the “Edit Assignments” button.
Then, check Sales Console User and save.
Next, using either Developer Console or Workbench or by performing an extract from the PermissionSetLicenseAssign object via Data Loader, perform the following query:
Select AssigneeId, PermissionSetLicenseId from PermissionSetLicenseAssign
Example: Using Developer Console as the tool to perform the above query, the value in the PermissionSetLicenseId field is the ID we need to reference to assign users to the Sales Console User permission set license.
In Classic setup, go to Create | Custom Labels. In Lightning setup, go to User Interface | Custom Labels. Let’s create a custom label to hold the ID for the Sales Console User permission set license assignment that the flow will reference.
Click on the New button, provide the following information and save:
Short Description: Sales Console User Permission Set License Assignment ID
Categories: ID References (this is so you can organize your custom labels)
Value: <ID of the Sales Console User permission set license assignment from your query that you performed>
The end result looks like this…
4. Now, we need to create a visual workflow to handle the assignment/removal of the Call Center and Sales Console User permission set license that will be invoked from process builder.
For those using Salesforce Classic, visual workflows can be found in Create | Workflows & Approvals | Flows. In Lightning Experience, it is found under Process Automation | Flows.
A. First, we will create all the variables we need to reference in our flow. This is done by going to the Resource tab in the Flow Designer and creating a new variable.
This variable will store the value of “Add” or “Remove” that is passed from Process Builder. This will tell flow whether we wish to add or remove the Call Center, Sales Console permission set license and the Access Sales Console permission set to/from the user.
Best practice tips: Don’t forget to provide a description so you and other/future admins know what the variable is used for.
B. Now, we need to create formulas that call the custom labels for the Call Center and the Sales Console User referenced in flow. In the field, you need to navigate to SYSTEM AND GLOBAL VARIABLES > $Label and then select the appropriate custom label.
Best practice tips: Don’t forget to provide a description so you and other/future admins know what the formula does.
The end result looks like this…
C. We want to do a record lookup to see if the user is already assigned to the Call Center. For whatever reason, the CallCenterId field is not exposed in process builder on the User object so I can just pass the value as a variable to flow. The reason why we are doing this is because if the user is already assigned to the Call Center, we will not try and assign it again (this will cause a flow error). We will assign the CallCenterID to the variable varUserCallCenterId if there is a value. If the CallCenterId field is blank, a null value will be assigned.
Name: Lookup whether user has an associated CallCenterId
Description: Lookup user to see if the user is assigned to the Call Center
Look up: User
Field: Id equals {!varUserID}
Assign the record fields to variables to reference them in flow: CallCenterId {!varUserCallCenterid}
Assign null values to the variables(s) if no records are found: Checked
Best practice tips: Don’t forget to provide a description so you and other/future admins know what this record lookup is used for.
The end result looks like this…
D. We want to do a record lookup to see if the user is already assigned to the Sales Console User permission set license. The reason why we are doing this is because if the user is already assigned to the Sales Console user permission set license, we will not try and assign it again (this will cause a flow error). We will assign the PermissionSetLicenseId to the variable {!varUserHasSalesConsolePermSetLicense} if there is a value. If the Sales Console User permission set license is not assigned to the user, a null value will be assigned to the variable.
Name: Lookup whether user has Sales Console User perm set license
Description: Lookup user to see if the user is assigned to the Sales Console User permission set license
Look up: PermissionSetLicenseAssign
Field:
AssigneeId equals {!varUserID}
PermissionSetLicenseId equals {!SalesConsoleUserPermissionSetLicenseFormula} (Note: This pulls the custom label that stores the Sales Console User permission set license ID.)
Assign the record fields to variables to reference them in flow: PermissionSetLicenseId {!varUserHasSalesConsolePermSetLicense}
Assign null values to the variables(s) if no records are found: Checked
Best practice tips: Don’t forget to provide a description so you and other/future admins know what this record lookup is used for.
The end result looks like this…
E. Now, we need to perform a record lookup of the Permission Set ID for your configured Sales Console permission set using the permission set’s API Name. Ours is called “Access_to_Sales_Console.” Then we will take the ID and store it in the variable varPermissionSetID.
Name: Lookup Perm Set ID
Description: Lookup permission set ID for the Access Sales Console
Lookup: PermissionSet
Field: Name equals Access_Sales_Console
Where we will assign the ID to the variable varPermissionSetID
Assign null values to the variable(s) if no records are found: Checked
Best practice tips: Don’t forget to provide a description so you and other/future admins know what this record lookup is used for.
The end result looks like this…
F. We are going to perform another record lookup to see if the user has the Access Sales Console permission set. We are going to perform a query on the PermissionSetAssignment object where the AssigneeId is the User’s ID and the PermissionSetId field matches the Access Sales Console permission set ID we looked up previously. If it finds a value, we will take the PermissionSetId (it can be any vvalue from the record, it doesn’t matter) and store it in the variable varUserHasPermissionSet. If Salesforce could not find a record, this means that the user is not assigned the permission set. In this case, we want to save a null value to the variable varUserHasPermissionSet.
Best practice tips: Don’t forget to provide a description so you and other/future admins know what this record lookup is used for.
The end result looks like this…
G. Now, we need to have the flow make a decision and see what action to take for the Call Center ID.
For the “Add CallCenterId” outcome, we are looking for the varFlowAction = “Add”, which was passed from process builder. However, we only want to assign the CallCenterId only if the user IS NOT already associated to a CallCenterId. In this case, our only choice is to use the “is null” operator so we have to set it to the variable varUserCallCenterId is null {!GlobalConstant.True}, meaning that the variable does not have a value or is null.
For the “Remove CallCenterId” outcome, we are looking for the varFlowAction = “Remove”, which was passed from process builder. However, we only want to remove the CallCenterId only if the user IS already associated to a CallCenterId. In this case, our only choice is to use the “is null” operator so we have to set it to the variable varUserCallCenterId is null {!GlobalConstant.False}, meaning that the variable does has a value.
Best practice tips: Don’t forget to provide a description so you and other/future admins know what this decision does.
Configure to match the screenshot below…
H. For the “Add” decision outcome, we will perform a record update called Add User to the Call Center where we update the record in the User object where the Id equals the variable varUserId passed from process builder with the value from our formula CallCenterIDFormula (i.e. this is the calling the Call Center Id custom label we created a while back) and update the field CallCenterId.
Best practice tips: Don’t forget to provide a description so you and other/future admins know what this record update does.
Your configuration should look like this…
I. For the “Remove” decision outcome, we will perform a record update called Remove User to the Call Center where we update the record in the User object where the Id equals the variable varUserId passed from process builder, where we update the field CallCenterId to blank (i.e. $Global.Constant.EmptyString).
Best practice tips: Don’t forget to provide a description so you and other/future admins know what this record update does.
Your configuration should look like this…
J. Now, we need to have the flow make a decision and see what action to take for the Sales Console User permission set license.
For the “Add Sales Console User” outcome, we are looking for the varFlowAction = “Add”, which was passed from process builder. However, we only want to assign the Sales Console User permission set license only if the user IS NOT already associated to a Sales Console User permission set license. In this case, our only choice is to use the “is null” operator so we have to set it to the variable varUserHasSalesConsolePermSetLicense is null {!GlobalConstant.True}, meaning that the variable does not have a value or is null.
For the “Remove Sales Console User” outcome, we are looking for the varFlowAction = “Remove”, which was passed from process builder. However, we only want to remove the Sales Console User permission set license only if the user IS already associated to a Sales Console User permission set license. In this case, our only choice is to use the “is null” operator so we have to set it to the variable varUserHasSalesConsolePermSetLicense is null {!GlobalConstant.False}, meaning that the variable does has a value.
Best practice tips: Don’t forget to provide a description so you and other/future admins know what this decision does.
Configure to match the screenshot below…
K. For the “Add” decision outcome, we will perform a record create called Add Sales Console User Permission Set License where we will create the record in the PermissionSetLicenseAssign object where the AssigneeId equals the variable varUserId passed from process builder and the PermissionSetLicenseId equals the variable SalesConsoleUserPermissionSetLicenseFormula (i.e. This calls the custom label created to hold the ID of the Sales Console User Permission Set License.
Best practice tips: Don’t forget to provide a description so you and other/future admins know what this record create does.
Your configuration should look like this…
L.For the “Remove” decision outcome, we will perform a record delete called Remove Sales Console User Permission Set License where we delete the record in the PermissionSetLicenseAssign object where the AssigneeId equals the variable varUserId passed from process builder and the PermissionSetLicenseId equals the variable SalesConsoleUserPermissionSetLicenseFormula.
Best practice tips: Don’t forget to provide a description so you and other/future admins know what this record delete is for.
Your configuration should look like this…
M. Now, we need to perform our last decision and see what action to take for the Access Sales Console permission set.
For the “Add Access to Sales Console Perm Set” outcome, we are looking for the varFlowAction = “Add”, which was passed from process builder. However, we only want to assign the Access to Sales Console permission set only if the user IS NOT already associated to the Access to Sales Console permission set. In this case, our only choice is to use the “is null” operator so we have to set it to the variable varUserHasPermissionSet is null {!GlobalConstant.True}, meaning that the variable does not have a value or is null.
For the “Remove Access to Sales Console Permission Set” outcome, we are looking for the varFlowAction = “Remove”, which was passed from process builder. However, we only want to remove the Access to Sales Console permission set only if the user IS already associated to the Access to Sales Console User permission set license. In this case, our only choice is to use the “is null” operator so we have to set it to the variable varUserHasSalesConsolePermSetLicense is null {!GlobalConstant.False}, meaning that the variable does has a value.
Best practice tips: Don’t forget to provide a description so you and other/future admins know what this decision does.
Configure to match the screenshot below…
N. For the “Add” decision outcome, we will perform a record create called Add Access to Sales Console Permission Set where we will create the record in the PermissionSetAssignment object where the AssigneeId equals the variable varUserId passed from process builder and the PermissionSetId equals the variable varPermissionSetID.
Best practice tips: Don’t forget to provide a description so you and other/future admins know what this record create does.
Your configuration should look like this…
O. For the “Remove” decision outcome, we will perform a record delete called Remove Access to Sales Console Permission Set where we delete the record in the PermissionSetAssignment object where the AssigneeId equals the variable varUserId passed from process builder and the PermissionSetId equals the variable varPermissionSetID.
Best practice tips: Don’t forget to provide a description so you and other/future admins know what this record delete is for.
Your configuration should look like this…
P. Add the subflow Send Flow Fault Email. For instructions on how to create this, go to Step 2 of blog post: Maximize Maintainability With Process Builder and Componentized Visual Workflow.
Q. Set your flow starting point. And connect the flow elements and the fault connectors to match the below…
Can’t seem to get the fault connector to appear? Create a temporary flow element (circled below), draw your first connector to that temporary flow element. Then, draw another connector to the send element. This connector has the word “FAULT” in it.
Once that is completed, delete the temporary flow element you created. This is the end result.
R. Save as and provide the following properties.
Best practice tip: Provide a description so you and other/future admins know what this flow element is used for.
S. Click the “Close” button.
T. On the flows screen, activate the flow.
5. As noted above, we have an invocable process and a “master” process. We need to first create the invocable process that the “master” process will invoke.
For those using Salesforce Classic, process builder can be found in Create | Workflows & Approvals | Process Builder. In Lightning Experience, it is found under Process Automation | Process Builder.
A. Provide following information for the new process and save:
Process Name: Profile Changes
Description: Execute process when there are profile changes
The process starts when: It’s invoked by another process
Best practice tips: Don’t forget to provide a description so you and other/future admins know what this custom field is used for.
The end result looks like this…
B. Select “User” as the object and save:
C. Specify the first criteria node:
Criteria Name: Custom: Sales Profile
Criteria for Executing Actions:Conditions are met
Field: [User].Profile_Name__c Equals String Custom: Sales Profile
Conditions: All of the conditions are met (AND)
The end result looks like this…
Now, we select the immediate action to invoke a flow.
Action Type: Flows
Action Name: InvokeFlow
Flow: Assign/Remove User To/From Call Center and Sales Console User Perm Set
Set Flow Variables:
varUserID Reference [User].Id
varFlowAction String Add (The “Add” value will tell the flow to add the CallCenterId, Sales Console User permission set license and the Access to Sales Console permission set to the user.)
The end result looks like this…
D. Specify the second criteria node:
Criteria Name: Not Custom: Sales Profile
Criteria for Executing Actions:Conditions are met
Field: [User].Profile_Name__c Does not equal String Custom: Sales Profile
Conditions: All of the conditions are met (AND)
The end result looks like this…
Now, we select the immediate action to invoke a flow.
Action Type: Flows
Action Name: InvokeFlow
Flow: Assign/Remove User To/From Call Center and Sales Console User Perm Set
Set Flow Variables:
varUserID Reference [User].Id
varFlowAction String Remove (The “Remove” value will tell the flow to add the CallCenterId, Sales Console User permission set license and the Access to Sales Console permission set to the user.)
The end result looks like this…
G. Lastly, activate the process by clicking on the “Activate” button.
6. Lastly, we need to create the “master” process builder – Take Action on New or Existing Users.
For those using Salesforce Classic, process builder can be found in Create | Workflows & Approvals | Process Builder. In Lightning Experience, it is found under Process Automation | Process Builder.
A. Provide following information for the new process and save:
Process Name: Take Action on New or Existing Users
Description: Process for new or changes to existing user records
The process starts when: A record changes
Best practice tips: Don’t forget to provide a description so you and other/future admins know what this custom field is used for.
The end result looks like this…
B. Select “User” as the object, select “when a record is created or edited” and save:
C. Specify the first criteria node:
Criteria Name: New User or Profile Changes
Criteria for Executing Actions: Formula evaluates to true (We need to select formula as that is the only way to use the IsNew() syntax.)
Formula: ISNEW() || ISCHANGED([User].ProfileId) (This says the record is new or the user’s profile changed)
The end result looks like this…
Now, we select the immediate action to invoke a process.
Action Type: Processes
Action Name: InvokeProcess-ProfileChanges
Set Process Variables: SObject Reference [User] (Note: On the Select a Field screen, select “Select the User record that started the process.”)
The end result looks like this…
D. Lastly, activate the process by clicking on the “Activate” button.
Congrats, you powered through it and made it to the end! You’ve implemented a process to automatically assign or remove a user from a call center and sales console permission set license assignment.
Now, before you deploy the changes to Production, don’t forget to test your configuration changes.
- Create a new user assigned to the Custom: Sales Profile.
- Confirm that the user is assigned to the Call Center, Sales Console User permission set license and Access to Sales Console permission set.
- Create a new user not assigned to the Custom: Sales Profile.
- Confirm that the user is not assigned to the Call Center, Sales Console User permission set license and Access to Sales Console permission set.
- Change an existing user to the Custom: Sales Profile.
- Confirm that the user is assigned to the Call Center, Sales Console User permission set license and Access to Sales Console permission set.
- Change an existing user to a profile that is not the Custom: Sales Profile.
- Confirm that the user is not assigned to the Call Center, Sales Console User permission set license and Access to Sales Console permission set.
- Assign an existing user who is not Custom: Sales Profile manually to the Call Center and/or Sales Console User permission set license and/or Access to Sales Console permission set. Update the user to the Custom: Sales Profile.
- Confirm that the user is still assigned to the Call Center, Sales Console User permission set license and Access to Sales Console permission set.
Deployment Notes/Tips:
- The new custom field, custom labels, process builders and visual workflow can be deployed to Production in a change set (or can be deployed using a tool such as Dreamfactory’s Snapshot).
- The field level security for the custom user field will need to be manually updated post deployment. I would caution against adding the related profiles in the changeset for deployment as the results of deploying a profile are not reliable. If you have a tool like Snapshot by Dreamfactory, you can use the tool to deploy field permissions.
- Activate the process builders and visual workflow as they are deployed as inactive into Production.
That’s an awesome blog Jennifer, really admire you for this.
LikeLike
Awe, thank you for that. It means a lot.
LikeLike