11 January 2009

CRM 4.0 External Connector License

It's very common to extend CRM to external users, however I saw many customers ask if they need license to do something. A External Connector License is used on:

Available for
• Professional Server
• Enterprise Server
Access License only – no additional software/licenses included
Extends access to external users (e.g. Partners, Customers, Suppliers)
Scenarios*

• Create new activities in CRM, such as a case via a portal
• Update information in CRM, such as contact information via a portal
• Fill orders, or update case status via a portal
* Access via Dynamics CRM Client technology requires a CAL


According to the Microsoft Dynamics® CRM 4.0 Licensing & Pricing Guide

The Microsoft Dynamics CRM 4.0 External Connector enables customers to extend Microsoft Dynamics CRM to their external users such as customers, partners, suppliers, and end users who access a copy of the server software (for which a license was acquired), through any application/graphical user interface (GUI), other than the Microsoft Dynamics CRM client. “External Users” are users who are not either (i) your or your affiliates’ employees, or (ii) your or your affiliates’ onsite contractors or agents, External users also does not include hosted-software service users, such as those already licensing via the Microsoft Service Provider License (SPLA).

An External Connector must be purchased for each server that hosts an application that provides external access to Microsoft Dynamics CRM 4.0 data as described above. External users should not be using the Microsoft Dynamics CRM 4.0 applications & GUIs directly. The alternative is for every external user to acquire a CAL

For the Microsoft Dynamics CRM Professional Server and Enterprise Server, there are 3 External Connector functionalities:

External Connector – The full use External Connector provides external users with full read-write access to Microsoft Dynamics CRM 4.0 data, such as that provided through any application/graphical user interface. The Full Use External Connector will appear on price lists as the Dyn CRM Extrnl Con, and consists of both the Limited External Connector and the Full Use Additive External Connector combined to provide full use capability.

Limited External Connector – The Limited External Connector provides external users with read-only access to Microsoft Dynamics CRM 4.0 data, such as described above. The Limited External Connector will appear on the price lists as the Dyn CRM Ltd Extrnl Con.

Full Use Additive External Connector – The Full Use Additive External Connector provides external users with write-access to Microsoft Dynamics CRM 4.0 data such as described above, and may only be purchased to supplement a Limited External Connector with write-access capability. The Full Use Additive External connector will appear on price lists as the Dyn CRM Additve ExtrnlCon.




External Connectors and Limited External Connectors may be mixed within an environment.

The number of Full Use Additive External Connectors may never exceed the total number of Limited External Connectors used within an organization.

An External Connector is a license only, and does not include any physical software components, and does not include licensing for any other Microsoft products. If external scenarios integrate with Microsoft SQL Server, Microsoft Office SharePoint or any other product license rights for these must be established separately.

For more information on Microsoft Dynamics CRM 4.0 Use Rights under Volume Licensing: http://www.microsoftvolumelicensing.com/userights/

Partners and Customers should work with their Microsoft Licensing Specialist or local Microsoft Representative to ensure their licensing compliance.

11 December 2008

CRM 4.0 Get attribute value from entity's GUID using JScript

Recently I have been asked many times about how to get attribute value from entity's GUID using JScript?
The following code demonstrate how to get a user's internalemailaddress by giving user's GUID.
*It has been modified to support multi-tenent deployment.


alert(GetAttributeValueFromID("systemuser", "09DF2AB7-E16D-DD11-88F3-0003FF884968", "internalemailaddress", "systemuserid"));

