Archive

Archive for June, 2008

Plug-in or Workflow?

WorkFlow Deciding when to use a workflow vs. a plug-in is usually a straight forward process. In general, I always recommend using workflow to automate business processes especially if the business process will be later modified/maintained by “business” people (non IT).

However, there are some characteristics that will guide you to use one versus the other that do require you to know a bit more details of the task that you are trying to achieve. For example, if you require performing an action right away, let’s say when a record is updated (synchronous), then you have to use plug-ins because workflows are always asynchronous.

The following table gives a quick comparison between workflows and plug-ins and when to use each one, hope you find it useful.

Humberto Lezama Guadarrama

Advertisements

Custom Workflow Activity for matching email addresses to customers

In an earlier blog (E-mail to Case/Lead Using CRM 4 Workflow ), I described a sample workflow that could be used to automatically create cases based on emails sent to a queue.

One of the questions that was frequently asked for the above blog was that the email activity’s regarding field set to blank. In this blog, I’ll show how this can be done using a custom CRM workflow activity.

Let’s summarize the problem we are trying to solve. Joe (joe@mycustomer.com) is a customer in your system and say you have an account that is capturing this. Joe sends an email to your support alias to report an issue. We would like the email activity that is created to be regarding Joe’s account.

For those of you new to writing custom workflow activities, I highly recommend that you take a look at the SDK documentation at: http://msdn.microsoft.com/en-us/library/cc151142.aspx –It contains all the information needed for you to start using custom workflow activities.

I’m going to split my solution into 2 parts:

1) A custom workflow activity that takes an email address as input and returns a matching account as output

2) A workflow rule that uses the above custom activity. This workflow rule is triggered when an email is created and updates the email activity to have the regarding field set to the output returned by the custom workflow activity.

Custom Workflow Activity

Let’s walk thru’ the code for the custom workflow activity.

1) Define the class skeleton and the using statements for the various namespaces that we will need. Please ensure you have read and understood the SDK documentation at: http://msdn.microsoft.com/en-us/library/cc151142.aspx to get an overview of how to develop CRM custom workflow activities.

using System.Workflow.Activities;

using System.Workflow.ComponentModel;

using Microsoft.Crm.Sdk;

using Microsoft.Crm.SdkTypeProxy;

using Microsoft.Crm.Workflow;

using Microsoft.Crm.Sdk.Query;

namespace CrmCustomWFActivity

{

   [CrmWorkflowActivity(“Find Customer with specified email address”)]

   public class MatchSenderWithExistingCustomerActivity:  

   System.Workflow.Activities.SequenceActivity

   {

       // Activity code goes here.

   }

}

2) Now, add properties that represent the inputs and outputs. As discussed earlier, the input is an email address (of type string) and the output will be the matching account (of type Lookup).

DependencyProperty is a Windows Workflow concept and you can read more about it here: http://msdn.microsoft.com/en-us/library/system.workflow.componentmodel.dependencyproperty.aspx

   1: // Input property
   2: public static DependencyProperty senderProperty = DependencyProperty.Register("sender", typeof(string), typeof(MatchSenderWithExistingCustomerActivity));
   3: 
   4:         [CrmInput("Sender")]
   5:         public string sender
   6:         {
   7:             get
   8:             {
   9:                 return (string)base.GetValue(senderProperty);
  10:             }
  11:             set
  12:             {
  13:                 base.SetValue(senderProperty, value);
  14:             }
  15: 
  16:         }
  17: 
  18: // Output property
  19: public static DependencyProperty accountIdProperty = DependencyProperty.Register("accountId", typeof(Lookup), typeof(MatchSenderWithExistingCustomerActivity));
  20: 
  21:         [CrmOutput("AccountId")]
  22:         [CrmReferenceTarget("account")]
  23:         public Lookup accountId
  24:         {
  25:             get
  26:             {
  27:                 return (Lookup)base.GetValue(accountIdProperty);
  28:             }
  29:             set
  30:             {
  31:                 base.SetValue(accountIdProperty, value);
  32:             }
  33: 
  34:         }

