Friday, 27 June 2008

The facility for adding Write-In products to the Order and Quote entities is implemented within CRM through 2 associated views on each of the Quote Product (quotedetail) and Order Product (salesorderdetail) entities. These are used for the Existing Products and Write-In Products navigation items respectively.

This can have effects elsewhere, however. If you create a custom one to many relationship from another entity to the Quote Product or Order Product entity, then only one of the associated views is used within the parent entity. This can cause a problem, because neither associated view displays all the data (one displays the write-in products only, and the other displays the existing products only). For example, the default associated view is the Existing Products view, so write-in products would not be displayed.

There are 2 possible solutions to this. One is to change which is the default view, the other is to change the filtering within one of the views. Both of these are configured via attributes of the savedquery entity. These can be modified in a supported way by using the CrmService.Update method for the savedquery entity, or in an unsupported way by modifying field values directly in the savedquerybase SQL table.

Which associated view is displayed is controlled by the IsDefault attribute - if you change this then it's your responsibility to ensure only one view has this set to true.

The filtering is applied based on the ColumnSetXml attribute, which is essentially a FetchXml expression. For example, the ColumnSetXml for the Existing Product view is:

If you wanted this view to include all Quote Products, then you could remove the whole filter and condition elements. Note that such a change would necessarily affect the Existing Product view within the Quote entity.

Friday, 20 June 2008

Although the CRM 4.0 SDK is generally pretty comprehensive, I find it doesn't contain as much information as I'd like about the information passed to plugins for each of the messages.

The following table lists the main parameters passed to plugins on the most common messages. If the message you want isn't listed here, post a comment and I'll update the table.

Message

Parameter

Direction

Type

Comments

Assign

Assignee

Input

SecurityPrincipal

Assign

Target

Input

Moniker

CancelSalesOrder

OrderClose

Input

DynamicEntity

Close

*ActivityClose

Input

DynamicEntity

Close

Status

Input

Int32

Create

id

Output

Guid

Only available on the Post Stage

Create

Target

Input

DynamicEntity

Delete

Target

Input

Moniker

Execute

FetchXml

Input

String

Execute

FetchXmlResult

Output

String

GrantAccess

PrincipalAccess

Input

PrincipalAccess

GrantAccess

Target

Input

Moniker

Handle

SourceQueueId

Input

Guid

Handle

Target

Input

DynamicEntity

Lose

*ActivityClose

Input

DynamicEntity

Lose

Status

Input

Int32

Retrieve

BusinessEntity

Output

DynamicEntity

Retrieve

ColumnSet

Input

ColumnSetBase

Retrieve

Target

Input

Moniker

RetrieveExchangeRate

ExchangeRate

Output

Decimal

RetrieveExchangeRate

TransactionCurrencyId

Input

Guid

RetrieveMultiple

BusinessEntityCollection

Output

BusinessEntityCollection

RetrieveMultiple

Query

Input

QueryExpression

RetrieveMultiple

ReturnDynamicEntities

Input

Boolean

RetrievePrincipalAccess

AccessRights

Output

AccessRights

RetrievePrincipalAccess

Principal

Input

SecurityPrincipal

RetrievePrincipalAccess

Target

Input

Moniker

RevokeAccess

Revokee

Input

PrincipalAccess

RevokeAccess

Target

Input

Moniker

Route

EndpointId

Input

Guid

Route

RouteType

Input

RouteType

Route

SourceQueueId

Input

Guid

Route

Target

Input

Moniker

Send

EmailId

Input

Guid

Send

IssueSend

Input

Boolean

Send

Subject

Output

String

This is the subject after the tracking token has been added

Send

TrackingToken

Input

String

SetStateDynamicEntity

EntityMoniker

Input

Moniker

SetStateDynamicEntity

State

Input

String

SetStateDynamicEntity

Status

Input

Int32

Update

Target

Input

DynamicEntity

To get the Primary Key, find the KeyProperty within the DynamicEntity

Win

*ActivityClose

Input

DynamicEntity

Win

QuoteClose

Input

DynamicEntity

Win

Status

Input

Int32

Notes:*ActivityClose. For the Win, Lose and Close messages, one of the parameters is an activity type whose name depends on the primary entity - e.g. the Win message could have a QuoteClose or OpportunityClose entity passed to it

Extra Parameters passed by CRMTo support multi-tenancy and multi-language deployments, CRM 4.0 passes additional parameters on the query string when the 'pass record object-type...' option is set for the IFrame. These extra parameters are orgname, UserLCID and OrgLCID.

For the report to work in reporting services you will have to add parameters with these names to your report. The orgname parameter has to be a string, the UserLCID and OrgLCID can be either strings or integers. As with the type and typename parameters, these new parameters don't have to be used in the report, they just need to exist for reporting services to accept values for them on the query string.

Changes to the query string for ISV.Config buttonsIn CRM 4.0, Microsoft have standardised the parameters such that they are the same for IFrames and ISV.Config buttons. This means that your report should have parameters id, type, typename, orgname, UserLCID and OrgLCID.

Wednesday, 11 June 2008

I recently had to debug some code that threw the 'This entity is already locked' error message (code 80043B1D) when updating an order product (salesorderdetail) entity.

This error can occur even if the state of both the order and order product allowed editing. The error occurs if the productid property is set on the BusinessEntity that is passed to the Update method. A general principle when coding with the CRM platform is that, if a property value is set on an entity passed to the Update method, then the CRM platform will assume that the value has been changed.