function GetAttributeValueFromID(sEntityName, sGUID, sAttributeName, sID)
{
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>"+sEntityName+"</q1:EntityName>" +
" <q1:ColumnSet xsi:type=\"q1:ColumnSet\">" +
" <q1:Attributes>" +
" <q1:Attribute>"+sAttributeName+"</q1:Attribute>" +
" </q1:Attributes>" +
" </q1:ColumnSet>" +
" <q1:Distinct>false</q1:Distinct>" +
" <q1:PageInfo>" +
" <q1:PageNumber>1</q1:PageNumber>" +
" <q1:Count>1</q1:Count>" +
" </q1:PageInfo>" +
" <q1:Criteria>" +
" <q1:FilterOperator>And</q1:FilterOperator>" +
" <q1:Conditions>" +
" <q1:Condition>" +
" <q1:AttributeName>"+sID+"</q1:AttributeName>" +
" <q1:Operator>Equal</q1:Operator>" +
" <q1:Values>" +
" <q1:Value xsi:type=\"xsd:string\">"+sGUID+"</q1:Value>" +
" </q1:Values>" +
" </q1:Condition>" +
" </q1:Conditions>" +
" </q1:Criteria>" +
" </query>" +
" </RetrieveMultiple>" +
" </soap:Body>" +
"</soap:Envelope>" +
"";

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

// retrieve response and find attribute value
var result = xmlHttpRequest.responseXML.selectSingleNode("//q1:" + sAttributeName);
if (result == null)
return "";
else
return result.text;
}

03 December 2008

Quick Find for Inactive Records

CRM Quick Find Active [Entity] view only return active records. It's a common requirement to return both Active/Inactive records. I use a easy way to allow Quick Find view to return both Active/Inactive records, here it is (unsupported!):

1. Export the entity's customization to a xml file;
2. Edit the xml file, search 'Quick Find Active' then locate to the right code piece;
3. Delete the filter which is:





4. Save the xml, import to CRM, then Publish.

Now the Quick Find view can return both Active and Inactive records. ;-)

28 November 2008

Code: CRM 4.0 Dashboard Intergate with FusionCharts

I have been asked many times through email/blog for sharing code about the CRM Dashboard with FusionChart integration. So I decide to extract some code and build a demo project to share, it's a simple work for demo, so please don't expect too much. :)

The demo dashboard supports:
• CRM 4.0, multi-tenants(one URL for different organizations);
• IFD and On-Premise deployment;
• CRM user security(users only see relevant data which their have privileges)

You may deploy the solution under ISV folder, you also need to change sitemap to show the Dashboard:




Download the solution

25 October 2008

Microsoft Outlook is not set as the default mail client?


Today I install CRM Outlook on my Vista(with Outlook 2007), it gives me a strange error:"Microsoft Outlook is not set as the default mail client. Please set Microsoft Outlook as the default mail client from Control Panel\Internet Options\Programs, and then re-run the check."

I'm sure the Outlook is my default mail client, just in case I reset it again. but the error still exist! I'm aware of CRM always query Registry to get information in such cases, so open the default application key: HKLM\SOFTWARE\Clients\Mail, the Default value is Windows Live Mail, so change it to Microsoft Outlook, the error gone!



19 October 2008

Ways to build up a CRM dashboard

There are servel ways to build up a dashboard to integrate with Dynamics CRM. Let's take a look(projects I have done):

1. Windows Sharepoint Service (WSS 3.0) + Office web part
In the previous version of WSS(v2.0), there is a free Office 2003 Add-in: Web Parts and Components, which is not available for WSS 3.0, however you can still add it manually. It's easy to use and config, but not flexible enough, it also requires the client PC has to have Office 2003/2007 software intsalled to see the graphic.



2. Windows Sharepoint Service (WSS3.0) + Reporting Service web part
You can also use Reporting Services Add-in in WSS 3.0, then create a rdl report and call it via Report Viewer web part. Because it's a rdl report, so it's very flexible .



3. ASP.Net + FusionCharts
FusionCharts is a flash charting component that can be used to render data-driven & animated charts for your web applications and presentations. It does provide a free version. So if you want to build up a flexable(let's say: multi-tenants etc.) dashboard to integrate with CRM, it's a good idea to build up your own ASP.Net page with FusionChart. I would say it won't disappoint you.



4. CRM Analytics Accelerator
This well-known add-ons is not available for CRM 4.0 at the moment, but it coming soon. More details see: CRM Accelerators – Part I – Analytics Accelerator



11 October 2008

MVP Award

I have been awarded Microsoft MVP - Dynamics CRM.
Thanks for Microsoft and my friends, colleagues and family. :)

