Thursday 31 January 2013

SOAP LookUp Retrieve Tool !!!


Introduction 

This tool is basically to retrieve the data from lookup field entity. When we do a lookup in CRM 2011 we want to auto populate some fields value in child entity based on parent entity fields.

Assumptions

Source fields and target fields should have same data types.
Source field and target field should have in same order.


Here is the JavaScript code.

///This function retrieves the specified data from the entity & puts into the target Attribute of the entity from where this function is called.


function GetLookUpRecordData(lookUpFieldName, sourceAttributesName, targetAttributeName, primaryKey) {
    //check source and target fields
    if (sourceAttributesName == null || targetAttributeName == null) {
        alert("Please check Source fields & Target fields");
        return;
    }
    //get all source fields
    var sourceFields = sourceAttributesName.split(',');
    var targetFields = targetAttributeName.split(',');

    if (sourceFields.length != targetFields.length) {
        alert("Source fields & Target fields lenght does not match");
        return;
    }

    try {

        //get the Entity Id and Entity Name from lookup field
        var lookUpField = Xrm.Page.data.entity.attributes.get(lookUpFieldName);
        if (lookUpField.getValue() != null) {
            var entityID = lookUpField.getValue()[0].id;
            var entityName = lookUpField.getValue()[0].entityType;
            var PKey = lookUpFieldName;

            //check if Primary Key is other then lookUpFieldName
            if (primaryKey != null)
                PKey = primaryKey;

            //build fetchXml request to get the data
            var _FetchRequest = "<fetch version='1.0' output-format='xml-platform' mapping='logical'>" +
            "<entity name='" + entityName + "'>";
            for (var a = 0; a < sourceFields.length; a++) {
                _FetchRequest += "<attribute name='" + sourceFields[a] + "' />";
            }

            _FetchRequest += "<filter type='and'>";
            _FetchRequest += "<condition attribute='" + PKey + "' operator='eq' value='" + entityID + "' /> ";
            _FetchRequest += "</filter></entity></fetch>";

            //send FetchXml for execute
            var xmlReturn = FetchXML(_FetchRequest);
            if (xmlReturn != null) {
                // Create an XML document that you can parse.
                var oXmlDoc = new ActiveXObject("Microsoft.XMLDOM");
                oXmlDoc.async = false;
                // Load the XML document that has the UnEncoded results.
                oXmlDoc.loadXML(xmlReturn.xml);

                for (var a = 0; a < sourceFields.length; a++) {
                    var targetField = Xrm.Page.data.entity.attributes.get(targetFields[a].replace(' ', ''));
                    if (targetField != null) {
                        //get the target field data type
                        var attributeType = targetField.getAttributeType();
                        // set the value in target attribute
                        SetTargetAttributeValue(oXmlDoc, sourceFields[a], targetFields[a], attributeType);

                    } //End of If
                } // End of For Loop

            } //End of If
        }
    } // End of try block

    catch (Err) {
        alert(Err.message);
        return;
    }
}

