Thursday, December 30, 2010

Assign roles to users using Code

There are times when we need to assign roles promatically may plugin or else threu any applications suing the sdk.
here is the code to assign the role.
make sure u have the suer GUID and the roles GUIDs u wan to assign.
and keep it in mind that the higher role previlege will apply for that user.

private static void assignRole(Guid userGUID, Guid[] rolesGUID)
{
// Set up the CRM service.
CrmAuthenticationToken token = new CrmAuthenticationToken();
// You can use enums.cs from the SDK\Helpers folder to get the enumeration for Active Directory authentication.
token.AuthenticationType = 0;
token.OrganizationName = "Default";

CrmService service = new CrmService();
service.Url = "http://<server>:<port>/mscrmservices/2007/crmservice.asmx";
service.CrmAuthenticationTokenValue = token;
service.Credentials = System.Net.CredentialCache.DefaultCredentials;

// Create the request object.
AssignUserRolesRoleRequest assign = new AssignUserRolesRoleRequest();

// Set the properties of the request object.
assign.UserId = userGUID;
// Set the ID of a role that is in the same business unit as the user.
assign.RoleIds = rolesGUID;

// Execute the request.
AssignUserRolesRoleResponse assigned = (AssignUserRolesRoleResponse)service.Execute(assign);
}

Sudhanshu

Tuesday, December 21, 2010

Use Custom View in the in form MS CRM 4.0

There is some times a requirement like people want to use custom views in MS CRM form instead of the available views also with some filtering criterias.
This is how it will work.

The followings are the things need to be taken care
1. collect the entity details
2. create an IFRAME
3. make sure the columns you want to put are present in CRM and searchable(imp)
4. this is just a sample, change it as per your requirements
5. this is just showing the record which you have selected, by taking the guid

so check the code,against most of the lines we have comments which will make it easy

//the main function which will do the majic

function EmbedAdvancedFindView (iFrameId, entityName, fetchXml, layoutXml, sortCol, sortDescend, defaultAdvFindViewId, entityTypeId) {
// Initialize our important variables
var httpObj = new ActiveXObject("Msxml2.XMLHTTP");
var url = SERVER_URL + "/AdvancedFind/fetchData.aspx";
var iFrame = document.getElementById(iFrameId);
var win = iFrame.contentWindow;
var doc = iFrame.contentWindow.document;

// Provide a global function within the parent scope to avoid XSS limitations
// in updating the iFrame with the results from our HTTP request
PushResponseContents = function (iFrame, httpObj, entityTypeId) {
var win = iFrame.contentWindow;
var doc = iFrame.contentWindow.document;
var m_iFrameShowModalDialogFunc = null;
var m_windowAutoFunc = null;

// Write the contents of the response to the Iframe
doc.open();
doc.write(httpObj.responseText);
doc.close();

// Set some style elements of the Advanced Find window
// to mesh cleanly with the parent record's form
doc.body.style.padding = "0px";
doc.body.scroll="no";

// Should we overwrite the functionality of the "New" button?
if ((typeof(entityTypeId) != "undefined") && (entityTypeId != null)) {
var buttonId = "_MBopenObj" + entityTypeId;
var newButton = doc.getElementById(buttonId);

eval("newButton.action = 'locAddRelatedToNonForm(" + entityTypeId + ", " + crmForm.ObjectTypeCode + ", \"" + crmForm.ObjectId + "\",\"\");'");
}

// Swap the showModalDialog function of the iFrame
if (m_iFrameShowModalDialogFunc == null) {
m_iFrameShowModalDialogFunc = win.showModalDialog;
win.showModalDialog = OnIframeShowModalDialog;
}

if (m_windowAutoFunc == null) {
m_windowAutoFunc = win.auto;
win.auto = OnWindowAuto;
}

// Configure the automatic refresh functionality for dialogs
function OnIframeShowModalDialog(sUrl, vArguments, sFeatures) {
m_iFrameShowModalDialogFunc(sUrl, vArguments, sFeatures);
doc.all.crmGrid.Refresh();
}

function OnWindowAuto(otc) {
doc.all.crmGrid.Refresh();

m_windowAutoFunc(otc);
}
}

// Without a null src, switching tabs in the form reloads the src
iFrame.src = null;

// Preload the iFrame with some HTML that presents a Loading image
var loadingHtml = ""
+ "<table height='100%' width='100%' style='cursor:wait'>"
+ " <tr>"
+ " <td valign='middle' align='center'>"
+ " <img alt='' src='/_imgs/AdvFind/progress.gif' />"
+ " <div /><i>Loading View...</i>"
+ " </td>"
+ " </tr>"
+ "</table>";

doc.open();
doc.write(loadingHtml);
doc.close();

// Compile the FetchXML, LayoutXML, sortCol, sortDescend, defaultAdvFindViewId, and viewId into
// a list of params to be submitted to the Advanced Find form
var params = "FetchXML=" + fetchXml
+ "&LayoutXML=" + layoutXml
+ "&EntityName=" + entityName
+ "&DefaultAdvFindViewId=" + defaultAdvFindViewId
+ "&ViewType=1039" // According to Michael Hohne over at Stunnware, this is static
+ "&SortCol=" + sortCol
+ "&SortDescend=" + sortDescend;

// Establish an async connection to the Advanced Find form
httpObj.open("POST", url, true);

// Send the proper header information along with the request
httpObj.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
httpObj.setRequestHeader("Content-length", params.length);

// Function to write the contents of the http response into the iFrame
httpObj.onreadystatechange = function () {
if (httpObj.readyState == 4 && httpObj.status == 200) {
parent.PushResponseContents(iFrame, httpObj, entityTypeId);
}
}
//alert(params);
// Set it, and forget it! and enjoy :)
httpObj.send(params);
}

///*********************************************
//Create the objects

//get the current record's GUID
var IFRAME_Name = "IFRAME_Accounts";
var entityName = "new_residencestatus";

var currentGUID = crmForm.ObjectId.toString();


// Embed an AF window
fetchXml = ""
+ "<fetch version='1.0' output-format='xml-platform' mapping='logical' distinct='false'>"
+ " <entity name='new_residencestatus'>" //the enityname for whoch u want to create the view
+ " <attribute name='new_residencestatusid'/>" //columns u want to fetch
+ " <attribute name='new_name'/>" //same as above
+ " <order attribute='new_name' descending='false'/>" //for which column u want to order
+ " <filter type='and'>"
+ " <condition attribute='new_residencestatusid' operator='eq' value='" //pass your conditional value
+ currentGUID
+"'/>"
+ " </filter>"
+ " </entity>"
+ "</fetch>";

layoutXml = ""
+ "<grid name='resultset'>"
+ " <row name='result' id='new_residencestatusid'>" //be careful for this is , it should be same as the primarykey
+ " <cell name='new_name' width='150' />" //columns you want to show and fetched in the column list
+ " </row>"
+ "</grid>";

var sortColumnName = "new_name";
var sortDescend = "false";
var associatedViewGUID = "{93A408E0-A6E5-4149-9510-4EF333C0FC43}";
var objectTypeCode = crmForm.ObjectTypeCode.toString();

//call the master and majic method :)

EmbedAdvancedFindView(IFRAME_Name, entityName, fetchXml, layoutXml, sortColumnName, sortDescend, associatedViewGUID, objectTypeCode);

//hide the unnecessary menu bar from the grid

