Convert lead to contact, account and/or opportunity programmatically

Update: The codeproject missed a line of code. After you have executed the InitializeFromRequest, then you'll get a InitializeFromResponse. This response has got a entity in it. This entity you will need to create. The entity does not yet get created by executing the InitializeFromRequest! The line to add is:


Guid entityId = service.Create(rps.Entity);

Today I needed some code which does convert a lead to a contact programmatically. Instead of just building, I first asked my mate Google if he knew how to do that. Kind as Google is, he told me that he didn't know, but he knew that Cem Onvar knows that. Cem has published the code on the codeproject website.

Basically it comes down to two steps. The first step is to disable the lead. This can be done by using the SetStateLeadRequest. The second step is to use an request class which is quite rare. It's the InitializeFromRequest class. On this class you can set the EntityMoniker attribute to the lead which you just disabled. On the same request you'll need to set the target entityname to the name of the entity you wish to convert the lead into (contact, account or opportunity) and you'll need to set the TargetFieldType. This would most likely be TargetFieldType.All. Now execute that request and you're done.

For the direct code look at the codeproject site.

Keep in mind that you can use this approach for all kind of conversions.

14 comments:

Anonymous said...

Hello Ronald


In my organization we want to qualify leads to accounts and set automatically the account field (relantionship) as lead.
Can you help me?
Best Regards

Ana Pinto

jmollis said...

I have a peculiar problem: I create leads from a website using a staging database and stored proc that creates a lead. It works. However, I want to set up a workflow for leads that will do a conversion of the lead to account and contact automatically. I can get that to work from the UI but not from a lead created from the staging database (the 'created' event for workflow never seems to get set). Any suggestions?

Ronald Lemmen said...

Hi,

The create event will be called as part of the business logic in the webservice call 'Create'. This means that you should not create the lead directly in the database by using a stored procedure. You should create a small integration program which would copy the lead data from your staging table to the CRM webservices. You can use an SSIS package for this as well, that can talk to webservices as well.

Ronald

jmollis said...

Thanks for the suggestion, I believe that your method would fit in with what we want to accomplish. I am wondering, though, if there are licensing issues for gathering information from a web site and having an SSIS process pull it in and populate the CRM tables?

You've been most helpful.

Ronald Lemmen said...

Hi,

I would expect that a single license for an integration user would be sufficient, just like when you're using a product like Scribe. You should check this with your local Microsoft people though since I'm a developer, no license guru :)

Kind regards,
Ronald

jmollis said...

Thanks, Ronald. I'm checking into licensing and should be okay.

One small thing- I am implementing a SSIS solution for creating a lead as you suggested but am running into a 'server unable to process request' which I believe is because I don't populate the DeletionStatusCode field from my input0 in the vb script to create the lead. The problem is, the DeletionStatusCode field does NOT come with the .wsdl refernce file and is not in the lead entity in the script. Since this is a required field, I don't know how to populate it via the script.

Sorry to keep bothering you but I'm new to this.

J

Ronald Lemmen said...

Hi J,

There is no need to specify the deletion state code in the webservice. You should enable tracing to find out why the server won't allow you to create the record.

Ronald

Anonymous said...

I find your post very helpful... I'm currently trying to convert a lead to account, contact, and opportunity. However, it gives me an error on the last line (Guid OpportunityID = service.Create(rps.Entity);) while trying to convert to opportunity, it it worked for both account and contact. Any suggestions? Thanks...

Ronald Lemmen said...

Hi,

There must be a good reason for CRM to throw an error message. Try to enable the trace logging, look into the log (with the trace log viewer) and try to determine the cause of the error. It would be great if you could share the solution here as well for other users as soon as you found the root cause.

Good luck!
Ronald

Nick said...

Hi Ronald

Thanks for this code! I am having the same issue that the previous poster mentioned about not being able to create an opportunity. I took your suggestion and used the traceviewer and discovered the issue is that we have not specified a customer record for the opportunity.
"Crm Exception: Message: Customer not specified., ErrorCode: -2147220947"

Any idea how we can associate the customer when creating the opportunity via this function?

Nick said...

Figured it out.
Basically convert the InitializeFromResponse entity to a dynamic entity and add what is missing.

Cheers
Nick

if (entityName == "opportunity")
{
DynamicEntity oppt = new DynamicEntity();
oppt = (DynamicEntity)rps.Entity;

//need to set correct status code
StatusProperty stat = new StatusProperty();
stat.Name = "statuscode";
stat.Value = new Status();
stat.Value.Value = 1;

//need to set to correct customer
CustomerProperty cust = new CustomerProperty();
cust.Name = "customerid";
cust.Value = new Customer();
cust.Value.type = EntityName.account.ToString();
cust.Value.Value = new Guid("C02BC834-451C-DF11-8B30-000C29990809");

oppt.Properties.Add(cust);
oppt.Properties.Add(stat);

Service.Create(oppt);
}

Ronald Lemmen said...

That's just what I wanted to answer ;)

No seriously, great that you figured this out and share this with the other readers of this blog Nick!

Unknown said...

throwing error at
oppt = (DynamicEntity)rps.Entity;
as "Unable to cast object of type 'WcfCrmService.CrmServiceWsdl.opportunity' to type 'WcfCrmService.CrmServiceWsdl.DynamicEntity'".

Curtis said...

Just in case no one has notice the properties Moniker1, Moniker2 and RelationshipName has been deprecated on the AssociateEntitiesRequest class in CRM 2011 on premise