Click here to Skip to main content
15,881,898 members
Articles / Web Development / ASP.NET
Tip/Trick

CRM to CRM Leads Qualification by Aggregated Leads Indicator Using Office 365 and Microsoft CRM Online

Rate me:
Please Sign up or sign in to vote.
0.00/5 (No votes)
26 May 2015CPOL8 min read 7.8K   1  
In this article I will demonstrate an advanced topic that can improve bussiness processes that start in one CRM and continue in another CRM.

Background

In this article I will demonstrate an advanced topic that can improve bussiness processes that start in one CRM and continue in another CRM. The topic is: communication between two Customer-Relationship-Management systems.

CRMs can communicate in the following ways, listed in decreasing order of programming effort:

  1. Integration
  2. Data import, batch
  3. Collaboration

There are at least two reasons for applying CRM2CRM:

The first reason of using CRM2CRM communication is related to service module: Two CRMs need to exchange information in order to serve the client. When no CRM2CRM communication is applied, the customer often has no alternative but to deliver the information, his own data, by himself. This situation occurs, for example, in Health Care systems and their pharmacies, medical institutes and hospitals. The customer has to get a printed copy of his data from the HealthCare system, and submit it to a pharmacy, or medical institute and vice versa, until the process ends.

The second reason of using CRM2CRM communication is related to sales module: Two CRMs need to exchange marketing data. Firms that are incapable of producing enough sales opportunities can supply desired client profiles and outsource lead creation to another company which has call centers, or or more workers or better global ecommerce functionality.

Image 1

The aim

The aim is to enable CRM2CRM communication in sales module so one CRM can use the other in order to test leads in a certain perspective. In this case, the perspective is geographical region. The number of leads per region should be above threshold. Why? because firms can loose money on successful leads, when there are not enough leads to cover expanses. The question is to invest money or not to invest money in marketing in a certain geographical region. Assume that the firm requires minimal count of 250,000 leads in order to have marketing efforts be worthwhile per city. Consequently, the indicator per region is the count of leads divided by 250,000. If the indicator turns out to be above 1, the list of leads is ok, and should be sent to the other CRM.

Two cloud platforms combined in the solution

Image 2

The solution includes two cloud platforms which are part of one cloud environment:

  1. Microsoft CRM Online
  2. (On-Permises is suitable to connect with Office 365 as well)
  3. Microsoft Office 365 (Office Online)

Authentication of Microsoft Dynamics CRM (Online) with Microsoft Office 365

The magic in Office365 is authentication. Consequently, there is no need to move the leads file from server to server. The two CRMs have to agree on authentication so the two parties will act as one, enabling to carry out one bussiness process starting in one of the CRMs and continuing in the other CRM.

The solution as improvement and preliminary stage to Microsoft CRM Lead Scoring Model

We know that profitability is not a matter of a single customer, or several deals. Furthermore, the firm can loose money by offering services or products which are not sold in big enough quantities. So, it is very important to know, in advance, if a new region to be explored will be profitable in terms of required magnitude of deals. If this isn't the case, it is better to avoid selling to few customers, and have the budget allocated to something else. The same rule holds for other characteristics of the lead, such as age segmentation, and so on. In the following code, we set a minimal number of leads as 250,000 per region. This number should be calculated according to the economic considerations of the firm.

The score per region is improvement and preliminary stage to Microsoft lead scoring because by having this used prior to lead scoring, the firm can test if all the leads as a whole will be profitable to the firm, before actually trying the leads.

Qualify or disqualify the region for further marketing efforts

Image 3

Desired lead profile as set of attributes

We can use several attributes as a set that describe the profile of the lead. These attributes can be filled directly by CRM1 staff, or get values from default Microsoft CRM lead entity attributes and Microsoft CRM Lead Scoring Model attributes. Getting the values from default attributes can be done by mapping, client side code or server side code. The criteria ensures that the lead scoring that will be used later by CRM2, will not grade highly a lead with partially missing features in its profile. In other words, only leads with mandatory set of fields will be taken into the model of lead scoring after they comply with the aggregated lead score by region. Again, we don't want to put marketing effort in new regions where there will be not enough good leads, because it will result in an overall loss of money.

In this context we mark the lead generating firm as CRM1 and the smaller firm that receives the lead as CRM2. The communication between the two CRMs is collaboration using Office 365: the two CRMs share data of leads.

Example of lead attributes that can be used for the purpose of lead profile

  1. Is contact form filled
  2. Is banner clicked
  3. Is number of clicks on our website is over 10
  4. Is the potential client not using competitor product
  5. Is the person in contact holding a position of decision maker
  6. Is the brochure or demo clicked by the potential client

Code for retrieving leads, filtering by criteria and calculating indicator per region

The development described in this article uses set of criteria attributes with equal weight of 1, and should be applied prior to using lead scoring and not as something instead of lead scoring. The leads indicator per region should filter leads on an aggregated level by CRM1, prior to processing of leads on a per lead level, done by CRM2.

