Thursday, May 28, 2009

Share Records programmatically

Few days back our client placed a new requirement that he needs the newly created lead needs to to be shared by all the team mates of the businessunit, and that needs to be done automatically. I thought a workflow on lead creation will do the job. But when I sit on the system and to my surprise found that there is no option in the workflow manager for the same. I started scratching my head and at last decided to write a plugin for the same. Now instead of writing everything from scratch I asked the same to my good old friend (GOOGLE) :-) and i was really surprised to get this post by David Fronk of Dynamic Methods Inc. He explained everything in such detail that ...... it starts looking like a kid's play.

With all credit to his great job the excerpts of the post is :

Most implementations just open things up at the business unit level, or even the global level (depending on the size of the company) and don't even worry about sharing. However, there are times when certain information can be sensitive and necessary to restrict access to. Typically these things can be activities, opportunities, cases, services billed, hours worked, etc.


For instance, suppose sales reps aren't allowed to see support cases but are allowed to see the accounts that they manage. Any good account manager would want to know what support issues their account has been having before engaging on a new business proposal, so obviously the sales rep should get to see the cases related to the account.


All that is required is a couple of plugins at two main points and upon creation of a case and reassignment of an account. Whenever a case is created, get the account manager of the account on the case and share the case with that user. If the account gets reassigned, remove the share from the old account manager and add rights to the new account manager. Now with simple logic you can make data more accessible to those who should see the data without them having to do anything more than their regular job.


One side note, be aware that the more items there are under a parent record the longer the reassignments of records will take. For instance, if I reassign an account with 50 cases that's going to take a lot longer to complete the reassignment than it would if there were 5 cases, or even none. Just keep that in mind as you develop your sharing solution.


Pretty simple, and the SDK has some great examples on how to do this. Look up "AccessRights Enumeration", "GrantAccess Message", and "RevokeAccess Message" in the SDK and you should have everything you need.


Here's a quick example on how to share and give all rights to a user:





SecurityPrincipal principal = new
SecurityPrincipal();
principal.Type = SecurityPrincipalType.User;
principal.PrincipalId = new
Guid("7B222F98-F48A-4AED-9D09-77A19CB6EE82");
PrincipalAccess access = new
PrincipalAccess();
access.Principal = principal;
access.AccessMask = AccessRights.ReadAccess;

TargetOwnedDynamic target = new
TargetOwnedDynamic();
target.EntityId = new
Guid("6A92D3AE-A9C9-4E44-9FA6-F3D5643753C1");
target.EntityName = "incident";

GrantAccessRequest readGrant = new
GrantAccessRequest();
readGrant.PrincipalAccess = access;
readGrant.Target = target;
GrantAccessResponse readGranted = (GrantAccessResponse)crmService.Execute(readGrant);

access.AccessMask = AccessRights.WriteAccess;
readGrant.PrincipalAccess = access;
GrantAccessResponse writeGranted = (GrantAccessResponse)crmService.Execute(readGrant);

access.AccessMask = AccessRights.AppendAccess;
readGrant.PrincipalAccess = access;
GrantAccessResponse appendGranted = (GrantAccessResponse)crmService.Execute(readGrant);

access.AccessMask = AccessRights.AppendToAccess;
readGrant.PrincipalAccess = access;
GrantAccessResponse appendToGranted = (GrantAccessResponse)crmService.Execute(readGrant);

access.AccessMask = AccessRights.AssignAccess;
readGrant.PrincipalAccess = access;
GrantAccessResponse assignGranted = (GrantAccessResponse)crmService.Execute(readGrant);

access.AccessMask = AccessRights.DeleteAccess;
readGrant.PrincipalAccess = access;
GrantAccessResponse deleteGranted = (GrantAccessResponse)crmService.Execute(readGrant);



And here is an example on how to revoke access:





SecurityPrincipal principal = new
SecurityPrincipal();
principal.Type = SecurityPrincipalType.User;
principal.PrincipalId = new
Guid("7B222F98-F48A-4AED-9D09-77A19CB6EE82");
PrincipalAccess access = new
PrincipalAccess();
access.Principal = principal;
access.AccessMask = AccessRights.ReadAccess;

TargetOwnedDynamic target = new
TargetOwnedDynamic();
target.EntityId = new
Guid("6A92D3AE-A9C9-4E44-9FA6-F3D5643753C1");
target.EntityName = "incident";
GrantAccessRequest readGrant = new
GrantAccessRequest();
readGrant.PrincipalAccess = access;
readGrant.Target = target;
GrantAccessResponse readGranted = (GrantAccessResponse)crmService.Execute(readGrant);

Override the tool tip of the field in Dynamics CRM

there are times when you want to give your users more information into what they should enter into a field.

As widely accepted the tooltips are the most commonly used and convenient way to achieve the same.

In Dynamics CRM you could use scripts to override the tool tip of the field.

Here's the code script to override the tool tip of the field in dynamics CRM:





var oPopup = window.createPopup();
var oPopupBody = oPopup.document.body;
oPopupBody.style.fontFamily = 'Tahoma';
oPopupBody.style.border = '1px solid black';

