Skip to content

Jenwlee's Salesforce Blog

Sharing my love for Salesforce with my #Ohana

  • How To
  • Salesforce Release
    • Summer ’21 Release Highlights
    • Spring ’21 Release Highlights
    • Winter ’21 Release Highlights
    • Summer ’20 Release Highlights
    • Spring ’20 Release Highlights
    • Winter ’20 Release Highlights
    • Summer ’19 Release Highlights
    • Spring ’19 Release Highlights
    • Winter ’19 Release Highlights
    • Summer ’18 Release Highlights
    • Spring ’18 Release Highlights
    • Winter ’18 Release Highlights
    • Summer ’17 Release Highlights
  • Certification
    • How I Studied for the Platform Developer I (Beta) Exam
    • How I Studied for the Sales Cloud Consultant Certification Exam
    • How I Studied for the Sharing & Visibility Designer Exam
    • How I Studied for the Data Architecture and Management Designer Exam
    • How I Studied for the Salesforce Platform App Builder Certification Exam
    • Salesforce Administrator Exam Preparation & Exam Taking Strategy
    • How I Studied for the Salesforce Advanced Administrator Certification Exam
  • Salesforce Events
  • Trailhead
  • About Me
  • Meet Jen Lee
How To

Automate the Assignment/Removal of MapAnything License and User Settings Based on User Role

June 20, 2017May 23, 2021 jenwlee

MapAnythingFeatureImage

Shoutout2I want to give a shout out to Bryan James, developer at MapAnything, for assistance on identifying the MapAnything customized user settings.

Thank you for your help, Bryan!

You’re the best!

Here are a few lessons learned from implementing this use case:

  • Learn how to automate package license assignment or removal on other criteria that is different from the user’s profile.
  • Learn how to invoke flow from process builder.
  • Use custom metadata type for reference purposes in flow.
  • 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 variables, the purpose of a flow, what each flow element does, etc.

For those who do not know what MapAnything is, MapAnything is available on the AppExchange.

MapAnything is a tool that helps you map your Salesforce data. MapAnything provides territory management, route planning & optimization, lead generation, and reporting through a real-time, interactive map of your Salesforce data.

 

Business Use Case:  Addison Dogster is the system administrator at Universal Containers. Steven Moon is the Director of Sales. Access requests are sent into Addison’s queue to assign or remove a MapAnything license from a user based on the user’s role (only if they belong to the Eastern Sales Team and Western Sales Team roles). Addison also needs to give users the ability to export MapAnything reports and give them access to a Jen Button as well as some other settings.

All of this is done manually and as we all know, when things are manual, manual steps can be missed. Steven asked Addison whether there was a way to automate this process.

Note: MapAnything can be automatically assigned/removed from the user based on the user’s profile. However, it does not provide the automation by user role.

License assignment and removal is handled via the Manage Licenses link in the Installed Packages screen for MapAnything.

MapAnythingInstalledPackage.GIF

When you click on the Manage Licenses link, you can add or remove users accordingly.

MapAnythingLicenses.GIF

There are also additional user permissions that are manually configured via the Configure link. For example, in Universal containers, there is a “Jen Button” button set that needs to be added and the permission to Export Reports.

MapAnythingButtonSet.GIF

MapAnythingSettings.GIF

Solution: Being the #AwesomeAdmin that Addison is, she was able to solution this declaratively using a custom field, process builder, flow and custom metadata type. The custom metadata type will be used to manage the MapAnything role assignments so that as they change over time, you can manage the setting in the custom metadata type records and not touch the flow.

To locate the MapAnything user permissions that you set via the Configure | Permissions screen to automate in your process, extract the user records using data loader and look for the fields named “sma_xxxx”. Then in your flow, set those fields to your specific settings accordingly.

In our scenario, we care about the settings in the two fields highlighted below.

UserExtract.GIF

ProcessBuilder-TakeActiononUser.GIF

Flow-AddAnAgreementToAnOpp.gif

For those who have not yet used custom metadata types, you DO NOT know what you are missing!

Custom metadata is customizable, deployable, packageable, and upgradeable application metadata. First, you create a custom metadata type, which defines the form of the application metadata. Then you build reusable functionality that determines the behavior based on metadata of that type. Similar to a custom object or custom setting, a custom metadata type has a list of custom fields that represent aspects of the metadata.

