Tuesday, June 17, 2008

CRM 4.0 Gotchas

After implementing a bunch of CRM 4.0 projects I have compiled a short list of "gotchas" that I always share with people as I am gathering requirements for the project. Some of these were around in v3.0 but were not rectified in v.4.0. If anyone has additional ones that they would like to add in the comments I will update this posting.
  • Service Activities have a max length of 3 days (cannot be changed)
  • Bug in WF/Customization: If you customize an entity, all WFs associated are "soft" unpublished. If you change a WF and re-publish, JS on that entity is disabled.
  • If you restrict Write access to an Account, Opportunities, Contacts, Cases associated to that Account cannot be created. One possible solution is to use Teams.
  • The KB and Queue views cannot be modified (use c360 My Workplace instead)
  • You cannot access related data from the Recipient of a Phone Call activity in workflow.
  • Contacts and Contract Lines cannot be removed from the Case form. They must be hidden with JavaScript.
  • It takes 15mins for a published KB article to be indexed and searchable in the Knowledge Base.
  • You cannot delete a KB template unless all articles using it are deleted.
  • In order for an Opportunity to show in the Pipeline report it must have a revenue value entered.

Monday, June 16, 2008

Field Level Security Function

Because of a security limitation with CRM v.4.0 we had to implement an onLoad function that locked form fields based on a user's security role. To detail the issue, CRM does not allow you to restrict write access to the Account while allowing write access to related entities, mainly Opportunities and Contacts. So if you want a specific user role to be able to edit Contacts and not Accounts you have to lock the Account form using JavaScript. I found this code below on forum (sadly I didn't save the original location so if it is yours - give yourself a shout-out).

//PUT THIS CODE IN THE ONLOAD
if(UserHasRole("System Administrator"))
{
var oField1 = crmForm.all.long_taxscheduleid;
oField1.Disabled = !oField1.Disabled;
}


//THIS CODE CHECKS FOR A SPECIFIC SECURITY ROLE AND ALLOW FOR FORM EDITING
//alert(UserHasRole("System Administrator"));

function UserHasRole(roleName)
{
//get Current User Roles, oXml is an object
var oXml = GetCurrentUserRoles();

if(oXml != null)
{
//select the node text
var roles = oXml.selectNodes("//BusinessEntity/q1:name");

if(roles != null)
{

for( i = 0; i < text ="="" xml = "" version="\" encoding="\">" +
"
" +
GenerateAuthenticationHeader() +
"
" +
" " +
" " +
" role" +
"
" +
"
" +
" name" +
"
" +
"
" +
" false" +
"
" +
"
" +
" roleid" +
" role" +
" systemuserroles" +
" roleid" +
" Inner" +
"
" +
"
" +
" systemuserid" +
" systemuserroles" +
" systemuser" +
" systemuserid" +
" Inner" +
"
" +
" And" +
"
" +
"
" +
" systemuserid" +
" EqualUserId" +
"
" +
"
" +
"
" +
"
" +
"
" +
"
" +
"
" +
" " +
" " +
"
" +
"
" +
"";

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", xml.length);
xmlHttpRequest.send(xml);

var resultXml = xmlHttpRequest.responseXML;
return(resultXml);
}

CRM 4.0 Sales Process Workflow

I found a great article today on creating Sales Processes with Workflow in CRM 4.0. Unfortunately in my experience the workflow engine is pretty finicky, especially when it comes to using Stages. A lot of times it hangs on the wait timers.

http://www.bizitpro.com/weblog/entry/microsoft_crm_40_workflow_stage_example_upgraded_from_crm_30/

Hiding Action Menu Items

Well, this is completely unsupported but we had to hide the Activate and Deactivate choices from the Actions menu on a form the other day. I highly suggest downloading the IE Developer Toolbar to accomplish this. It will assist with getting the ids for these two menu choices. Here is the javascript we implemented:

//HIDE DEACTIVATE AND ACTIVATE MENU ITEM if (document.all._MIchangeStatedeactivate100145 != null) { document.all._MIchangeStatedeactivate100145.style.display = "none";} if (document.all._MIchangeStateactivate100146 != null) { document.all._MIchangeStateactivate100146.style.display = "none";}