Tuesday, 17 February 2015

XrmServiceToolkitSOAP.js

/*function endSession(crmParameter) {
   //alert('End Session');
   //alert(crmParameter);
   debugger;
   var _sessionId = crmParameter;
   var _fetchXML = "<fetch version='1.0' output-format='xml-platform' mapping='logical' distinct='false'>" +
                    "<entity name='hppscm_docketapplication'>" +
                       "<attribute name='hppscm_docketapplicationid'/>" +
                       "<attribute name='hppscm_applicationnumber'/>" +
                       "<attribute name='createdon'/>" +
                       "<order descending='false' attribute='hppscm_applicationnumber'/>" +
                       "<filter type='and'>" +
                       "<condition attribute='hppscm_sessionid' value='" + _sessionId + "' uitype='hppscm_session'  operator='eq'/>" +
                       "</filter>" +
                       "</entity>" +
                       "</fetch>";
   var _VISAApplication = XrmServiceToolkit.Soap.Fetch(_fetchXML);
   alert(_VISAApplication.length);



   <title></title>
    <link href="../styles/styles.css" rel="stylesheet" type="text/css">
    <script src="../Scripts/JQuery1.4.4.min.js" type="text/javascript"></script>
    <script src="../Scripts/JQueryLibrary.js" type="text/javascript"></script>

    <script src="../Scripts/json2.js" type="text/javascript"></script>
    <script src="../Scripts/XrmServiceToolkitSOAP.js" type="text/javascript"></script>
    <script type="text/javascript">

}

*/


if (typeof (XrmServiceToolkit) == "undefined") {
    XrmServiceToolkit = function () {

    };
}