function hideViewMenu(){
var formview = document.all.IFRAME_Accounts;
if( formview.readyState != 'complete' )
return;

formview.contentWindow.document.getElementById("gridMenuBar").style.display = "none";
formview.contentWindow.document.getElementById("mnuBar1").parentNode.style.display = "none";
}
//hide the menubar from the view
var Form = crmForm.all.IFRAME_Accounts;
Form.attachEvent("onreadystatechange",hideViewMenu);
Sudhanshu

Monday, December 20, 2010

DateTime to CrmDateTime conversion

We all know that DateTime in C# is different than CrmDateTime.
In CrmDateTime we also have two things 1. UserTime and 2. UniversalTime.
To convert from normal DateTime to CrmDateTime follow the follwoing code.

public static CrmDateTime ConvertToCRMDateTime(DateTime dateTime)
{
CrmDateTime crmDateTime = new CrmDateTime();
crmDateTime.date = dateTime.ToShortDateString(); //assign the date
crmDateTime.time = dateTime.ToShortTimeString();//assign the time
//now create the offset from the timezone
TimeSpan offset = TimeZone.CurrentTimeZone.GetUtcOffset(dateTime);
string sOffset = string.Empty;
if (offset.Hours < 0)
{
sOffset = "-" + (offset.Hours * -1).ToString().PadLeft(2, '0') + ":";
}
else
{
sOffset = "+" + offset.Hours.ToString().PadLeft(2, '0') + ":";//":" is more inmportant
}
sOffset += offset.Minutes.ToString().PadLeft(2, '0');
crmDateTime.Value = dateTime.ToString(string.Format("yyyy/MM/ddTHH:mm:ss{0}", sOffset));
return crmDateTime; //finally return the CrmDateTime format
}

Sunday, December 19, 2010

Create a header with the form information in ms crm

Some times we need to show a header informations in ms crm 4.0.(but its available OTB in 5.0). as in pic.

just follw the followings and change ur attributes as per your requirements.

var elem = document.getElementById("leftNavBreadcrumbText");

var fullName = (crmForm.all.name.DataValue != null) ? crmForm.all.name.DataValue : "";
var NRIC = (crmForm.all.new_nric.DataValue != null) ? crmForm.all.new_nric.DataValue : "";
var handPhone= (crmForm.all.new_handphone.DataValue != null) ? crmForm.all.new_handphone.DataValue : "";

if (elem != null) {
var actualHTML = elem.innerHTML;
actualHTML += '
actualHTML
';
elem.innerHTML = actualHTML ;
}

Sudhanshu

Put a View in a form and on select of that record load the same to the Form in another Iframe

Its very frequent requirement.
like i want to put a view to the forma and on select(double click) it should load also to the same form(another iframe).

So just follow the following steps.
make sure the IFRAME names. change as per yours.

//*********************************************************************************
//put the two iframes and load the record on double cick of the record from one Iframe
//*********************************************************************************

//get the server url with port (if anything else 80) u can not really rely ;)
function getServerUrlWithPort()
{
return window.location.protocol + "//" + window.location.host ;
}

//this is for the
function OnGridViewReady()
{

var gridview = document.all.IFRAME_Grid;
if( gridview.readyState != 'complete' )
return;
gridview.contentWindow.document.getElementById('crmGrid_JumpBar').parentNode.parentNode.style.display = 'none';
gridview.contentWindow.document.getElementById("quickFindContainer").parentNode.parentNode.parentNode.parentNode.parentNode.parentNode.parentNode.parentNode.style.display = "none";

gridview.contentWindow.document.getElementById("crmMenuBar").parentNode.parentNode.style.display = 'none';

var gridviewDocument = gridview.document.frames["IFRAME_Grid"].document;
var gridviewWindow = gridviewDocument.parentWindow;
gridviewWindow.open = OnWindowOpen;
gridviewDocument.body.scroll = "no";
}

//this will bind the url to the 2nd IFrame instead of opening it as new window
function OnWindowOpen( url )
{
var formview = document.all.IFRAME_Form;
//alert("aaaa"+url+"#######"+formview );
formview.src = getServerUrlWithPort() + url;

if (url != "/" + this.parent.ORG_UNIQUE_NAME + "/sfa/accts/edit.aspx")
return false;
}

//this will be fired when the form will be loaded to the 2nd IFrame
//hide the left nav area and other menu items also
function OnFormViewReady()
{
var formview = document.all.IFRAME_Form;

if( formview.readyState != 'complete' )
return;

formview.document.frames['IFRAME_Form'].document.body.style.border = "1px solid #6893cf";

if (formview.contentWindow.document.getElementById('leftNavBreadcrumbImg') == null)
return;
formview.contentWindow.document.getElementById('leftNavBreadcrumbImg').parentNode.parentNode.parentNode.parentNode.parentNode.style.display = 'none';
formview.contentWindow.document.getElementById('leftNavBreadcrumbImg').parentNode.parentNode.parentNode.parentNode.parentNode.parentNode.parentNode.height = '45';

formview.contentWindow.document.getElementById('crmMenuBar').parentNode.parentNode.style.display = 'none';
formview.contentWindow.document.getElementById('crmNavBar').parentNode.style.display = 'none';
formview.contentWindow.document.getElementById('tdAreas').colSpan = 2;
formview.contentWindow.document.getElementById('crmRenderStatus').parentNode.parentNode.style.display = 'none';
formview.contentWindow.document.getElementById('help').parentNode.parentNode.parentNode.parentNode.parentNode.style.display = 'none';

}

var Grid = crmForm.all.IFRAME_Grid;
var Form = crmForm.all.IFRAME_Form;
Grid.attachEvent("onreadystatechange",OnGridViewReady);
Form.attachEvent("onreadystatechange",OnFormViewReady);


//hide tab
crmForm.all.tab1Tab.style.display="none";

document.getElementById('help').style.display = "none";
document.getElementById('mnuDown').style.display = "none";
if(document.getElementById('navAsyncOperations') !=null)
{
document.getElementById('navAsyncOperations').style.display="none";
}

Sudhanshu

Monday, November 29, 2010

Tuesday, November 2, 2010

Guide to Dynamics CRM 4.0 Editions and Licensing

The purpose of this guide is to help you find the Dynamics CRM server and licenses appropriate to your organization's needs.

Microsoft Dynamics CRM 4.0 is available in three editions, each appropriate for different sizes and types of organizations. Additionally, several different licensing configurations are available, depending on the number and kind of users who will access the CRM database, as well as the type of access necessary.

Server Editions

Three separate versions of the Dynamics CRM 4.0 server are available through TechSoup Stock: Workgroup Server, Professional Server, and Enterprise Server.

Dynamics CRM 4.0 Workgroup Server: Dynamics CRM 4.0 Workgroup Server offers the same features as Professional Server, but does not operate under the Server/CAL licensing model. CRM 4.0 Workgroup Server includes licenses for a maximum of five users to access the server from any number of computers or other devices. There are no licenses available for additional users, devices, or external users.

Dynamics CRM 4.0 Professional Server: Dynamics CRM 4.0 Professional Server operates under a Server/CAL licensing model, similar to many other Microsoft server products. Client access licenses may be acquired on a per-user or per-device model, depending on the needs of the organization. See Client Access Licenses below.

Dynamics CRM 4.0 Enterprise Server: Dynamics CRM 4.0 Enterprise Server offers the same features and licensing model as Dynamics CRM 4.0 Professional Server, with the additional benefit of a multi-tenant architecture. In other words, the Enterprise Server allows organizations to maintain multiple, distinct CRM databases on one server with only one server license.