The best part is that the data records associated to a custom metadata type is METADATA! Why is this huge? This means that like configuration and code, after a sandbox refresh or a sandbox creation, the data records stay from Production! This means that like configuration and code, it is deployable via changesets, Dreamfactory’s Snapshot, Eclipse, etc.

Quick Steps: 

 

1. Create a custom formula field on the User Object called “Role.” This will hold the Role’s API name for use in process builder.

In Classic, go to Customize | User | Fields. In Lightning, you can find it under Object Manager | User  | Fields. When in doubt, use the Quick Find to search.

In the formula field, we will use the syntax: UserRole.DeveloperName

UserObject-Role.GIF

2. We need to first create custom metadata type to store the roles that should receive a MapAnything license.

In Classic, Custom Metadata Types is found under Develop | Custom Metadata Types. In Lightning, you can find it under Custom Code | Custom Metadata Types. When in doubt, use the Quick Find to search.

Click on the “New” button. Provide the label, plural label and the object name. We are going to call it “MapAnything Role Assignment.”

CMT-MapAnythingRoleAssignment.GIF

Click on the “Manage” button to create the data records for the custom metadata type.

CMT-MapAnythingRoleAssignment-Button.GIF

For the Label, we will use the label from the role record and for the MapAnything Role Assignment Name, we will use the role name, which is the API name.

Role.GIF

The resulting CMT record should look like this.

CMT-MapAnythingRoleAssignment-RoleRecord.GIF

 

3. Let’s create a visual workflow to handle the assignment and removal of the MapAnything package license and additional user settings.

Flow-AddAnAgreementToAnOpp.gif

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. Let’s create our flow resources upfront.

This constant will store the MapAnything Settings information in the value field.

MapAnythingSettingsConstant.GIF

This variable will store the value from the user custom field Role created in Step 1 passed from process builder.

varRole.GIF

This variable stores the user’s ID passed from process builder.

varUserId.GIF

This variable stores whether the user’s role is a MapAnything Role. If this variable has a value, then the user’s role is a MapAnything Role.

varRoleisMapAnything.GIF

This variable contains the package namespace prefix to lookup the package license ID.

varPackageNamespacePrefix.GIF

This variable contains the MapAnything License ID for use in assigning or removing the license.

varPackageLicenseID.GIF

This variable stores whether the user already has a MapAnything package license. If this variable has a value, then the user already has the MapAnything license.

varUserHasPackageLicense.GIF

B. Let’s lookup the user’s role in the MapAnything Role Assignment custom metadata type using the Record Lookup flow element on the MapAnything Role Assignment object using the DeveloperName (which is MapAnything Role Assignment Name) equals the variable varRoleName that we will pass from process builder.

Best practice tip: Don’t forget to provide a description so you and other/future admins know what this record lookup is used for.

Flow-AutomateMapAnything-RecordLookup.GIF

C. Now, let’s create a Decision flow element to determine whether the user’s role is a defined MapAnything Role. We will set the outcome to be the MapAnything Role where the variable varRoleIsMapAnything has a value or as a condition is varRoleIsMapAnything is null false. Let’s set the default outcome as “Not a MapAnything Role.”

Best practice tip: Don’t forget to provide a description so you and other/future admins know what this decision is used for.

Flow-AutomateMapAnything-Decision.GIF

D. Next, we will create a Record Lookup flow element that will lookup the Package License object using the Namespace Prefix field equals the variable varPackageNamespacePrefix passed from process builder for the MapAnything package license ID to store as variable varPackageLicenseID.

Best practice tip: Don’t forget to provide a description so you and other/future admins know what this record lookup is used for.

Flow-AutomateMapAnything-RecordLookupLicenseID.GIF

E. Let’s create another Record Lookup flow element that will lookup the UserPackageLicense object with the PackageLicenseId as the variable varPackageLicenseID and the UserId as the variable varUserID. If it finds that record, this means the user is already assigned to the license. We will take the PackageLicenseID value and store it in the variable varUserHasPackageLicense. If no record exists, then the variable varUserHasPackageLicense will be empty.

Best practice tip: Don’t forget to provide a description so you and other/future admins know what this record lookup is used for.