3) This custom workflow activity needs to be able to retrieve accounts whose email address matches the sender property value. To do this, it needs to be able to call into CRM SDK methods and can do this thru’ IcrmService interface that is provided to all crm custom workflow activities. The following is code for a helper method that uses CRM query functionality to return account that matches the email address.

   1: private Guid MatchSenderWithExistingAccount(ICrmService crmService, string fromAddress)
   2: {
   3:     // Retrieve accounts with this email address.
   4:     QueryByAttribute query = new QueryByAttribute();
   5:     query.EntityName = EntityName.account.ToString();
   6:     query.Attributes = new string[] { "emailaddress1" };
   7:     query.Values = new string[] { fromAddress };
   8: 
   9:     RetrieveMultipleRequest retrieveMultipleRequest = new RetrieveMultipleRequest();
  10:     retrieveMultipleRequest.Query = query;
  11:     retrieveMultipleRequest.ReturnDynamicEntities = true;
  12: 
  13:     RetrieveMultipleResponse retrieveMultipleResponse = (RetrieveMultipleResponse)crmService.Execute(retrieveMultipleRequest);
  14: 
  15: 
  16: 
  17:     Guid accountId = Guid.Empty;
  18: 
  19:     foreach (BusinessEntity busEntity in retrieveMultipleResponse.BusinessEntityCollection.BusinessEntities)
  20:     {
  21:         // Pick the first accountid.
  22:         accountId = ((Key)(((DynamicEntity)busEntity)["accountid"])).Value;
  23:         break;
  24:     }
  25: 
  26:     return accountId;
  27: }

4) Now, we can implement the Execute method of the custom workflow activity.

   1: protected override System.Workflow.ComponentModel.ActivityExecutionStatus Execute(System.Workflow.ComponentModel.ActivityExecutionContext executionContext)
   2:         {
   3:             IContextService contextService = (IContextService)executionContext.GetService(typeof(IContextService));
   4:             IWorkflowContext context = contextService.Context;
   5: 
   6:         // Obtain IcrmService so we can call into CRM SDK to retrieve
   7:         // accounts
   8:             ICrmService crmService = context.CreateCrmService();
   9: 
  10:             // this.sender property will have the email address that needs to be matched.
  11:             Guid accountId = MatchSenderWithExistingAccount(crmService, this.sender);
  12: 
  13:             // Set the accountId output property to return this data
  14:         // back to the calling workflow
  15:             this.accountId = new Lookup("account", accountId);
  16: 
  17:             return ActivityExecutionStatus.Closed;
  18:         }
  19:
  20:     return accountId;

Using The Custom Workflow Activity

In order to use MatchSenderWithExistingCustomerActivity in workflow rules, you need to register the activity. Follow the steps at: http://msdn.microsoft.com/en-us/library/cc151144.aspx to accomplish this.

We will create a workflow rule that does the following:

1) When an email is created, it checks if the email’s regarding field is set.

2) If not set, it invokes MatchSenderWithExistingCustomerActivity

3) It updates email with the accountid returned by MatchSenderWithExistingCustomerActivity.

Let’s walk through these in more detail.

1) Create the workflow rule, call it SetEmailRegarding and set it to trigger on email create

clip_image002

2) Insert a check condition step and configure it to check if Email:regarding field does not contain data

clip_image004

3) If Email:regarding is not set, we want to invoke the MatchSenderWithExistingCustomerActivity. Under the add step drop-down, you should find the custom workflow activity as shown below:

clip_image006

4) After you select MatchSenderWithExistingCustomerActivity, you need to ensure that it is being invoked with the correct input. Click ‘Set Properties’ and set the value of the input parameter Sender to that of Email:Sender

clip_image008

5) The next step would be to update the email’s regarding to the value returned by the custom workflow activity in the previous step. To do this, add a Update Email step, select ‘Set Properties’ and tab to the ‘Regarding’ field. In the dynamic values form assistant, you will now find that it shows ‘Match email address:accountid’ to indicate the return value from the previous step. Select this to be the value for regarding field as shown below.

clip_image010

6) Publish the workflow and verify that it is working.

Since the functionality to match email address to an account has been captured as a custom workflow activity, you will be able to use that activity in all your workflow rules. You can also enhance the custom workflow activity by making it return either a matching account or contact if needed. If you need to create an account/contact if a match wasn’t found, you can do this by adding a Create step to the workflow rule.

Web Services & DLLs or What’s up with all the duplicate classes?

You may have noticed that the Microsoft Dynamics CRM 4.0 SDK contains Web services, assemblies and helper code that have LOTS of the same classes. Which should you use, when and why? It depends on what you are creating:

Plug-ins

A plug-in is an assembly that it registered to run before or after CRM does it’s processing for an action.