Client Access Licenses

Dynamics CRM 4.0 Professional and Enterprise require a client access license (CAL) for each user or device accessing the server. There are three different types of CALs available on either a per-user or per-device model.

Limited CAL: The limited CAL allows a user or device read-only access to the CRM server. In other words, users with a limited CAL may access CRM information but may not make any edits or updates to it.

Full Use Additive CAL: When used in conjunction with a limited CAL, a full use additive CAL allows a user or device write access to the CRM server, thus allowing the user or device full read-write access to the server. The full use additive CAL may be used only in conjunction with a limited CAL.

CAL: The CAL provides a user or device full read-write access to the CRM server. The CAL is functionally equivalent to a combined limited and full use additive CAL.

As with many other Microsoft server technologies, the CALs listed above are each available on a per-user or per-device basis. A user CAL authorizes one user to access the CRM server from any computer or other device (for example, when an employee accesses the server from a computer at work and another at home). A device CAL authorizes one computer or other device to access the CRM server, regardless of the number of users (for example, on a shared workstation).

External Connector Licenses


An external connector (EC) license allows any number of external users to access a single installation of Dynamics CRM 4.0 Professional or Enterprise. External users may not use the Dynamics CRM applications directly.

Generally, an external user is defined as anyone who is not an employee of the organization. For example, external users can include clients, suppliers, and alumni of the organization. External users do not include independent contractors, agents, service providers, or other persons providing services to or on behalf of the organization holding the license. As an alternative to an EC license, some organizations may choose to license each external user with a separate CAL or CALs.

EC licenses may not be used as a means of reselling or repackaging Dynamics CRM as a hosted service.

Limited External Connector: The limited EC license allows external users read-only access to the CRM server. In other words, external users may access CRM information but may not make any edits or updates to it.

Full Use Additive External Connector: When used in conjunction with a limited EC license, a full use additive EC license allows external users write access to the CRM server, thus allowing full read-write access to the server. The full use additive EC license may be used only in conjunction with a limited EC license.

External Connector: The EC license provides external users full read-write access to the CRM server. The EC license is functionally equivalent to a combined limited and full use additive EC license.

Wednesday, October 27, 2010

Disabling Notes for deactivated records MS CRM

In the OnLoad event:




Code Snippet
/* [s] Disables the creation of new Notes, and editing of existing notes. Attachments can still be opened. */
//If the 'Close' button is showing, means that form Status = Resolved or Cancelled
var btnClose = document.getElementById("_MBwindowclose");
if (btnClose != null)
{
//Need to attachEvent, because IFRAME elements load asynchronously, and elements like 'newNoteButton' are not accessible on form load
var iframe = document.getElementById("notescontrol");
iframe.attachEvent('onreadystatechange', DisableNotes);
}
/* [e] */





The function DisableNotes:




Code Snippet
function DisableNotes()
{
//Hide 'Create a New Note' link
window.frames[0].document.getElementById('newNoteButton').style.visibility="Hidden";
var NotesTable = window.frames[0].document.getElementById('NotesTable');
//Disable the entire table
NotesTable.disabled = true;
var TextArea = NotesTable.getElementsByTagName('TEXTAREA');
//It's still necessary to individually disable the Textareas where users edit the existing notes.
for (i=0;i<TextArea.length;i++)
{
TextArea[i].disabled = true;
}

return;
}

Wednesday, October 20, 2010

Displaying the Number of Notes on the Notes Tab

The Microsoft CRM default form layout displays the Notes section on a separate tab. I often hear complaints from users that they don't know if any notes have been added without first clicking that tab. Many people don't realize that just as with any other section, you can move the Notes section to another tab, just as you would any other section. So one approach that many of our users have liked is to place the Notes section on the first tab as shown below.



This works, but I personally find it annoying as the the cursor will 'jump' down to the Notes section, sometimes scrolling past the info on top set of information, and you have less room to see multiple notes. Since I tend to keep the Notes section on its own separate tab, I wanted to find a way to let users know that data exists on that tab prior to clicking it. I created the following script to display the number of notes on the tab label as shown in the screen shot below.



The script I used is shown below and should be added to the entity's form onLoad function. Since this approach is entirely script based, it should also work on CRM Online. The tab where the Notes section exists must be called Notes for the script to work.
var totalNotes = getTotalNotes(crmForm.ObjectId);
setNoteTabName(totalNotes);
function setNoteTabName(count) {
/* update note tab */
if (crmForm.FormType != 1) {
var cells = document.getElementsByTagName("A");
for (var i = 0; i < cells.length; i++) {
if (cells[i].innerText == "Notes") {
if (count > 0) {
cells[i].innerText = "Notes (" + count + ")";
document.all.crmTabBar.style.width = "auto";
}
break;
}
}
}
}
// Helper method to return the total notes associated with an object
function getTotalNotes(objectId) {
// Define 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\">",
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>annotation</q1:EntityName>",
"<q1:ColumnSet xsi:type=\"q1:ColumnSet\"><q1:Attributes><q1:Attribute>createdon</q1:Attribute></q1:Attributes></q1:ColumnSet>",
"<q1:Distinct>false</q1:Distinct><q1:Criteria><q1:FilterOperator>And</q1:FilterOperator>",
"<q1:Conditions><q1:Condition><q1:AttributeName>objectid</q1:AttributeName><q1:Operator>Equal</q1:Operator>",
"<q1:Values><q1:Value xsi:type=\"xsd:string\">",
objectId,
"</q1:Value></q1:Values></q1:Condition></q1:Conditions></q1:Criteria>",
"</query>",
"</RetrieveMultiple>",
"</soap:Body>",
"</soap:Envelope>"
].join("");
var resultXml = executeSoapRequest("RetrieveMultiple", xml);
return getMultipleNodeCount(resultXml, "q1:createdon");
}
// Helper method to execute a SOAP request
function executeSoapRequest(action, xml) {
var actionUrl = "http://schemas.microsoft.com/crm/2007/WebServices/";
actionUrl += action;
var xmlHttpRequest = new ActiveXObject("Msxml2.XMLHTTP");
xmlHttpRequest.Open("POST", "/mscrmservices/2007/CrmService.asmx", false);
xmlHttpRequest.setRequestHeader("SOAPAction", actionUrl);
xmlHttpRequest.setRequestHeader("Content-Type", "text/xml; charset=utf-8");
xmlHttpRequest.setRequestHeader("Content-Length", xml.length);
xmlHttpRequest.send(xml);
var resultXml = xmlHttpRequest.responseXML;
return resultXml;
}
// Helper method to return total # of nodes from XML
function getMultipleNodeCount(tree, el) {
var e = null;
e = tree.getElementsByTagName(el);
return e.length;
}
Naturally, all of the caveats apply...this code is presented as is and may not upgrade with future releases of Microsoft CRM.

Thursday, October 14, 2010

How to get users and primary email address from server database

just execute the below query

DECLARE @DB_Name varchar(100)
DECLARE @Command nvarchar(200)
DECLARE database_cursor CURSOR FOR
SELECT name
FROM master.sys.sysdatabases

OPEN database_cursor

FETCH NEXT FROM database_cursor INTO @DB_Name

WHILE @@FETCH_STATUS = 0
BEGIN
SELECT @Command = 'SELECT SF.fullname, SF.internalemailaddress FROM '+@DB_NAME+'.dbo.systemuserbase SF'
IF @DB_NAME like '%_MSCRM'
EXEC sp_executesql @Command