As described in the flowchart above, if lead profile attributes meet the criteria, the lead will be included in leads list that will be further processed by CRM2 and using the regular lead scoring, with additional attributes and different incremented points.

For simplicity purpose, the code uses user-defined fields. The following code does a retrieve multiple to get a collection of leads, uses a query with criteria and conditions expressions to filter leads in order to reach a desired profile. The foreach clause counts the leads in the output collection. If the count of leads divided by 250,000 is greater than one, so the indicator per region is greater than one, indicating that the region is worthwhile for further marketing efforts.
Else, lead list file of this region will not be shared with CRM2.

In the lead list file, every line in the file is a concatenation of attributes from the column set of lead entity. The new_feedack attribute can store feedback of CRM2 salespersons to be read by CRM1.

C#
using System;
using System.Collections.Generic;
using System.ServiceModel;
using Microsoft.Crm.Sdk.Messages;
using Microsoft.Xrm.Sdk;
using Microsoft.Xrm.Sdk.Client;
using Microsoft.Xrm.Sdk.Query;
using System.IO;

namespace LeadsQualification
{
    public class RetrieveLeadsAboveRegionTreshold
    {        
        private OrganizationServiceProxy _serviceProxy;          
        private List<Guid> _leadIdList = new List<Guid>();

        public void Run(ServerConnection.Configuration serverConfig)
        {
         using (_serviceProxy = new OrganizationServiceProxy(serverConfig.OrganizationUri,
								serverConfig.HomeRealmUri,
								serverConfig.Credentials,  
								serverConfig.DeviceCredentials))			                                             						   				                               						  
            {
             //This statement is required to enable early-bound type support.
             _serviceProxy.EnableProxyTypes();                
             DoQueryExpression();                
            }
        }

        private void DoQueryExpression()
        {
            // Build a query expression
            var queryExpression = new QueryExpression()
            {   
              Distinct = false,
              EntityName = Lead.EntityLogicalName,
              ColumnSet = new ColumnSet("fullname", 
				  	"address1_telephone1",
				   	"emailaddress1",
				    	"address1_city", 
				    	"new_IsContactFormFilled", 
				    	"new_IsBannerClicked", 
				    	"new_IsDecMaker",
				    	"new_IsNotUsingCompetProd", 
				    	"new_NumWebsiteClicks",
					"new_feedback";),  												 								 
                Criteria =
                {
                    Filters = 
                        {
                            new FilterExpression
                            {
                                FilterOperator = LogicalOperator.And,
                                Conditions = 
                                { 
				//we want explore leads coming from region of Jerusalem, for example:
				new ConditionExpression("address1_city", ConditionOperator.Equals, "Jerusalem"),
				
				//we want that candidate leads will meet all the following criteria:
				new ConditionExpression("new_IsContactFormFilled", ConditionOperator.Equals, "true"),
				new ConditionExpression("new_IsBannerClicked", ConditionOperator.Equals, "true"),
				new ConditionExpression("new_IsNotUsingCompetProd", ConditionOperator.Equals, "true"),
				new ConditionExpression("new_IsDecMaker", ConditionOperator.Equals, "true")
				},
			},
                            new FilterExpression
                            {
                                FilterOperator = LogicalOperator.Or,
                                Conditions =
                                {
				new ConditionExpression("address1_telephone1", ConditionOperator.NotNull),
				new ConditionExpression("emailaddress1", ConditionOperator.NotNull)
                                }
                            }
                        }
                }
            };
	
	// Run the query as a query expression.
	EntityCollection queryExpressionResult =
	_serviceProxy.RetrieveMultiple(queryExpression);
	DisplayLeadQueryResults(queryExpressionResult);
    }

    
    private static void DisplayLeadQueryResults(EntityCollection result)
    {            
	//create a writer and open a file that will store list of leads
	TextWriter tw = new StreamWriter("C:\\temp.docx");             
	int count_of_leads_per_region=0;
	double indicator_leads_per_region=0; // Use exact result in order to test the quality of the indicator								
	
	foreach (Entity entity in result.Entities)
		{
		var lead = entity.ToEntity<Lead>();
		++count_of_leads_per_region;

		// write a line of text to the file
		tw.WriteLine(lead.Id + ", " + 
		     lead.Fullname + ", " +
		     lead.address1_telephone1 + ", " +			             
		     lead.emailaddress1 + ", " +
		     lead.address1_city + ", " +
		     lead.new_NumWebsiteClicks + ", " +
		     lead.new_feedback);
		} //end foreach

	// Create the region indicator:
	indicator_leads_per_region=( (double)((count_of_leads_per_region +0.0)/250000) );

	// If the region is greater than 1, the leads should be used:
	if( indicator_leads_per_region >1 )
		{
		Console.Writeline("Leads indicator per region is sufficient: " + indicator_leads_per_region);
		System.IO.File.Move(@"C:\temp.docx", @"C:\leads.docx");
		}
	else
		{
		Console.Writeline("Leads list disqualified for this region ");
		}
	// close the stream
	tw.Close();
	}

        
        
