Dynamics CRM 2011: Diving into the sales pipeline – Part 2

In my previous post of this series, we discussed some fundamental concepts of the sales pipeline and how Dynamics CRM handles the sales process. While considering the requirements of ACME (a fictitious company), we defined the stages of their sales pipeline, and started to outline the functional specification of the opportunity entity, including the elaboration of an opportunity probability matrix.

In this post we will discuss how to apply what have been defined so far by covering the customisation of the Opportunity entity form, including some scripting.

Important Update: This article series has been written before the release of Dynamics CRM 2011 Update Rollup 12 (also known as Polaris). You might continue to read the articles in this series, but it is strongly recommended that you read this addendum before performing any customisations suggested in the series.

So let’s start by customising the Opportunity form.

Opportunity form: Adding and editing fields

  1. Add the Process Code field (salesstagecode) above the Rating field (opportunityratingcode).
  2. Edit the Process Code field properties. Under Display, change the field label to Pipeline Phase.
  3. Now under Details, click on Edit to add the Pipeline Phase stages as options into the option set field, remembering the caveats concerning naming and numbering the pipeline phases we mentioned in the previous post. As per the previous post, we should add the following options:
    1 - Prospect
    2 - Proposal
    3 - Negotiation

    Make sure to save and close the properties dialog for the Process Code field.
  4. Back at the Opportunity form under Forecast Information, make the Probability field (closeprobability) read-only.
  5. Add the Pipeline Phase field (stepname) just under the Probability field, which is the field used by the Sales Pipeline Funnel Chart. Change the properties of the field and make sure that under Visibility, the field is not selected as visible by default.

Our Goal: What we are going to achieve here is that using the Process Code field labeled (i.e.: “disguised”) as the Pipeline Phase field, users will be able to manually select the Pipeline Phase in which the opportunity is at. The label of the option selected in this field will then be copied into the real Pipeline Phase field, which we just added as hidden in the form. Furthermore, we made the Probability field read-only because its value will be automatically calculated based on the combination of values from the Pipeline Phase and Rating fields, following our probability matrix we defined in the previous post.

Adding our JScript: Creating the web resource