FETCH NEXT FROM database_cursor INTO @DB_Name
END

CLOSE database_cursor
DEALLOCATE database_cursor


Sudhanshu

Wednesday, October 13, 2010

only showing one typename for lookup

if the lookup is matching to more than one entities and if you want to match to only one entity from a particular lookup just use the following code on onload of the form.

crmForm.all..setAttribute(”lookuptypes”, “2″);


Sudhanshu

Tuesday, October 12, 2010

Change typename in lookup ms crm

i have one challenge as follows, if you can....

on look up, onclick of it a popup window will come, there you can select a record.

there also a picklist will be there(sometimes) where you can also change. the best example is the regarding attribute on letter.

suppose on that picklist i have 3 options as a,b,c.

bydefault a is selected and on basis of some condition i want b to be selected.
its doable and as follows.

just put the following code on load of the form.

crmForm.all..defaulttype = "2";//the number of the picklist value, starts from 1


Sudhanshu

Friday, October 8, 2010

Check which Update Rollup version is installed on your CRM environments



Browse to the CRM website.
Click on the “Help” button on the top right side of the window.
Click on “About Microsoft Dynamics CRM”
Get the build number displayed as follows else the image in side.

Version Build Number Released on
RTM 4.0.7333.3 12/19/2007
Update Rollup 1 4.0.7333.1113 11/24/2008
Update Rollup 2 4.0.7333.1312, 4.0.7333.1316 1/15/2009, 2/8/2009
Update Rollup 3 4.0.7333.1408 3/12/2009
Update Rollup 4 4.0.7333.1551 5/7/2009
Update Rollup 5 4.0.7333.1644, 4.0.7333.1645 7/2/2009
Update Rollup 6 4.0.7333.1750 9/27/2009
Update Rollup 7 4.0.7333.2138 10/22/2009
Update Rollup 8 4.0.7333.2542 12/17/2009
Update Rollup 9 4.0.7333.2644 2/11/2010
Update Rollup 10 4.0.7333.2741 4/8/2010
Update Rollup 11 4.0.7333.2861 6/25/2010
Update Rollup 12 4.0.7333.2935 8/2/2010
Roll up 13 also has been come, will udate that latter.
Sudhanshu

Remotely enable the RDP(mstsc) and restart the system(computer)



Some times while installing CRM or rollups the RDP suddenly stops working.
so enable the rdp and retstart the system remotely follow following steps.

Enable the RDP(mstsc)

From you own system or any other system(it should in the same network)
#1. run and type "regedit"
#2. Click on File, then choose "Connect Network Registry".
#3. In the Select Computer search box either browse Active Directory to locate the remote server, or type its name in the dialog box.
#4. In the remote machine's registry browse to the following key:
HKLM\SYSTEM\CurrentControlSet\Control\Terminal Server

#5. Under the Terminal Server key find the value named fDenyTSConnections (REG_DWORD). Change the value data from 1 (Remote Desktop disabled) to 0 (Remote Desktop enabled). Even if its 0 just change it to 1 and make again to 0.
#6. Reboot the remote machine for the change to take effect. You can easily do so by opening a command prompt and typing the following command:

Restart the system remotely
#1. Start -> Run and type shutdown -i
This window will show up. Press Add and type either IP or DNS of remote server.

Select shutdown or restart and press OK. That 's it. For your convenience you may run from command line constanct ping (ping servername -t) when the server actually stopped to respond to pings and when it started again.

#2. Alternatively you can go to command prompt (start -> run -> cmd) on your workstation and Type
shutdown -r -m \\x.x.x.x
Replace x.x.x.x with the IP address or computer name of the remote machine. -r option is for restart, don't use -r if want to just shut down the system

so be carefull about the input parameter -r

Have fun
Sudhanshu

Thursday, October 7, 2010

Disable the Links in a Lookup Field MS CRM 4.0

Sometimes simply making a Lookup field “read only” isn’t enough. Sometimes, you may want to restrict the ability to even follow the links held inside the field. so this is here how to handel that from the user.

//this a general function which takes the name of the lookup

function DisableLookupLinks(lookupFieldName) {
var lookupParentNode = document.getElementById(lookupFieldName + "_d");
var lookupSpanNodes = lookupParentNode.getElementsByTagName("SPAN");

for (var spanIndex = 0; spanIndex < lookupSpanNodes.length; spanIndex ++) {
var currentSpan = lookupSpanNodes[spanIndex];

currentSpan.onclick = function() {};
}
}

now To disable a field's Lookup links, pass the field's schema name into the function.
DisableLookupLinks("<lookupfield_name>");

Sudhanshu

Extreme Fast AsyncOperations MS CRM 4.0

This white paper from MS might be more applicable to you.

http://www.microsoft.com/downloads/en/details.aspx?FamilyID=e76d8916-81a6-4330-90ae-b24f8263fff8&DisplayLang=en

CRM Configuration Changes

These configurations were done so that the workflow service would pick up the workflows as fast as it can and would not create a backlog of workflows and overload the workflows stack. Changes were made in the MSCRM_CONFIG database, on the dbo.DeploymentProperties table.


Parameters that were changed:



•AsyncSelectInterval
•Default value: 5
•New value: 1

•AsyncStateStatusUpdateInterval
•Default value: 5
•New value: 1

•AsyncItemsInMemoryLow
•Default value: 1000
•New value: 10

•AsyncItemsInMemoryHigh
•Default value: 2000
•New value: 20

Sudhanshu

Wednesday, October 6, 2010

set the time in the time picker in MS CRM Date time field

Hi all,

some times we need the exact time , while some body is picking the date from the date picker. and the attribute is of date and time and showing full date and time also.
So once the user selects the date the time goes to 12:00 AM.
if (s)he wats to get the current time then just follow the followings

#1 get the selected date values by user

var selectedDate = crmForm.all.<datefieldname>.DataValue;
var date = selectedDate.getDate();
var month = selectedDate.getMonth();
var year = selectedDate.getYear();

#2 create the client date and fetch the time values

var clientDate = new Date();
var hr = clientDate .getHours();
var mnt = clientDate .getMinutes();
var sec = clientDate .getSeconds();

//change the value to hr and min
if(mnt >= 0 && mnt <=30){
hr = hr; // no change
mnt = 30; //make the mnt to 30
}
if(mnt > 30 && mnt <=59){
hr = hr+1; // add 1 to hr to round up
mnt = 0; // reset the mnt
}


#3 now create a new date with the year,month,date from the selected date and the hour,minutes,seconds from the client time

var finalDate = new Date(year,month,date,hr,mnt,sec);
//alert(finalDate);

#4 finally assing the time to the destination


crmForm.all.<datefieldname>.DataValue = finalDate;

Sudhanshu

Tuesday, October 5, 2010

Enable CRM 4.0 URL QueryString Parameter Passing…

Sometimes we need to pass some parameters and values the URL as querystring.
and it will not work due to some reason.
to make it happen follow the following steps.

open the regedit
Create a DWORD registry key named [DisableParameterFilter] under [HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\MSCRM], set the value to 1 , and the do a iisreset, this enable the url querystring parameter passing under CRM 4.

Sudhanshu

Wednesday, September 29, 2010

Are you sure you want to navigate away from this page?

