Thursday, October 29, 2009

Auto Numbers in in MS CRM 4.0

I was looking for the simple, supported and mostly acceptable way of auto numbering and got in some blog to use a custom entity in CRM called AutoNumber that tracks the max used autonumber by entity type.

Use a post create callout to populate corresponding entity type’s max value + 1 to the newly-created record, and also to write that new max value to the entry in the AutoNumber record for the entity type.

That way the process fires when offline clients sync their new records to the central database and you end up with no duplicate record contention, since that part of the post callout is (I believe) transaction bound to ensure we don’t get dupes.


There is another simple, supported and mostly acceptable way of auto numbering suggested by “Ayaz Ahmad”.


Read the autonumber attribute Max value and then add 1 to get next auto number. For example you have a custom entity named Project and you want to auto number Project_Ref_Number attribute. But do not retrieve all records. Just retrieve the record with maximum number value by using following two properties of PageInfo Class in SDK and set descending order.

PageInfo.Count = 1;
PageInfo.PageNumber = 1;

Code:-

ColumnSet cols = new ColumnSet();
cols.AddColumns(new string[] { "leadid", "new_autonumber" });

PagingInfo pages = new PagingInfo();
pages.PageNumber = 1;
pages.Count = 1;

QueryExpression query = new QueryExpression();
query.EntityName = EntityName.lead.ToString();
query.ColumnSet = cols;
query.AddOrder("new_autonumber", OrderType.Descending);
query.PageInfo = pages;

RetrieveMultipleRequest request = new RetrieveMultipleRequest();
request.ReturnDynamicEntities = true;
request.Query = query;

RetrieveMultipleResponse retrieved = (RetrieveMultipleResponse)service.Execute(request);

if (retrieved.BusinessEntityCollection.BusinessEntities.Count > 0)
{
DynamicEntity results = (DynamicEntity)retrieved.BusinessEntityCollection.BusinessEntities[0];
if (results.Properties.Contains("new_autonumber"))
{
nextNumber = Convert.ToInt32(results.Properties["new_autonumber"].ToString()) + 1;
//add nextNumber as the entity property for the coresponding entity
}
}

One more consideration should be taken in account to register your auto number plugin to at PreCreate rather at PostCreate.

Limitation:
In multi-user environment, this approach can come up with duplicate numbers in Project_Ref_Number when more than one user is creating project records.

Wednesday, October 28, 2009

Datetime format in SSRS report while running in CRM/Web App in MS CRM 4.0

When we run our report in CRM/ Web App automatically date format get change from MM/DD/YYYY to DD/MM/YYYY or vice versa in report parameters.
Actually this is the limitation of the reporting service. By default the “language property of the report” is US English. But when we run the report in Client browser the date time format get decided by the Language settings of client browser not by the language property of the report.

The format of date time parameter is always decided by the Language settings of client browser regardless of the Language property of our report (or in CRM).

Examples:-
If we have the Client browser language settings in English (AU), the date format in parameter bar will be as (regardless of the Language property of our report (or in CRM)):-
But when we run the same in the Client browser where language settings is in French (Canada) the date format in parameter bar will be as (regardless of the Language property of our report (or in CRM)):-

We can change the date time format in the report data using
1. CultureInfo (by adding the vb script in code section of the report) in Web App
2. CRM_CalendarTypeCode from the user settings in CRM.

Monday, October 19, 2009

OnLoad, Onsave and OnChange code sharing/reuse in MS CRM 4.0

There are three events in CRM form, OnLoad, OnSave, OnChange. OnLoad and OnSave are in the form level and OnChange is in field level. Sometimes it’s needed to write the same code/method in OnLoad, or Onsave or OnChange or all three events.

Actually these events trigger in a sequence, first OnLoad then OnChange (if any) and finally OnSave. So whatever methods we have written in the OnLoad of the form it will be available in OnChange and OnSave of the form.

If there are any method/methods in OnLoad event we can reuse those methods in OnChange event of any field and OnSave of the form just by calling the method (no need to redefine the method definition again).

And also sometimes it’s required to write the same code what we have in OnChange of any field in OnLoad/OnSave. We can achieve the same just by calling the OnChange code of the field using “<field_Schema>_onchange0();” method.

Tuesday, October 13, 2009

UserId of the Calling User in MS CRM 4.0

function GetCurrentUserInfo() {
var xmlhttp = new ActiveXObject("Msxml2.XMLHTTP");
xmlhttp.open("POST", "/mscrmservices/2007/crmservice.asmx", false);
xmlhttp.setRequestHeader("Content-Type", "text/xml; charset=utf-8");
xmlhttp.setRequestHeader("SOAPAction", "http://schemas.microsoft.com/crm/2007/WebServices/Execute");
var soapBody = "<soap:Body>" +
"<Execute xmlns='http://schemas.microsoft.com/crm/2007/WebServices'>" +
"<Request xsi:type='WhoAmIRequest' />" +
"</Execute></soap:Body>";
var soapXml = "<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'>";
soapXml += GenerateAuthenticationHeader();
soapXml += soapBody;
soapXml += "</soap:Envelope>";
xmlhttp.send(soapXml);
xmlDoc = new ActiveXObject("Microsoft.XMLDOM");
xmlDoc.async = false;
xmlDoc.loadXML(xmlhttp.responseXML.xml);
var userid = xmlDoc.getElementsByTagName("UserId")[0].childNodes[0].nodeValue;

return userid;
}

How to edit the list of entities displayed in the Look for picklist in Lookup window in MS CRM 4.0

The regarding lookup windows generally display a list of all entities that can be associated with an activity. Quite often this feature becomes quite an issue with the users always having to select the appropriate entity from the list before applying the search. The longer the list of entities the more time consuming it is to search using the lookup window.It would be a boon to have only selected entities in the list. Well this is not available for customization through the CRM customization area. But it could be done by adding the Jscript to onload of the form.

There are few properties of the Lookup control being set when we open a form and those are “Lookup Types”, “Lookup Type names” ,”Lookup Type Icons” and “default type”.

We need to over load the default settings by writing our own logic in onload of the form to load specific list of entities to show up in the Look for section.

/*Give the entity type code that you want in below script we want to show account, contact, Lead and Opportunity in order in the list */
crmForm.all.regardingobjectid.lookuptypes = "1,2,3,4";

/*Make sure you set the path of the entity images correctly for the list specified above */
crmForm.all.regardingobjectid.lookuptypeIcons = "/_imgs/ico_16_1.gif:/_imgs/ico_16_2.gif:/_imgs/ico_16_3.gif:/_imgs/ico_16_4.gif:";

/*The below script is to set default entity in the multiple entity lookup. Here we set the default entity to be Opportunity */
crmForm.all.regardingobjectid.defaulttype = "3";


Above example will show Account, Contact, Opportunity and Lead in the Look For entity list and default entity is Opportunity.