Showing posts with label fetch xml. Show all posts
Showing posts with label fetch xml. Show all posts

Wednesday, September 12, 2012

My View and My Teams View in CRM 2011

Hi,

I have been working with Siebel CRM before and I have been pretty much used to My Views and My Teams views in Siebel. (Position based visibility on records)
We used to have position (team) owned entities like Account, Contact, Opportunity and user owned entities like Activities and SR. Also in case of activities and service request quite often we need to look into your teams activities and teams requests. Although they are user owned entities in Siebel, we used the reporting logic to display this managerial view.

Similarly if we want to achieve a similar kind of functionality in CRM 2011, it's quite simple.

Use the advanced query editor to define the query as below.
Select the owner as the current user OR equal to the current user's teams


Also if you have used Siebel, when you are in Activities view, you will also see a view called "My Contact's activities" or "My Company's Activities". We can achieve the same in CRM 2011 as below. This is quite a powerful feature.


Note: Since these queries are resource intensive use with CAUTION. Use other filter conditions to filter more records. For example, I have used to filter only open activities.

See the next episode here

Monday, September 10, 2012

Testing of FetchXml

I have come across few instances where I want to test the custom written fetch xml query to test against the CRM. The reason being you cannot test aggregate queries in CRM and if you need to be sure to test the output before implementation, here you go with the solution. You can see the output so that it's easy before implementing the actual query.
Create a VS 2010 project (form based application).
Design the form by creating the following

Type
Name
Label
Button
buttonClearInput
Clear Input
Button
buttonClearOutput
Clear Output
Button
convert
Convert
TextBox
FetchXmlReq
Fetch Xml
TextBox
FetchXmlResp
Fetch Xml Response








        private void buttonClearInput_Click(object sender, EventArgs e)
        {
            FetchXmlReq.Text = "";
        }

        private void buttonClearOutput_Click(object sender, EventArgs e)
        {
            FetchXmlResp.Text = "";
        }

        private void convert_Click(object sender, EventArgs e)
        {
            string fetchXml = FetchXmlReq.Text;
            string fetchXmlResp =fetchXml;
            fetchXmlResp = testFetch(fetchXml);
            FetchXmlResp.Text = fetchXmlResp;
        }





private string testFetch(string fetchXml)
        {
            Uri organizationUri = new Uri("http://servername:port/SSBCapgemini/XRMServices/2011/Organization.svc");
            Uri homeRealmUri = null;
            ClientCredentials credentials = new ClientCredentials();

            credentials.Windows.ClientCredential.Domain = "domain";
            credentials.Windows.ClientCredential.UserName = "username";
            credentials.Windows.ClientCredential.Password = "Password";
            String fetchXmlresp = string.Empty;
            Guid _accountid = Guid.Empty;
            OrganizationServiceProxy orgProxy = new OrganizationServiceProxy(organizationUri, homeRealmUri, credentials, null);
            IOrganizationService _service = (IOrganizationService)orgProxy;
            try
            {
              
                /*
                string estimatedvalue_avg = @"  <fetch version='1.0' mapping='logical' distinct='false' aggregate='true'>
                                                  <entity name='ssb_stock'>
                                                    <attribute name='ssb_market_value' aggregate='SUM' alias='sum_market_value'/>
                                                    <attribute name='ssb_cost_value' aggregate='SUM' alias='sum_cost_value'/>
                                                    <filter>
                                                      <condition attribute='ssb_contact' operator='eq' value='{AE6A2F6E-13B9-8451-3775-0E328DF08230}' />
                                                    </filter>
                                                  </entity>
                                                </fetch>";
                //*/
                string estimatedvalue_avg = fetchXml;

                EntityCollection estimatedvalue_avg_result = _service.RetrieveMultiple(new FetchExpression(estimatedvalue_avg));

                foreach (var c in estimatedvalue_avg_result.Entities)
                {
                    decimal aggregate1 = ((Money)((AliasedValue)c.Attributes["sum_market_value"]).Value).Value;
                    decimal aggregate2 = ((Money)((AliasedValue)c.Attributes["sum_cost_value"]).Value).Value;
                    fetchXmlresp += "Sum of Market value: " + aggregate1 + Environment.NewLine;
                    fetchXmlresp += "Sum of Cost value: " + aggregate2;

                }

                /*
                // Display the results.
                fetchXmlresp += @"List all stocks matching specified parameters";
                fetchXmlresp += @"===============================================";
                foreach (var e in entityResults.Entities)
                {
                    fetchXmlresp += String.Format("Stock ID: {0}\n", e.Id;
                }


                fetchXmlresp += "<End of Listing>\n\n";
                 */
            }
            catch (Exception ex)
            {
               fetchXmlresp += ex.Message;
            }
           
            return fetchXmlresp;
        }

