Sunday, September 26, 2010

login log out informations for users in ms crm

We all are aware of this thing that ms crm does have the tracking system of the users logging in and logging out to crm.

so here is some idea how to make it

#1 make a custom entity named "LogUserInfo" and create the following minimun required attributes
UserName : this will keep the users full name
OrgName : the corresponding Organization name , this will help in multi-tenancy environment.
LoginTime : the login time of the user(it will be calculated once the loader.aspx page will get loaded.)
LogoutTime : the log out time of the user(it will be calculated once the user will X-off means close the browser or refresh the main window)

#2 write the following bunch of code in the loader.aspx page which is available in the inetpub\wwwroot\, with in the javascript tag

//register the onload and unonload events 1st
window.onload = logLoginInfo;
window.onunload = logLogoutInfo;

//get user full name
function getUserFullName(){
//Create the XML that will fetch the required info.
//You can inspect this web service call using a tool called FIDDLER.
var XMLRequest = "" +
"<?xml version=\"1.0\" encoding=\"utf-8\"?>" +
"<soap:Envelope xmlns:soap=\"http://schemas.xmlsoap.org/soap/envelope/\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\">" +
GenerateAuthenticationHeader() +
" <soap:Body>" +
" <RetrieveMultiple xmlns=\"http://schemas.microsoft.com/crm/2007/WebServices\">" +
" <query xmlns:q1=\"http://schemas.microsoft.com/crm/2006/Query\" xsi:type=\"q1:QueryExpression\">" +
" <q1:EntityName>systemuser</q1:EntityName>" +
" <q1:ColumnSet xsi:type=\"q1:ColumnSet\">" +
" <q1:Attributes>" +
" <q1:Attribute>systemuserid</q1:Attribute>" +
" <q1:Attribute>fullname</q1:Attribute>" +
" </q1:Attributes>" +
" </q1:ColumnSet>" +
" <q1:Distinct>false</q1:Distinct>" +
" <q1:Criteria>" +
" <q1:FilterOperator>And</q1:FilterOperator>" +
" <q1:Conditions>" +
" <q1:Condition>" +
" <q1:AttributeName>systemuserid</q1:AttributeName>" +
" <q1:Operator>EqualUserId</q1:Operator>" +
" </q1:Condition>" +
" </q1:Conditions>" +
" </q1:Criteria>" +
" </query>" +
" </RetrieveMultiple>" +
" </soap:Body>" +
"</soap:Envelope>" +
"";
try{
//Create Http request object
var xmlHttpRequest = new ActiveXObject("Msxml2.XMLHTTP");
xmlHttpRequest.Open("POST", "/mscrmservices/2007/CrmService.asmx", false);
xmlHttpRequest.setRequestHeader("SOAPAction","http://schemas.microsoft.com/crm/2007/WebServices/RetrieveMultiple");
xmlHttpRequest.setRequestHeader("Content-Type", "text/xml; charset=utf-8");
xmlHttpRequest.setRequestHeader("Content-Length", XMLRequest.length);
xmlHttpRequest.send(XMLRequest);
//alert("aaa"+xmlHttpRequest.responseText);
//Store the response which would be XML
var Result = xmlHttpRequest.responseXML;
/*
The return is of type "BusinessEntity" if you were using similar code one server side.
Hence we need to select node of type "BusinessEntity"
In our case It should be not more one than one node
*/
var BusinessEntityNodes = Result.selectNodes("//RetrieveMultipleResult/BusinessEntities/BusinessEntity");
// Check If data was retrived
if (BusinessEntityNodes.length != 0){
var BusinessEntityNode = BusinessEntityNodes[0];
var SystemUserId = BusinessEntityNode.selectSingleNode("q1:systemuserid");
var FullName = BusinessEntityNode.selectSingleNode("q1:fullname");
var SystemUserId = (SystemUserId == null) ? null : SystemUserId.text;
var FullName = (FullName == null) ? null : FullName.text;
// alert("FullName"+FullName);
}
return FullName;

} catch (e){
alert(e.message);
}
}

//get the current Organization(tenant) name
function getOrgName(){
var url = window.location;
var arr = url.toString().split("/");
return arr[3];
}