    static public void Main(string[] args)
    {
        try
            {
            // Obtain the target organization's web address and client logon 
            // credentials from the user.
            ServerConnection serverConnect = new ServerConnection();
            ServerConnection.Configuration config = serverConnect.GetServerConfiguration();

            var app = new RetrieveLeadsAboveRegionTreshold();
            app.Run(config, true);
            }
            catch (FaultException<Microsoft.Xrm.Sdk.OrganizationServiceFault> ex)
            {
            Console.WriteLine("The application terminated with an error.");
            Console.WriteLine("Timestamp: {0}", ex.Detail.Timestamp);
            Console.WriteLine("Code: {0}", ex.Detail.ErrorCode);
            Console.WriteLine("Message: {0}", ex.Detail.Message);
            Console.WriteLine("Plugin Trace: {0}", ex.Detail.TraceText);
            Console.WriteLine("Inner Fault: {0}",
				null == ex.Detail.InnerFault ? "No Inner Fault" : "Has Inner Fault");
            }
            catch (System.TimeoutException ex)
            {
            Console.WriteLine("The application terminated with an error.");
            Console.WriteLine("Message: {0}", ex.Message);
            Console.WriteLine("Stack Trace: {0}", ex.StackTrace);
            Console.WriteLine("Inner Fault: {0}",
                null == ex.InnerException.Message ? "No Inner Fault" : ex.InnerException.Message);
            }
            catch (System.Exception ex)
            {
            Console.WriteLine("The application terminated with an error.");
            Console.WriteLine(ex.Message);

            // Display the details of the inner exception.
            if (ex.InnerException != null)
              {
              Console.WriteLine(ex.InnerException.Message);

              FaultException<Microsoft.Xrm.Sdk.OrganizationServiceFault> fe = ex.InnerException
                        as FaultException<Microsoft.Xrm.Sdk.OrganizationServiceFault>;
              if (fe != null)
                {
                Console.WriteLine("Timestamp: {0}", fe.Detail.Timestamp);
                Console.WriteLine("Code: {0}", fe.Detail.ErrorCode);
                Console.WriteLine("Message: {0}", fe.Detail.Message);
                Console.WriteLine("Plugin Trace: {0}", fe.Detail.TraceText);
                Console.WriteLine("Inner Fault: {0}",
                 null == fe.Detail.InnerFault ? "No Inner Fault" : "Has Inner Fault");
                }
              }
            }            

            finally
            {
            Console.WriteLine("Press <Enter> to exit.");
            Console.ReadLine();
            }
        }       
    }
}

Authentication between Office 365 and Microsoft CRM Online

Micosoft CRM Online and Office 365 enable you to Manage user account synchronization. The authentication with Office 365 can be combined not only with Microsoft CRM Online but also with Microsoft CRM on-premises.

In the Microsoft Dynamics CRM Online trial, administrators are provided with a recommended workflow called Start here tasks. You can sign-in to the Office 365 Admin Center, or sign-in directly to the Multiple Microsoft Dynamics CRM Online Services which includes Microsoft Social Listening, Microsoft Dynamics Marketing, Yammer, etc.

Microsoft published a detailed integration guide: Microsoft Dynamics CRM Online and Office 365. The guide is very detailed and covers several aspects such as: authentication, licensing, configuration and so on. When you sign-in to Office 365 you will see in the upper menu bar a link button that can connect directly to CRM. It is important to know that Office 365 is already designed to work smoothly with main products of Microsoft. Microsoft already did the integration for you.

One of the things that helps admins to connect users between Office 365 and CRM Online is called Active Directory Federation Services. This approach uses corporate credentials for users. There is a variety of methods to connect Office 365 and Microsoft CRM Online. As explained in the guide, your decision on which method to choose is based largely on the size of your company and the depth and breadth of your IT resources.

One of the tips to admins is to consider using Single Sign On (SSO).

Image 4

SSO has the advantage of easy synchronization: you can provide URL to your users that takes advantage of your company's Active Directory and simplifies the sign-in experience.

For developers who wish to do more in authentication of applications for Microsoft CRM and Office 365, you can read about authentication methods on MSDN, there are several methods.

Store, sync and share

The lead list file created in the code above can be uploaded to Office 365 by upload button and browsing or by drag and drop to the desired online libraries on the left pane of the product you use for online Office documents. Then, you can synchronize and share.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Software Developer (Senior)
Israel Israel
This member has not yet provided a Biography. Assume it's interesting and varied, and probably something to do with programming.

Comments and Discussions

 
-- There are no messages in this forum --