Flow-AutomateMapAnything-RecordLookupUserLicense.GIF

F. Now, let’s create a Decision flow element to determine whether the user already has the MapAnything license. If the user already has the license, we do not want to try and assign the license to the user again or else, Salesforce will fault the flow as it cannot assign a duplicate MapAnything license. We will set the outcome to be Package License User where the variable varUserHasPackageLicense has a value or as a condition is varUserHasPackageLicense is null false. Let’s set the default outcome as “Not a Package License.”

Best practice tip: Don’t forget to provide a description so you and other/future admins know what this decision is used for.

Flow-AutomateMapAnything-DecisionUserPackageLicense.GIF

G. Now, we will create a Record Create flow element to create the UserPackageLicense record – essentially, assign the MapAnything package license to the user where the PackageLicenseId is the variable varPackageLicenseID and the UserId is the variable varUserID.

Best practice tip: Don’t forget to provide a description so you and other/future admins know what this record create is used for.

Flow-AutomateMapAnything-RecordCreate.GIF

H. We now need to update the user record using a Record Update flow element with the additional MapAnything user settings that can be manually configured via the MapAnything Configure | Permissions screen. In our scenario, we will automatically set the Export Reports permission and set the MapAnything settings (JSON) to the additional settings.

So, we will first find the user record where the Id equals the variable varUserID and then we will update the sma__AllowMapAnythingExports__c field to true and the sma__MapAnythingSettings__c to our constants MapAnythingSettingsConstant.

Best practice tip: Don’t forget to provide a description so you and other/future admins know what this record update is used for.

Flow-AutomateMapAnything-RecordUpdate.GIF

I. Copy Steps D, E and F.

Ideally, you would create these three flow elements as its own flow so you are following the DRY (“Don’t Repeat Yourself”) principle. For more information on how to reference subflows, read my previous blog post “Maximize Maintainability With Process Builder and Componentized Visual Workflow.”

But, here, to keep it simple, we will copy another version of these steps in this same flow.

It’s easy to copy and paste. Follow the animated gif.

Flow-AddAnAgreementToAnOpp-CopyPaste.gif

J. We need to create a Record Delete flow element to remove the MapAnything License from the user as it should no longer need the license if the user’s role is not a MapAnything defined role. We need to find the record in the UserPackageLicense object where the PackageLicenseId is the variable varPackageLicenseID and the UserId is the variable varUserID.

Best practice tip: Don’t forget to provide a description so you and other/future admins know what this record update is used for.

Flow-AutomateMapAnything-RecordDelete.GIF

K. Lastly, using a Record Update flow element, if the user should not have the MapAnything license, then we should also remove the additional MapAnything user settings that can be manually configured via the MapAnything Configure | Permissions screen. In our scenario, we will automatically set the Export Reports permission to false and clear out the MapAnything settings (JSON) to the additional settings.

So, we will first find the user record where the Id equals the variable varUserID and then we will update the sma__AllowMapAnythingExports__c field to false and the sma__MapAnythingSettings__c to $GlobalConstant.EmptyString.

Best practice tip: Don’t forget to provide a description so you and other/future admins know what this record update is used for.

Flow-AutomateMapAnything-RecordUpdateRemove.GIF

L. 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.

Flow-AddAnAgreementToAnOpp-Fault.gif

M. Set your flow starting point. And connect the flow elements and the fault connectors to match the below…

Flow-AddAnAgreementToAnOpp-Connectors.GIF

N. 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.

Flow-AutomateMapAnything-FlowProperties.GIF

O. Click the “Close” button.

P. On the flows screen, activate the flow.

Flow-AddAnAgreementToAnOpp-Activate.gif

4. Lastly, we need to create the process builder that will execute the process upon user creation or changes to the user’s role which will then invoke the flow we created in Step 3.

ProcessBuilder-TakeActiononUser.GIF

Create a process builder (Create | Workflows & Approvals | Process Builder in Salesforce Classic or Process Automation | Process Builder in Lightning Experience).

A. Set the process builder properties. We will call this process “Take Action on a New/Existing User”, provide it a description and select this process to start when “A record changes.”

PB-TakeActiononUser-Properties.GIF

Best practice tips: Don’t forget to provide a description so you and other/future admins know what this process is used for.