Some times we used to put some default values in the form level as per the requirements.
Even if the user is doing to create a new record and with out changing anything doing X-off or close, it will give an alert saying "Are you sure you want to navigate away from this page? ...".
So it should not come, as the user did not do anything.
To avoid this there are ways and it depends on the type of attribute it is.

#1 for non-lookup types

window.setTimeout("crmForm.all.<non-lookup_Name>.defaultValue = crmForm.all.<non-lookup_Name>.DataValue",200);

#2 for lookup types

crmForm.<lookup_name>.DataValue = crmForm.<lookup_name>.defaultValue;

if(crmForm.FormType == 1) {
var lookupItem = new Object();
var lookup = new Array();
lookupItem.name = '<lookup_name>';//which will be displayed in lookup
lookupItem.id = <lookUpGUID> // This is the Guid of the record
languageitem.typename = 'new_lookupname';//schema name of the lookup attribute
lookup[0] = lookupItem;

crmForm.<lookup_name>.DataValue = lookup;
crmForm.<lookup_name>.defaultValue = crmForm.<lookup_name>.DataValue;
}

Sudhanshu

Monday, September 27, 2010

How to move the Microsoft Dynamics CRM 4.0 deployment

follow the link on microsoft

How to move the Microsoft Dynamics CRM 4.0

Sudhanshu

get data from grid Ms crm

Here are a few useful examples of getting some data from the grid in CRM. I’ve used these in my ISV.config customizations in order to grab certain data that i want to pass to my custom pages. For the most part, a lot of this stuff gets passed automatically when you specify PassParams = 1, but I often have to construct page links dynamically in ISV.config using Javascript, so the PassParams argument does not work.

First, here’s how to get the Id of the displayed view and the Object Type Code of the records it returns:

// get guid and object type code of view being displayed (otc 1039 = savedquery, system view)
var sViewId = document.all['crmGrid'].GetParameter('viewid');
var sViewType = document.all['crmGrid'].GetParameter('viewtype');

You may notice that the code is slightly different from what I’ve presented before. The method above is a more robust way of getting the data, as it also works with the Associated Grids on an entity’s form.
To get the Object Type Code of the records that are in the grid, use the following:

var sOtc = document.all['crmGrid'].GetParameter('otc');

The following snippet will allow you to retrieve an array containing the Id values of the selected records in the grid:

// get array of selected records
var a = document.all['crmGrid'].InnerGrid.SelectedRecords;
var selectedItems = new Array(a.length);
for (var i=0; i < a.length; i++)
{
selectedItems = a[0];
}
alert(selectedItems);

To get all of the records in the grid (ie. “All Records on Current Page”):

// array of all records on current page
var iTotal = document.all['crmGrid'].InnerGrid.NumberOfRecords;
var o = document.all['crmGrid'].InnerGrid;
var allItems = new Array;
for (var i=0; i < iTotal; i++)
{
allItems[i] = o.rows.oid;

}
alert(allItems);

If the grid you are working with is displaying records from an Associated View, you can use the following to retrieve the Id and Object Type Code of the main record:

// get object id and type code of main record when grid is an associated view
var oId = document.all['crmGrid'].GetParameter('oId');
var oType = document.all['crmGrid'].GetParameter('oType');

For kicks and giggles, here is some code that will retrieve the Grid XML. you can use this for researching other types of properties that are available from the grid object that I have not presented here (and there are a few):

var gridXml = document.all['crmGrid'].gridXml;

Bonus Snippet!I’ve seen a bunch of questions on how to retrieve the query used in an Advanced Find that has not yet been saved. Well, here ya go:

// Advanced Find fetchXml
alert(window.top.resultRender.FetchXml.value);

This piece of code will display the Fetch XML that is used by the Advanced Find to query CRM.

To make scripts a little bit more readable, it is also possible to use crmGrid object directly instead of document.all['crmGrid']. e.g.:
crmGrid.InnerGrid.SelectedRecords
crmGrid.GetParameter("otc")
crmGrid.Refresh()

Sudhanshu

Filtered Lookup in MS CRM 4.0

MS CRM 4.0 does not provide filtered lookup facility, but we have some couple of options that we can use to implement filtered lookup in ms crm 4.0 like

1.Change lookupsingle.aspx page
http://crm.georged.id.au/post/2008/02/16/Filtering-lookup-data-in-CRM-4.aspx

2. Buy stunware filtered lookup tool

http://www.stunnware.com/default.aspx?area=products&group=fld4&subarea=fld4-download

3. Using JS Code

http://advantageworks.blogspot.com/2008/02/pseudo-filtered-lookup-dialog-in.html

4. Writing plugin.

http://mscrmfilteredlookup.codeplex.com/

Have fun
Sudhanshu

Stopping and continuing a save event with different types of save

For some customizations you do need to stop the form onsave event, perform some business logic and continue the save event. An example would be that in specific conditions are met when a record is saved, then a popup will need to be shown. After filling in data in the popup and pressing a continue button on the popup, then the save operation would need to continue. The SDK helps in this situation. Look at the following page for more information.

On that page you will see that you can stop the onsave event by setting the 'event.returnValue = false'. Don't forget to follow that line with a 'return false'. This will cause the save procedure to stop right at that point. Otherwise statements after that will still be executed.

To call the save event from your javascript code, you can use the javascript functions crmForm.Save(); and crmForm.SaveAndClose(). By looking at the 'event.Mode' you can determine which event was executed before. If the code is 1, then it is a crmForm.Save(); or it is 2 for a crmForm.SaveAndClose(). There's only one small issue. There can be other save events as well. There's the 'save and new', 'save as completed', and also the 'send' for emails. Below is a list of save events with the corresponding javascript functions to call. Once again, this is not documented in the SDK, so this might change with a hotfix or new version.


Save
Code: 1
Function: crmForm.Save();


SaveAndClose
Code: 2
Function: crmForm.SaveAndClose();


Send
Code: 7
Function: send();


SaveAsCompleted
Code: 58
Function: SaveAsCompleted();


SaveAndNew
Code: 59
Function: crmForm.SubmitCrmForm(59, true, true, false);

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

get the full name of the user by using javascript in MS CRM

use the following bunch of code to get it


//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);
}
}


have happy coding

Sudhanshu

Friday, September 24, 2010

MS CRM 4.0 Attachment Size Limitation

MS CRM stores attachments directly in the database, and there is a 5Mb attachment limit by default with CRM 4.0. This limit is set for good reason, and if you want to increase it, you may want to see if it starts to impact your system performance.

This can be overwritten by doing the following:

Changing the maxRequestLength value in the main CRM web.config file. By default it is 8Mb which doesn't impact the System Setting below. However if you increase the Maximum File size above the maxRequestLength you will have problems.





There are many examples on the web that show something like the following which pretty well removes any size constraints from the web.config.




Save the web.config and restart IIS.

For MS CRM 4.0 that just leaves adjusting the Maximum file size in System Settings with default of 5,120 Kb shown below to something higher but less than the maxRequestLength.

Go to Settings -> administrator -> system settings -> email tab -> Exterem down you will get it.









Sudhanshu

Invoking MSCRM service from any client like Java Client(Sun Microsystem)

Below is the Soap request we execute from SOAP UI tool we have to just pass UId , pwd, domain from left side screen which comes in SOAP UI tool and we will get the response . WE don't need WSE Security required for interpolation among webservices.



