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.
















Wednesday 9 January 2013

MS CRM 2011 integration with SharePoint 2010 !!!


MS CRM 2011 provides OOB support for SharePoint integration.This is good post about OOB SharePoint integration.
http://blogs.msdn.com/b/crm/archive/2010/10/08/crm-with-sharepoint-integration-introduction.aspx

We got a new requirement from one of our client where client want to create new documents folders in different SharePoint libraries.

I found good post about SharePoint Client Object Model. Following topics are covered on this post
  1. How to connect with SharePoint 2010 using SharePoint Client Object Model.
  2. How to retrieve SharePoint 2010 documents libraries.
  3. How to create folder in a document library


Download SharePoint Client Object Model and add the reference of following API in your project

Microsoft.SharePoint.Client
Microsoft.SharePoint.Client.Runtime

Here is the sample code.

//create client context
ClientContext _clientContext = new ClientContext(“http://server/SharePointDev”);
_clientContext.Credentials = new System.Net.NetworkCredential("username", "password", "domain");
//create web object
Web web = _clientContext.Web;
_clientContext.Load(web);
_clientContext.ExecuteQuery();

 //read entire document libraries from SharePoint site
var DocumentLibraries = _clientContext.LoadQuery(web.Lists.Where(p => p.BaseType == BaseType.DocumentLibrary && p.Hidden == false));
_clientContext.ExecuteQuery();

If you want to read specific libraries then code will be like
var DocumentLibraries = _clientContext.LoadQuery(web.Lists.Where(p => p.BaseType == BaseType.DocumentLibrary && p.Hidden == false && (p.Title == " library1 " || p.Title == " library2")));
_clientContext.ExecuteQuery();

// check if document libraries are available
if (DocumentLibraries.Count() > 0)
{
foreach (var DocumentLibrary in DocumentLibraries)
{
//Inside each library, create a folder
CreateFolder(_clientContext, web, DocumentLibrary.Title, _FolderName);

//Get Library URL
string url = DocumentLibrary.DefaultViewUrl;
int index = url.LastIndexOf("/Forms/");
url = url.Substring(0, index);
int index1 = url.LastIndexOf("/");
string libURLName = url.Substring(index1 + 1);

//Create SharePoint Document Location Record in CRM.
//string _CreatedFolderPath=_siteUrl+"/"+DocumentLibrary.Title+"/"+_FolderName;
string _CreatedFolderPath = _siteUrl + "/" + libURLName + "/" + _FolderName;
CreateDocumentLocationRecord(CrmService, DocumentLibrary.Title, _CreatedFolderPath, entity.Id);
}
}

private List GetDocumentLibrary(ClientContext _clientContext, Web web, string libraryName)
{
try
{
if (web != null)
{
var query = _clientContext.LoadQuery(
web.Lists.Where(p => p.Title == libraryName));
_clientContext.ExecuteQuery();
return query.FirstOrDefault();
}
}
catch (Exception ex)
{
throw new Exception(ex.Message);
}
return null;
}

private void CreateFolder(ClientContext _clientContext, Web web, string libraryName, string folder)
{
try
{
var list = GetDocumentLibrary(_clientContext, web, libraryName);
if (list != null)
{
var folders = list.RootFolder.Folders;
_clientContext.Load(folders);
_clientContext.ExecuteQuery();
var newFolder = folders.Add(folder);
_clientContext.ExecuteQuery();
}
}
catch (Exception ex)
{
throw new Exception(ex.Message);
}
}

private void CreateDocumentLocationRecord(IOrganizationService service,string _locationName,string _locationURL,Guid _regarding)
{
try
{
// Instantiate an account object.
Entity DocumentLocation = new Entity("sharepointdocumentlocation");
//set the fields values
DocumentLocation["name"] = _locationName;
DocumentLocation["regardingobjectid"] = new EntityReference("account", _regarding);
DocumentLocation["absoluteurl"] = _locationURL;
//create the record
Guid DocumentLocationid = service.Create(DocumentLocation);

}
catch (Exception ex)
{
throw new Exception(ex.Message);
}
}