//get the just login time
function getLoginOutTime(){
var currentTime = new Date();
var month = currentTime.getMonth() + 1;
var day = currentTime.getDate();
var year = currentTime.getFullYear();
var hours = currentTime.getHours();
var minutes = currentTime.getMinutes();
var finalTime = month+"/"+day+"/"+year+" "+hours+":"+minutes;
if(hours > 11){
finalTime += " PM";
} else {
finalTime += " AM";
}
return finalTime;
}
//logging the login info
var loginInfoGUID = "";
function logLoginInfo(){
// Prepare values for the Login User Info.
var sdv_username = getUserFullName();
var sdv_orgname = getOrgName();
var sdv_name = sdv_orgname +"_"+sdv_username;
//var sdv_logintime = getLoginOutTime();
var authenticationHeader = GenerateAuthenticationHeader();

// Prepare the SOAP message.
var xml = "<?xml version='1.0' encoding='utf-8'?>" +
"<soap:Envelope xmlns:soap='http://schemas.xmlsoap.org/soap/envelope/'"+
" xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance'"+
" xmlns:xsd='http://www.w3.org/2001/XMLSchema'>"+
authenticationHeader+
"<soap:Body>"+
"<Create xmlns='http://schemas.microsoft.com/crm/2007/WebServices'>"+
"<entity xsi:type='sdv_loguserinfo'>"+
"<sdv_name>"+sdv_name+"</sdv_name>"+
"<sdv_username>"+sdv_username+"</sdv_username>"+
"<sdv_orgname>"+sdv_orgname+"</sdv_orgname>"+
// "<sdv_logintime>"+sdv_logintime+"</sdv_logintime>"+
"</entity>"+
"</Create>"+
"</soap:Body>"+
"</soap:Envelope>";
//alert("value"+xml);
// Prepare the xmlHttpObject and send the request.
var xHReq = new ActiveXObject("Msxml2.XMLHTTP");
xHReq.Open("POST", "/mscrmservices/2007/CrmService.asmx", false);
xHReq.setRequestHeader("SOAPAction","http://schemas.microsoft.com/crm/2007/WebServices/Create");
xHReq.setRequestHeader("Content-Type", "text/xml; charset=utf-8");
xHReq.setRequestHeader("Content-Length", xml.length);
xHReq.send(xml);
// Capture the result
var resultXml = xHReq.responseXML;
//alert("xml"+xHReq.responseText);
xmlDoc = new ActiveXObject("Microsoft.XMLDOM");
xmlDoc.async=false;
xmlDoc.loadXML(xHReq.responseXML.xml);
var guid = xmlDoc.getElementsByTagName("CreateResult");
//this guid will be used for updating the logout time
loginInfoGUID = guid[0].childNodes[0].text;
//alert("guid"+guid[0].childNodes[0].text);
// Check for errors.
var errorCount = resultXml.selectNodes('//error').length;
if (errorCount != 0)
{
var msg = resultXml.selectSingleNode('//description').nodeTypedValue;
alert("Ignore it, It was for tracking the loging infos"+msg);
}

else
{
//alert("done");
}
}

//logging the louout info
function logLogoutInfo(){
// Prepare variables for updating a contact.
//var sdv_logouttime = getLoginOutTime();
var authenticationHeader = GenerateAuthenticationHeader();

// Prepare the SOAP message.
var xml = "<?xml version='1.0' encoding='utf-8'?>"+
"<soap:Envelope xmlns:soap='http://schemas.xmlsoap.org/soap/envelope/'"+
" xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance'"+
" xmlns:xsd='http://www.w3.org/2001/XMLSchema'>"+
authenticationHeader+
"<soap:Body>"+
"<Update xmlns='http://schemas.microsoft.com/crm/2007/WebServices'>"+
"<entity xsi:type='sdv_loguserinfo'>"+
//"<sdv_logouttime>"+sdv_logouttime+"</sdv_logouttime>"+
"<sdv_loguserinfoid>"+loginInfoGUID+"</sdv_loguserinfoid>"+
"</entity>"+
"</Update>"+
"</soap:Body>"+
"</soap:Envelope>";
// Prepare the xmlHttpObject and send the request.
var xHReq = new ActiveXObject("Msxml2.XMLHTTP");
xHReq.Open("POST", "/mscrmservices/2007/CrmService.asmx", false);
xHReq.setRequestHeader("SOAPAction","http://schemas.microsoft.com/crm/2007/WebServices/Update");
xHReq.setRequestHeader("Content-Type", "text/xml; charset=utf-8");
xHReq.setRequestHeader("Content-Length", xml.length);
xHReq.send(xml);
// Capture the result
var resultXml = xHReq.responseXML;

// Check for errors.
var errorCount = resultXml.selectNodes('//error').length;
if (errorCount != 0)
{
var msg = resultXml.selectSingleNode('//description').nodeTypedValue;
alert("Ignore it, It was for tracking the loging infos"+msg);
}
// Display a confirmation message and open the updated contact.
else
{
// alert("done");
}
}

put the above code as it is, if you have created the custom entity with attributes as above.

#3 Finally one plugin need to be registered on ccreate and update of that entity to get the server time

for precreate

#region IPlugin Members

public void Execute(IPluginExecutionContext context)
{
try
{
DynamicEntity entity = getDynamicEntity(context, "sdv_loguserinfo");
entity.Properties.Add(new CrmDateTimeProperty("sdv_logintime", new CrmDateTime(DateTime.Now.ToString())));
}
catch (InvalidPluginExecutionException ipee)
{
throw ipee;
}
catch (Exception e)
{
throw new InvalidPluginExecutionException("Uncaught Exception\r\n" + e.Message + "\r\n" + e.StackTrace);
}
}

#endregion

private static DynamicEntity getDynamicEntity(IPluginExecutionContext context, string name)
{
if (!(context.InputParameters.Properties.Contains("Target") &&
context.InputParameters.Properties["Target"] is DynamicEntity))
{
return null;
}

DynamicEntity entity = (DynamicEntity)context.InputParameters.Properties["Target"];

if (entity.Name != name)
{
return null;
}

return entity;
}


for preupdate

#region IPlugin Members

public void Execute(IPluginExecutionContext context)
{
try
{
DynamicEntity entity = getDynamicEntity(context, "sdv_loguserinfo");
entity.Properties.Add(new CrmDateTimeProperty("sdv_logouttime", new CrmDateTime(DateTime.Now.ToString())));
}
catch (InvalidPluginExecutionException ipee)
{
throw ipee;
}
catch (Exception e)
{
throw new InvalidPluginExecutionException("Uncaught Exception\r\n" + e.Message + "\r\n" + e.StackTrace);
}
}

#endregion

private static DynamicEntity getDynamicEntity(IPluginExecutionContext context, string name)
{
if (!(context.InputParameters.Properties.Contains("Target") &&
context.InputParameters.Properties["Target"] is DynamicEntity))
{
return null;
}

DynamicEntity entity = (DynamicEntity)context.InputParameters.Properties["Target"];

if (entity.Name != name)
{
return null;
}

return entity;
}

Register the plugins by using the registration tool and test it.

Have fun.

Sudhanshu

No comments:

Post a Comment