See my MVP profile here: https://mvp.support.microsoft.com/profile/Jim.Wang

30 September 2008

Customize the crmForm

There are some useful crmForm customization skills which I want to share:

1. Change a filed label style

/* change new_button field label style */
if (crmForm.all.new_button != null)
{
var field = crmForm.all.new_button_c;
field.style.fontWeight = 'bold'; // change font to bold
field.style.fontSize = '12px'; // change font size
field.style.color = '#ff0000'; //change font color
}

2. Replace a field to a button, and attach the onclick() event

/* replace new_button_d to a button */
if (crmForm.all.new_button != null)
{
var field = crmForm.all.new_button_d;
var html = "<table border='0' cellspacing='0' cellpadding='0'><tr><img width='32' height='32' style='cursor:hand' src='/_imgs/ico_32_134.gif' alt='Click button' onclick='Button_OnClick()' /></tr></table>";
field.innerHTML = html;
}
Button_OnClick = function()
{
alert("button clicked!");
}

3. Replace a field to a lable (use replaceNode())

/* replace new_button_d to a label */
if (crmForm.all.new_button != null)
{
var html = document.createElement( "<TD id='new_button_d'>");
html.innerText = "this is a lable";
crmForm.all.new_button_d.replaceNode(buttonText);
}

4. Append text under a field (you don't need to create an attribute for that)

/* append text under new_button */
if(crmForm.all.new_button != null)
{
var html= document.createElement( "<LABEL>");
html.innerText = "this is a text field";
crmForm.all.new_button.parentNode.appendChild(html);
}

18 September 2008

Double Click EmailAddress to Open in Outlook

There is a question on Microsoft CRM Forum asking how to: Double Click EmailAddress to Open in Outlook

I think it's worth to bring it here because it's also demonstrate how to send parameters in attachEvent method, so here is the answer:


/* Double Click EmailAddress to Open in Outlook, put into entity.OnLoad */
function CreateEmail(emailAddress)
{
return function()
{
if (emailAddress != null && emailAddress.value.length > 0)
{
window.navigate("mailto:" + emailAddress.value);
}
}
}

crmForm.all.emailaddress1.attachEvent('ondblclick', CreateEmail(crmForm.all.emailaddress1));
crmForm.all.emailaddress2.attachEvent('ondblclick', CreateEmail(crmForm.all.emailaddress2));
crmForm.all.emailaddress3.attachEvent('ondblclick', CreateEmail(crmForm.all.emailaddress3));

06 September 2008

FilteredView and CrmImpersonator?!

I was curious about how to use FilteredView in the CrmImpersnator class for a IFD(Internet-Facing Deployment) solution? Thanks to David Jennaway who gave me a clue.

Ok, the reason for that is because I'm building a CRM dashboard for an On-Premise/IFD CRM deployment. In order to use the Web services from an APSX page, I have to use the Microsoft.Crm.Sdk.CrmImpersonator class, however by doing that it's not possible to get relevant data from the FilteredView, because the CrmImpersnator() will authenticate as [NT AUTHORITY\SYSTEM] account(which is a system account in CRM).

The solution is to use SQL Execute As statement, see the sample code below:


using (new CrmImpersonator())
{
........
string username = "domain\\Guest";
string sqlQuery = "SELECT name FROM FilteredAccount";
string queryString = "GRANT IMPERSONATE ON USER::[NT AUTHORITY\\SYSTEM] TO [" + username + "] EXECUTE AS USER='" + username + "' " + sqlQuery + " REVERT";

........
}

In this example, you have to give user the Impersonate permission first, then use Execute As statement to impersonate the user.
After running the code, if you have a look the CRM database, under the Security\Users folder, the impersonated user account is added in the list, and it grant the 'Impersonate' permission to user [NT AUTHORITY\SYSTEM], see picture below:



By using this technic, you also need to map the user [NT AUTHORITY\SYSTEM] to the CRM database(e.g: Contoso_MSCRM).