Use:

  • Microsoft.Crm.Sdk.dll
  • Microsoft.Crm.SdkTypeProxy.dll

Use the SDK assembly because contains the IPlguin and IPluginExecutionContext. It also contains the helper classes you can use for building queries, instantiating types and enumerations you can use to make your code more readable and maintainable.

Use the SDK type proxy assembly because it contains the messages (request and response classes). This assembly also includes all the entity classes but do not use them! In other words, do not use the account or contact classes; instead use the DynamicEntity class, which provides a property bag to access the attributes of an entity instance (record). This is better for you anyway, since the entity classes included in this DLL will not contain any of your customizations. The entity classes are deprecated and will be removed from this assembly in a future version.

Custom Workflow Assemblies

Custom workflow activities are assemblies that can be called from a workflow.

Use:

  • Microsoft.Crm.Sdk.dll
  • Microsoft.Crm.SdkTypeProxy.dll

Use the SDK assembly because it contains the Workflow namespace which includes all the classes you need to create custom workflow activities.

You can use the messages (request and response classes) contained in the SDK type proxy in your custom workflow activities. The same warning against using the entity classes applies here.

Add-ins for the Web app or for the Outlook client

If you are adding new functionality to the CRM Web application or to the Outlook client, you should use the Web services. This includes adding custom ASPX pages or adding ISV menu items that calls your custom code. Remember that if you customize your entities, you need to recompile any code that uses those customized entity classes.

Use:

  • CrmDiscoveryService – Use this to get the URL for your organization or to get a CRM ticket
  • CrmService – Use this to access the data (records or entity instances) stored in CRM
  • MetadataService – Use this to access the definitions for the data (entities)
  • Microsoft.Crm.Outlook.dll – Use this for code that can work online (connected to the server) or offline
  • Helper Code – Optional helper code to make your coding easier

There is another Web service covered in the CRM Deployment SDK but this is not used in this sort of custom code.

If you are adding functionally to the CRM Outlook client, use the Outlook SDK assembly because it contains methods to detect whether the client is online or offline, to make the client go online or offline or to synchronize the data after going online.

You can also use the helper classes by adding the C# files from CrmHelpers. These classes can be used for easier type instantiation, for building queries and contains enumerations you can use to write more readable and maintainable code.

You can also get the identical helper classes by adding the Microsoft.Crm.Sdk.dll assembly. Adding this DLL requires a bit more care because the SDK assembly contains the classes for the metadata Web service so this may be confusing if you are also using the MetadataService.

Do not include Microsoft.Crm.SdkTypeProxy.dll to these types of projects. The Web services contain the entity classes and the message classes so this assembly is not needed.

References

Read about these topics in the SDK:

Amy Langlois

Use Workflow To Set The Primary Contact

Welcome Matt Wittemann, CRM MVP and today’s guest blogger. He is the director of the CRM practice at Customer Connect and has been working with CRM since it was first released. Matt has a passion for helping businesses get more profitable and efficient through the effective use of CRM tools and improved processes.”

It is often a business requirement to have a Primary Contact designated on every Account, but it’s easy for users to create Account records and Contact records at different times which can lead to Accounts that have no Primary Contact set. A request was recently posted on the Dynamics Feedback site on Microsoft Connect asking for an easier way to automate this process.

In CRM 4.0, the powerful new workflow functionality can ensure that every Account has a Primary Contact. The simple workflow rule described below is run whenever a Contact is created. It checks to see if the parent account has a Primary Contact set. If it doesn’t, it sets the new Contact as the Primary Contact for the Account.

Note: Making the Parent Customer field required on the Contact form would help to close this loophole in data entry.

1. To create this workflow, go to Settings > Workflows and click the “New” button. Name the workflow rule “Set Primary Contact” and choose the Contact as the entity for the rule.
clip_image002
Click OK to launch the Workflow editor.

2. Leave the default settings for the “Scope” and the “Start When” options and click where it says “Select this row and click Add Step.” Add the step “Check Condition” as shown below:
clip_image004

3. For the step description, type “Check if parent account has primary contact.” Then, in the “If” clause, click the link to configure the condition. Check to see if the related “Parent Customer (Account)” Primary Contact field Does Not Contain Data.
clip_image006
Save and close this window.

4. Next, click the second row of the If statement, and click Add Step > Update Record. Let’s give this one the description “Set Primary Contact.” In the Update drop down, choose “Parent Customer (Account)” under the Related Entities.
clip_image008

