Showing posts with label rating. Show all posts
Showing posts with label rating. Show all posts

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.