locked
CRM 2011 Convert Lead RRS feed

  • Question

  • Dear All,

    I want to get the "Notes" tab information whenever I convert the lead to contact or Account or opportunity. This is not a out of box functionality. But how to do this through plugin or scripting?

    Please anybody share me information.

    Thanks in advanc.


    Thanks & Regards, Sudhakar

    Tuesday, February 28, 2012 6:41 AM

Answers

  • Hi sudhakar,

    Find the blow code incase any doubt let me know.

    //Code for the notes and attachments entered in the Lead are carried to Contact, Account and Opportunities when a lead is qualified. //Register your plugin when step when any of the three (Contact, Account and Opportunities) are creating. //First check the target entity is containing the “originatinglead” field or not. //If it not contain then revert back. public void Execute(IServiceProvider serviceProvider) { //Get the Plugin Contex from service provider IPluginExecutionContext context = (IPluginExecutionContext)serviceProvider.GetService(typeof(IPluginExecutionContext));

    //Check weather the "Traget" exists in the inpu parameter if (context.InputParameters.Contains("Target") == false) return;

    //Check weather the Input Parameter is a entity or not if (context.InputParameters["Target"] is Entity == false) return;

    //Get service and service factory from service provider IOrganizationServiceFactory serviceFactory = (IOrganizationServiceFactory)serviceProvider.GetService(typeof(IOrganizationServiceFactory)); IOrganizationService service = (IOrganizationService)serviceFactory.CreateOrganizationService(context.UserId);

    //Extract the tracing service for use in debugging and to do tracing ITracingService tracingService = (ITracingService)serviceProvider.GetService(typeof(ITracingService));

    //Check weather the Target entity have the originating lead filed or not Entity selectedEntity = (Entity)context.InputParameters["Target"]; if (selectedEntity.Attributes.Contains("originatingleadid") == false) return;

    EntityReference entLead = (EntityReference)selectedEntity.Attributes["originatingleadid"]; Guid LeadGuid = entLead.Id; try { if (context.MessageName == "Create") { #region Get Originatimg Lead Notes and attachment details from Lead Entity string strFetchNotes = @"<fetch version='1.0' output-format='xml-platform' mapping='logical' distinct='false'> <entity name='annotation'> <attribute name='subject' /> <attribute name='notetext' /> <attribute name='documentbody' /> <attribute name='filename' /> <attribute name='annotationid' /> <order attribute='subject' descending='false' /> <link-entity name='lead' from='leadid' to='objectid' alias='aa'> <filter type='and'> <condition attribute='leadid' operator='eq' value='{0}' /> </filter> </link-entity> </entity> </fetch>"; #endregion strFetchNotes = string.Format(strFetchNotes, LeadGuid); EntityCollection entNotes = (EntityCollection)service.RetrieveMultiple(new FetchExpression(strFetchNotes)); if (entNotes != null && entNotes.Entities.Count > 0) { for (int i = 0; i < entNotes.Entities.Count; i++) { Entity entNote = (Entity)entNotes.Entities[i]; #region Creating new Notes record from Existing Notes Record //array to remove from notes record string[] strAttributesNotestoRemove = new string[] { "createdon", "createdby", "modifiedon", "modifiedby", "annotationid", "objecttypecode", "objectid" }; //Clone new notes object from existing notes record Entity entNewAnnotation = CloneRecordForEntity("annotation", entNote, strAttributesNotestoRemove); //Add object id to attach this new notes to Invoice sponsor item record entNewAnnotation["objectid"] = new EntityReference(context.PrimaryEntityName, context.PrimaryEntityId); entNewAnnotation["objecttypecode"] = context.PrimaryEntityName; service.Create(entNewAnnotation); #endregion }//End for notes count }//End entities count }//End of create contex } catch (System.Web.Services.Protocols.SoapException ex) { throw new InvalidPluginExecutionException( String.Format("An error occurred in the {0} plug-in.", this.GetType().ToString()), ex); } } #region Clone Record /// <summary> /// Creates Cloned copy of soure entity for the given entity object /// </summary> /// <param name="targetEntityName">Schemaname of the cloned copy target entity</param> /// <param name="sourceEntity">Entity object of the record to be Cloned</param> /// <param name="strAttributestoRemove">Array of records not to include in the cloned copy</param> /// <returns>Entity object (Cloned Copy)</returns> private Entity CloneRecordForEntity(string targetEntityName, Entity sourceEntity, string[] strAttributestoRemove) { //Initiate target entity (cloned copy) Entity clonedEntity = new Entity(targetEntityName); //read the attributes from source entity AttributeCollection attributeKeys = sourceEntity.Attributes; //Loop through each of the key and check and add that in the target entity foreach (string key in attributeKeys.Keys) { //Check if key is not there in the list of removed keys if (Array.IndexOf(strAttributestoRemove, key) == -1) { //add key from source in the destination clonedEntity[key] = sourceEntity[key]; } //end if checking removed attributes }//end foreach keys return clonedEntity; } #endregion


    You can register the 3 steps for the same dll (Account, Contact and opportunity). It will work for all the 3.


    Friday, May 18, 2012 12:24 PM

All replies

  • Hi Sudhakar,

    You can create a post-operation plugin that runs on the 'QualifyLead' message. In the plugin, you can examine the OutputParameters collection of the plugin context. There will be a 'CreatedEntities' collection. From here, you can retrieve the newly created entities ids (contact, account or opportunity).

    From the original lead (passed in to the InputParameters), you can retrieve the associated notes using a Retrieve request and then create new notes and attach them to the newly created records using their ids.

    That's just a rough overview of the steps I think you'd need to take. If you need more details on any of the steps let me know.

    Kind regards

    Kirsten

    Tuesday, February 28, 2012 10:56 AM
  • Thanks for replying Kirste,

    Really it is a goood input for developing the plugin. But I have a small query.

    how to retrieve newly created id's from "CreatedEntities' collection.

    I would be very happy if you reply the answer with code.


    Thanks & Regards, Sudhakar

    Tuesday, March 20, 2012 11:31 AM
  • Please anybody respond the above query.

    Thanks & Regards, Sudhakar

    Tuesday, March 20, 2012 6:10 PM
  • Is there any valubale input from CRM fans? If so I would be very happy.


    Thanks & Regards, Sudhakar

    Monday, March 26, 2012 12:40 PM
  • Hi Sudhakar,

    Sorry for taking a while to get back to you. Full time job doesn't leave me much time to check the forum currently!

    With regards retrieveing the ids from the CreatedEntities object, this object is a EntityReferenceCollection. Each item in it is a EntityReference, which has a LogicalName property and Id. You can use the EntityReference if you need a lookup, or if you want the guids all you need to do is the following. Iterate through the collection, check the LogicalName property (this contains a string value for the entity name i.e. "account" or "contact") and then access the Id property (this is the Guid pointing to the newly created record).

    I;ve attached some code to exemplify this, but it is AS IS and has NOT been tested.

     IPluginExecutionContext pluginContext = (IPluginExecutionContext)serviceProvider.GetService(typeof(IPluginExecutionContext));
                if (pluginContext.OutputParameters.Contains("CreatedEntities") &&
                    pluginContext.OutputParameters["CreatedEntities"] is EntityReferenceCollection)
                {
                    EntityReferenceCollection createdEntities = pluginContext.OutputParameters["CreatedEntities"] as EntityReferenceCollection;
    
                    Guid accountId=Guid.Empty;
                    Guid contactId = Guid.Empty;
                    Guid opportunityId = Guid.Empty;
    
                    foreach (EntityReference item in createdEntities)
                    {
                        switch (item.LogicalName)
                        {
                            case "account":
                                accountId = item.Id;
                                break;
                            case "contact":
                                contactId = item.Id;
                                break;
                            case "opportunity":
                                opportunityId = item.Id;
                                break;
                            default:
                                break;
                        }
                    }
                }

    Kind regards

    Kirsten

    Monday, March 26, 2012 4:22 PM
  • Hi Kristen,

    Thanks for remembering me and reply with code.

    It is clear and I understood. Please send me the code for this one also. 

    "From the original lead (passed in to the InputParameters), you can retrieve the associated notes using a Retrieve request and then create new notes and attach them to the newly created records using their ids."


    Thanks & Regards, Sudhakar

    Tuesday, March 27, 2012 12:37 PM
  • Hi Sudhakar,

    Did you slove your problem (To copy all the notes and attachments to account/Contact/Opportunity while converting a lead) , Or still you have?

    I have also experienced the same problem.

    I solve it through a plugin.

    If you have still the problem let me know.

    Regards,

    Priya.

    Thursday, May 17, 2012 12:20 PM
  • No Priya, I didn't solve the problem. Please send me the plugin code.

    Thanks & Regards, Sudhakar

    Friday, May 18, 2012 9:45 AM
  • Hi sudhakar,

    Find the blow code incase any doubt let me know.

    //Code for the notes and attachments entered in the Lead are carried to Contact, Account and Opportunities when a lead is qualified. //Register your plugin when step when any of the three (Contact, Account and Opportunities) are creating. //First check the target entity is containing the “originatinglead” field or not. //If it not contain then revert back. public void Execute(IServiceProvider serviceProvider) { //Get the Plugin Contex from service provider IPluginExecutionContext context = (IPluginExecutionContext)serviceProvider.GetService(typeof(IPluginExecutionContext));

    //Check weather the "Traget" exists in the inpu parameter if (context.InputParameters.Contains("Target") == false) return;

    //Check weather the Input Parameter is a entity or not if (context.InputParameters["Target"] is Entity == false) return;

    //Get service and service factory from service provider IOrganizationServiceFactory serviceFactory = (IOrganizationServiceFactory)serviceProvider.GetService(typeof(IOrganizationServiceFactory)); IOrganizationService service = (IOrganizationService)serviceFactory.CreateOrganizationService(context.UserId);

    //Extract the tracing service for use in debugging and to do tracing ITracingService tracingService = (ITracingService)serviceProvider.GetService(typeof(ITracingService));

    //Check weather the Target entity have the originating lead filed or not Entity selectedEntity = (Entity)context.InputParameters["Target"]; if (selectedEntity.Attributes.Contains("originatingleadid") == false) return;

    EntityReference entLead = (EntityReference)selectedEntity.Attributes["originatingleadid"]; Guid LeadGuid = entLead.Id; try { if (context.MessageName == "Create") { #region Get Originatimg Lead Notes and attachment details from Lead Entity string strFetchNotes = @"<fetch version='1.0' output-format='xml-platform' mapping='logical' distinct='false'> <entity name='annotation'> <attribute name='subject' /> <attribute name='notetext' /> <attribute name='documentbody' /> <attribute name='filename' /> <attribute name='annotationid' /> <order attribute='subject' descending='false' /> <link-entity name='lead' from='leadid' to='objectid' alias='aa'> <filter type='and'> <condition attribute='leadid' operator='eq' value='{0}' /> </filter> </link-entity> </entity> </fetch>"; #endregion strFetchNotes = string.Format(strFetchNotes, LeadGuid); EntityCollection entNotes = (EntityCollection)service.RetrieveMultiple(new FetchExpression(strFetchNotes)); if (entNotes != null && entNotes.Entities.Count > 0) { for (int i = 0; i < entNotes.Entities.Count; i++) { Entity entNote = (Entity)entNotes.Entities[i]; #region Creating new Notes record from Existing Notes Record //array to remove from notes record string[] strAttributesNotestoRemove = new string[] { "createdon", "createdby", "modifiedon", "modifiedby", "annotationid", "objecttypecode", "objectid" }; //Clone new notes object from existing notes record Entity entNewAnnotation = CloneRecordForEntity("annotation", entNote, strAttributesNotestoRemove); //Add object id to attach this new notes to Invoice sponsor item record entNewAnnotation["objectid"] = new EntityReference(context.PrimaryEntityName, context.PrimaryEntityId); entNewAnnotation["objecttypecode"] = context.PrimaryEntityName; service.Create(entNewAnnotation); #endregion }//End for notes count }//End entities count }//End of create contex } catch (System.Web.Services.Protocols.SoapException ex) { throw new InvalidPluginExecutionException( String.Format("An error occurred in the {0} plug-in.", this.GetType().ToString()), ex); } } #region Clone Record /// <summary> /// Creates Cloned copy of soure entity for the given entity object /// </summary> /// <param name="targetEntityName">Schemaname of the cloned copy target entity</param> /// <param name="sourceEntity">Entity object of the record to be Cloned</param> /// <param name="strAttributestoRemove">Array of records not to include in the cloned copy</param> /// <returns>Entity object (Cloned Copy)</returns> private Entity CloneRecordForEntity(string targetEntityName, Entity sourceEntity, string[] strAttributestoRemove) { //Initiate target entity (cloned copy) Entity clonedEntity = new Entity(targetEntityName); //read the attributes from source entity AttributeCollection attributeKeys = sourceEntity.Attributes; //Loop through each of the key and check and add that in the target entity foreach (string key in attributeKeys.Keys) { //Check if key is not there in the list of removed keys if (Array.IndexOf(strAttributestoRemove, key) == -1) { //add key from source in the destination clonedEntity[key] = sourceEntity[key]; } //end if checking removed attributes }//end foreach keys return clonedEntity; } #endregion


    You can register the 3 steps for the same dll (Account, Contact and opportunity). It will work for all the 3.


    Friday, May 18, 2012 12:24 PM
  • Thank for sending the code Priya. I executed the plugin. It's working fine.

    Thanks & Regards, Sudhakar

    Tuesday, May 22, 2012 8:58 AM
  • Hi Priya ,

    Thank you for the code to copy notes on converting Lead to account , contact and opportunity.

    While registering this i have selected Message as "Qulifying Lead" and primary entity as "Lead" and left Secondary as blank.

    But it did not invoke the plugin on Qualifying lead.

    Could any one please explain me the Plugin steps.

    Thanks in Advance.


    Sreeni Pavalla

    Tuesday, May 22, 2012 5:41 PM
  • Hi Sreenivasulu,

    The above plugin code will invoke when message is “Create” not for “Qulifying Lead”.

    Steps to work the plugin

    1. Register the new assembly.
    2. Add new step
    3. Primary entity as contact
    4. Secondary as blank.

    When a new contact is creating it will check for the “Originating Lead” field.

    If it is there it will copy all the notes and attachments to contact or else it will revert back.

    The same step you can follow for account and opportunity. ( The same dll will take care of the 3).

    If still it not working let me know.

    Regards,

    Priya.

    http://osmosys.asia



    Wednesday, May 23, 2012 7:29 AM
  • Thank you so much Priya.

    I will register as suggested  and let you know.


    Sreeni Pavalla

    Wednesday, May 23, 2012 11:13 AM
  • Hi Priya,

    Thanks for the reply. It is working fine. I have named it as "CopyNotesonQualifiedlead"

    I have also registered a plugin on creation of annotation which is named "CopyNotesDescription". The requirement is , If a annotation is being created for Account, It should be able to copy the note to its parent account. It is working as expected.

    But i am getting an time out error in "CopyNotesDescription", While creating an annotation of the  "CopyNotesonQualifiedlead".

    I have just written code which can do the needful, But i did not taken of concurrency and other things.

    Could you please help me by telling what is causing the issue.

    Thanks,


    Sreeni Pavalla

    Wednesday, May 23, 2012 3:34 PM
  • Hi Sreeni,

    What I understood from your problem is you are firing your plugin in annotation creation.

    So what’s happening when a new note is creating for Account1, If the Account1 having a parent account2 it is coping/creating the notes to account2.

    Let’s say if the Account2 having a parent Account3 it trying to create notes for Account3…so on…

    So it is going through an infinite loop.

    Once try by checking the in the starting of your code as

    If(Context.Depth == 1)

    {

    //

    }

    May be it will work……

    Regards,

    Priya.

    http://osmosys.asia

    Thursday, May 24, 2012 11:45 AM
  • Hi Everyone,

    where should I add the following code so it becomes functional??

    Thank you for your fast reply,

    Regards,

    Samer

    Tuesday, July 30, 2013 6:35 AM
  • Hi Priya Diz IZ Santhosh...This Code IS Not working For ME.whatz wrong?

    is der any changes to do in code.

    and am new to crm. plz respond me

    Wednesday, November 27, 2013 5:52 AM
  • Hi Priya Diz IZ Santhosh...This Code IS Not working For ME.whatz wrong?

    is der any changes to do in code.

    and am new to crm. plz respond me

    Wednesday, November 27, 2013 5:54 AM
  • In That COde Entity Name Is Annonation right. so am not getting that one what is annonation entity? plz respond me asap.

    thank uh.

    Wednesday, November 27, 2013 5:59 AM
  • is der any changes to do in code please Hel me Sudhakar
    • Edited by Nani11 Wednesday, November 27, 2013 6:29 AM
    Wednesday, November 27, 2013 6:25 AM
  • Hello Santhosh,

    Sorry for the late reply.

    Could you please tell exact issue what you are facing and in which line?

    Regards,

    Priya

    Monday, December 16, 2013 5:34 AM
  • Priya, may I just say I love you!!

    I have next to no experience with programming and even less with Visual studio. I found a YouTube video walking through the process to register a plugin and with your code THIS WORKED ON THE FIRST TRY!! Yahoo!!!

    I really have no idea why there isn't just a checkbox to enable this functionality (or rather it should be on by default).

    Thanks!
    Devin

    Friday, January 24, 2014 4:22 AM
  • Hi Priya,

    I used your code in a solution where I have a custom workflow activity. I set the class as "Public" and it derives from "iPlugin". Then I register the solution with the "PluginRegistration.exe", but in the CRM when I call the plugin to add it as step I can only see my Custom Workflow Activity, is there anything else to change here to be able to see the Plugin class?

    Thanks for your help!

    Tuesday, March 11, 2014 5:04 PM
  • Hi Rawler, 


    You can create a new solution for plugin and the add the code. Register the plugin using the plugin registration exe.

    Then the see if it is working or not?

    Regards,

    Priya.


    • Edited by PriyaSwain Thursday, March 13, 2014 4:59 AM
    Thursday, March 13, 2014 4:58 AM
  • Hi Priya, yes it worked. Thanks!
    Monday, March 17, 2014 3:49 PM