//Execute fetchxml request
function ExecuteRequest(_XML) {
    try {
        var _ResultXML = null;
        var xmlhttp = new XMLHttpRequest();
        xmlhttp.open("POST", Xrm.Page.context.getServerUrl() + "/XRMServices/2011/Organization.svc/web", false);
        xmlhttp.setRequestHeader("Accept", "application/xml, text/xml, */*");
        xmlhttp.setRequestHeader("Content-Type", "text/xml; charset=utf-8");
        xmlhttp.setRequestHeader("SOAPAction", "http://schemas.microsoft.com/xrm/2011/Contracts/Services/IOrganizationService/Execute");
        xmlhttp.send(_XML);
        _ResultXML = xmlhttp.responseXML;
        var errorCount = _ResultXML.selectNodes('//faultstring').length
        if (errorCount != 0) {
            var msg = _ResultXML.selectNodes('//faultstring')[0].nodeTypedValue;
            alert(msg);
            _ResultXML = null;
            return _ResultXML;
        }
        else {
            return _ResultXML;
        }
    }
    catch (Err) {
        alert(Err.message);
        return;
    }
}
//set fetchxml request
function FetchXML(_FetchXml) {
    try {
        var requestMain = "<s:Envelope xmlns:s=\'http://schemas.xmlsoap.org/soap/envelope/\'>" +
    "<s:Body>" +
     "    <Execute xmlns=\'http://schemas.microsoft.com/xrm/2011/Contracts/Services\' xmlns:i=\'http://www.w3.org/2001/XMLSchema-instance\'>" +
     "      <request i:type=\'a:RetrieveMultipleRequest\' xmlns:a=\'http://schemas.microsoft.com/xrm/2011/Contracts\'>" +
     "        <a:Parameters xmlns:b=\'http://schemas.datacontract.org/2004/07/System.Collections.Generic\'>" +
     "          <a:KeyValuePairOfstringanyType>" +
     "            <b:key>Query</b:key>" +
     "            <b:value i:type=\'a:FetchExpression\'>" +
     "              <a:Query>" + CrmEncodeDecode.CrmXmlEncode(_FetchXml) + "</a:Query>" +
     "</b:value>" +
     "</a:KeyValuePairOfstringanyType>" +
     "</a:Parameters>" +
     "  <a:RequestId i:nil=\'true\' />" +
     "        <a:RequestName>RetrieveMultiple</a:RequestName>" +
     " </request>" +
     "</Execute>" +
     "</s:Body></s:Envelope>";
        return ExecuteRequest(requestMain);
    }
    catch (Err) {
        alert(Err.message);
        return;
    }

}