<soap:Envelope xmlns:soap="http://www.w3.org/2003/05/soap-envelope" xmlns:web="http://schemas.microsoft.com/crm/2007/WebServices" xmlns:cor="http://schemas.microsoft.com/crm/2007/CoreTypes" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
        <soap:Header>
     <web:CrmAuthenticationToken>
         <cor:AuthenticationType>0</cor:AuthenticationType>
         <!--Optional:-->
       <cor:OrganizationName>Ath</cor:OrganizationName>
       <cor:CallerId>00000000-0000-0000-0000-000000000000</cor:CallerId>
    </web:CrmAuthenticationToken>
 </soap:Header>
   <soap:Body>
      <web:RetrieveMultiple>
         <!--Optional:-->
        <web:query xmlns:q1="http://schemas.microsoft.com/crm/2006/Query" xsi:type="q1:QueryExpression">
                 <q1:EntityName>contact</q1:EntityName>
                 <q1:ColumnSet xsi:type="q1:ColumnSet">
                                <q1:Attributes>
                                <q1:Attribute>fullname</q1:Attribute>
                                                <q1:Attribute>createdon</q1:Attribute>
                                </q1:Attributes>
                 </q1:ColumnSet>
                 <q1:Distinct>false</q1:Distinct>
                 <q1:Criteria>
                                <q1:FilterOperator>And</q1:FilterOperator>
                                <q1:Conditions>
                                                <q1:Condition>
                                                                <q1:AttributeName>createdon</q1:AttributeName>
                                                                <q1:Operator>ThisWeek</q1:Operator>
                                                </q1:Condition>
                                </q1:Conditions>
                <q1:Conditions>
                                                <q1:Condition>
                                                                <q1:AttributeName>fullname</q1:AttributeName>
                                                                <q1:Operator>Equal</q1:Operator>
                                <q1:Values>
                                                                                <q1:Value xsi:type="xsd:string">Jesper Aaberg</q1:Value>
                                                                </q1:Values>
                                                </q1:Condition>
                                </q1:Conditions>
                </q1:Criteria>
                <q1:Orders>
                                <q1:Order>
                                                <q1:AttributeName>fullname</q1:AttributeName>
                                                <q1:OrderType>Descending</q1:OrderType>
                                </q1:Order>
                </q1:Orders>
</web:query>
      </web:RetrieveMultiple>
   </soap:Body>
</soap:Envelope>

Retrieve Plug-in/Custom Workflow Activity DLL from Database

Some times we used get some scenarios to register the dll into DB and after wards we will loose the dll and source code.

the following may help to get the dll atleast and some extend the source code also.

1.Retrieve the Plug-in encoded string from the Organization MSCRM database. The plug-ins are stored in the Plugin PluginAssemblyBase table.


SELECT Content FROM PluginAssemblyBase
WHERE PluginAssemblyId = '[Plugin Guid]'

2.Copy and paste the Content string into a text file.

3.Write a simple C# command line application to convert the plug-in string to DLL.


string inputFileName = "Plugin.txt";
string outputFileName = "Plugin.dll";

FileStream fileStream = File.Open(fileName, FileMode.Open);
byte[] buffer = new byte[fileStream.Length];
fileStream.Read(buffer, 0, buffer.Length);
fileStream.Close();
ASCIIEncoding encoding = new ASCIIEncoding( );
this.buffer = encoding.GetString(buffer);

FileStream fileStream = new FileStream(outputFileName, FileMode.Create);
byte[] buffer = Convert.FromBase64String(this.buffer);
fileStream.Write(buffer, 0, buffer.Length);
fileStream.Close();

4.After you retrieved the DLL from the database, then you may use .Net Reflector to extract the code from this plug-in.

That’s it! Just in case you run into the same situation that you have to retrieve your plug-in or custom workflow activity from MSCRM database, you can follow the steps above. I hope this helps!


Sudhanshu

Thursday, September 23, 2010

Customizing Online Help

its availabe in the sdk also online click here
online custom help

Sudhanshu

CRM4 Set Auto-Numbering for case, quote , order etc

The funda for the auto numbering as follows

# In the Prefix box, enter up to 3 characters, symbols or numbers.
Prefixes are system-wide and are used for all system-generated numbers for the selected record type. If you change the prefix for a record type, it will not change the prefix of numbers that have already been assigned.

# In the Number box, enter the starting number.
If you have not set a numbering format before, the Number box displays 1000. After you set the numbering format and save your settings, this field is set to read-only and you cannot modify it.

# If you are setting auto-numbering formats on any tab except Articles, in the Suffix Length list, select a number

the max value will be 99999 as per the length specified,
but once it will reach 99999 and we will create the next record the value will become the next one 1000000 and it will keep going.


Sudhanshu

Unable to load DLL 'CRMCore.dll' when installing Update Rollup 7

just do as follows
CRMWatson.dll didn't help, but copy CRMCore.dll from C:\Program Files\Microsoft CRM\Server\bin to C:\WINDOWS. Update Rollup 7 installed properly then. CRMCore.dll in C:\WINDOWS was still the UR6 version. Delete this and then install UR12 perfectly fine with the version in the bin directory...

I guess there was an environment variable that did not get set properly, either during the initial upgrade from CRM 3.0 or a subsequent update rollup. It seems rollup 7 fixed the path.

Wednesday, September 22, 2010

Customizing CRM 4.0 print preview form

Here is the most flexible way to customize the Dynamics CRM 4.0 print
preview of any entity:

http://adrian-alexan.blogspot.com/2009/12/customizing-entities-print-preview-form.html

Cannot add a new user to CRM 4.0

if adding user in crm is not possible means giving error, follow the followings

#1 you should have the privileg to ccreate user.
#2 check whether the user has been created and disabled
#3 finally On the CRM Server check the following in the Registry: HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\MSCRM you should set a registry key AutoGroupManagementOff to value 1 (false).

Sudhanshu

Tuesday, September 21, 2010

All system jobs are waiting also workflows

Some times we will face scenarios like this, if we will go to settings -> system jobs and the status.

It happens if the asynch is not perfect.
1st check whether the asynch service is running or not.
If that is running, then check 3 things in DB.

go to the MSCRM_Config DB and the table it "DeploymentProperties".
make sure the following three values are perfect of the "NVarCharColumn" column.
ADRootDomainScheme :http
ADSdkRootDomain :<platformserver>:<port no>
ADWebApplicationRootDomain :<applicationserver>:<port no>
and if the "NVarCharColumn" value of columnaname "AsyncSdkRootDomain" in blank (mostly it happens), make it to :<applicationserver>:<port no>.

Then start the asynch service and test your work.

Sudhanshu

While connecting to a specific tenant if Plugin registration tool will give exception

While connecting to a specific tenant if Plugin registration tool will give exception
and at the same time try to access the web services from platform box, if those wo;t work then follow the below

#1 check the three groups(PrivReportingGroup{....},ReportingGroup {...},SQLAccessGroup{...}) with id in {...} from the security -> login of database
#2 make all the three groups to be available in MSCRM_config as well as the tenant_MSCRM tables by giving the following "Roles"
PrivReportingGroup{....} : CRMReaderRole
ReportingGroup {...} : none
SQLAccessGroup{...} : db_owner

#3 if possible restart the app pool in each application and platform servers

this happens sometimes if we are just importing the tenants, so it will have unnecessary groups from the earlier server.
All these things need to be deleted.


Sudhanshu

Cannot generate SSPI context

While accessing tenants , is the exception will come like "Cannot generate SSPI context" followed by the stacktrace