XrmServiceToolkit.Soap = function () {

    var htmlEncode = function (s) {
        if (s == null || s == "") return s;
        for (var count = 0, buffer = "", hEncode = "", cnt = 0; cnt < s.length; cnt++) {
            var c = s.charCodeAt(cnt);
            if (c > 96 && c < 123 || c > 64 && c < 91 || c == 32 || c > 47 && c < 58 || c == 46 || c == 44 || c == 45 || c == 95)
                buffer += String.fromCharCode(c);
            else buffer += "&#" + c + ";";
            if (++count == 500) {
                hEncode += buffer; buffer = ""; count = 0;
            }
        }
        if (buffer.length) hEncode += buffer;
        return hEncode;
    };

    var innerSurrogateAmpersandWorkaround = function (s) {
        var buffer = '';
        var c0;
        for (var cnt = 0; cnt < s.length; cnt++) {
            c0 = s.charCodeAt(cnt);
            if (c0 >= 55296 && c0 <= 57343)
                if (cnt + 1 < s.length) {
                    var c1 = s.charCodeAt(cnt + 1);
                    if (c1 >= 56320 && c1 <= 57343) {
                        buffer += "CRMEntityReferenceOpen" + ((c0 - 55296) * 1024 + (c1 & 1023) + 65536).toString(16) + "CRMEntityReferenceClose"; cnt++;
                    }
                    else
                        buffer += String.fromCharCode(c0);
                }
                else buffer += String.fromCharCode(c0);
            else buffer += String.fromCharCode(c0);
        }
        s = buffer;
        buffer = "";
        for (cnt = 0; cnt < s.length; cnt++) {
            c0 = s.charCodeAt(cnt);
            if (c0 >= 55296 && c0 <= 57343)
                buffer += String.fromCharCode(65533);
            else buffer += String.fromCharCode(c0);
        }
        s = buffer;
        s = htmlEncode(s);
        s = s.replace(/CRMEntityReferenceOpen/g, "&#x");
        s = s.replace(/CRMEntityReferenceClose/g, ";");
        return s;
    };

    var crmXmlEncode = function (s) {
        // ReSharper disable UsageOfPossiblyUnassignedValue
        if ("undefined" == typeof s || "unknown" == typeof s || null == s) return s;
            // ReSharper restore UsageOfPossiblyUnassignedValue
        else if (typeof s != "string") s = s.toString();
        return innerSurrogateAmpersandWorkaround(s);
    };

    var crmXmlDecode = function (s) {
        if (typeof s != "string") s = s.toString();
        return s;
    };

    var padNumber = function (s, len) {
        len = len || 2;

        s = '' + s;
        while (s.length < len) {
            s = "0" + s;
        }
        return s;
    };

    var encodeDate = function (dateTime) {
        return dateTime.getFullYear() + "-" +
               padNumber(dateTime.getMonth() + 1) + "-" +
               padNumber(dateTime.getDate()) + "T" +
               padNumber(dateTime.getHours()) + ":" +
               padNumber(dateTime.getMinutes()) + ":" +
               padNumber(dateTime.getSeconds());
    };

    var encodeValue = function (value) {
        return (typeof value === "object" && value.getTime)
               ? encodeDate(value)
               : ((typeof window.CrmEncodeDecode != 'undefined') ? window.CrmEncodeDecode.CrmXmlEncode(value) : crmXmlEncode(value));
    };

    var context = function () {
        ///<summary>
        /// Private function to the context object.
        ///</summary>
        ///<returns>Context</returns>
        var oContext;
        if (typeof window.GetGlobalContext != "undefined") {
            oContext = window.GetGlobalContext();
        }
        else {
            if (typeof Xrm != "undefined") {
                oContext = Xrm.Page.context;
            }
            else if (typeof window.parent.Xrm != "undefined") {
                oContext = window.parent.Xrm.Page.context;
            }
            else if (typeof parent.Xrm != "undefined") {
                oContext = parent.Xrm.Page.context;
            }
            else {
                throw new Error("Context is not available.");
            }
        }
        return oContext;
    };

    var getServerUrl = function () {
        ///<summary>
        /// Private function to return the server URL from the context
        ///</summary>
        ///<returns>String</returns>
        if (typeof context().getClientUrl != "undefined") {
            return context().getClientUrl();
        }

        var serverUrl = context().getServerUrl();
        if (serverUrl.match(/\/$/)) {
            serverUrl = serverUrl.substring(0, serverUrl.length - 1);
        }

        return serverUrl;
    };

    var orgServicePath = function () {
        ///<summary>
        /// Private function to return the path to the organization service.
        ///</summary>
        ///<returns>String</returns>
        return getServerUrl() + "/XRMServices/2011/Organization.svc/web";
    };

    // ReSharper disable UnusedLocals
    var dateReviver = function (key, value) {
        // ReSharper restore UnusedLocals
        ///<summary>
        /// Private function to convert matching string values to Date objects.
        ///</summary>
        ///<param name="key" type="String">
        /// The key used to identify the object property
        ///</param>
        ///<param name="value" type="String">
        /// The string value representing a date
        ///</param>
        var a;
        if (typeof value === 'string') {
            a = /Date\(([-+]?\d+)\)/.exec(value);
            if (a) {
                return new Date(parseInt(value.replace("/Date(", "").replace(")/", ""), 10));
            }
        }
        return value;
    };

    var xrmValue = function (sType, sValue) {
        this.type = sType;
        this.value = sValue;
    };

    var xrmEntityReference = function (gId, sLogicalName, sName) {
        this.id = gId;
        this.logicalName = sLogicalName;
        this.name = sName;
        this.type = 'EntityReference';
    };

    var xrmEntityCollection = function (items) {
        this.value = items;
        this.type = 'EntityCollection';
    };

    var xrmOptionSetValue = function (iValue, sFormattedValue) {
        this.value = iValue;
        this.formattedValue = sFormattedValue;
        this.type = 'OptionSetValue';
    };

    var businessEntity = function (logicalName, id) {
        ///<summary>
        /// A object represents a business entity for CRM 2011.
        ///</summary>
        ///<param name="logicalName" type="String">
        /// A String represents the name of the entity.
        /// For example, "contact" means the business entity will be a contact entity
        /// </param>
        ///<param name="id" type="String">
        /// A String represents the id of the entity. If not passed, it will be autopopulated as a empty guid string
        /// </param>
        this.id = (!id) ? "00000000-0000-0000-0000-000000000000" : id;
        this.logicalName = logicalName;
        this.attributes = new Object();
    };

    var getXhr = function () {
        ///<summary>
        /// Get an instance of XMLHttpRequest for all browers
        ///</summary>
        if (XMLHttpRequest) {
            // Chrome, Firefox, IE7+, Opera, Safari
            // ReSharper disable InconsistentNaming
            return new XMLHttpRequest();
            // ReSharper restore InconsistentNaming
        }
        // IE6
        try {
            // The latest stable version. It has the best security, performance,
            // reliability, and W3C conformance. Ships with Vista, and available
            // with other OS's via downloads and updates.
            return new ActiveXObject('MSXML2.XMLHTTP.6.0');
        } catch (e) {
            try {
                // The fallback.
                return new ActiveXObject('MSXML2.XMLHTTP.3.0');
            } catch (e) {
                alert('This browser is not AJAX enabled.');
                return null;
            }
        }
    };

    businessEntity.prototype = {
        /**
        * Serialize a CRM Business Entity object to XML string in order to be passed to CRM Web Services.
        * @return {String} The serialized XML string of CRM entity.
        */
        serialize: function () {
            var xml = ['<entity xmlns:a="http://schemas.microsoft.com/xrm/2011/Contracts">'];
            xml.push('<a:Attributes xmlns:b="http://schemas.datacontract.org/2004/07/System.Collections.Generic">');

            for (var attributeName in this.attributes) {
                var attribute = this.attributes[attributeName];

                xml.push('<a:KeyValuePairOfstringanyType>');
                xml.push('<b:key>', attributeName, '</b:key>');

                if (attribute === null || attribute.value === null) {
                    xml.push('<b:value i:nil="true" />');
                }
                else {
                    var sType = (!attribute.type)
                            ? typeof attribute
                            : ((typeof window.CrmEncodeDecode != 'undefined') ? window.CrmEncodeDecode.CrmXmlEncode(attribute.type) : crmXmlEncode(attribute.type));
                    var value;
                    var encodedValue;
                    var id;
                    var encodedId;
                    var logicalName;
                    var encodedLogicalName;
                    switch (sType) {
                        case "OptionSetValue":
                            value = (attribute.hasOwnProperty("value")) ? attribute["value"] : attribute;
                            encodedValue = encodeValue(value);
                            xml.push('<b:value i:type="a:OptionSetValue">');
                            xml.push('<a:Value>', encodedValue, '</a:Value>', '</b:value>');
                            break;

                        case "EntityCollection":
                            xml.push('<b:value i:type="a:EntityCollection">');
                            xml.push('<a:Entities>');
                            value = (attribute.hasOwnProperty("value")) ? attribute["value"] : attribute;
                            var collections = isArray(value) ? value : [value];

                            for (var i = 0; i < collections.length; i++) {
                                var item = collections[i];
                                id = (item.hasOwnProperty("id")) ? item["id"] : item;
                                encodedId = encodeValue(id);
                                logicalName = (item.hasOwnProperty("logicalName")) ? item["logicalName"] : item;
                                encodedLogicalName = encodeValue(logicalName);
                                xml.push('<a:Entity>');
                                xml.push('<a:Attributes>');
                                xml.push('<a:KeyValuePairOfstringanyType>');
                                xml.push('<b:key>partyid</b:key>');
                                xml.push('<b:value i:type="a:EntityReference">');
                                xml.push('<a:Id>', encodedId, '</a:Id>');
                                xml.push('<a:LogicalName>', encodedLogicalName, '</a:LogicalName>');
                                xml.push('<a:Name i:nil="true" />');
                                xml.push('</b:value>');
                                xml.push('</a:KeyValuePairOfstringanyType>');
                                xml.push('</a:Attributes>');
                                xml.push('<a:EntityState i:nil="true" />');
                                xml.push('<a:FormattedValues />');
                                xml.push('<a:Id>00000000-0000-0000-0000-000000000000</a:Id>');
                                xml.push('<a:LogicalName>activityparty</a:LogicalName>');
                                xml.push('<a:RelatedEntities />');
                                xml.push('</a:Entity>');
                            }
                            xml.push('</a:Entities>');
                            xml.push('<a:EntityName i:nil="true" />');
                            xml.push('<a:MinActiveRowVersion i:nil="true" />');
                            xml.push('<a:MoreRecords>false</a:MoreRecords>');
                            xml.push('<a:PagingCookie i:nil="true" />');
                            xml.push('<a:TotalRecordCount>0</a:TotalRecordCount>');
                            xml.push('<a:TotalRecordCountLimitExceeded>false</a:TotalRecordCountLimitExceeded>');
                            xml.push('</b:value>');
                            break;

                        case "EntityReference":
                            id = (attribute.hasOwnProperty("id")) ? attribute["id"] : attribute;
                            encodedId = encodeValue(id);
                            logicalName = (attribute.hasOwnProperty("logicalName")) ? attribute["logicalName"] : attribute;
                            encodedLogicalName = encodeValue(logicalName);
                            xml.push('<b:value i:type="a:EntityReference">');
                            xml.push('<a:Id>', encodedId, '</a:Id>');
                            xml.push('<a:LogicalName>', encodedLogicalName, '</a:LogicalName>');
                            xml.push('<a:Name i:nil="true" />', '</b:value>');
                            break;

                        case "Money":
                            value = (attribute.hasOwnProperty("value")) ? attribute["value"] : attribute;
                            encodedValue = encodeValue(value);
                            xml.push('<b:value i:type="a:Money">');
                            xml.push('<a:Value>', encodedValue, '</a:Value>', '</b:value>');
                            break;

                        case "guid":
                            value = (attribute.hasOwnProperty("value")) ? attribute["value"] : attribute;
                            encodedValue = encodeValue(value);
                            xml.push('<b:value i:type="c:guid" xmlns:c="http://schemas.microsoft.com/2003/10/Serialization/">');
                            xml.push(encodedValue, '</b:value>');
                            break;

                        case "number":
                            value = (attribute.hasOwnProperty("value")) ? attribute["value"] : attribute;
                            encodedValue = encodeValue(value);
                            var oType = (parseInt(encodedValue) == encodedValue) ? "c:int" : "c:decimal";
                            xml.push('<b:value i:type="', oType, '" xmlns:c="http://www.w3.org/2001/XMLSchema">');
                            xml.push(encodedValue, '</b:value>');
                            break;

                        default:
                            value = (attribute.hasOwnProperty("value")) ? attribute["value"] : attribute;
                            encodedValue = encodeValue(value);
                            sType = (typeof value === "object" && value.getTime) ? "dateTime" : sType;
                            xml.push('<b:value i:type="c:', sType, '" xmlns:c="http://www.w3.org/2001/XMLSchema">', encodedValue, '</b:value>');
                            break;
                    }
                }
                xml.push('</a:KeyValuePairOfstringanyType>');
            }

            xml.push('</a:Attributes><a:EntityState i:nil="true" />');
            xml.push('<a:FormattedValues xmlns:b="http://schemas.datacontract.org/2004/07/System.Collections.Generic" />');
            xml.push('<a:Id>', encodeValue(this.id), '</a:Id>');
            xml.push('<a:LogicalName>', this.logicalName, '</a:LogicalName>');
            xml.push('<a:RelatedEntities xmlns:b="http://schemas.datacontract.org/2004/07/System.Collections.Generic" />');
            xml.push('</entity>');
            return xml.join("");
        },

        /**
        * Deserialize an XML node into a CRM Business Entity object. The XML node comes from CRM Web Service's response.
        * @param {object} resultNode The XML node returned from CRM Web Service's Fetch, Retrieve, RetrieveMultiple messages.
        */
        deserialize: function (resultNode) {
            var obj = new Object();
            var resultNodes = resultNode.childNodes;

            for (var j = 0; j < resultNodes.length; j++) {
                var k;
                var sKey;
                var vKey;
                switch (resultNodes[j].nodeName) {
                    case "a:Attributes":
                        var attr = resultNodes[j];
                        for (k = 0; k < attr.childNodes.length; k++) {

                            // Establish the Key for the Attribute
                            vKey = $(attr.childNodes[k].firstChild).text();
                            sKey = vKey.replace('.', '');

                            var sType = '';

                            // Determine the Type of Attribute value we should expect
                            for (var l = 0; l < attr.childNodes[k].childNodes[1].attributes.length; l++) {
                                if (attr.childNodes[k].childNodes[1].attributes[l].nodeName == 'i:type') {
                                    sType = $(attr.childNodes[k].childNodes[1].attributes[l]).val();
                                }
                            }
                            var entRef;
                            var entCv;
                            switch (sType) {
                                case "a:OptionSetValue":
                                    var entOsv = new xrmOptionSetValue();
                                    entOsv.type = sType.replace('a:', '');
                                    entOsv.value = parseInt($(attr.childNodes[k].childNodes[1]).text());
                                    obj[sKey] = entOsv;
                                    break;

                                case "a:EntityReference":
                                    entRef = new xrmEntityReference();
                                    entRef.type = sType.replace('a:', '');
                                    entRef.id = $(attr.childNodes[k].childNodes[1].childNodes[0]).text();
                                    entRef.logicalName = $(attr.childNodes[k].childNodes[1].childNodes[1]).text();
                                    entRef.name = $(attr.childNodes[k].childNodes[1].childNodes[2]).text();
                                    obj[sKey] = entRef;
                                    break;

                                case "a:EntityCollection":
                                    entRef = new xrmEntityCollection();
                                    entRef.type = sType.replace('a:', '');

                                    //get all party items....
                                    var items = [];
                                    for (var y = 0; y < attr.childNodes[k].childNodes[1].childNodes[0].childNodes.length; y++) {
                                        var itemNodes = attr.childNodes[k].childNodes[1].childNodes[0].childNodes[y].childNodes[0].childNodes;
                                        for (var z = 0; z < itemNodes.length; z++) {
                                            if (itemNodes[z].childNodes[0].text == "partyid") {
                                                var itemRef = new xrmEntityReference();
                                                itemRef.id = $(itemNodes[z].childNodes[1].childNodes[0]).text();
                                                itemRef.logicalName = $(itemNodes[z].childNodes[1].childNodes[1]).text();
                                                itemRef.name = $(itemNodes[z].childNodes[1].childNodes[2]).text();
                                                items[y] = itemRef;
                                            }
                                        }
                                    }
                                    entRef.value = items;
                                    obj[sKey] = entRef;
                                    break;

                                case "a:Money":
                                    entCv = new xrmValue();
                                    entCv.type = sType.replace('a:', '');
                                    entCv.value = parseFloat($(attr.childNodes[k].childNodes[1]).text());
                                    obj[sKey] = entCv;
                                    break;

                                default:
                                    entCv = new xrmValue();
                                    entCv.type = sType.replace('c:', '').replace('a:', '');
                                    if (entCv.type == "int") {
                                        entCv.value = parseInt($(attr.childNodes[k].childNodes[1]).text());
                                    }
                                    else if (entCv.type == "decimal" || entCv.type == "double") {
                                        entCv.value = parseFloat($(attr.childNodes[k].childNodes[1]).text());
                                    }
                                    else if (entCv.type == "dateTime") {
                                        entCv.value = new Date($(attr.childNodes[k].childNodes[1]).text());
                                    }
                                    else if (entCv.type == "boolean") {
                                        entCv.value = ($(attr.childNodes[k].childNodes[1]).text() == 'false') ? false : true;
                                    }
                                    else if (entCv.type == "AliasedValue") {
                                        entCv.value = $(attr.childNodes[k].childNodes[1].childNodes[2]).text();
                                    }
                                    else {
                                        entCv.value = $(attr.childNodes[k].childNodes[1]).text();
                                    }
                                    obj[sKey] = entCv;
                                    break;
                            }
                        }
                        this.attributes = obj;
                        break;

                    case "a:Id":
                        this.id = $(resultNodes[j]).text();
                        break;

                    case "a:LogicalName":
                        this.logicalName = $(resultNodes[j]).text();
                        break;

                    case "a:FormattedValues":
                        var foVal = resultNodes[j];

                        for (k = 0; k < foVal.childNodes.length; k++) {
                            // Establish the Key, we are going to fill in the formatted value of the already found attribute
                            sKey = $(foVal.childNodes[k].firstChild).text();
                            sKey = sKey.replace('.', '');
                            this.attributes[sKey].formattedValue = $(foVal.childNodes[k].childNodes[1]).text();
                            if (isNaN(this.attributes[sKey].value) && this.attributes[sKey].type == "dateTime") {
                                this.attributes[sKey].value = new Date(this.attributes[sKey].formattedValue);
                            }
                        }
                        break;
                }
            }
        }
    };

    var xmlParser = function (txt) {
        ///<summary>
        /// cross browser responseXml to return a XML object
        ///</summary>
        var xmlDoc = null;
        try {
            // code for Mozilla, Firefox, Opera, etc.
            if (window.DOMParser) {
                // ReSharper disable InconsistentNaming
                var parser = new DOMParser();
                // ReSharper restore InconsistentNaming
                xmlDoc = parser.parseFromString(txt, "text/xml");
            }
            else // Internet Explorer
            {
                xmlDoc = new ActiveXObject("Microsoft.XMLDOM");
                xmlDoc.async = false;
                xmlDoc.loadXML(txt);
            }
        } catch (e) {
            alert("Cannot convert the XML string to a cross-browser XML object.");
        }

        return xmlDoc;
    };

    var xmlToString = function (responseXml) {
        var xmlString = '';
        try {
            if (responseXml != null) {
                //IE
                if (window.ActiveXObject) {
                    xmlString = responseXml.xml;
                }
                    // code for Mozilla, Firefox, Opera, etc.
                else {
                    // ReSharper disable InconsistentNaming
                    xmlString = (new XMLSerializer()).serializeToString(responseXml[0]);
                    // ReSharper restore InconsistentNaming
                }
            }
        } catch (e) {
            alert("Cannot convert the XML to a string.");
        }
        return xmlString;
    };

    var doRequest = function (soapBody, requestType, async, internalCallback) {
        async = async || false;

        // Wrap the Soap Body in a soap:Envelope.
        var soapXml =
        ["<soap:Envelope xmlns:soap='http://schemas.xmlsoap.org/soap/envelope/'>",
            "<soap:Body>",
                "<", requestType, " xmlns='http://schemas.microsoft.com/xrm/2011/Contracts/Services' xmlns:i='http://www.w3.org/2001/XMLSchema-instance'>", soapBody, "</", requestType, ">",
            "</soap:Body>",
            "</soap:Envelope>"
        ].join("");

        var req = getXhr();
        req.open("POST", orgServicePath(), async);
        req.setRequestHeader("Accept", "application/xml, text/xml, */*");
        req.setRequestHeader("Content-Type", "text/xml; charset=utf-8");
        req.setRequestHeader("SOAPAction", "http://schemas.microsoft.com/xrm/2011/Contracts/Services/IOrganizationService/" + requestType);

        req.send(soapXml);

        if (async) {
            req.onreadystatechange = function () {
                if (req.readyState == 4) { // "complete"
                    if (req.status == 200) { // "OK"
                        internalCallback(processResponse(req.responseXML, req.responseText));
                    }
                    else {
                        alert("Refund transaction error" + " " + req.responseXML.text);
                        throw new Error("HTTP-Requests ERROR: " + req.statusText);
                    }
                }
            };
        }
        else {
            var result = processResponse(req.responseXML, req.responseText);
            return !!internalCallback ? internalCallback(result) : result;
        }
        // ReSharper disable NotAllPathsReturnValue
    };
    // ReSharper restore NotAllPathsReturnValue

    var processResponse = function (responseXml, responseText) {
        var error;
        var faultString;
        var xmlDoc;
        if (responseXml === null || typeof responseXml === 'undefined' || responseXml.xml === null || responseXml.xml === "") {
            if (responseText !== null && responseText !== "") {
                throw new Error(responseText);
            }
            else
                throw new Error("No response received from the server. ");
        }

        // Report the error if occurred


        // Load responseXML and return as an XML object
        if (typeof responseXml.xml === 'undefined') {
            error = $(responseText).find("error").text();
            faultString = $(responseText).find("faultstring").text();
            if (error != '' || faultString != '') {
                throw new Error(error !== '' ? $(responseText).find('description').text() : faultString);
            }

            xmlDoc = xmlParser(responseText);
        } else {
            error = $(responseXml).find("error").text();
            faultString = $(responseXml).find("faultstring").text();
            if (error != '' || faultString != '') {
                throw new Error(error !== '' ? $(responseXml).find('description').text() : faultString);
            }

            xmlDoc = xmlParser(xmlToString(responseXml));
        }

        return xmlDoc;
    };

    var sCreate = function (be, callback) {
        ///<summary>
        /// Sends synchronous/asynchronous request to create a new record.
        ///</summary>
        ///<param name="be" type="Object">
        /// A JavaScript object with properties corresponding to the Schema name of
        /// entity attributes that are valid for create operations.
        /// </param>
        ///<param name="callback" type="Function">
        /// A Function used for asynchronous request. If not defined, it sends a synchronous request.
        /// </param>
        var request = be.serialize();

        var async = !!callback;

        return doRequest(request, "Create", async, function (resultXml) {
            var response = $(resultXml).find('CreateResult').eq(0);

            var result = ((typeof window.CrmEncodeDecode != 'undefined') ? window.CrmEncodeDecode.CrmXmlDecode(response.text()) : crmXmlDecode(response.text()));

            if (!async)
                return result;
            else
                callback(result);
            // ReSharper disable NotAllPathsReturnValue
        });
        // ReSharper restore NotAllPathsReturnValue
    };

    var sUpdate = function (be, callback) {
        ///<summary>
        /// Sends synchronous/asynchronous request to update an existing record.
        ///</summary>
        ///<param name="businessEntity" type="Object">
        /// A JavaScript object with properties corresponding to the Schema name of
        /// entity attributes that are valid for update operations.
        /// </param>
        ///<param name="callback" type="Function">
        /// A Function used for asynchronous request. If not defined, it sends a synchronous request.
        /// </param>
        var request = be.serialize();

        var async = !!callback;

        return doRequest(request, "Update", async, function (resultXml) {
            var response = $(resultXml).find("UpdateResponse").eq(0);
            var result = ((typeof window.CrmEncodeDecode != 'undefined') ? window.CrmEncodeDecode.CrmXmlDecode(response.text()) : crmXmlDecode(response.text()));

            if (!async)
                return result;
            else
                callback(result);
            // ReSharper disable NotAllPathsReturnValue
        });
        // ReSharper restore NotAllPathsReturnValue
    };

    var sDelete = function (entityName, id, callback) {
        ///<summary>
        /// Sends synchronous/asynchronous request to delete a record.
        ///</summary>
        ///<param name="entityName" type="String">
        /// A JavaScript String corresponding to the Schema name of
        /// entity that is used for delete operations.
        /// </param>
        ///<param name="id" type="String">
        /// A JavaScript String corresponding to the GUID of
        /// entity that is used for delete operations.
        /// </param>
        ///<param name="callback" type="Function">
        /// A Function used for asynchronous request. If not defined, it sends a synchronous request.
        /// </param>
        var request =
                [
                    "<entityName>", entityName, "</entityName>",
                    "<id>", id, "</id>"
                ].join("");

        var async = !!callback;

        return doRequest(request, "Delete", async, function (resultXml) {
            var response = $(resultXml).find("DeleteResponse").eq(0);
            var result = ((typeof window.CrmEncodeDecode != 'undefined') ? window.CrmEncodeDecode.CrmXmlDecode(response.text()) : crmXmlDecode(response.text()));

            if (!async)
                return result;
            else
                callback(result);
            // ReSharper disable NotAllPathsReturnValue
        });
        // ReSharper restore NotAllPathsReturnValue
    };

    var execute = function (request, callback) {
        ///<summary>
        /// Sends synchronous/asynchronous request to execute a soap request.
        ///</summary>
        ///<param name="request" type="String">
        /// A JavaScript string corresponding to the soap request
        /// that are valid for execute operations.
        /// </param>
        ///<param name="callback" type="Function">
        /// A Function used for asynchronous request. If not defined, it sends a synchronous request.
        /// </param>
        var async = !!callback;

        return doRequest(request, "Execute", async, function (resultXml) {
            if (!async)
                return resultXml;
            else
                callback(resultXml);
        });
    };

    var fetch = function (fetchXml, callback) {
        ///<summary>
        /// Sends synchronous/asynchronous request to do a fetch request.
        ///</summary>
        ///<param name="fetchXml" type="String">
        /// A JavaScript String with properties corresponding to the fetchXml
        /// that are valid for fetch operations.
        /// </param>
        ///<param name="callback" type="Function">
        /// A Function used for asynchronous request. If not defined, it sends a synchronous request.
        /// </param>
        var msgBody = "<query i:type='a:FetchExpression' xmlns:a='http://schemas.microsoft.com/xrm/2011/Contracts'>" +
                            "<a:Query>" +
                                ((typeof window.CrmEncodeDecode != 'undefined') ? window.CrmEncodeDecode.CrmXmlEncode(fetchXml) : crmXmlEncode(fetchXml)) +
                            "</a:Query>" +
                        "</query>";
        var async = !!callback;

        return doRequest(msgBody, "RetrieveMultiple", async, function (resultXml) {
            var fetchResult;
            if ($(resultXml).find("a\\:Entities").length != 0) {
                fetchResult = $(resultXml).find("a\\:Entities").eq(0)[0];
            } else {
                fetchResult = $(resultXml).find("Entities").eq(0)[0]; //chrome could not load node
            }

            var fetchResults = [];

            for (var i = 0; i < fetchResult.childNodes.length; i++) {
                var entity = new businessEntity();

                entity.deserialize(fetchResult.childNodes[i]);
                fetchResults[i] = entity;
            }

            if (!async)
                return fetchResults;
            else
                callback(fetchResults);
            // ReSharper disable NotAllPathsReturnValue
        });
        // ReSharper restore NotAllPathsReturnValue
    };

    var retrieve = function (entityName, id, columnSet, callback) {
        ///<summary>
        /// Sends synchronous/asynchronous request to retrieve a record.
        ///</summary>
        ///<param name="entityName" type="String">
        /// A JavaScript String corresponding to the Schema name of
        /// entity that is used for retrieve operations.
        /// </param>
        ///<param name="id" type="String">
        /// A JavaScript String corresponding to the GUID of
        /// entity that is used for retrieve operations.
        /// </param>
        ///<param name="columnSet" type="Array">
        /// A JavaScript Array corresponding to the attributes of
        /// entity that is used for retrieve operations.
        /// </param>
        ///<param name="callback" type="Function">
        /// A Function used for asynchronous request. If not defined, it sends a synchronous request.
        /// </param>
        var attributes = "";
        // ReSharper disable AssignedValueIsNeverUsed
        var query = "";
        // ReSharper restore AssignedValueIsNeverUsed
        if (columnSet != null) {
            for (var i = 0; i < columnSet.length; i++) {
                attributes += "<b:string>" + columnSet[i] + "</b:string>";
            }
            query = "<a:AllColumns>false</a:AllColumns>" +
                    "<a:Columns xmlns:b='http://schemas.microsoft.com/2003/10/Serialization/Arrays'>" +
                        attributes +
                    "</a:Columns>";
        }
        else {
            query = "<a:AllColumns>true</a:AllColumns><a:Columns xmlns:b='http://schemas.microsoft.com/2003/10/Serialization/Arrays' />";
        }

        var msgBody =
            [
                "<entityName>", entityName, "</entityName>",
                "<id>", id, "</id>",
                "<columnSet xmlns:a='http://schemas.microsoft.com/xrm/2011/Contracts'>",
                    query,
                "</columnSet>"
            ].join("");

        var async = !!callback;

        return doRequest(msgBody, "Retrieve", !!callback, function (resultXml) {
            var retrieveResult = $(resultXml).find("RetrieveResult").eq(0)[0];
            var entity = new businessEntity();
            entity.deserialize(retrieveResult);

            if (!async)
                return entity;
            else
                callback(entity);
            // ReSharper disable NotAllPathsReturnValue
        });
        // ReSharper restore NotAllPathsReturnValue
    };

    var retrieveMultiple = function (query, callback) {
        ///<summary>
        /// Sends synchronous/asynchronous request to do a retrieveMultiple request.
        ///</summary>
        ///<param name="query" type="String">
        /// A JavaScript String with properties corresponding to the retrievemultiple request
        /// that are valid for retrievemultiple operations.
        /// </param>
        ///<param name="callback" type="Function">
        /// A Function used for asynchronous request. If not defined, it sends a synchronous request.
        /// </param>
        var msgBody =
                [
                    "<query i:type='a:QueryExpression' xmlns:a='http://schemas.microsoft.com/xrm/2011/Contracts'>", query, "</query>"
                ].join("");

        var async = !!callback;

        return doRequest(msgBody, "RetrieveMultiple", async, function (resultXml) {
            var resultNodes;

            if ($(resultXml).find("a\\:Entities").length != 0) {
                resultNodes = $(resultXml).find("a\\:Entities").eq(0)[0];
            } else {
                resultNodes = $(resultXml).find("Entities").eq(0)[0]; //chrome could not load node properly
            }
            var retriveMultipleResults = [];

            for (var i = 0; i < resultNodes.childNodes.length; i++) {
                var entity = new businessEntity();

                entity.deserialize(resultNodes.childNodes[i]);
                retriveMultipleResults[i] = entity;
            }

            if (!async)
                return retriveMultipleResults;
            else
                callback(retriveMultipleResults);
            // ReSharper disable NotAllPathsReturnValue
        });
        // ReSharper restore NotAllPathsReturnValue
    };

    var joinArray = function (prefix, array, suffix) {
        var output = [];
        for (var i = 0; i < array.length; i++) {
            if (array[i] != '' && array[i] != undefined) {
                output.push(prefix, array[i], suffix);
            }
        }
        return output.join("");
    };

    var joinConditionPair = function (attributes, values) {
        var output = [];
        for (var i = 0; i < attributes.length; i++) {
            if (attributes[i] != '') {
                output.push("<condition attribute='", attributes[i], "' operator='eq' value='", values[i], "' />");
            }
        }
        return output.join("");
    };

    var isArray = function (input) {
        return input.constructor.toString().indexOf("Array") != -1;
    };

    var queryByAttribute = function (queryOptions, callback) {
        ///<summary>
        /// Sends synchronous/asynchronous request to do a queryByAttribute request.
        ///</summary>
        ///<param name="queryOptions" type="Object">
        /// A JavaScript Object with properties corresponding to the queryByAttribute Criteria
        /// that are valid for queryByAttribute operations.
        /// queryOptions.entityName is a string represents the name of the entity
        /// queryOptions.attributes is a array represents the attributes of the entity to query
        /// queryOptions.values is a array represents the values of the attributes to query
        /// queryOptions.columnSet is a array represents the attributes of the entity to return
        /// queryOptions.orderBy is a array represents the oder conditons of the results
        /// </param>
        ///<param name="callback" type="Function">
        /// A Function used for asynchronous request. If not defined, it sends a synchronous request.
        /// </param>
        var entityName = queryOptions.entityName;
        var attributes = queryOptions.attributes;
        var values = queryOptions.values;
        var columnSet = queryOptions.columnSet;
        var orderBy = queryOptions.orderBy || '';

        attributes = isArray(attributes) ? attributes : [attributes];
        values = isArray(values) ? values : [values];
        orderBy = (!!orderBy && isArray(orderBy)) ? orderBy : [orderBy];
        columnSet = (!!columnSet && isArray(columnSet)) ? columnSet : [columnSet];

        for (var i = 0; i < values.length; i++) {
            values[i] = encodeValue(values[i]);
        }

        var xml =
                [
                    "<fetch mapping='logical'>",
                    "   <entity name='", entityName, "'>",
                           joinArray("<attribute name='", columnSet, "' />"),
                           joinArray("<order attribute='", orderBy, "' />"),
                    "      <filter>",
                              joinConditionPair(attributes, values),
                    "      </filter>",
                    "   </entity>",
                    "</fetch>"
                ].join("");

        return fetch(xml, callback);
    };

    var fetchMore = function (queryOptions, pageNumber, pageCookie, fetchResults) {
        var entityName = queryOptions.entityName;
        var attributes = queryOptions.attributes;
        var values = queryOptions.values;
        var columnSet = queryOptions.columnSet;
        var orderBy = queryOptions.orderBy || '';

        attributes = isArray(attributes) ? attributes : [attributes];
        values = isArray(values) ? values : [values];
        orderBy = (!!orderBy && isArray(orderBy)) ? orderBy : [orderBy];
        columnSet = (!!columnSet && isArray(columnSet)) ? columnSet : [columnSet];

        for (var i = 0; i < values.length; i++) {
            values[i] = encodeValue(values[i]);
        }

        //Build new query
        var moreFetchXml =
                [
                    "<fetch mapping='logical' page='" + pageNumber + "' count='5000' paging-cookie='" + pageCookie + "'>",
                    "   <entity name='", entityName, "'>",
                           joinArray("<attribute name='", columnSet, "' />"),
                           joinArray("<order attribute='", orderBy, "' />"),
                    "      <filter>",
                              joinConditionPair(attributes, values),
                    "      </filter>",
                    "   </entity>",
                    "</fetch>"
                ].join("");

        var moreMsgBody = "<query i:type='a:FetchExpression' xmlns:a='http://schemas.microsoft.com/xrm/2011/Contracts'>" +
                            "<a:Query>" +
                                ((typeof window.CrmEncodeDecode != 'undefined') ? window.CrmEncodeDecode.CrmXmlEncode(moreFetchXml) : crmXmlEncode(moreFetchXml)) +
                            "</a:Query>" +
                        "</query>";


        return doRequest(moreMsgBody, "RetrieveMultiple", false, function (moreResultXml) {
            var newFetchResult;
            if ($(moreResultXml).find("a\\:Entities").length != 0) {
                newFetchResult = $(moreResultXml).find("a\\:Entities").eq(0)[0];
            } else {
                newFetchResult = $(moreResultXml).find("Entities").eq(0)[0]; //chrome
            }

            var newMoreRecords;
            if ($(moreResultXml).find("a\\:MoreRecords").length != 0) {
                newMoreRecords = $(moreResultXml).find("a\\:MoreRecords").eq(0)[0].firstChild.text === "true";
            } else {
                newMoreRecords = $(moreResultXml).find("MoreRecords").eq(0)[0].firstChild.text === "true"; //chrome
            }

            for (var iii = 0; iii < newFetchResult.childNodes.length; iii++) {
                var entity = new businessEntity();

                entity.deserialize(newFetchResult.childNodes[iii]);
                fetchResults.push(entity);
            }

            if (newMoreRecords) {
                pageNumber += 1;
                var newPageCookie;
                if ($(moreResultXml).find("a\\:PagingCookie").length != 0) {
                    newPageCookie = $(moreResultXml).find("a\\:PagingCookie").eq(0)[0].firstChild.text.replace(/\"/g, '\'').replace(/</g, '&lt;').replace(/>/g, '&gt;').replace(/'/g, '&quot;');
                } else {
                    newPageCookie = $(moreResultXml).find("PagingCookie").eq(0)[0].firstChild.text.replace(/\"/g, '\'').replace(/</g, '&lt;').replace(/>/g, '&gt;').replace(/'/g, '&quot;');
                }

                fetchMore(queryOptions, pageNumber, newPageCookie, fetchResults);
            }
        });
    };

    var queryAll = function (queryOptions, callback) {

        var entityName = queryOptions.entityName;
        var attributes = queryOptions.attributes;
        var values = queryOptions.values;
        var columnSet = queryOptions.columnSet;
        var orderBy = queryOptions.orderBy || '';

        attributes = isArray(attributes) ? attributes : [attributes];
        values = isArray(values) ? values : [values];
        orderBy = (!!orderBy && isArray(orderBy)) ? orderBy : [orderBy];
        columnSet = (!!columnSet && isArray(columnSet)) ? columnSet : [columnSet];

        for (var i = 0; i < values.length; i++) {
            values[i] = encodeValue(values[i]);
        }

        var fetchXml =
                [
                    "<fetch mapping='logical'>",
                    "   <entity name='", entityName, "'>",
                           joinArray("<attribute name='", columnSet, "' />"),
                           joinArray("<order attribute='", orderBy, "' />"),
                    "      <filter>",
                              joinConditionPair(attributes, values),
                    "      </filter>",
                    "   </entity>",
                    "</fetch>"
                ].join("");

        var msgBody = "<query i:type='a:FetchExpression' xmlns:a='http://schemas.microsoft.com/xrm/2011/Contracts'>" +
                            "<a:Query>" +
                                ((typeof window.CrmEncodeDecode != 'undefined') ? window.CrmEncodeDecode.CrmXmlEncode(fetchXml) : crmXmlEncode(fetchXml)) +
                            "</a:Query>" +
                        "</query>";
        var async = !!callback;

        return doRequest(msgBody, "RetrieveMultiple", !!callback, function (resultXml) {

            //Logic here is inspired by http://nishantrana.wordpress.com/2012/09/11/paging-cookie-is-required-when-trying-to-retrieve-a-set-of-records-on-any-high-pages-error-in-crm-2011/

            var fetchResult;
            var moreRecords;

            if ($(resultXml).find("a\\:Entities").length != 0) {
                fetchResult = $(resultXml).find("a\\:Entities").eq(0)[0];
            } else {
                fetchResult = $(resultXml).find("Entities").eq(0)[0]; //chrome
            }

            if ($(resultXml).find("a\\:MoreRecords").length != 0) {
                moreRecords = $(resultXml).find("a\\:MoreRecords").eq(0)[0].firstChild.text === "true";
            } else {
                moreRecords = $(resultXml).find("MoreRecords").eq(0)[0].firstChild.text === "true"; //chrome
            }

            var fetchResults = [];

            for (var ii = 0; ii < fetchResult.childNodes.length; ii++) {
                var entity = new businessEntity();

                entity.deserialize(fetchResult.childNodes[ii]);
                fetchResults.push(entity);
            }

            if (moreRecords) {
                var pageNumber = 2;
                var pageCookie;
                if ($(resultXml).find("a\\:PagingCookie").length != 0) {
                    pageCookie = $(resultXml).find("a\\:PagingCookie").eq(0)[0].firstChild.text.replace(/\"/g, '\'').replace(/</g, '&lt;').replace(/>/g, '&gt;').replace(/'/g, '&quot;');
                } else {
                    pageCookie = $(resultXml).find("PagingCookie").eq(0)[0].firstChild.text.replace(/\"/g, '\'').replace(/</g, '&lt;').replace(/>/g, '&gt;').replace(/'/g, '&quot;');
                }
                fetchMore(queryOptions, pageNumber, pageCookie, fetchResults);
            }

            if (!async)
                return fetchResults;
            else
                callback(fetchResults);
            // ReSharper disable NotAllPathsReturnValue
        });
    };

    var setState = function (entityName, id, stateCode, statusCode, callback) {

        var request = [
            "<request i:type='b:SetStateRequest' xmlns:a='http://schemas.microsoft.com/xrm/2011/Contracts' xmlns:b='http://schemas.microsoft.com/crm/2011/Contracts'>",
                "<a:Parameters xmlns:c='http://schemas.datacontract.org/2004/07/System.Collections.Generic'>",
                    "<a:KeyValuePairOfstringanyType>",
                        "<c:key>EntityMoniker</c:key>",
                        "<c:value i:type='a:EntityReference'>",
                          "<a:Id>", id, "</a:Id>",
                          "<a:LogicalName>", entityName, "</a:LogicalName>",
                          "<a:Name i:nil='true' />",
                        "</c:value>",
                      "</a:KeyValuePairOfstringanyType>",
                      "<a:KeyValuePairOfstringanyType>",
                        "<c:key>State</c:key>",
                        "<c:value i:type='a:OptionSetValue'>",
                          "<a:Value>", stateCode.toString(), "</a:Value>",
                        "</c:value>",
                      "</a:KeyValuePairOfstringanyType>",
                      "<a:KeyValuePairOfstringanyType>",
                        "<c:key>Status</c:key>",
                        "<c:value i:type='a:OptionSetValue'>",
                          "<a:Value>", statusCode.toString(), "</a:Value>",
                        "</c:value>",
                      "</a:KeyValuePairOfstringanyType>",
                "</a:Parameters>",
                "<a:RequestId i:nil='true' />",
                "<a:RequestName>SetState</a:RequestName>",
            "</request>"
        ].join("");

        var async = !!callback;

        return doRequest(request, "Execute", async, function (resultXml) {
            var response = $(resultXml).find('ExecuteResult').eq(0);
            var result = ((typeof window.CrmEncodeDecode != 'undefined') ? window.CrmEncodeDecode.CrmXmlDecode(response.text()) : crmXmlDecode(response.text()));
            if (!async)
                return result;
            else
                callback(result);
            // ReSharper disable NotAllPathsReturnValue
        });
        // ReSharper restore NotAllPathsReturnValue
    };

    var associate = function (relationshipName, targetEntityName, targetId, relatedEntityName, relatedBusinessEntities, callback) {

        var relatedEntities = relatedBusinessEntities;

        relatedEntities = isArray(relatedEntities) ? relatedEntities : [relatedEntities];

        var output = [];
        for (var i = 0; i < relatedEntities.length; i++) {
            if (relatedEntities[i].id != '') {
                output.push("<a:EntityReference>",
                                "<a:Id>", relatedEntities[i].id, "</a:Id>",
                                "<a:LogicalName>", relatedEntityName, "</a:LogicalName>",
                                "<a:Name i:nil='true' />",
                            "</a:EntityReference>");
            }
        }

        var relatedXml = output.join("");

        var request = [
            "<request i:type='a:AssociateRequest' 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>Target</b:key>",
                        "<b:value i:type='a:EntityReference'>",
                            "<a:Id>", targetId, "</a:Id>",
                            "<a:LogicalName>", targetEntityName, "</a:LogicalName>",
                            "<a:Name i:nil='true' />",
                        "</b:value>",
                    "</a:KeyValuePairOfstringanyType>",
                    "<a:KeyValuePairOfstringanyType>",
                        "<b:key>Relationship</b:key>",
                        "<b:value i:type='a:Relationship'>",
                            "<a:PrimaryEntityRole i:nil='true' />",
                            "<a:SchemaName>", relationshipName, "</a:SchemaName>",
                        "</b:value>",
                    "</a:KeyValuePairOfstringanyType>",
                    "<a:KeyValuePairOfstringanyType>",
                    "<b:key>RelatedEntities</b:key>",
                    "<b:value i:type='a:EntityReferenceCollection'>",
                        relatedXml,
                    "</b:value>",
                    "</a:KeyValuePairOfstringanyType>",
                "</a:Parameters>",
                "<a:RequestId i:nil='true' />",
                "<a:RequestName>Associate</a:RequestName>",
            "</request>"
        ].join("");

        var async = !!callback;

        return doRequest(request, "Execute", async, function (resultXml) {
            var response = $(resultXml).find('ExecuteResult').eq(0);
            var result = ((typeof window.CrmEncodeDecode != 'undefined') ? window.CrmEncodeDecode.CrmXmlDecode(response.text()) : crmXmlDecode(response.text()));
            if (!async)
                return result;
            else
                callback(result);
            // ReSharper disable NotAllPathsReturnValue
        });
        // ReSharper restore NotAllPathsReturnValue
    };

    var disassociate = function (relationshipName, targetEntityName, targetId, relatedEntityName, relatedBusinessEntities, callback) {
        var relatedEntities = relatedBusinessEntities;

        relatedEntities = isArray(relatedEntities) ? relatedEntities : [relatedEntities];

        var output = [];
        for (var i = 0; i < relatedEntities.length; i++) {
            if (relatedEntities[i].id != '') {
                output.push("<a:EntityReference>",
                                "<a:Id>", relatedEntities[i].id, "</a:Id>",
                                "<a:LogicalName>", relatedEntityName, "</a:LogicalName>",
                                "<a:Name i:nil='true' />",
                            "</a:EntityReference>");
            }
        }

        var relatedXml = output.join("");

        var request = [
            "<request i:type='a:DisassociateRequest' 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>Target</b:key>",
                        "<b:value i:type='a:EntityReference'>",
                            "<a:Id>", targetId, "</a:Id>",
                            "<a:LogicalName>", targetEntityName, "</a:LogicalName>",
                            "<a:Name i:nil='true' />",
                        "</b:value>",
                    "</a:KeyValuePairOfstringanyType>",
                    "<a:KeyValuePairOfstringanyType>",
                        "<b:key>Relationship</b:key>",
                        "<b:value i:type='a:Relationship'>",
                            "<a:PrimaryEntityRole i:nil='true' />",
                            "<a:SchemaName>", relationshipName, "</a:SchemaName>",
                        "</b:value>",
                    "</a:KeyValuePairOfstringanyType>",
                    "<a:KeyValuePairOfstringanyType>",
                    "<b:key>RelatedEntities</b:key>",
                    "<b:value i:type='a:EntityReferenceCollection'>",
                        relatedXml,
                    "</b:value>",
                    "</a:KeyValuePairOfstringanyType>",
                "</a:Parameters>",
                "<a:RequestId i:nil='true' />",
                "<a:RequestName>Disassociate</a:RequestName>",
            "</request>"
        ].join("");

        var async = !!callback;

        return doRequest(request, "Execute", async, function (resultXml) {
            var response = $(resultXml).find('ExecuteResult').eq(0);
            var result = ((typeof window.CrmEncodeDecode != 'undefined') ? window.CrmEncodeDecode.CrmXmlDecode(response.text()) : crmXmlDecode(response.text()));
            if (!async)
                return result;
            else
                callback(result);
            // ReSharper disable NotAllPathsReturnValue
        });
        // ReSharper restore NotAllPathsReturnValue
    };

    var getCurrentUserId = function () {
        ///<summary>
        /// Sends synchronous request to retrieve the GUID of the current user.
        ///</summary>
        var request = "<request i:type='b:WhoAmIRequest' xmlns:a='http://schemas.microsoft.com/xrm/2011/Contracts' xmlns:b='http://schemas.microsoft.com/crm/2011/Contracts'>" +
                        "<a:Parameters xmlns:c='http://schemas.datacontract.org/2004/07/System.Collections.Generic' />" +
                        "<a:RequestId i:nil='true' />" +
                        "<a:RequestName>WhoAmI</a:RequestName>" +
                      "</request>";
        var xmlDoc = doRequest(request, "Execute");
        if ($(xmlDoc).find('a\\:Results').length != 0) {
            return $(xmlDoc).find('a\\:Results').children().eq(0).children().eq(1).text();
        } else {
            return $(xmlDoc).find('Results').children().eq(0).children().eq(1).text(); //Chrome 24.0.1312.52 could not find node by the previous code
        }

    };

    var getCurrentUserBusinessUnitId = function () {
        ///<summary>
        /// Sends synchronous request to retrieve the GUID of the current user's business unit.
        ///</summary>
        var request = "<request i:type='b:WhoAmIRequest' xmlns:a='http://schemas.microsoft.com/xrm/2011/Contracts' xmlns:b='http://schemas.microsoft.com/crm/2011/Contracts'>" +
                        "<a:Parameters xmlns:c='http://schemas.datacontract.org/2004/07/System.Collections.Generic' />" +
                        "<a:RequestId i:nil='true' />" +
                        "<a:RequestName>WhoAmI</a:RequestName>" +
                      "</request>";
        var xmlDoc = doRequest(request, "Execute");

        if ($(xmlDoc).find('a\\:Results').length != 0) {
            return $(xmlDoc).find('a\\:Results').children().eq(1).children().eq(1).text();
        } else {
            return $(xmlDoc).find('Results').children().eq(1).children().eq(1).text(); //Chrome 24.0.1312.52 could not find node by the previous code
        }
    };

    var getCurrentUserRoles = function () {
        ///<summary>
        /// Sends synchronous request to retrieve the list of the current user's roles.
        ///</summary>
        var xml =
                [
                    "<fetch version='1.0' output-format='xml-platform' mapping='logical' distinct='true'>" +
                      "<entity name='role'>" +
                        "<attribute name='name' />" +
                        "<attribute name='businessunitid' />" +
                        "<attribute name='roleid' />" +
                        "<order attribute='name' descending='false' />" +
                        "<link-entity name='systemuserroles' from='roleid' to='roleid' visible='false' intersect='true'>" +
                          "<link-entity name='systemuser' from='systemuserid' to='systemuserid' alias='aa'>" +
                            "<filter type='and'>" +
                              "<condition attribute='systemuserid' operator='eq-userid' />" +
                            "</filter>" +
                          "</link-entity>" +
                        "</link-entity>" +
                      "</entity>" +
                    "</fetch>"
                ].join("");

        var fetchResult = fetch(xml);
        var roles = [];

        if (fetchResult !== null && typeof fetchResult != 'undefined') {
            for (var i = 0; i < fetchResult.length; i++) {
                roles[i] = fetchResult[i].attributes["name"].value;
            }
        }

        return roles;
    };

    var isCurrentUserInRole = function () {
        ///<summary>
        /// Sends synchronous request to check if the current user has certain roles
        /// Passs name of role as arguments. For example, IsCurrentUserInRole('System Administrator')
        /// Returns true or false.
        ///</summary>
        var roles = getCurrentUserRoles();
        for (var i = 0; i < roles.length; i++) {
            for (var j = 0; j < arguments.length; j++) {
                if (roles[i] === arguments[j]) {
                    return true;
                }
            }
        }

        return false;
    };

    var assign = function (targetEntityName, targetId, assigneeEntityName, assigneeId, callback) {

        var request = "<request i:type='b:AssignRequest' xmlns:a='http://schemas.microsoft.com/xrm/2011/Contracts' xmlns:b='http://schemas.microsoft.com/crm/2011/Contracts'>" +
                        "<a:Parameters xmlns:c='http://schemas.datacontract.org/2004/07/System.Collections.Generic'>" +
                          "<a:KeyValuePairOfstringanyType>" +
                            "<c:key>Target</c:key>" +
                            "<c:value i:type='a:EntityReference'>" +
                              "<a:Id>" + targetId + "</a:Id>" +
                              "<a:LogicalName>" + targetEntityName + "</a:LogicalName>" +
                              "<a:Name i:nil='true' />" +
                            "</c:value>" +
                          "</a:KeyValuePairOfstringanyType>" +
                          "<a:KeyValuePairOfstringanyType>" +
                            "<c:key>Assignee</c:key>" +
                            "<c:value i:type='a:EntityReference'>" +
                              "<a:Id>" + assigneeId + "</a:Id>" +
                              "<a:LogicalName>" + assigneeEntityName + "</a:LogicalName>" +
                              "<a:Name i:nil='true' />" +
                            "</c:value>" +
                          "</a:KeyValuePairOfstringanyType>" +
                        "</a:Parameters>" +
                        "<a:RequestId i:nil='true' />" +
                        "<a:RequestName>Assign</a:RequestName>" +
                      "</request>";
        var async = !!callback;

        return doRequest(request, "Execute", async, function (resultXml) {
            var response = $(resultXml).find('ExecuteResult').eq(0);
            var result = ((typeof window.CrmEncodeDecode != 'undefined') ? window.CrmEncodeDecode.CrmXmlDecode(response.text()) : crmXmlDecode(response.text()));
            if (!async)
                return result;
            else
                callback(result);
            // ReSharper disable NotAllPathsReturnValue
        });
        // ReSharper restore NotAllPathsReturnValue
    };

    var grantAccess = function (accessOptions, callback) {


        var targetEntityName = accessOptions.targetEntityName;
        var targetEntityId = accessOptions.targetEntityId;
        var principalEntityName = accessOptions.principalEntityName;
        var principalEntityId = accessOptions.principalEntityId;
        var accessRights = accessOptions.accessRights;

        accessRights = isArray(accessRights) ? accessRights : [accessRights];

        var accessRightString = "";
        for (var i = 0; i < accessRights.length; i++) {
            accessRightString += encodeValue(accessRights[i]) + " ";
        }

        var request = "<request i:type='b:GrantAccessRequest' xmlns:a='http://schemas.microsoft.com/xrm/2011/Contracts' xmlns:b='http://schemas.microsoft.com/crm/2011/Contracts'>" +
                   "<a:Parameters xmlns:c='http://schemas.datacontract.org/2004/07/System.Collections.Generic'>" +
                     "<a:KeyValuePairOfstringanyType>" +
                   "<c:key>Target</c:key>" +
                   "<c:value i:type='a:EntityReference'>" +
                     "<a:Id>" + targetEntityId + "</a:Id>" +
                     "<a:LogicalName>" + targetEntityName + "</a:LogicalName>" +
                     "<a:Name i:nil='true' />" +
                   "</c:value>" +
                     "</a:KeyValuePairOfstringanyType>" +
                     "<a:KeyValuePairOfstringanyType>" +
                   "<c:key>PrincipalAccess</c:key>" +
                   "<c:value i:type='b:PrincipalAccess'>" +
                     "<b:AccessMask>" + accessRightString + "</b:AccessMask>" +
                     "<b:Principal>" +
                   "<a:Id>" + principalEntityId + "</a:Id>" +
                   "<a:LogicalName>" + principalEntityName + "</a:LogicalName>" +
                   "<a:Name i:nil='true' />" +
                     "</b:Principal>" +
                   "</c:value>" +
                     "</a:KeyValuePairOfstringanyType>" +
                   "</a:Parameters>" +
                   "<a:RequestId i:nil='true' />" +
                   "<a:RequestName>GrantAccess</a:RequestName>" +
                    "</request>";
        var async = !!callback;

        return doRequest(request, "Execute", async, function (resultXml) {
            var response = $(resultXml).find('ExecuteResult').eq(0);
            var result = ((typeof window.CrmEncodeDecode != 'undefined') ? window.CrmEncodeDecode.CrmXmlDecode(response.text()) : crmXmlDecode(response.text()));
            if (!async)
                return result;
            else
                callback(result);
            // ReSharper disable NotAllPathsReturnValue
        });
        // ReSharper restore NotAllPathsReturnValue
    };

    var modifyAccess = function (accessOptions, callback) {


        var targetEntityName = accessOptions.targetEntityName;
        var targetEntityId = accessOptions.targetEntityId;
        var principalEntityName = accessOptions.principalEntityName;
        var principalEntityId = accessOptions.principalEntityId;
        var accessRights = accessOptions.accessRights;

        accessRights = isArray(accessRights) ? accessRights : [accessRights];

        var accessRightString = "";
        for (var i = 0; i < accessRights.length; i++) {
            accessRightString += encodeValue(accessRights[i]) + " ";
        }

        var request = "<request i:type='b:ModifyAccessRequest' xmlns:a='http://schemas.microsoft.com/xrm/2011/Contracts' xmlns:b='http://schemas.microsoft.com/crm/2011/Contracts'>" +
                   "<a:Parameters xmlns:c='http://schemas.datacontract.org/2004/07/System.Collections.Generic'>" +
                     "<a:KeyValuePairOfstringanyType>" +
                   "<c:key>Target</c:key>" +
                   "<c:value i:type='a:EntityReference'>" +
                     "<a:Id>" + targetEntityId + "</a:Id>" +
                     "<a:LogicalName>" + targetEntityName + "</a:LogicalName>" +
                     "<a:Name i:nil='true' />" +
                   "</c:value>" +
                     "</a:KeyValuePairOfstringanyType>" +
                     "<a:KeyValuePairOfstringanyType>" +
                   "<c:key>PrincipalAccess</c:key>" +
                   "<c:value i:type='b:PrincipalAccess'>" +
                     "<b:AccessMask>" + accessRightString + "</b:AccessMask>" +
                     "<b:Principal>" +
                   "<a:Id>" + principalEntityId + "</a:Id>" +
                   "<a:LogicalName>" + principalEntityName + "</a:LogicalName>" +
                   "<a:Name i:nil='true' />" +
                     "</b:Principal>" +
                   "</c:value>" +
                     "</a:KeyValuePairOfstringanyType>" +
                   "</a:Parameters>" +
                   "<a:RequestId i:nil='true' />" +
                   "<a:RequestName>ModifyAccess</a:RequestName>" +
                    "</request>";
        var async = !!callback;

        return doRequest(request, "Execute", async, function (resultXml) {
            var response = $(resultXml).find('ExecuteResult').eq(0);
            var result = ((typeof window.CrmEncodeDecode != 'undefined') ? window.CrmEncodeDecode.CrmXmlDecode(response.text()) : crmXmlDecode(response.text()));
            if (!async)
                return result;
            else
                callback(result);
            // ReSharper disable NotAllPathsReturnValue
        });
        // ReSharper restore NotAllPathsReturnValue
    };

    var revokeAccess = function (accessOptions, callback) {


        var targetEntityName = accessOptions.targetEntityName;
        var targetEntityId = accessOptions.targetEntityId;
        var revokeeEntityName = accessOptions.revokeeEntityName;
        var revokeeEntityId = accessOptions.revokeeEntityId;

        var request = "<request i:type='b:RevokeAccessRequest' xmlns:a='http://schemas.microsoft.com/xrm/2011/Contracts' xmlns:b='http://schemas.microsoft.com/crm/2011/Contracts'>" +
                   "<a:Parameters xmlns:c='http://schemas.datacontract.org/2004/07/System.Collections.Generic'>" +
                     "<a:KeyValuePairOfstringanyType>" +
                   "<c:key>Target</c:key>" +
                   "<c:value i:type='a:EntityReference'>" +
                     "<a:Id>" + targetEntityId + "</a:Id>" +
                     "<a:LogicalName>" + targetEntityName + "</a:LogicalName>" +
                     "<a:Name i:nil='true' />" +
                   "</c:value>" +
                     "</a:KeyValuePairOfstringanyType>" +
                     "<a:KeyValuePairOfstringanyType>" +
                   "<c:key>Revokee</c:key>" +
                            "<c:value i:type='a:EntityReference'>" +
                              "<a:Id>" + revokeeEntityId + "</a:Id>" +
                              "<a:LogicalName>" + revokeeEntityName + "</a:LogicalName>" +
                              "<a:Name i:nil='true' />" +
                            "</c:value>" +
                     "</a:KeyValuePairOfstringanyType>" +
                   "</a:Parameters>" +
                   "<a:RequestId i:nil='true' />" +
                   "<a:RequestName>RevokeAccess</a:RequestName>" +
                    "</request>";
        var async = !!callback;

        return doRequest(request, "Execute", async, function (resultXml) {
            var response = $(resultXml).find('ExecuteResult').eq(0);
            var result = ((typeof window.CrmEncodeDecode != 'undefined') ? window.CrmEncodeDecode.CrmXmlDecode(response.text()) : crmXmlDecode(response.text()));
            if (!async)
                return result;
            else
                callback(result);
            // ReSharper disable NotAllPathsReturnValue
        });
        // ReSharper restore NotAllPathsReturnValue
    };

    var retrievePrincipalAccess = function (accessOptions, callback) {


        var targetEntityName = accessOptions.targetEntityName;
        var targetEntityId = accessOptions.targetEntityId;
        var principalEntityName = accessOptions.principalEntityName;
        var principalEntityId = accessOptions.principalEntityId;

        var request = "<request i:type='b:RetrievePrincipalAccessRequest' xmlns:a='http://schemas.microsoft.com/xrm/2011/Contracts' xmlns:b='http://schemas.microsoft.com/crm/2011/Contracts'>" +
                   "<a:Parameters xmlns:c='http://schemas.datacontract.org/2004/07/System.Collections.Generic'>" +
                     "<a:KeyValuePairOfstringanyType>" +
                   "<c:key>Target</c:key>" +
                   "<c:value i:type='a:EntityReference'>" +
                     "<a:Id>" + targetEntityId + "</a:Id>" +
                     "<a:LogicalName>" + targetEntityName + "</a:LogicalName>" +
                     "<a:Name i:nil='true' />" +
                   "</c:value>" +
                     "</a:KeyValuePairOfstringanyType>" +
                     "<a:KeyValuePairOfstringanyType>" +
                   "<c:key>Principal</c:key>" +
                            "<c:value i:type='a:EntityReference'>" +
                              "<a:Id>" + principalEntityId + "</a:Id>" +
                              "<a:LogicalName>" + principalEntityName + "</a:LogicalName>" +
                              "<a:Name i:nil='true' />" +
                            "</c:value>" +
                     "</a:KeyValuePairOfstringanyType>" +
                   "</a:Parameters>" +
                   "<a:RequestId i:nil='true' />" +
                   "<a:RequestName>RetrievePrincipalAccess</a:RequestName>" +
                    "</request>";
        var async = !!callback;

        return doRequest(request, "Execute", async, function (resultXml) {
            var response;
            if ($(resultXml).find('c\\:value').length != 0) {
                response = $(resultXml).find('c\\:value').eq(0);
            } else {
                response = $(resultXml).find('value').eq(0);; //Chrome 24.0.1312.52 could not find node by the previous code
            }
            var result = ((typeof window.CrmEncodeDecode != 'undefined') ? window.CrmEncodeDecode.CrmXmlDecode(response.text()) : crmXmlDecode(response.text()));
            if (!async)
                return result;
            else
                callback(result);
            // ReSharper disable NotAllPathsReturnValue
        });
        // ReSharper restore NotAllPathsReturnValue
    };

    var createErrorLog = function (functionalityName, message, stackTrace) {

        var _errorLog = new XrmServiceToolkit.Soap.BusinessEntity("hppscm_errorlog");
        _errorLog.attributes["hppscm_name"] = functionalityName;
        _errorLog.attributes["hppscm_message"] = message;
        _errorLog.attributes["hppscm_errordatetime"] = new Date();
        _errorLog.attributes["hppscm_stacktrace"] = stackTrace;
        var _createdId = XrmServiceToolkit.Soap.Create(_errorLog);
    };

    //Toolkit's Return Static Methods
    return {
        BusinessEntity: businessEntity,
        Execute: execute,
        Fetch: fetch,
        Retrieve: retrieve,
        RetrieveMultiple: retrieveMultiple,
        Create: sCreate,
        Update: sUpdate,
        Delete: sDelete,
        QueryByAttribute: queryByAttribute,
        QueryAll: queryAll,
        SetState: setState,
        Associate: associate,
        Disassociate: disassociate,
        Assign: assign,
        RetrievePrincipalAccess: retrievePrincipalAccess,
        GrantAccess: grantAccess,
        ModifyAccess: modifyAccess,
        RevokeAccess: revokeAccess,
        GetCurrentUserId: getCurrentUserId,
        GetCurrentUserBusinessUnitId: getCurrentUserBusinessUnitId,
        GetCurrentUserRoles: getCurrentUserRoles,
        IsCurrentUserRole: isCurrentUserInRole,
        GetServerURL: getServerUrl,
        CreateErrorLog: createErrorLog
    };
}();




No comments:

Post a Comment