// get the value from SOAP response and set to target attribute
function SetTargetAttributeValue(oXmlDoc, sourceAttributeName, targetAttributeName, targetAttributeType) {
    try {
        var FetchedAttributes = oXmlDoc.selectSingleNode('//a:Attributes');
        var targetField = Xrm.Page.data.entity.attributes.get(targetAttributeName.replace(' ', ''));
        targetField.setValue(null);
        //check for datatype
        switch (targetAttributeType.toLowerCase()) {

            case 'lookup':
                if (FetchedAttributes.childNodes.length > 0) {
                    for (var a = 0; a < FetchedAttributes.childNodes.length; a++) {
                        if (FetchedAttributes.childNodes[a].childNodes[0].nodeTypedValue == sourceAttributeName) {
                            var lookupValue = new Array();
                            lookupValue[0] = new Object();
                            lookupValue[0].id = FetchedAttributes.childNodes[a].childNodes[1].childNodes[0].nodeTypedValue;
                            lookupValue[0].entityType = FetchedAttributes.childNodes[a].childNodes[1].childNodes[1].nodeTypedValue;
                            lookupValue[0].name = FetchedAttributes.childNodes[a].childNodes[1].childNodes[2].nodeTypedValue;
                            targetField.setValue(lookupValue);
                            break;
                        } //End of If
                    } // End of Loop
                }   // End of If

                break;
            case 'datetime':
                if (FetchedAttributes.childNodes.length > 0) {
                    for (var a = 0; a < FetchedAttributes.childNodes.length; a++) {
                        if (FetchedAttributes.childNodes[a].childNodes[0].nodeTypedValue == sourceAttributeName) {
                            var targetAttributeValue = FetchedAttributes.childNodes[a].childNodes[1].nodeTypedValue;
                            if (targetAttributeValue != null) {
                                var newDate = new Date();
                                var indexofT = targetAttributeValue.indexOf("T");
                                var strdatepart = targetAttributeValue.substring(0, indexofT);
                                var month = strdatepart.substring(5, 7);
                                var year = strdatepart.substring(0, 4);
                                var day = strdatepart.substring(8);
                                if (month.substring(0, 1) == '0') {
                                    month = month.substring(1);
                                } // End of If
                                newDate.setMonth(parseInt(month) - 1);
                                newDate.setFullYear(year);
                                newDate.setDate(day);
                                targetField.setValue(newDate);
                            } // End of null check
                            break;
                        } // End of For Loop
                    } // End of If

                }   // End of If
                break;
            case 'integer':
                if (FetchedAttributes.childNodes.length > 0) {
                    for (var a = 0; a < FetchedAttributes.childNodes.length; a++) {
                        if (FetchedAttributes.childNodes[a].childNodes[0].nodeTypedValue == sourceAttributeName) {
                            var targetAttributeValue = FetchedAttributes.childNodes[a].childNodes[1].nodeTypedValue;
                            targetField.setValue(parseInt(targetAttributeValue));
                            break;
                        } // End of If
                    } // End of For Loop
                }   // End of If
                break;
            case 'string':
            case 'memo':
                if (FetchedAttributes.childNodes.length > 0) {
                    for (var a = 0; a < FetchedAttributes.childNodes.length; a++) {
                        if (FetchedAttributes.childNodes[a].childNodes[0].nodeTypedValue == sourceAttributeName) {
                            var targetAttributeValue = FetchedAttributes.childNodes[a].childNodes[1].nodeTypedValue;
                            targetField.setValue(targetAttributeValue);
                            break;
                        } // End of If
                    } // End of For Loop

                }   // End of If

                break;

            case 'boolean':
                if (FetchedAttributes.childNodes.length > 0) {
                    for (var a = 0; a < FetchedAttributes.childNodes.length; a++) {
                        if (FetchedAttributes.childNodes[a].childNodes[0].nodeTypedValue == sourceAttributeName) {
                            var targetAttributeValue = FetchedAttributes.childNodes[a].childNodes[1].nodeTypedValue;
                            if (targetAttributeValue == 'true')
                                targetField.setValue(true);
                            else
                                targetField.setValue(false);
                            break;
                        } // End of If
                    } // End of For Loop

                }   // End of If
                break;
            default:
                if (FetchedAttributes.childNodes.length > 0) {
                    for (var a = 0; a < FetchedAttributes.childNodes.length; a++) {
                        if (FetchedAttributes.childNodes[a].childNodes[0].nodeTypedValue == sourceAttributeName) {
                            var targetAttributeValue = FetchedAttributes.childNodes[a].childNodes[1].nodeTypedValue;
                            targetField.setValue(parseFloat(targetAttributeValue));
                            break;
                        } // End of If
                    } // End of For Loop

                }   // End of If
        } // end of switch statement

    }
    catch (Err) {
        alert(Err.message);
        return;
    }
}

How to use this Tool 

Following function needs to be call using these required parameters -

GetLookUpRecordData (lookUpFieldName, sourceAttributesName, targetAttributeName, primaryKey)

lookUpFieldName – Name of lookup field in child entity.

sourceAttributesName – Source attributes name list using comma separated values. i.e. (“name, lastname, firstname) etc.

targetAttributeName – Target attributes name list using comma separated values i.e. (“name, lastname, firstname) etc.

primaryKey – if lookUpFieldName parameter value is same as primary key of the source entity then pass null value for this parameter otherwise pass primary key field name of the source entity. i.e. (accountid, contactid, opportunityid) etc.


For example, we want to auto populate Main Phone and Parent Account fields with contact's Business Phone and Parent Customer values when Primary Contact gets associated with account.

Create a function and call GetLookUpRecordData inside that with required parameters. then call your function

function SetContactFields() {
    GetLookUpRecordData("primarycontactid", "telephone1,parentcustomerid", "telephone1,parentaccountid", "contactid");
}

Hope this helps,

Please provide your valuable suggestions / feedback.
















2 comments:

  1. I have been looking FOREVER for an example script that will allow me to pull lookup data from one record to another. Thank you SO MUCH!! If I weren't so old I would be doing cartwheels! It works perfectly.

    -TWelch

    ReplyDelete