Wednesday, August 14, 2013

Re-create deleted records using Audit History

Many a times we come across situations where we accidentally, delete a particular record and wish to recover that record back in CRM. This is possible only if you have “Auditing” enabled for that respective entity. So from the audit history we can re-create deleted records in CRM.

Let us take an example, supposing some records were deleted today and needs to be recovered.

//fetch XML for retrieving auditing records which were deleted today

                string fetchXML = "<fetch version='1.0' output-format='xml-platform' mapping='logical' no-lock='true' distinct='false'> " +
    "<entity name='audit'>  " +
    "<attribute name='auditid' /> " +
     "<attribute name='operation' /> " +
    "<filter type='and'> " +
    "<condition attribute='createdon' operator='today' /> " +
   "<condition attribute='operation' operator='eq' value='3' /> " +
    "</filter>   " +
    "</entity> " +
    "</fetch>";

                //retrieve the audit records from fetchxml
                var auditrecords = service.RetrieveMultiple(new FetchExpression(fetchXML));

                //loop through each audit entity record found and create deleted records
                foreach (Entity audit in auditrecords.Entities)
                {
                    // create retrieve audit detail request object
                    RetrieveAuditDetailsRequest auditDetailsRequest = new RetrieveAuditDetailsRequest();

                    //assign audit id value
                    auditDetailsRequest.AuditId = audit.Id;

                    //execute request and retrieve response
                    RetrieveAuditDetailsResponse auditDetailsResponse =
                        (RetrieveAuditDetailsResponse)_service.Execute(auditDetailsRequest);
                 
                    //create auditDetail variable and assign its value
                    AuditDetail auditDetail = auditDetailsResponse.AuditDetail;

                    //type cast audtitDetail as AttributeAuditDetail
                     AttributeAuditDetail attributeAuditDetail = auditDetail as AttributeAuditDetail;

                    //create the deleted record
                     service.Create(attributeAuditDetail.OldValue);
                }


In above code first we have retrieved audit entity records which were created “today” and operation was “Delete”.

“Operation” field is an “Option Set” field and values are

-              Create = 1
-              Update = 2
-              Delete = 3
-              Assign = 4





Hope this post helps!


Tuesday, July 30, 2013

How to pass Object or collection of Objects to a web resource in CRM 2011


In Dynamics CRM if we want to pass data to a web resource, then we use Xrm.Utility.openWebResource function and pass as second parameter. But in this case we can’t pass Object or Array as parameter.
 
So to solve this problem one can use JSON. Using JSON we can convert Object or Collection of Object (Array) in string format. This converted data can be used to pass data to web resource. Let us take an example of passing collection of object to web resource. Here I have used collection of array that contains Id, Description and Name of Record. 

   var arrayObject = new Array();
              arrayObject[0] = new Object();
              arrayObject[0].name = "Sample Record 1";
              arrayObject[0].id = “1.";
              arrayObject[0].decription = "Test Description ";


Then after defining collection of object we will pass that object to JSON.stringify. This function will return collection in JSON String format. Then this JSON string is encoded to get parameter that is going to passed to the web resource.

var customParameters = encodeURIComponent(JSON.stringify(arrayObject));

This encoded JSON string can be passed to web resource using below code: 

Xrm.Utility.openWebResource("new_/Records.html", customParameters);

Here “Records.html” is used for displaying this collection of object on HTML page. In web resource “Records.html”, passed parameter can be collected as follows:

var queryParam = Xrm.Page.context.getQueryStringParameters();

The collected parameter is in JSON string format so we have to convert array using JSON.parse to convert it into collection of object.

if (queryParam.Data) {
                        arrayObject = JSON.parse(queryParam.Data);
                       }


In this way we can pass collection of object as parameter to web resource. Similarly we can do for object as well. 

We have used above code for passing some data to HTML web resource Records.html. This web resource takes collection of objects. And then show in table format as you can see in below screen shot.




But when we pass parameter to web resource it is passed as query string. Query string has limitation based on browsers used. So when we pass parameter to web resource it trims/neglects extra characters from the query string. So it will cause problem while converting JSON string object into Object. And this problem of query string limitation can be solved using window.opener

