Friday, February 20, 2009

Autofill Account from Contact (custom fields)

There are many times where I have come across requests to fill in fields automatically based on other fields in order to help cut down the time for data entry and also to help keep data integrity higher. One of the great ways to do this is to help in filling out "related" lookup fields. For instance, on an Opportunity a lot of companies can't always decide whether they want to see an Account or an Account in the Customer field. Or, management decides on Accounts and then the end users put Contacts in the Customer field because that's what makes sense to each role. However, this is a disaster for reports and getting the correct metrics at the end of a month, quarter, or year. A majority of the time it just makes more sense to show both Account and Contact fields on the Opportunity.

There is a script that can be used to help fill in one of the lookups for your end users. If you have them fill in the Contact field first you can figure out who that Contact works for by looking up their Parent Customer field. Sure, you could do this in a Plugin/Callout, but why do that when you can have the end user see it all filled out right in front of them? It makes a big difference to the end users. There are only a couple of lines that should have to be modified:

1. lookupItem = crmForm.all.[insert your Contact field here].DataValue;
2. crmForm.all.[your Account field].DataValue = larrray;

Outside of that if you shouldn't have to change anything if you are querying an Account via the ContactId. If you want to change the query that's up to you. Last thing before I post the script, this uses the 2006 WSDL, so don't expect this to work come CRM 5.0. We might get lucky and it could still work, but just know that it might not.

Here's the script:

var lookupItem = new Array;
lookupItem = crmForm.all.new_clientcontactid.DataValue;
var clientid;
if (lookupItem != null)
{
clientid = lookupItem[0].id;

var prodxml = GetClientInfo();
var companyid = "";

function GetClientInfo()
{
var xml = "" + "<?xml version=\"1.0\" encoding=\"utf-8\"?>" + "<soap:envelope soap="\" href="http://schemas.xmlsoap.org/soap/envelope/">http://schemas.xmlsoap.org/soap/envelope/\</a>" xmlns:xsi=\"<a href="http://www.w3.org/2001/XMLSchema-instance/">http://www.w3.org/2001/XMLSchema-instance\</a>" xmlns:xsd=\"<a href="http://www.w3.org/2001/XMLSchema/">http://www.w3.org/2001/XMLSchema\</a>">" + "<soap:body>" + " <query q1="\" href="http://schemas.microsoft.com/crm/2006/Query/">http://schemas.microsoft.com/crm/2006/Query\</a>" xsi:type=\"q1:QueryExpression\" xmlns=\"<a href="http://schemas.microsoft.com/crm/2006/WebServices/%22%3e">http://schemas.microsoft.com/crm/2006/WebServices\"></a>" + "<q1:entityname>contact</q1:EntityName>" +"<q1:columnset type="\">" + "<q1:attributes>" + "<q1:attribute>parentcustomerid</q1:Attribute>" + "</q1:Attributes>" + "</q1:ColumnSet>" + "<q1:distinct>false</q1:Distinct>" + "<q1:criteria>" + "<q1:filteroperator>And</q1:FilterOperator>" + "<q1:conditions>" + "<q1:condition>" + " <q1:attributename>contactid</q1:AttributeName>" + "<q1:operator>Equal</q1:Operator>" + "<q1:values>" + "<q1:value type="\">" + clientid + "</q1:Value>" + "</q1:Values>" + "</q1:Condition>" + "</q1:Conditions>" + "</q1:Criteria>" + "</query>" + "</soap:Body>" + "</soap:Envelope>" + "";
var xmlHttpRequest = new ActiveXObject("Msxml2.XMLHTTP");
xmlHttpRequest.Open("POST", "/mscrmservices/2006/CrmService.asmx", false);
xmlHttpRequest.setRequestHeader("SOAPAction","<a href="http://schemas.microsoft.com/crm/2006/WebServices/RetrieveMultiple">http://schemas.microsoft.com/crm/2006/WebServices/RetrieveMultiple</a>");
xmlHttpRequest.setRequestHeader("Content-Type", "text/xml; charset=utf-8");
xmlHttpRequest.setRequestHeader("Content-Length", xml.length);
xmlHttpRequest.send(xml);

var resultXml = xmlHttpRequest.responseXML;
//alert("resultxml = " + resultXml);

var entityNodes = resultXml.selectNodes("//RetrieveMultipleResult/BusinessEntities/BusinessEntity");

for (var i = 0; i < entityNodes.length; i++)
{
var entityNode = entityNodes[i];

var companyidnode = entityNode.selectSingleNode("q1:parentcustomerid");

companyid = (companyidnode == null) ? null : companyidnode.text;
}

/** get the name of the company **/
var xml1 = "" + "<?xml version=\"1.0\" encoding=\"utf-8\"?>" + "<soap:envelope soap="\" href="http://schemas.xmlsoap.org/soap/envelope/">http://schemas.xmlsoap.org/soap/envelope/\</a>" xmlns:xsi=\"<a href="http://www.w3.org/2001/XMLSchema-instance/">http://www.w3.org/2001/XMLSchema-instance\</a>" xmlns:xsd=\"<a href="http://www.w3.org/2001/XMLSchema/">http://www.w3.org/2001/XMLSchema\</a>">" + "<soap:body>" + " <query q1="\" href="http://schemas.microsoft.com/crm/2006/Query/">http://schemas.microsoft.com/crm/2006/Query\</a>" xsi:type=\"q1:QueryExpression\" xmlns=\"<a href="http://schemas.microsoft.com/crm/2006/WebServices/%22%3e">http://schemas.microsoft.com/crm/2006/WebServices\"></a>" + "<q1:entityname>account</q1:EntityName>" +"<q1:columnset type="\">" + "<q1:attributes>" + "<q1:attribute>name</q1:Attribute>" + "</q1:Attributes>" + "</q1:ColumnSet>" + "<q1:distinct>false</q1:Distinct>" + "<q1:criteria>" + "<q1:filteroperator>And</q1:FilterOperator>" + "<q1:conditions>" + "<q1:condition>" + " <q1:attributename>accountid</q1:AttributeName>" + "<q1:operator>Equal</q1:Operator>" + "<q1:values>" + "<q1:value type="\">" + companyid + "</q1:Value>" + "</q1:Values>" + "</q1:Condition>" + "</q1:Conditions>" + "</q1:Criteria>" + "</query>" + "</soap:Body>" + "</soap:Envelope>" + "";
var xmlHttpRequest = new ActiveXObject("Msxml2.XMLHTTP");
xmlHttpRequest.Open("POST", "/mscrmservices/2006/CrmService.asmx", false);
xmlHttpRequest.setRequestHeader("SOAPAction","<a href="http://schemas.microsoft.com/crm/2006/WebServices/RetrieveMultiple">http://schemas.microsoft.com/crm/2006/WebServices/RetrieveMultiple</a>");
xmlHttpRequest.setRequestHeader("Content-Type", "text/xml; charset=utf-8");
xmlHttpRequest.setRequestHeader("Content-Length", xml.length);
xmlHttpRequest.send(xml1);

var resultXml1 = xmlHttpRequest.responseXML;

var entityNodes = resultXml1.selectNodes("//RetrieveMultipleResult/BusinessEntities/BusinessEntity");

for (var j = 0; j < entityNodes.length; j++)
{
var entityNode = entityNodes[j];

var namenode = entityNode.selectSingleNode("q1:name");

var companyname = (namenode == null) ? null : namenode.text;
}

var larray = new Array;
var l = new Object();
l.id = companyid;
l.typename = 'account';
l.name = companyname;
larray[0] = l;
crmForm.all.new_clientcompanyid.DataValue = larray;

return resultXml;
}
}

Please note, I tested this in CRM Online and it doesn't work. Perhaps the 2006 WSDL isn't exposed with CRM Online, I'm not 100% sure, but just be aware that this script won't work there. Sorry.

David Fronk
Dynamic Methods Inc.

2 comments:

Unknown said...

Fonk Rocks!
Great Post definately better than the call out method.

Pierre Hulsebus
http://blog.solomon2crm.com

Andy said...

Dr. Fronk,

Just to go along with your qualification of the 2006 WSDL, I have also experienced some issues with the 2006 WSDL when the form is accessed over IFD.

Post a Comment