Friday, September 07, 2012

Fetch XML and Javascript

I had a requirement to show the financial summary of the customers.

I tried different options and ended up using Javascript.

I created an new button in the ribbon and then called the javascript to update the values using fetchxml.
Call the "GetOverview" function in the ssb_contact_links.js file.


Upload the below Javascript as webresources and then link these libraries to the form so that we can call those functions.


// JScript source code
//===============================================================================================
//ssb_FetchXmlLib.js
var XMLHTTPSUCCESS = 200;
var XMLHTTPREADY = 4;
function FetchUtil(sOrg, sServer) {
    this.org = sOrg;
    this.server = sServer;
    if (sOrg == null) {
        if (typeof (ORG_UNIQUE_NAME) != "undefined") {
            this.org = ORG_UNIQUE_NAME;
        }
    }
    if (sServer == null) {
        this.server = window.location.protocol + "//" + window.location.host;
    }
}
FetchUtil.prototype._ExecuteRequest = function (sXml, sMessage, fInternalCallback, fUserCallback) {
    var xmlhttp = new XMLHttpRequest();
    xmlhttp.open("POST", this.server + "/XRMServices/2011/Organization.svc/web", (fUserCallback != null));
    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");
    if (fUserCallback != null) {
        //asynchronous: register callback function, then send the request.
        var crmServiceObject = this;
        xmlhttp.onreadystatechange = function () {
            fInternalCallback.call(crmServiceObject, xmlhttp, fUserCallback)
        };
        xmlhttp.send(sXml);
    } else {
        //synchronous: send request, then call the callback function directly
        xmlhttp.send(sXml);
        return fInternalCallback.call(this, xmlhttp, null);
    }
}
FetchUtil.prototype._HandleErrors = function (xmlhttp) {
    /// <summary>(private) Handles xmlhttp errors</summary>
    if (xmlhttp.status != XMLHTTPSUCCESS) {
        var sError = "Error: " + xmlhttp.responseText + " " + xmlhttp.statusText;
        alert(sError);
        return true;
    } else {
        return false;
    }
}
FetchUtil.prototype.Fetch = function (sFetchXml, fCallback) {
    /// <summary>Execute a FetchXml request. (result is the response XML)</summary>
    /// <param name="sFetchXml">fetchxml string</param>
    /// <param name="fCallback" optional="true" type="function">(Optional) Async callback function if specified. If left null, function is synchronous </param>
    var request = "<s:Envelope xmlns:s=\"http://schemas.xmlsoap.org/soap/envelope/\">";
    request += "<s:Body>";
    request += '<Execute xmlns="http://schemas.microsoft.com/xrm/2011/Contracts/Services">' + '<request i:type="b:RetrieveMultipleRequest" ' + ' xmlns:b="http://schemas.microsoft.com/xrm/2011/Contracts" ' + ' xmlns:i="http://www.w3.org/2001/XMLSchema-instance">' + '<b:Parameters xmlns:c="http://schemas.datacontract.org/2004/07/System.Collections.Generic">' + '<b:KeyValuePairOfstringanyType>' + '<c:key>Query</c:key>' + '<c:value i:type="b:FetchExpression">' + '<b:Query>';
    request += CrmEncodeDecode.CrmXmlEncode(sFetchXml);
    request += '</b:Query>' + '</c:value>' + '</b:KeyValuePairOfstringanyType>' + '</b:Parameters>' + '<b:RequestId i:nil="true"/>' + '<b:RequestName>RetrieveMultiple</b:RequestName>' + '</request>' + '</Execute>';
    request += '</s:Body></s:Envelope>';
    return this._ExecuteRequest(request, "Fetch", this._FetchCallback, fCallback);
}
FetchUtil.prototype._FetchCallback = function (xmlhttp, callback) {
    ///<summary>(private) Fetch message callback.</summary>
    //xmlhttp must be completed
    if (xmlhttp.readyState != XMLHTTPREADY) {
        return;
    }
    //check for server errors
    if (this._HandleErrors(xmlhttp)) {
        return;
    }
    var sFetchResult = xmlhttp.responseXML.selectSingleNode("//a:Entities").xml;
    var resultDoc = new ActiveXObject("Microsoft.XMLDOM");
    resultDoc.async = false;
    resultDoc.loadXML(sFetchResult);
    //parse result xml into array of jsDynamicEntity objects
    var results = new Array(resultDoc.firstChild.childNodes.length);
    for (var i = 0; i < resultDoc.firstChild.childNodes.length; i++) {
        var oResultNode = resultDoc.firstChild.childNodes[i];
        var jDE = new jsDynamicEntity();
        var obj = new Object();
        for (var j = 0; j < oResultNode.childNodes.length; j++) {
            switch (oResultNode.childNodes[j].baseName) {
                case "Attributes":
                    var attr = oResultNode.childNodes[j];
                    for (var k = 0; k < attr.childNodes.length; k++) {
                        // Establish the Key for the Attribute
                        var sKey = attr.childNodes[k].firstChild.text;
                        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].baseName == 'type') {
                                sType = attr.childNodes[k].childNodes[1].attributes[l].text;
                            }
                        }
                        switch (sType) {
                            case "a:OptionSetValue":
                                var entOSV = new jsOptionSetValue();
                                entOSV.type = sType;
                                entOSV.value = attr.childNodes[k].childNodes[1].text;
                                obj[sKey] = entOSV;
                                break;
                            case "a:EntityReference":
                                var entRef = new jsEntityReference();
                                entRef.type = sType;
                                entRef.guid = 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:AliasedValue":
                                var entAV = new jsAliasedValue();
                                //entAV.type = sType;
                                entAV.name = attr.childNodes[k].childNodes[1].childNodes[0].text;
                                entAV.logicalName = attr.childNodes[k].childNodes[1].childNodes[1].text;
                                entAV.value = attr.childNodes[k].childNodes[1].childNodes[2].text;
                                obj[sKey] = entAV;
                                break;
                            default:
                                var entCV = new jsCrmValue();
                                entCV.type = sType;
                                entCV.value = attr.childNodes[k].childNodes[1].text;
                                obj[sKey] = entCV;
                                break;
                        }
                    }
                    jDE.attributes = obj;
                    break;
                case "Id":
                    jDE.guid = oResultNode.childNodes[j].text;
                    break;
                case "LogicalName":
                    jDE.logicalName = oResultNode.childNodes[j].text;
                    break;
                case "FormattedValues":
                    var foVal = oResultNode.childNodes[j];
                    for (var k = 0; k < foVal.childNodes.length; k++) {
                        // Establish the Key, we are going to fill in the formatted value of the already found attribute
                        var sKey = foVal.childNodes[k].firstChild.text;
                        jDE.attributes[sKey].formattedValue = foVal.childNodes[k].childNodes[1].text;
                    }
                    break;
            }
        }
        results[i] = jDE;
    }
    //return entities
    if (callback != null) callback(results);
    else return results;
}
function jsAliasedValue(sLogicalName, sName, sValue, sFormattedValue) {
    this.value = sValue;
    this.logicalName = sLogicalName;
    this.name = sName;
    this.type = 'AliasedValue';
    this.formattedValue = sFormattedValue;
}
function jsDynamicEntity(gID, sLogicalName) {
    this.guid = gID;
    this.logicalName = sLogicalName;
    this.attributes = new Object();
}
function jsCrmValue(sType, sValue) {
    this.type = sType;
    this.value = sValue;
}
function jsEntityReference(gID, sLogicalName, sName) {
    this.guid = gID;
    this.logicalName = sLogicalName;
    this.name = sName;
    this.type = 'EntityReference';
}
function jsOptionSetValue(iValue, sFormattedValue) {
    this.value = iValue;
    this.formattedValue = sFormattedValue;
    this.type = 'OptionSetValue';
}

//===============================================================================================
//ssb_fetchXml.js

// JScript source code
function fetchOnLoadSync() {
    var _oService;
    var _sOrgName = "OrgName";
    var _sServerUrl = Xrm.Page.context.getServerUrl();
    // Get the ID of the Customer
    var sCustGUID = Xrm.Page.data.entity.getId();
    var entityName = Xrm.Page.data.entity.getEntityName();
    var linkEntity = "";

    if (entityName == "contact") linkEntity = "ssb_contact";
    if (entityName == "account") linkEntity = "ssb_account";
    var msg = "";
    msg += "Logical Entity Name = " + entityName + "\n";
    msg += "Guid of the current record = " + sCustGUID + "\n";
    msg += "Link Entity Name = " + linkEntity + "\n";
    //alert(sCustGUID);
    var sFetch =    "<fetch version='1.0' mapping='logical' distinct='false' aggregate='true'>"+
                      "<entity name='ssb_stock'>"+
                        "<attribute name='ssb_market_value' aggregate='SUM' alias='sum_market_value'/>" +
                        "<attribute name='ssb_cost_value' aggregate='SUM' alias='sum_cost_value'/>" +
                        "<attribute name='ssb_stock_name' aggregate='count' alias='count_of_stock'/>" +
                        "<filter>"+
                          "<condition attribute='" + linkEntity + "' operator='eq' value='"+ sCustGUID + "' />"+
                        "</filter>"+
                      "</entity>"+
                    "</fetch>";
    _oService = new FetchUtil(_sOrgName, _sServerUrl);
    var res = _oService.Fetch(sFetch);
    //for (x in res) {
    // for (y in res[x]) {
            //alert("Type = " + res[0].attributes["sum_market_value"].type);
           // alert("Value = " + res[0].attributes["sum_market_value"].value);
            //alert("Formatted Value = " + res[0].attributes["sum_market_value"].formattedValue);
         //   alert(res[x].attributes[y].value);
     //   }
    // }
    msg += "Type = " + res[0].attributes["sum_market_value"].type + "\n";
    msg += "Market Value = " + res[0].attributes["sum_market_value"].value + "\n";
    msg += "Market Value Formatted = " + res[0].attributes["sum_market_value"].formattedValue;
    msg += "Cost Value = " + res[0].attributes["sum_cost_value"].value + "\n";
    msg += "Cost Value Formatted = " + res[0].attributes["sum_cost_value"].formattedValue;
    msg += "Count of Records = " + res[0].attributes["count_of_stock"].value + "\n";
    //alert(msg);
   return (res[0].attributes["sum_market_value"].value );
}

//=======================================================================
//ssb_contact_links.js

function GetOverview()
{
//<script src="ssb_FetchXml.js"></script>
//alert("Overview Start");
//var fetch: ScriptName;
//fetch = this.GetComponent("ssb_FetchXml");
//alert (Xrm.Page.getAttribute("ssb_sum_of_stocks").getValue());
var marketValue =Number( fetchOnLoadSync());
//alert (marketValue )
Xrm.Page.getAttribute("ssb_sum_of_stocks").setValue(marketValue);
var idag = new Date();
//alert (idag);
Xrm.Page.getAttribute("ssb_overview_updated_date").setValue(idag);
//alert("Overview Refreshed");
Xrm.Page.data.entity.save();

}