The opener property returns a reference to the window that created the window. When opening a window with window.open(), you can use this property from the destination window to return details of the source (parent) window. By using window.opener we can access global parameters defined in parent web resource. In this way we can access Objects or collection without any limitations.
Let us take same example of passing collection of object to web resource. We will take collection of object defined as follows. 

               var _arrayObject = new Array();
              arrayObject[0] = new Object();
              arrayObject[0].name = "Record 1";
              arrayObject[0].id = "1.";
              arrayObject[0].decription = "Test Description";
              arrayObject[0] = new Object();
              arrayObject[0].name = "Record 2";
              arrayObject[0].id = "2.";
              arrayObject[0].decription = "Test Description";


Then we open web resource i.e. Records.html using Xrm.Utility.openWebResource.

Xrm.Utility.openWebResource("new_/Records.html");

In web resource, passed data can be collected as follows:

if (window.opener._arrayObject != null) {
                           var  _arrayObject = window.opener._arrayObject
                        }

By using above we can pass large amount of data to HTML web resource.
I have used the windows.opener to collect the data from _arrayObject global object. This collection is converted into HTML table format. I have used this code for displaying selected records into grid.



Wednesday, July 24, 2013

How to load a web resource using Java Script

In Dynamics CRM 2011, if we implement JavaScript for particular form we add script web resource in the Form Libraries list under form customization, if there is any related script which need to be referred,  then we need to include that script as well in the Form Libraries. As you can see in the below screen, we have included “new_SDK.Rest” and “new_Json2”. We have not called the function of those scripts in the “Event Handlers”, but we have used them in our library “new_Account_Library.jsa

 




Now suppose if you need to add a button on the Home Page ribbon of entity, and this button should call some function in the “new_Account_Library.js” library. This means the button is *not* calling any HTML or Silverlight page.


In such case, if we use the HTML page instead of the javascript then you can load the related script library with the following line of code.

<script src="../new_sdk.rest" type="text/javascript"></script>




 

Here the problem is how to add/ load related JScript reference like in this case sdk.rest jscript and json Jscript reference. To retrieve the data from CRM we generally use functions from the sdk.rest library. Hence this library “sdk.rest” needs to be loaded as we are referring the function of “sdk.rest” library in this “new_Account_Library.js” script.


So to resolve this we can simply load referred web resource from JScript programmatically before performing our business logic, below is the function you can refer to.


We need to pass name of web resource.


LoadWebResource(Name of the Web Resource);

e.g.

LoadWebResource(“new_json2”)

LoadWebResource(“new_SDK.Rest”)


Function for load web resource:


//Function to Load webResource


function LoadWebResource(resource) {

 var httpRequest = null;


 try {    



if (window.XMLHttpRequest) {  // code for IE7+, Firefox, Chrome, Opera, Safari

            httpRequest = new XMLHttpRequest();


}
      else// code for IE6, IE5


httpRequest = new ActiveXObject("Microsoft.XMLHTTP");



}
              var serverUrl= Xrm.Page.context.getServerUrl();

             if (serverUrl.match(/\/$/)) {


serverUrl = serverUrl.substring(0, serverUrl.length - 1);

}
 
httpRequest.open("GET", serverUrl + "/webresources/" + resource, false);

httpRequest.send(null);

eval(httpRequest.responseText);

}


catch (e) {
 
alert("LoadWebResource >> Error loading " + resource + ":\n" + e.description);


  }

}

Thursday, July 18, 2013

Maplytics Dashboards

Today we will demonstrate a simple though very useful feature of our flagship product Maplytics, which is Dashboards. Maplytics Dashboards provides a fast and easy way to view and communicate business data in a visual format.


Maplytics is a plug and play application made available as Managed solution that can be easily installed and uninstalled without affecting other CRM components. Maplytics is a Geo-Analytics tool designed for Microsoft Dynamics CRM 2011(Online/On-Premise/IFD/Office 365) using the API services provided by Bing maps.

Maplytics Dashboards make it simple for sales, marketing, and customer service people to create dashboards on the fly—so they can spend more time acting on critical data, and less time gathering it.

Here we have taken an example of Appointments; Maplytics Dashboard will provide you with detailed information of the appointment scheduled with the contact for that day.



 
Another example could be for Cases to be resolved today or your sales pipeline which is shown in below screen shot.


As we are always looking for ways to better understand our data and showing data on Map alone like new leads within the month, monthly sales; provides quick and easy insights. However it doesn’t allow you to see trends like new leads within this month, new accounts within this month, volume of sales. Maplytics provides you with a feature called Heat Map. Heat map is an Advanced Map based visualization which allows better analysis of such data.


Thus Maplytics will provide you with easy insights with trends being followed and would also help you to serve your customer better in every possible way.


Please contact us at crm@inogic.com for more details and trial requests of Maplytics