In this case, if the productid is passed, CRM assumes that you are trying to change the product, which is not permitted if the ispricelocked attribute is set to true on the order. So, the solution is to always ensure that you know which attributes are actually changing, and ensure that only these properties and the primary key value are passed to the update method.

Tuesday, 3 June 2008

A common question I get is ‘what is the difference between workflow and plugins, and when should I use one or the other ?’. This article is intended to be a comprehensive answer to these 2 questions.

First of all, I want to clarify the distinction between what I consider 3 distinct categories of workflow – the terminology is my own:

Simple workflow. This is one or more workflow rules created within the MSCRM interface, and which do not include custom workflow activities.

Workflow with custom workflow activities. I’ll explain more about custom workflow activities later in this article; for now the key point is that a custom workflow activity is .Net code that is written to perform functions not possible in simple workflow, and this code can be called from a workflow rule

Workflows created with the Workflow Designer in Windows Workflow Foundation. It is possible to build workflows outside of the CRM user interface, but I’m not going to include them in this article.

Simple workflowsThe main characteristics of simple workflows are:

* Creating a simple workflow involves no code

Workflows run only on the CRM server – workflow processing is not available within a client that is offline

Workflows run asynchronously – any data changes made within a workflow rule will not show up immediately within the CRM user interface

Workflows can be run manually or automatically. The automatic running of workflows is based on several data modification events

Workflow rules are entity specific

The state and stage of a workflow instance can be viewed within the CRM user interface by any CRM user with appropriate permissions

Some limitations of workflows are:

Workflow rules cannot be created for all entities

Although workflow rules can be triggered by the most common data modification events, there are some events that don’t trigger workflow rules

Characteristics and limitations marked with an asterix (*) do not apply if using custom workflow activities; the others do still apply.

Custom workflow activitiesCustom workflow activities allow you to extend the capabilities of workflow rules. Three common uses are to perform calculations on CRM data, to access CRM functionality that is not available in the out-of-the-box workflow activities, and to access external data.

Custom workflow activities are written as .Net assemblies which have to be registered on the CRM server. These assemblies can include information about parameters that can be passed into or out of the activity.

PluginsA plugin is .Net code that is registered on the CRM server. A plugin assembly can be registered for one or more steps – these steps correspond to the combination of the message (event), entity and stage. An example of a step would be the Create message for the account entity on the pre-event stage. Registration of the assembly and steps is part of the plugin deployment process, and there is no direct user interaction with plugins

The main characteristics of plugins are:

They have to be written as .Net code

Although they typically run on the CRM server, they can be deployed and configured to run on a CRM client that is offline

They can run either synchronously or asynchronously. If they run synchronously, any data changes made within the plugin will show up immediately within the CRM user interface

Synchronous plugins can run on either the pre-event or post-event stage. The pre-event stage happens before data is written to the CRM database, and a plugin registered on a pre-event step can cancel the data writing and provide an error message to the user.

More entities can have plugins registered for them than can have workflow rules

Plugins can run on more events than can workflow rules. An example is that plugins can run on data retrieval, not just modification events

The main limitations of plugins are:

Plugins cannot be run manually; they only run on the steps for which they are registered

There is no user interaction with plugins, other than error messages that might be throw by a synchronous plugin

Sample ScenariosSo, having covered the main characteristics and limitations of simple workflows, custom workflow activities and plugins, when should you choose one or another ? Here are some common scenarios:

What you want to achieve can be done with a simple workflow, and it is acceptable or desirable for this to happen asynchronously and on the server onlyIn this case I’d go with simple workflows; there’s no point writing code if you don’t have to.

What you want to achieve has to run synchronouslyIf so, workflow won’t do, so it would have to be a plugin. An alternative could be to use client script, but I don’t intend to complicate this article by including this in any more detail

You need to be able to cancel the data operationA pre-event plugin is the only option covered here, though again client script should be considered

You want to give users the discretion to run the operation manuallyHere you’ll need a workflow. Whether or not you need a custom workflow activity depends on the complexity of the operations. Again, there may be an option outside of the scope of this article – to write an ASP .Net application that is called from an ISV Config button

You need to write custom code, but you want users to decide whether this code should run, and under what circumstancesIn this case I’d go with a custom workflow activity, as you could make this available for users to add to their own workflows

Further InformationThere is more detail about how to write and deploy plugins and custom workflow assemblies within the CRM 4.0 SDK, though unfortunately there’s not a lot of information about when to choose one or the other.

The classroom training material ‘Extending Microsoft Dynamics CRM 4.0’, course number 8969, should have more information both about building plugins and custom workflow assemblies, and when to use them. This course will also cover other solution technologies such as client script and ASP .Net extensions.

One of the MS team, Humberto Lezama has also produced a useful matrix indicating the relative merits of workflow and plugins. This can be found here

Feeds

Who I am

Professionally:I'm a founder member of Excitation Ltd, a Microsoft Gold Partner in the UK that specializes in Microsoft CRM, and I've been the technical lead in over 50 CRM implementations since the release of CRM 1.2.This is a personal blog, and any views expressed here do not necessarily reflect those of Excitation; sometimes they will, but that should be treated as a happy coincidence rather than a normal state of affairs.

Personally: We'll see if I get onto this in the blog; if so, I expect it will include some permutation of mountains, snow and gravity