Just make sure the asynch service is running, if its running just rerun it.
next is make sure the sql service and agent are also running.

Sudhanshu

Monday, September 20, 2010

MS CRM5(CRM2011) released for testing

Hi All,

Good news , MS CRM 5 or MS CRM 2011 beta has been released for online.
You can get it from http://crm2011beta.com
Register and enjoy.

Sudhanshu

Happy Birthday via Workflow using Custom Workflow Activity

The following steps need to be completed:

1. Create and Register the custom workflow activity

2. Create a Workflow that uses the activity to update the custom attribute

Step #1: Creating the Activity
Note: Windows Workflow Foundations (WinWF) must be installed on your machine (it is included with .NET Framework 3.5 and is available as an extension to.NET Framework 3.0). I am using Visual Studio 2005 to build the activity.

Create the Visual Studio project with the following references (CRM assemblies can be found in the GAC of the Platform Server role machine):

•Microsoft.Crm.Sdk
•Microsoft.Crm.SdkTypeProxy
•System
•System.Workflow.Activities
•System.Workflow.ComponentModel
•System.Workflow.Runtime
Copy and paste the code that follows into a new C# class.

using System;

using System.Workflow.ComponentModel;

using System.Workflow.ComponentModel.Design;

using System.Workflow.ComponentModel.Compiler;

using System.Workflow.Activities;

using Microsoft.Crm.Workflow;

using Microsoft.Crm.Sdk;

using Microsoft.Crm.SdkTypeProxy;

using Microsoft.Crm.Sdk.Query;

namespace ExampleActivities

{

[PersistOnClose]

[CrmWorkflowActivity("Calculate Next Occurrence", "Examples")]

public partial class CalculateNextOccurrence : SequenceActivity

{

protected override ActivityExecutionStatus Execute(ActivityExecutionContext executionContext)

{

DateTime today = DateTime.Today;

DateTime initialDate = this.InitialDate.UserTime;

DateTime upcomingDate = DetermineDateForYear(initialDate, today.Year);

if (upcomingDate.Date <= today)

{

upcomingDate = DetermineDateForYear(initialDate, today.Year + 1);

}

this.UpcomingDate = CrmDateTime.FromUser(upcomingDate);

return ActivityExecutionStatus.Closed;

}

private DateTime DetermineDateForYear(DateTime date, int year)

{

if (date.Month == 2 && date.Day == 29 && !DateTime.IsLeapYear(year))

{

return new DateTime(year, 3, 1);

}

else

{

return new DateTime(year, date.Month, date.Day);

}

}

//Define the dependency properties. CRM requires dependency properties used.

public static DependencyProperty InitialDateProperty = DependencyProperty.Register("InitialDate", typeof(CrmDateTime), typeof(CalculateNextOccurrence));

public static DependencyProperty UpcomingDateProperty = DependencyProperty.Register("UpcomingDate", typeof(CrmDateTime), typeof(CalculateNextOccurrence));

[CrmInput("Initial Date")] //Input Label

[ValidationOption(ValidationOption.Required)]

public CrmDateTime InitialDate

{

get

{

return (CrmDateTime)base.GetValue(InitialDateProperty);

}

set

{

base.SetValue(InitialDateProperty, value);

}

}

[CrmOutput("Upcoming Date")] //Output Label

public CrmDateTime UpcomingDate

{

get

{

return (CrmDateTime)base.GetValue(UpcomingDateProperty);

}

set

{

base.SetValue(UpcomingDateProperty, value);

}

}

}

}
Explanation of the Code
The activity has one input parameter, Initial Date, which is set to the Birthday. The activity’s output parameter, Upcoming Date, can be used to update the Upcoming Birthday field.

The actual date calculation has been placed in a helper method, DetermineDateForYear. If we tried to set the Upcoming Birthday to be February 29th in a year that was not a leap year, an exception will be thrown. To avoid that issue, if February 29th is encountered in a non-leap year, March 1st is used instead.

The Activity’s Execute method utilizes this helper method to determine the date for a given year.

NOTE: CRM 4.0 stores all dates and times in Universal Time (UTC) within CRM 4.0. The date / time is converted to the current user’s time zone when it is retrieved and converted to UTC when it is updated. Any calculations that require a date / time to be at the same moment globally (e.g. an event occurring at 6:00 PM in Los Angeles would occur at 2:00 AM in London) should perform calculations using Universal Time.

Date Only fields (such as Birthday) are stored in the database as DateTime fields, which means that they are subject to Time Zone conversions. Initially, the activity used Universal Time, but this resulted in an incorrect date in certain time zones. To get around this issue, the activity calculates the upcoming birthday using User Time.

Step #2: Register the Assembly
Register the assembly as a Workflow Activity in the CRM deployment. If you want to debug the assembly, place the Symbols file (.pdb file) in the Server\bin\assembly folder of your CRM installation folder.

Option #2 – Step #3: Create the Workflow
This workflow will manage all updates to the Upcoming Birthday field.

1. Create a Workflow for Contact with these triggers:
- On demand
- Record is created
- Record attributes change – should trigger on updates to the Birthday attribute

2. Set the scope of the workflow as appropriate

3. The Workflow should have the following structure:

•Check if Contact.Birthday has a value, then
- Calculate Upcoming Birthday using the Custom activity with Initial Date set to the Birthday attribute

- Update Contact.Upcoming Birthday to be the output parameter

•Otherwise Clear Contact.Upcoming Birthday’s value
How do I do that?

Follow these steps:

1. Create a new Workflow for the Contact entity (click Settings, Workflows, and create a new Workflow). The following Workflow triggers (events or actions that will start the Workflow) should be selected:

•a. On demand – will appear on the Contact form and grid. This button allows the Workflow to be applied manually. If there are existing contacts that have not yet had their Upcoming Birthday set, you can apply the Workflow using this button.
•b. Record is created – Workflow should run when the Contact is initially created.
•c. Record attributes change – Runs when the Birthday attribute is changed.
To set the attribute, click Select and check the Birthday checkbox in the list of attributes.
2. Set the Scope of the Workflow to the appropriate level (does not affect the On Demand trigger). The scope should match the other Workflow (discussed in the original blog post).

a. User: Workflow will only trigger on records with same as owner as the Workflow.

b. Business Unit: Workflow will trigger on records owned by any user in the same Business Unit as the owner of the Workflow.

c. Parent: Child Business Units: Workflow will trigger on records owned by any user in the same Business Unit (and any child Business Units) as the owner of the Workflow.

d. Organization: Workflow will trigger on records owned by any user.

3. Add a Check Condition and configure it.

a. Select Contact from the entity list (first drop-down list).

b. Select Birthday from the attribute list (second drop-down list).

c. Select Contains Data from the operator list (third drop-down list).

4. Add the custom activity to the Check Condition branch.

a. Click Select this row and click Add step

b. Select Examples from the Add Steps menu and click Calculate Next Occurrence.

5. Configure the custom activity with Contact.Birthday as a Dynamic Expression.

a. Click Set Properties to configure the step

b. Select the Initial Date field

c. In the Form Assistant, select Birthday from the attribute list (second drop-down list under Look for).

d. Click the Add button to add it to the list of attributes that will be used in the Dynamic Expression.

e. Click OK to add the Dynamic Expression

f. Save the configuration

6. Add an Update Record step to the Workflow (should follow the Custom Activity step) and configure it.

a. Select the Additional Fields tab
This tab contains attributes that are not shown on the regular form (such as Upcoming Birthday).