B. We need to select “User” as the object and we want our process to run when a record is created or edited, click the “Save” button.

PB-TakeActiononUser-Object.GIF

C. We need to specify the criteria node that needs to be met to then execute the flow. Let’s call out criteria “New or Change in Role” which will execute when “Formula evaluates to true” where the user record is new or the user’s role has change.

The syntax to use is “ISNEW() || ISCHANGED([User].UserRoleId)”

PB-TakeActiononUser-CriteriaNode.GIF

D. Next, we want to set the immediate action to invoke the flow created in Step 3.

Set the immediate action to the below.

  • Action Type: Flows
  • Action Name: InvokeFlow
  • Flow: Assign/Remove User from MapAnything
  • Set the flow variables to the following:
    • varUserID Reference [User].Id
    • varPackageNamespacePrefix String sma
    • varRoleName Reference [User].Role__c

Save the immediate action.

The end result looks like this…

PB-TakeActionOnUser-InvokeFlow.gif

E. Click on the “Activate” button to activate the process.

PB-TakeActiononUser-Activate.GIF

Here are the animated steps:

PB-TakeActionOnUser.gif

Congrats, you made it to the end! You’ve implemented a process to automatically assign or remove a MapAnything license and settings to/from a user based on the user’s role.

Now, before you deploy the changes to Production, don’t forget to test your configuration changes.

  1. Create a new user where the role matches that in the MapAnything Role Assignment custom metadata type.
  2. Confirm that the user has the MapAnything License and the updated MapAnything user permissions.
  3. Create a new user with a role that is not in the MapAnything Role Assignment custom metadata type.
  4. Confirm that user DOES NOT HAVE the MapAnything License and the updated MapAnything user permissions.
  5. Repeat above steps with an existing user.

Deployment Notes/Tips:

  • The process builder, flow, custom user field, custom metadata type and CMT associated records can be deployed to Production in a change set (or can be deployed using a tool such as Dreamfactory’s Snapshot).
  • You will find the custom metadata type information under the Custom Metadata Type in the Component Type dropdown. However, locate the data record for the custom metadata types by looking for the custom metadata type name in the Component Types dropdown.
  • Don’t forget to set FLS on the profile for the custom user field Role.
  • You will find the process builder and flow component in a change set under the Flow Definition component type.
  • Activate process builder and flow as they are deployed as inactive in Production.

 

Share this:

  • Tweet

Like this:

Like Loading...

Related

Share this:

  • Tweet

Like this:

Like Loading...
Custom Metadata Type Flow MapAnything Process Automation Salesforce visual workflow

Post navigation

Previous Post NYC/Boston World Tours: My Company Just Purchased Salesforce. Now What?
Next Post Log an Email Sent via Email Alert to the Activity History

Enter your email address to follow this blog and receive notifications of new posts by email.

Join 12,838 other subscribers

Check out my previous posts

About the Author

Native Bostonian. 4x Salesforce MVP, Dreamforce 16-19 presenter & other Salesforce and community hosted events, 8x Salesforce Certified (Salesforce Application Architech, Salesforce Administrator, Advanced Administrator, Platform App Builder, Sales Cloud Consultant, Security and Visibility Designer, Data Management and Architecture Designer, Platform Developer I), co-host of Automation Hour, Salesforce enthusiast and blogger, Trailhead addict (8x Ranger!), #LifeWithGoldie, and Lightning Champion.

Named Salesforce MVP on 7/29/16

Trailblazer!

Salesforce Trailblazer post published on 8/16/17.

#AwesomeAdmin Award Recipient

I am so truly honored to be the recipient of Salesforce's #AwesomeAdmin Award at the 2016 Boston Salesforce World Tour.

1/14/16 Girly Geek of the Week

My Tweets
Website Powered by WordPress.com.
  • Follow Following
    • Jenwlee's Salesforce Blog
    • Join 1,676 other followers
    • Already have a WordPress.com account? Log in now.
    • Jenwlee's Salesforce Blog
    • Customize
    • Follow Following
    • Sign up
    • Log in
    • Copy shortlink
    • Report this content
    • View post in Reader
    • Manage subscriptions
    • Collapse this bar
 

Loading Comments...
 

    %d bloggers like this:
      %d bloggers like this: