Sonoma Partners Microsoft CRM and Salesforce Blog

Some Assembly Required – Unmanaged Solution Gotchas

In Microsoft Dynamics CRM 2011, you can use solutions to bundle and export customizations from one environment into a different Microsoft CRM system (perfect for moving from development to QA to production). You might assume that exporting the solutions from one system to another would provide a perfect duplicate of the original environment. However this is not always the case! We have found a few gotchas regarding importing solutions that I wanted to share. Specifically:

  • Audit Settings
  • View Status
  • Default Views and Dashboards

Let’s explore each of these in more detail.

Audit Settings

During the export process of a solution, you can now select which system settings you want to migrate between the two environments.

 01 - Export System Settings

This flexibility to pick and choose is excellent. However, if you carefully compare the full list of System Settings to which settings you can export, you will notice that some of the options (such as Auditing) are missing: 

02 - System Settings 

What we found is that the Enable Auditing in the following areas checkboxes are transferred from one environment to another, without needing to select any of the system settings for export. However, the Start Auditing is not. When documenting the steps to perform a deployment, make sure that manually checking this important box if you are performing auditing on any of your entities is one of those steps.

 

View Status

A new feature with Microsoft Dynamics CRM 2011 is the ability to deactivate views. For example, I have customers who do not use Campaigns so the native Accounts: No Campaign Activities in the Last 3 Months view is irrelevant. To remove confusion for those end users, I simply deactivate this view. To do this, simply select the view you want to remove from the user interface and select Deactivate. As always, don’t forget to publish.

03 - Deactivate View 

However what we found is that when you import solution into a target system, the deactivated views do NOT remain deactivated within the destination environment. Therefore, if you want to hide these views from the users, you will need to go into the target system and manually deactivate the views again (bummer). If you're writing up deployment notes, please remember to include this step!

 

Default Views and Dashboards

Microsoft Dynamics CRM allows administrators to specify the Default Views and Dashboards that users see when they navigate to a specific part of CRM. Unfortunately, similar to the inactive views gotcha we just explained, the default settings on views and dashboards do not import into new environments as you might exepect them to. Let's explain in a little more detail.

First, let’s look at what happens when you change default views on entities. In my example, I changed the default view on the Account entity in my development environment to Accounts: No Campaign Activities in the Last 3 Months. I then exported a solution containing the Account entity and imported it into an environment where the default Account system view was set to My Active Accounts. The result was two default system views for the Account entity!

04 - Multiple Default Views 

Alternatively, when you import customizations with a different default dashboard, the imported solution ignores that setting entirely.

We were thinking that these were actually defects in the product but Microsoft support informed us otherwise. Apparently they think that the issue with duplicate default views is acceptable behavior since it really only affects users the first time that they view that entity. Each user has the option to set their own default view which overrides the default view (or views!) set by the administrator. The Microsoft CRM support team indicated that the issue with imported solutions ignoring default settings is (a-hem) “by design”. Again, users have the option to set their own default dashboard which overrides the system wide settings. Granted that's a little hinky and it requires an extra step by the user, but it does work.

I hope this helps smooth out some bumps with your deployments and we would love to hear any other gotchas that you would like to share!

Topics: Microsoft Dynamics CRM 2011

Creating Your Own Custom Privilege Settings in Dynamics CRM 2011

Today’s guest blogger is Jacob Cynamon-Murphy, a CRM Development Manager at Sonoma Partners.

This post assumes the reader is familiar with how to customize their Application Ribbons and add or revise JavaScript web resources. Special thanks go to my colleague, Bob Lauer, our JavaScript guru.

The problem

In virtually every client project we have implemented for Microsoft Dynamics CRM 2011, clients have had a need for custom settings that we could use with ribbon buttons or other web resources to restrict functionality. These are akin to “Miscellaneous Privileges” in the native CRM configuration.

There is currently no native support for custom privileges (although I have an outstanding request on Microsoft Connect that you can vote up). In the meantime, we have come up with a solution to allow clients to have a generic settings entity definition and some JavaScript to support a set of dynamically growing settings records and a means to wire them up to ribbon button enable rules or web resource functionality.

A specific example that we will consider below is the case of closing opportunities. Natively, having the Update Opportunity privilege allows a user to close Opportunity records as won or lost. If a CRM administrator wanted to restrict the ability to close these records to a subset of users who could edit opportunities, he or she would have used a blank role, assigned it to users granted to “close” privilege and then detect this with custom code. It was effective, but didn’t scale well to additional rules; having many CRM security roles for privilege management could become unwieldy.

The solution

A more scalable solution would allow settings to be defined dynamically by a power user and use common code to to properly restrict the functionality. For our solution, we’re focusing on basic settings that a user can be granted and providing a means to easily retrieve these rules for use in CustomRule definitions within the EnableRules node of RibbonDiffXml.

The entity, which we have entitled Privilege Setting, is a simple entity with a Name field to store the name of the custom privilege. I’ve also enabled this entity for Connections, which allow us to easily enable or disable the users granted the privilege. Administrators can create additional rules very easily through the Dynamics CRM 2011 UI and consume those rules with JavaScript and ribbon customizations, as outlined below.

clip_image001

To take advantage of the power of Connections, I have defined two custom Connection Roles. One, exclusive to Users, is called Has Permission To. The second, exclusive to Privilege Settings, is called Is Granted To. When you create the Connection, you grant a user the permission to the custom privilege. Another benefit of this approach is these roles enhance the understanding of the assignment and know why the association exists.

clip_image002

In this example above, both Jim and I are configured with the ability to close opportunities.

Once the configuration is complete, the next step is to apply a custom ribbon rule to use the privilege setting.

Defining CustomRule JavaScript, you have to produce an asynchronous JavaScript call to retrieve the settings record(s). This technique is outlined in the CRM 2011 SDK in a note under <CustomRule>, although I personally would direct you to Makarand Keer’s blog post which demonstrates the process with a JavaScript sample. I have adapted the script that Keer uses, providing a generic JavaScript method to support retrieving settings records for CustomRules.

Once the entity, connection roles and JavaScript web resources are in place, we have to define the RibbonDiffXml to create rules based on these settings records. I’ve provided a sample CustomRule that would consume a settings record and sample CommandDefinitions that use the CustomRule for CanCloseOpportunities to enable/disable the Close As Won and Close As Lost ribbon buttons for opportunities. This ribbon XML assumes the settings record named "CanCloseOpportunities" exists. The CustomRule for json2.js forces Dynamics CRM 2011 to load the JSON library on which settings.js is dependent; isNaN without a parameter is guaranteed to return true.

CustomRule

<EnableRule Id="Sonoma.PrivilegeSetting.CanCloseOpportunity">
  <CustomRule FunctionName="isNaN" Library="$webresource:sonoma_/Scripts/Utils/json2.js" />
    <CustomRule Default="false" FunctionName="Sonoma.Ribbon.Settings.hasPrivilege" Library="$webresource:sonoma_/Scripts/Ribbon/settings.js">
    <StringParameter Value="CanCloseOpportunities" />
   </CustomRule>
</EnableRule>

CommandDefinitions

<CommandDefinition Id="Mscrm.HomepageGrid.opportunity.MarkAsWon">
  <EnableRules>
    <EnableRule Id="Mscrm.SelectionCountExactlyOne" />
    <EnableRule Id="Mscrm.VisualizationPaneNotMaximized" />
    <EnableRule Id="Sonoma.PrivilegeSetting.CanCloseOpportunity" />
  </EnableRules>
  <DisplayRules>
    <DisplayRule Id="Mscrm.CanWriteOpportunity" />
  </DisplayRules>
  <Actions>
    <JavaScriptFunction Library="/_static/_common/scripts/ribbonactions.js" FunctionName="Mscrm.OpportunityActions.close">
      <CrmParameter Value="SelectedControlSelectedItemReferences" />
      <BoolParameter Value="true" />
      <CrmParameter Value="SelectedControl" />
    </JavaScriptFunction>
  </Actions>
</CommandDefinition>
<CommandDefinition Id="Mscrm.HomepageGrid.opportunity.MarkAsLost">
  <EnableRules>
    <EnableRule Id="Mscrm.SelectionCountExactlyOne" />
    <EnableRule Id="Mscrm.VisualizationPaneNotMaximized" />
    <EnableRule Id="Sonoma.PrivilegeSetting.CanCloseOpportunity" />
  </EnableRules>
  <DisplayRules>
    <DisplayRule Id="Mscrm.CanWriteOpportunity" />
  </DisplayRules>
  <Actions>
    <JavaScriptFunction Library="/_static/_common/scripts/ribbonactions.js" FunctionName="Mscrm.OpportunityActions.close">
      <CrmParameter Value="SelectedControlSelectedItemReferences" />
      <BoolParameter Value="false" />
      <CrmParameter Value="SelectedControl" />
    </JavaScriptFunction>
  </Actions>
</CommandDefinition>
<CommandDefinition Id="Mscrm.Form.opportunity.MarkAsLost">
  <EnableRules>
    <EnableRule Id="Mscrm.CanWritePrimary" />
    <EnableRule Id="Sonoma.PrivilegeSetting.CanCloseOpportunity" />
  </EnableRules>
  <DisplayRules>
    <DisplayRule Id="Mscrm.CanWriteOpportunity" />
    <DisplayRule Id="Mscrm.OpportunityIsOpen" />
  </DisplayRules>
  <Actions>
    <JavaScriptFunction Library="/_static/sfa/opps/opps.js" FunctionName="complete">
       <BoolParameter Value="false" />
    </JavaScriptFunction>
  </Actions>
</CommandDefinition>
<CommandDefinition Id="Mscrm.Form.opportunity.MarkAsWon">
  <EnableRules>
     <EnableRule Id="Mscrm.CanWritePrimary" />
     <EnableRule Id="Sonoma.PrivilegeSetting.CanCloseOpportunity" />
  </EnableRules>
  <DisplayRules>
    <DisplayRule Id="Mscrm.CanWriteOpportunity" />
    <DisplayRule Id="Mscrm.OpportunityIsOpen" />
  </DisplayRules>
  <Actions>
    <JavaScriptFunction Library="/_static/sfa/opps/opps.js" FunctionName="complete">
      <BoolParameter Value="true" />
    </JavaScriptFunction>
  </Actions>
</CommandDefinition>

We’ve packaged the Privilege Setting entity, the two Connection Roles and the two JavaScript files into a managed solution (download here). This solution can be imported into your Dynamics CRM 2011 environment and consumed immediately; you simply need to create 1 or more Privilege Settings records and revise your ribbon definitions to include CustomRules that call the settings.js library, as shown above. Then connect the users to that custom privilege record to allow access.