b. In the Form Assistant, select Calculate Next Occurrence from the entity list (first drop-down list under Look for).

c. Select Upcoming Date from the attribute list (second drop-down list under Look for).

d. Click Add to add to the list of attributes

e. Click OK to add the Dynamic Expression

f. Save the configuration

7. Add an Otherwise step.
Sometimes adding this step can be a bit tricky. In order to select the item from the menu, you need to click in the row that contains the condition (If Contact:Birthday contains data, then).

8. Add an Update Record step to the Otherwise branch and configure it

a. In the Additional Fields tab, select the Upcoming Birthday field

b. In the Form Assistant, select Clear from the Operator drop-down list.

c. Save the configuration

Your Workflow should look similar to this:



9. Publish the Workflow. Don’t forget to run this Workflow on any contacts that already exist.

Happy Birthday via Workflow using Client-Side Scripting

Step #1: Create the Attribute
Create a custom datetime attribute called Upcoming Birthday (schema name should be new_upcomingbirthday). The attribute should have Date Only format.

How do I do it?

1. Open the Entity form for the Contact entity (click Settings, Customization, Customize Entities, and select Contact from the grid).

2. Create a new attribute (from the Attributes grid).

3. Set these properties and Save and Close the form:

Display Name: Upcoming Birthday
Name: new_upcomingbirthday
Type: datetime
Format: Date Only
4. Publish the customizations to the Contact entity (under Actions menu, select Publish)

Step #2: Updating the Attribute
Two approaches can be used:

1. Client-Side Scripting – Update the attribute based on changes to the birthday field.

Pros: Quick, simple, very little coding required, no .NET assembly needs to be registered.
Cons: Attribute needs to be visible on the form, relies on JavaScript

2. Custom Workflow Activity – Update the attribute using a .NET assembly

Pros: Attribute is not visible on the form, no possibility of JavaScript issues
Cons: Requires .NET assembly be registered (requires Deployment Manager privileges)
I will be discussing the first option in this blog post. The second option will be discussed in a future blog posting.

Option #1: Client-Side Scripting
1. Add the new Upcoming Birthday field to the form

2. Add the code (shown below) to the onChange event for the Birthday field (be sure to enable the event)

3. Add Upcoming Birthday for the dependencies for the event

Code

var birthdate = crmForm.all.birthdate.DataValue;

if (birthdate == null)

{

crmForm.all.new_upcomingbirthday.DataValue = null;

return;

}

var today = new Date();

today.setHours(0);

today.setMinutes(0);

today.setSeconds(0);

birthdate.setFullYear(today.getFullYear());

crmForm.all.new_upcomingbirthday.DataValue = birthdate;


How do I do that?

1. Open the Entity form for the Contact entity (click Settings, Customization, Customize Entities, and select Contact from the grid).

2. Open the Form (click Forms and Views and select Form from the grid) and select the Details tab

3. Add Upcoming Birthday to the Personal Information section

4. Change the Properties of the Birthday field (select the field and click Change Properties)

5. Select the onChange event, on the Events tab, and click Edit.

6. Check the Event is enabled checkbox and copy and paste the code (shown above) into the text box.

7. Select the Dependencies tab and add Upcoming Birthday to the list of Dependent fields
Dependencies ensure that fields required by events are not removed from the form – in this case, Upcoming Birthday.

8. Save the changes

9. Publish the customizations to the Contact entity (under Actions menu, select Publish).

Step #3: Send E-mail Workflow
This workflow will send the e-mail on the contact’s birthday.

1. Create a Workflow for Contact with these triggers:

- On demand
- As a child workflow
- Record is created

2. Set the scope of the Workflow as appropriate.

3. The Workflow should have the following structure:

· Wait until Contact.Upcoming Birthday is today

· Send the Contact an e-mail wishing them a happy birthday

· Increment the Contact.Upcoming Birthday by a year

· Call itself as a Child Workflow (creates a loop)

How do I do that?
Follow these steps:

1. Create a new Workflow for the Contact entity (click Settings, Workflows, and create a new Workflow). The following Workflow triggers (events or actions that will start the Workflow) should be selected:

a. On demand – will appear on the Contact form and grid. This button allows the Workflow to be applied manually. If there are existing contacts that have not yet had their Upcoming Birthday set, you can apply the Workflow using this button.

b. As a child workflow – Allows the Workflow to continue to call itself on annual basis using a Start Child Workflow step.

c. Record is created – Workflow should run when the Contact is initially created.

2. Set the Scope of the Workflow to the appropriate level (does not affect the On Demand trigger).

a. User: Workflow will only trigger on records with same as owner as the Workflow.

b. Business Unit: Workflow will trigger on records owned by any user in the same Business Unit as the owner of the Workflow.

c. Parent: Child Business Units: Workflow will trigger on records owned by any user in the same Business Unit (and any child Business Units) as the owner of the Workflow.

d. Organization: Workflow will trigger on records owned by any user.

3. Add a Wait Condition step and configure the step.

a. Select Workflow from the entity list (first drop-down list).

b. Select Timeout from the attribute list (second drop-down list).

c. Select Equals from the operator list (third drop-down list).

d. Select Upcoming Birthday from the Form Assistant

e. Save the configuration


Note: Derik Stenerson has written an article that gives more detailed instructions about the Wait Condition step, and some of its other uses, called “Turning Inaction into Action”.

4. Add a Send E-mail step and configure the step.

a. Select the To field and click the attribute drop-down list in the Form Assistant.

b. Select Contact from the attribute list, click Add, and then click OK.

c. Once you have configured the rest of the Send E-mail form as needed, save the changes.
Note: If the Contact does not have an e-mail address the Workflow will fail. As an extra precaution you may want to add a Check Condition that checks if the Contact’s e-mail address has been set.

5. Add an Update Record step and configure it.

a. In the Additional Fields tab, select the Upcoming Birthday attribute.

b. In the Form Assistant, select 12 from the Months drop-down list

c. Select After from the drop-down list under Months

d. Select Upcoming Birthday from the attribute list (second drop-down list under Look for)

e. Click Add and OK

f. Save the configuration

6. If you have not done so, click the button to save the changes to the triggers.

7. Add a Start Child Workflow step. Using the Lookup control, select the current Workflow (so that Workflow is calling itself). Since I called my Workflow “Recurring Reminders – Send E-mail”, I will select that item from the list.

8. Your Workflow should look something like this:




9. Publish the Workflow. Don’t forget to run this Workflow on existing contacts.

Now new and existing contacts will receive e-mails congratulating them on their birthday.

Sunday, September 19, 2010

Automatic Workflow for Birthday Reminders

Well, this is not beyond the scope of workflow functionality. You need to think a bit and plan your fuctionality. Since workflow normally waits for a future date so let me give you a simple solution for this.



- Create a custom field at contact named next birthday

- Create two workflows:



#1 Update Next Birthday (This workflow sets the next birthday first time and will not execute thereafter)

Fire this workflow on create of contact/account or on change of birthday field.

If Birthday contains data Then

Update Contact Next Birthday Field by adding 12 Months in Birthday field



2) Birthday Reminder (This workflow sends reminder emails and updates Next Birthday Field after each execution by adding 12 months)



If Next Birthday contains data Then

Wait untill 5 days Before Birthday

Send Email reminder to user - Receptionist

Update Next Birthday = After 12 months of Current birthday



Hope it will work out.



Cheers,