5. Click the “Set Properties” button and the Account form will open. Place your cursor in the Primary Contact field, and in the form assistant on the right you’ll notice that CRM has set the Operator and Look For values to Contact. Leave these as they are and click the “Add” and “OK” buttons to add this value to the Primary Contact field.
clip_image010
Save and Close this window, and then publish your workflow.

To test the rule, create a new Contact for an Account that has no Primary Contact. When creating your new contact be sure to fill in the Parent Customer field on the Contact form. Save the contact and navigate to your Accounts list view and open the Account. Your new Contact should now be set as the Primary Contact for the Account. (You may need to wait a minute or so, since CRM’s workflow runs in the background and may take a moment to process.)

Matt Wittemann

Market Forecasting using Microsoft Dynamics CRM

Forecasting is an interesting area in marketing. In Microsoft Dynamics CRM data can be collected and reported on to aid with forecasting and analysis of the results of a marketing campaign. I’m considering writing an article about creating and using this data in Microsoft Dynamics CRM, but I’m having some difficulty figuring out how customers are actually using the fields provided in Microsoft Dynamics CRM.

Inside Microsoft Dynamics CRM we find some summary fields provided to place cost and revenue estimates. In campaigns themselves, the Campaign > Information > Financials tab provides fields in which you can enter summary numbers for Budget Allocated, Miscellaneous Costs, Estimated Revenue. While under Campaign Activities, once an activity is opened, Budget Allocated and Actual Cost are fields provided for this information. It would make sense that Campaign Responses, Target Products, Sales Literature, Target Marketing Lists, and Related Campaigns all contribute to the forecasting or analysis effort. The issue for me is where are users accumulating the detail data that goes in to these summary fields? Are we all just using Excel to manage the details and generate the summary information that can then be placed in the above fields?

It seems likely to me that the forecast and results data available within CRM for use in marketing include:

1. Support contracts (associated with support call centers). These have a history of costs and revenue associated with the contracts. If marketing plan includes contracts, you should be able to create a forecast of revenue from this data.

2. Support Cases. Contracts usually deal with cases. Reports on time spent on cases and billing activities resulting from the case, should be easy to create, track, and therefore forecasts of future efforts can be created.

3. Service activities. CRM already has a default service report titled Service Activity Volume. It seems possible that scheduling services could provide another window into revenue forecasts for marketing campaigns associated with services.

4. Sales activities. If increased sales of products is the goal of a marketing campaign, you can use the default Campaign Performance report to show all the dates, targets, definitions, responses, and financial returns from the campaign. The key indicator here is the campaign response. So a way to measure the effectiveness of campaign generated appointments, E-mails, Faxes, Letters, and Phone Calls is essential. Opportunities are designed to aid Microsoft Dynamics CRM users to create sales forecasts. These can be included in a marketing forecast. For example, the Sales Pipeline report displays anticipated sales grouped by various types from Sales Users to Sales Territory among others.

5. Campaigns. Additional default reports include Campaign Activity Status report displays a summary for one campaign and the Campaign Comparison report identifies most and least successful campaigns. However, if multiple campaigns occur at the same time, then multiple Campaign Activity Status report would have to be combined in a marketing forecast.

6. Quick Campaigns. This marketing tool can be used within a standard campaign; otherwise, some of its potential data may be lost or end up in notes attached to Accounts, Leads, or Contacts.

The key issue appears to be how users are accumulating field or report data to create a marketing forecast. If you have experience using Microsoft Dynamics CRM to create a marketing forecast, please leave a comment on this post.

James Matteson

Quick Tip: Send a shortcut link to a record in an e-mail

Sometimes rather than send instructions how to find a record, it’s easier just to e-mail it. The Outlook e-mail may not be automatically tracked in CRM (depends on your settings), and the link only works for other CRM users with at least Read permissions, but to ask a quick question or answer one, it works pretty slick.

· On just about any record, in the Actions menu click Send Shortcut.

clip_image002

An Outlook e-mail message opens with the link to the record already in it and the record’s name in the Subject Line. Just add your recipients, message, and then send.

clip_image004

When the recipient gets the mail, they just need to click on the link. If they aren’t already signed into CRM, they will need to sign in. The record or list displays without the rest of the CRM chrome, which can be a little disorienting, but it is the live CRM record, not a snapshot. Sending a shortcut is a great way to ask someone about a record, remind them to complete a form, or answer a question.

