Sunday, May 31, 2009

Set customer rating by workflow


Have you ever been tasked with implementing a system for rating the customer acccounts in MS CRM? Many clients have different rules for rating their MS CRM accounts. The concept is basically that the account is given a rating in different disciplines, and the total determines the general standing of the account.

This is often accomplished in JavaScript, but in my opinion this is a rather poor approach. First of all because I hate JavaScript, but more important because JavaScript only fires when a user opens the account form. There's a lot of scenarios where this isn't sufficient:

  • You're importing data from other sources and wants to use them in a campaign without actually open them
  • You have lot's and lot's of accounts in your database, but they are seldom opened - in that case you should probably consider some sort of maintenance function
  • Your system's integrated with other systems, who might change information without human intervention
  • Etc
The code is pretty simple. This example uses hard-coded values of A, B and C, and requieres drop down lists with those values. Perhaps not the most elegant solution - I should probably have read out the values from a settings entity or something in order to avoid the hard coding. On the other hand I have never come across a client who was very inventive in their ratings

Anyway, the following code will accomplish the task:

[CrmWorkflowActivity("Rating")]
public class Rating : SequenceActivity
{
protected override ActivityExecutionStatus Execute(ActivityExecutionContext executionContext)
{
IContextService contextService = (IContextService)executionContext.GetService(typeof(IContextService));
IWorkflowContext context = contextService.Context;

ICrmService crmService = context.CreateCrmService();
//Possible ratings
char[] ratings = new char[] { 'A', 'B', 'C' };

//Combinations:
string rating = this.CriteriaOne.ToUpper () + this.CriteriaOne.ToUpper () + this.CriteriaOne.ToUpper ();

//A equals 1, B equals 2 and C equals 3. Max 9, min 3. 3-5 equals a total A, 6-7 equals B 8-9 equals C
//Alternately a single A criteria can generate a total rating of A if this is specified
int i = 0;
bool A = false;
foreach (char c in rating)
{
if (c == 'A')
{
i = i + 1;
A = true;
}
if (c == 'B')
{
i = i + 2;
}
if (c == 'C')
{
i = i + 3;
}
}

if(i<6) totalrating = "A"> 5) && (i< totalrating = "B"> 7)
{
this.TotalRating = "C";
}
if (this.ARating.Value)
{
if (A)
{
this.TotalRating = "A";
}
}
return ActivityExecutionStatus.Closed;
}

public static DependencyProperty CriteriaOneProperty = DependencyProperty.Register ("CriteriaOne", typeof (System.String), typeof (Rating));
[CrmInput("Criteria One")]
public string CriteriaOne
{
get
{
return base.GetValue (CriteriaOneProperty).ToString ();
}
set
{
base.SetValue (CriteriaOneProperty, value);
}
}
public static DependencyProperty CriteriaTwoProperty = DependencyProperty.Register ("CriteriaTwo", typeof (System.String), typeof (Rating));
[CrmInput ("Criteria Two")]
public string CriteriaTwo
{
get
{
return base.GetValue (CriteriaTwoProperty).ToString ();
}
set
{
base.SetValue (CriteriaTwoProperty, value);
}
}
public static DependencyProperty CriteriaThreeProperty = DependencyProperty.Register ("CriteriaThree", typeof (System.String), typeof (Rating));
[CrmInput ("Criteria Three")]
public string CriteriaThree
{
get
{
return base.GetValue (CriteriaThreeProperty).ToString ();
}
set
{
base.SetValue (CriteriaThreeProperty, value);
}
}
public static DependencyProperty ARatingProperty = DependencyProperty.Register ("ARating", typeof (CrmBoolean), typeof (Rating));
[CrmInput ("Return always A if one criteria is A)]
public CrmBoolean ARating
{
get
{
return (CrmBoolean)base.GetValue (ARatingProperty);
}
set
{
base.SetValue (ARatingProperty, value);
}
}
public static DependencyProperty TotalRatingProperty = DependencyProperty.Register ("TotalRating", typeof (System.String), typeof (Rating));
[CrmOutput ("Total Rating")]
public string TotalRating
{
get
{
return this.GetValue (TotalRatingProperty).ToString ();
}
set
{
this.SetValue (TotalRatingProperty, value);
}
}
}


The code reads three different criterias from picklists, evaluates them and returns the average which can be used to generate a total rating. Some clients would like an 'A'-rating in one criteria to override the others, so this is a configurable option.

If you need more criterias than three, just add more properties and assign them other values.

1 comment:

  1. Hi Torstein, I've read your code and it's interesting but from my experience I can say:
    I usually depend on how volume & profit would a client generate as some clients take more time and provide less volume than others...

    ReplyDelete