locked
Is there any way (maybe a plugin) of converting Accounts and/or Contacts to Leads? RRS feed

  • Question

  • The scenario: we imported our leads as Accounts and Contacts, and have been using them this way for the past 3-4 months and have now realise it's not working. We've amassed over 6000 Activities that have Regarding against these Contacts and Accounts. We're hoping to move these over to the Lead entity - what's the best way?

    The current method in my head is

    1. Export all leads in the Contact entity

    2. Re-import to the Lead entity

    3. Do an advanced find and look for the Activities in these Contacts, manually change the Set Regards from the Contact entity to the Leads entity.

    4. Done!

    Step 3. is where I need some help - it's quite tedious with 6000 Activities over more than 1900 unique Contacts! Of course this could even be completely avoided if there was another way of doing it... Looking for a magic plugin or workflow...

    Thanks in advance!


    Friday, November 28, 2014 10:11 AM

All replies

  • You export your contacts which you need to convert to Leads. There you can get hold of the Guids of those contacts in Excel.
    Then create a console application and use the follwing code. What you need is a data fix.

    First the program is going to loop through your contacts and create a lead for each contact with the relevant details. Then it will go 

    through the activities for that contact and move them to that lead record. Finally it will delete the contact record. (if you don't want 

    to delete you an deactivate it).

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Threading.Tasks;
    using System.ServiceModel.Description;
    using Microsoft.Xrm.Sdk.Client;
    using Microsoft.Xrm.Sdk.Query;
    using Microsoft.Xrm.Sdk;
    
    namespace Test
    {
        class Program
        {
            static void Main(string[] args)
            {
                //read the extracted contacts list and add the contact ids to the list.
                List<Guid> contactIds = new List<Guid>(); 
                CreateLeads(contactIds);
            }
    
            private static void CreateLeads(List<Guid> contactIds)
            {
                ClientCredentials cc = new ClientCredentials();            
                cc.Windows.ClientCredential = new System.Net.NetworkCredential("Administrator", "password", "DEV");
                Uri serviceUri = new Uri("http://localhost:5555/DEV1/XRMServices/2011/Organization.svc");
                OrganizationServiceProxy proxy = new OrganizationServiceProxy(serviceUri, null, cc, null);
                proxy.EnableProxyTypes();
    
                foreach (Guid contactId in contactIds)
                {
                    Entity contact = proxy.Retrieve("contact", contactId, new ColumnSet(true));
                    Entity lead = new Entity("lead");
                    lead.Attributes.Add("firstname", contact.Attributes["firstname"].ToString());
                    lead.Attributes.Add("lastname", contact.Attributes["lastname"].ToString());
                    lead.Attributes.Add("emailaddress1", contact.Attributes["emailaddress1"].ToString());
                    //
                    //Follow this pattern for other attributes as well.
                    //
                    Guid leadId = proxy.Create(lead);
                    MoveEmails(contactId, leadId, proxy);
                    MovePhoneCalls(contactId, leadId, proxy);
                    MoveTasks(contactId, leadId, proxy);
                    MoveAppointments(contactId, leadId, proxy);
                    //Follow the same pattern for all other activity types
                    proxy.Delete("contact", contactId);//deleting the contact.
                }
            }
    
            private static void MoveEmails(Guid contactId, Guid leadId, OrganizationServiceProxy proxy)
            {
                ConditionExpression condition = new ConditionExpression("regardingobjectid", ConditionOperator.Equal, contactId);
                FilterExpression filter = new FilterExpression();
                filter.AddCondition(condition);
                QueryExpression query = new QueryExpression("email");
                query.Criteria.AddFilter(filter);
                EntityCollection activities = proxy.RetrieveMultiple(query);
                foreach (var activity in activities.Entities)
                {
                    activity["regardingobjectid"]=new EntityReference("lead", leadId);
                    proxy.Update(activity);
                }
            }
    
            private static void MovePhoneCalls(Guid contactId, Guid leadId, OrganizationServiceProxy proxy)
            {
                ConditionExpression condition = new ConditionExpression("regardingobjectid", ConditionOperator.Equal, contactId);
                FilterExpression filter = new FilterExpression();
                filter.AddCondition(condition);
                QueryExpression query = new QueryExpression("phonecall");
                query.Criteria.AddFilter(filter);
                EntityCollection activities = proxy.RetrieveMultiple(query);
                foreach (var activity in activities.Entities)
                {
                    activity["regardingobjectid"] = new EntityReference("lead", leadId);
                    proxy.Update(activity);
                }
            }
            private static void MoveTasks(Guid contactId, Guid leadId, OrganizationServiceProxy proxy)
            {
                ConditionExpression condition = new ConditionExpression("regardingobjectid", ConditionOperator.Equal, contactId);
                FilterExpression filter = new FilterExpression();
                filter.AddCondition(condition);
                QueryExpression query = new QueryExpression("task");
                query.Criteria.AddFilter(filter);
                EntityCollection activities = proxy.RetrieveMultiple(query);
                foreach (var activity in activities.Entities)
                {
                    activity["regardingobjectid"] = new EntityReference("lead", leadId);
                    proxy.Update(activity);
                }
            }
    
            private static void MoveAppointments(Guid contactId, Guid leadId, OrganizationServiceProxy proxy)
            {
                ConditionExpression condition = new ConditionExpression("regardingobjectid", ConditionOperator.Equal, contactId);
                FilterExpression filter = new FilterExpression();
                filter.AddCondition(condition);
                QueryExpression query = new QueryExpression("appointment");
                query.Criteria.AddFilter(filter);
                EntityCollection activities = proxy.RetrieveMultiple(query);
                foreach (var activity in activities.Entities)
                {
                    activity["regardingobjectid"] = new EntityReference("lead", leadId);
                    proxy.Update(activity);
                }
            }
        }
    }
    

    Thanks


    Sachith Chandrasiri

    Saturday, November 29, 2014 8:05 AM
  • Hi,

    There is a simple way of doing it using sql update.

    1. Create a new field on lead as contactid (Single line of text) and export all the contacts with contactid in an excel.

    2. Re-import the excel as lead and contactid of lead entity is mapped to contactid of excel.

    3. Create Update script and run it.

    update activitypointer
    set regardingobjectid = L.Leadid
    from activitypointer as AP inner join Lead as L on L.new_contactid = AP.regardingobjectid
    

    4. delete the contactid field on lead.


    Regards, Saad

    Monday, December 1, 2014 11:01 AM
  • Hi Saad,

    Isn't it unsupported to update the CRM database using SQL??

    Thanks

    Sachith


    Sachith Chandrasiri

    Monday, December 1, 2014 7:43 PM
  • It is unsupported.

    Rickard Norström Developer CRM-Konsulterna
    http://www.crmkonsulterna.se
    Swedish Dynamics CRM Forum: http://www.crmforum.se
    My Blog: http://rickardnorstrom.blogspot.se

    Tuesday, December 2, 2014 2:33 PM
  • I really don't like the plugin method. You will face a lot of problems doing batch processing with a synchronous/asynchronous plugins. All Plugins have a 2 minute timeout limit - so the plugin route will fail, not to mention cause a huge performance hit, possible deadlocks in the DB. A custom workflow is better. What is even more simplistic is to use the workflow designer.

    Tuesday, December 2, 2014 5:11 PM
  • Is it possible to somehow make a search that retrieves your accounts and contacts (two searches) that you want to chage to leads? If so, I would probably do a program that uses those searches and make the lead and then move all activites to that lead since this is a one shot job. Well, you can use it later too if it would happen again.

    Rickard Norström Developer CRM-Konsulterna
    http://www.crmkonsulterna.se
    Swedish Dynamics CRM Forum: http://www.crmforum.se
    My Blog: http://rickardnorstrom.blogspot.se

    Wednesday, December 3, 2014 7:25 AM