function showPopupMessage (Tool_Tip_Text)
{
oPopupBody.innerHTML = "
";
oPopupBody.innerHTML += "
" + Tool_Tip_Text +"
";
var X_Coordinate= -100;
var Y_Coordinate= 20;
var width = 350;
var height = 90;
var documentElement = event.srcElement;
oPopup.show(X_Coordinate, Y_Coordinate, width, height, documentElement);
}

//Be sure to attach your OnMouseOver event with the field's caption

crmForm.all.new_customfield1_c.attachEvent('onmouseover', showPopupMessage ("custom tooltip for new_customfield1 "));
crmForm.all.new_customfield2_c.attachEvent('onmouseover', showPopupMessage ("custom tooltip for new_customfield2 "));
crmForm.all.new_customfield3_c.attachEvent('onmouseover', showPopupMessage ("custom tooltip for new_customfield3 "));


Now you can hover your mouse over the field labels to see your custom tooltip popup

CRM 4 Certification Practice Tests

Hi all,

Richard recently authored practice test questions for the three core CRM 4 certification exams. he is having LOTS of other articles on the exams and how to prepare for them in the certification category. So if you are thinking of clearing the MB 631 , MB 632 or MB 633 you must visit this place.

you can test your knowledge with these practice test here

i have gone through the tests and it is really great. try your knowledge there and best of luck :-)

How to Convert lead to contact, account and/or opportunity programmatically

Sometime we need to convert a lead to a contact, account and/or opportunity programmatically. to achieve this we have to follow the below mentioned process:

it is a two step process. in the first step we need to disable the lead. This can be done by using the SetStateLeadRequest. In the second step we need to use the InitializeFromRequest and InitializeFromResponse classes. It's the InitializeFromRequest class in which we will need to set the EntityMoniker attribute to the lead which you just disabled in the first step. On the same request we'll need to set the target entityname to the name of the entity we wish to convert the lead into (contact, account or opportunity) and then we'll need to set the TargetFieldType. This would most likely be TargetFieldType.All. Now execute that request and here we go .

code example: in this example we will create a function to convert a lead into account programmatically


// <summary>
// Convert Lead To Account
// </summary>
// <param name="service">CrmService</param>
// <param name="leadID">Guid of the Lead that needs to be converted</param>
// <returns>Guid of ctreated account</returns>
public Guid convertLeadToAccount(CrmService service, Guid leadID)
{
//step one : qualify the lead
SetStateLeadRequest qualifier = new SetStateLeadRequest();
qualifier.EntityId = leadID;
qualifier.LeadState = LeadState.Qualified;
qualifier.LeadStatus = -1;
service.Execute(qualifier);
//Note: lead is qualified, but not converted to account yet

InitializeFromRequest req = new InitializeFromRequest();
// this is the very thing that does the job.
req.EntityMoniker = new Moniker();
req.EntityMoniker.Id = leadID;
req.EntityMoniker.Name = "lead";
req.TargetEntityName = EntityName.account.ToString();
req.TargetFieldType = TargetFieldType.All;
InitializeFromResponse rps = (InitializeFromResponse)service.Execute(req);
Guid AccountID = service.Create(rps.Entity);
return AccountID;
}

Monday, May 18, 2009

How to Create a Dynamic IFRAME

Change the Page Displayed in the IFRAME
You may want to change the target of the IFRAME based on considerations such as the data in the form or whether the user is working offline. You can set the target of the IFRAME dynamically.
Note When you change the URL for the IFRAME, parameters are not passed to the new URL automatically. You need to append the querystring parameters to the URL before setting the src property.
Example
The following code example shows you how to set the src for the IFRAME and pass the parameters.


var params = crmForm.all.IFRAME_test.url;
params = params.substr(params.indexOf('?'));
var newTarget = "http://mysite/mypage.aspx";
newTarget = newTarget + params;
crmForm.all.IFRAME_test.src = newTarget ;


Allow Access to Form Data
If you trust the target site of the IFRAME you can disable the security attribute so cross-frame scripting is enabled. This allows the target page to reference or change data in the entity form.


A script in the target of the IFRAME can access objects in the parent. The crmForm cannot be referenced by name because it does not have an ID associated with it, but it is the first form in the forms collection.
For example, to set the value of a variable named AccountName to the name of the Account, use the following code in a page that is the target of an IFRAME in the account form:


var AccountName = parent.document.forms[0].all.name.DataValue;


This value, or any other value in the form, can then be processed by the Web page that is the target of the IFRAME.
The Web page that is the target of the IFRAME can also update the crmForm field values, as shown in the following code example:

parent.document.forms[0].all.name.DataValue = AccountName;


Note : Scripts in Microsoft Dynamics CRM cannot interact with DHTML elements within the IFRAME. This is a security restriction that is set within Internet Explorer for all IFRAME elements.

Reading field values from a lookup

Here is how the value of a lookup field can be retrieved :


crmForm.all.lookupfield.DataValue[0].name
//gives us the name of the lookup field's selected record.

crmForm.all.lookupfield.DataValue[0].id
//gives us the GUID of the lookup field's selected record.