In order to achieve the goal mentioned above, we must add some code that will work with the customisation we did so far.

  1. Create a new JScript web resource and name it new_SalesPipeline.
  2. Add the following code into the web resource:
  3. SalesPipelineProbCalc = function() {
      var CRM_FORM_TYPE = Xrm.Page.ui.getFormType();
      if (CRM_FORM_TYPE == 4 || CRM_FORM_TYPE == 3) { return; }
    	// Get value of Pipeline Phase set by user
    	if (Xrm.Page.getAttribute("salesstagecode").getSelectedOption() != null)
    	{var val_salesstagecode = Xrm.Page.getAttribute("salesstagecode").getSelectedOption().value;}
    	else {var val_salesstagecode = null;}
    	// Get text of Pipeline Phase set by user (this text should be the same for all languages)
    	if (Xrm.Page.getAttribute("salesstagecode").getSelectedOption() != null)
    	{var txt_salesstagecode = Xrm.Page.getAttribute("salesstagecode").getSelectedOption().text;}
    	else {var txt_salesstagecode = null;}
    	 // Set the text of Pipeline Phase field
    	// Set the submition mode of closeprobability (which is set as read-only) in order to commit the value when saving the record
    	var closeprobabilityAttr = Xrm.Page.getAttribute("closeprobability");
    	// Get value of the Rating selected by user
    	if (Xrm.Page.getAttribute("opportunityratingcode").getSelectedOption() != null)
    	{var val_rating = Xrm.Page.getAttribute("opportunityratingcode").getSelectedOption().value;}
    	else {var val_rating = null;}
    	// Calculation of Close Probability Rating as per Phase X Rate matrix
    	if (val_salesstagecode == 1 && val_rating == 3)
    	{ Xrm.Page.getAttribute("closeprobability").setValue(10); }
    	else if (val_salesstagecode == 1 && val_rating == 2)
    	{ Xrm.Page.getAttribute("closeprobability").setValue(25); }
    	else if (val_salesstagecode == 1 && val_rating == 1)
    	{ Xrm.Page.getAttribute("closeprobability").setValue(50); }
    	else if (val_salesstagecode == 2 && val_rating == 3)
    	{ Xrm.Page.getAttribute("closeprobability").setValue(20); }
    	else if (val_salesstagecode == 2 && val_rating == 2)
    	{ Xrm.Page.getAttribute("closeprobability").setValue(50); }
    	else if (val_salesstagecode == 2 && val_rating == 1)
    	{ Xrm.Page.getAttribute("closeprobability").setValue(75); }
    	else if (val_salesstagecode == 3 && val_rating == 3)
    	{ Xrm.Page.getAttribute("closeprobability").setValue(40); }
    	else if (val_salesstagecode == 3 && val_rating == 2)
    	{ Xrm.Page.getAttribute("closeprobability").setValue(75); }
    	else if (val_salesstagecode == 3 && val_rating == 1)
    	{ Xrm.Page.getAttribute("closeprobability").setValue(95); }
    	else { Xrm.Page.getAttribute("closeprobability").setValue(0); }
  4. Save your changes and make sure to publish the customisation.

A warning on pipeline phases: At the moment, users can move both forward and backwards in the sales pipeline stages without any limitations. For instance, a user could jump from step 1 to 3, or move backwards from step 2 to 1. There are two issues at hand here. First, I personally don’t think an opportunity should move backwards — it should either move forward or be cancelled/lost. Second, the default Sales Pipeline report is based on steps within a workflow that we have yet to create (which we will cover in my next post), and workflows created within Dynamics CRM doesn’t allow us to jump backward on steps.
A workaround would be to add a JScript that prevent users from moving backward on the pipeline phases. See the “bonus JScript” section below for further information.

Opportunity form: Binding JScript into form and fields

Now that we added our JScript as a web resource, we must bind it into the Opportunity form and into field events to ensure the calculation will take place when the user changes the correspondent values within the form. So let’s go back to customise the Opportunity form.

  1. Click the Form Properties button located in the Ribbon. In the Form Properties dialog under the Events tab, click on Add under the Forms Libraries section and select the new_SalesPipeline web resource we created previously. Then close the Form Properties.
  2. Double click on the Process Code field (which we labeled Pipeline Phase) in order to bring its properties. In the Field Properties dialog under the Events tab, click on Add under the Event Handlers section.
  3. On the Handler Properties dialog, where it says Library, select new_SalesPipeline. Where it says Function, type in SalesPipelineProbCalc, which is the name of the function we created in the new_SalesPipeline web resource. Then click on OK, then OK again in the previous dialog to confirm our customisation.
  4. Repeat the two previous steps (2, and 3) for the Rating field.
  5. Save the form and publish the customisation.

What we just did: We have now added the JScript library we created (i.e.: the JScript web resource) into the Opportunity form and bound the SalesPipelineProbCalc into the onChange event for the Process Code (“disguised” as Pipeline Phase) and Rating fields. So when the user changes the value of either one of these fields, the value within the Probability field will change accordingly as per the Probability Matrix we defined previously.
onLoad Form: We could have add this function to the form’s onLoad event. This means that as soon as the form loads, the script will be executed. The script contains a conditional at the top that checks if the form isn’t read-only (e.g.: if viewing a closed opportunity) in order to execute the calculation.

Testing our solution

When can now go ahead and test our solution by creating an opportunity. We can manually specify the pipeline phase in which the opportunity is at, and this will reflect in the Pipeline Funnel chart. We can also give our opportunity the rating of hot, warm or cold, and along with the pipeline phase selected, the system will automatically calculate the probability for closing the opportunity.

Bonus JScript: Filtering option set values

In order to prevent users from jumping backward or skipping phases from the sales pipeline, we can filter the options available within the Pipeline Phase option set based on the current value with a simple JScript:

SalesPipelineOptFilter = function() {
  var CRM_FORM_TYPE = Xrm.Page.ui.getFormType();
  if (CRM_FORM_TYPE == 4 || CRM_FORM_TYPE == 3) { return; }

	// Get value of Pipeline Phase set by user
	if (Xrm.Page.getAttribute("salesstagecode").getSelectedOption() != null)
	{var val_salesstagecode = Xrm.Page.getAttribute("salesstagecode").getSelectedOption().value;}
	else {var val_salesstagecode = null;}

	if (val_salesstagecode == 1)
	{ Xrm.Page.getControl("salesstagecode").removeOption(3); }

	else if (val_salesstagecode == 2)
	{ Xrm.Page.getControl("salesstagecode").removeOption(1); }

	else if (val_salesstagecode == 3)


Make sure you add this JScript on the onLoad event of the form as well as in the onChange event of the Process Code field (salesstagecode) field (labeled as Pipeline Phase in our customised form).

Coming up next: Creating a workflow

In my next post we will be discussing how to create workflows to support our customisation. This is important if we want to use the default Sales Pipeline report that comes with Dynamics CRM.

Tags: , , ,


Blog Categories

Recent Posts