Crystal Smithwick

Report on Processes Not Just Data

You didn’t want to write code to get insight into your business? Alright, that’s fair. Check out CRM 4.0 because the CRM investment will really pay off – business users can now build their own reports with the report building wizard.

Since it’s a wizard there may be an assumption that there’s no explanation needed around it – that’s partially true: it’s easy to use and most people can move right though it and get exactly what they want. But you can get way more than you think out of it. Read on and you’ll get a walk through of how to build reports on processes that are being managed in CRM; reports like this really boost the value of CRM because they can show movement through the system, not just a static view of data.

But first, let me provide a little foundation on the choices in the Report Wizard. The report wizard asks which record types you want to include in the report and offers Primary and Related records. The “Primary” list is a list of all entities that are valid for Advanced Find. The Related records are the entities that have a many to one or a many to many relationship back to the Primary record. You can access properties of objects with one to many relationships to the Primary or Related records in a later screen when you choose columns for your tables. In any case, selecting a secondary object here will allow you to access properties and of that object in a later screen. If that isn’t quite clear, don’t worry, you can still create great reports without understanding the underlying data model.

In order to report on process you need a process, or more precisely a workflow, to report on. Without going into details on how to define a multi stage process using CRM workflow let’s just say that you have one, it has some objects running against it and that, within the editor, it looks something like this:

clip_image002

Note the stage names, those are the items in white text on a darker blue background, I’ve named them and included a number in the stage name this will be important later when we sort the results of the report.

The idea with reporting on a process is that we want to see what items are within a given stage of the process. In the Lead Distribution workflow above we have a lead qualification stage, a distribution stage and follow-up stage. Each stage has a different set of people responsible for it so knowing where leads are in the process is pretty important. So let’s go create a report showing a listing of leads grouped by the process stage that they’re in. Head to the Reports area and click the New button to create a new report, indicate that you want to create a Report Wizard based Report (the default) and then click the “Report Wizard” button on the form then within the wizard:

1. Indicate that you want to create a new report and click Next.

2. Type a report name and description if you like.

3. Choose the record with the process you want to report on. In my example that’s a Lead.

4. For the Related record type choose System Jobs; System Jobs have a many to one relationship to Leads (and anything else that can engage in workflow).

clip_image004

System Jobs are the generic term we use for any sort of operation that occurs in our asynchronous event pipeline. That includes workflows but a ton of other things like duplicate detection, bulk editing, bulk deletion – the list goes on and includes some interesting items. If you want some insight into the list of things that the CRM application does behind the scenes look at that list.

5. Once you’ve chosen System Jobs as your related record type click Next.

6. You now get to filter the records that will show up in your report.

This information gets converted into a SQL WHERE clause but all you need to know here is that the UI is just like the Advanced Find UI in the application. It’s a little different from the normal Advanced Find UI in that you have two different entities that you can filter – the primary as well as the related entity type. The key thing here is to make sure that you filter the System Jobs records so the next step is:

7. Within the System Jobs section click “Select” and choose “System Job Type”, “Equals” and “Workflow”. This will limit the System Jobs listing to just workflow items.

clip_image006

The next page of the wizard lets you define the columns and groupings for your report.

8. Choose to add a Grouping

9. In the dialog that pops up indicate that the record type you want to use is System Jobs

10. In the column selector choose Workflow Stage

clip_image008

11. Add which ever columns you want to the report like the Lead Name and Owner but include some other columns from the System Jobs object – Started On is one of the more interesting.

clip_image010

12. Skip the charts for now and click Next through the wizard to confirm the report definition and then to publish the report to SQL Server Reporting Services.

When you are returned to the Report form you can click on the Run Report button on the top of the Report form. That should open a new page and let you run the report. Depending on the columns that you’ve chosen you’ll get something like this:

clip_image012

And there you have a report on process. Note that the “Started On” column contains the date and time that the lead entered that workflow stage. Using that data you can see how long a given lead has been sitting at a particular stage – pretty useful. You can certainly do this sort of thing by having a picklist on the Lead and having users change the picklist based on stage. But this just gives users more work to do and requires that they remember to change yet another thing while managing their work.

Building processes that are triggered off of the work itself is far more likely to meet success – users will be more likely to comply and your data will reflect the reality of what is happening within the business process, not just the data that’s been entered into the system.

Barry Givens