Tuesday, August 9, 2011

Hide/Show the CRM modules based on roles in MS CRM 2011

We have sale, marketing and service modules in the CRM. We want to show the sale module only to the sales user, marketing module only to marketing users, service module to service users.

Create a custom Entity named “link”.

Edit the sitemap.
In sales for all the SubArea add the Privilege only to “create” on the custom entity “link”.
<Privilege Entity="new_link" Privilege="Create" />
In Marketing for all the SubArea add the Privilege only to “Read” for the custom entity “link”.
<Privilege Entity="new_link" Privilege="Read" />
In Settings for all the SubArea add the Privilege only to “Write” for the custom entity “link”.
<Privilege Entity="new_link" Privilege="Write" />

Save and import the soluntion.

In security roles give the Create Privilege on “link” to all sales roles, Read Privilege on “link” to all marketing roles, Write Privilege on “link” to all service roles.

Wednesday, October 6, 2010

Deploying Wizard Report to Different Server in MS CRM 4.0

When we create a wizard report in CRM, it’s really difficult to move the same report to production. Once you download the wizard report, we get an RDL file.

When we upload this RDL file to production, we get a report but wizard is lost. User can’t update the report (like column, group etc).

I searched into the database and found a solution (its unsupported) to enable the wizard of the wizard report after uploading the RDL.

Steps to upload a wizard report to production:

Create a wizard report in CRM in Dev environment.
Download the wizard report, it will give an RDL file.
Upload the same RDL file to the Production as “Existing file”.
Login to ORG_MSCRM DB, update the Report table entry, set IsCustomReport = 1 for the corresponding report.

Monday, June 28, 2010

CRM update web service call in Java Script in MS CRM 4.0

// Record Owner
var Owner = new Array;
Owner = crmForm.all.ownerid.DataValue;
var oppOwner = Owner[0].name;

// updating Opportunity
/* setting opportunuty owner name to a text field in the same record using crm update web service call in JScript */
try
{
var xml1 = "<?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>"+
"<Update xmlns='http://schemas.microsoft.com/crm/2007/WebServices'>"+
"<entity xsi:type='opportunity'>" +
"<new_text>"+ xmlencode(oppOwner) +"</new_text>" +
"<opportunityid>" + crmForm.ObjectId + "</opportunityid>" +
"</entity>"+
"</Update>"+
"</soap:Body>"+
"</soap:Envelope>";

var xHReq1 = new ActiveXObject("Msxml2.XMLHTTP");
xHReq1.Open("POST", "/mscrmservices/2007/CrmService.asmx", false);
xHReq1.setRequestHeader("SOAPAction","http://schemas.microsoft.com/crm/2007/WebServices/Update");
xHReq1.setRequestHeader("Content-Type", "text/xml; charset=utf-8");
xHReq1.setRequestHeader("Content-Length", xml1.length);
xHReq1.send(xml1);
// Capture the result
var resultXml1 = xHReq1.responseXML;

var errorCount1 = resultXml1.selectNodes('//error').length;
}
catch (e)
{ }

/* xml encoding to convert "&" and single quote (') symbol*/
function xmlencode(string) {
return string.replace(/\&/g,'&'+'amp;').replace(/</g,'&'+'lt;').replace(/>/g,'&'+'gt;').replace(/\'/g,'&'+'apos;').replace(/\"/g,'&'+'quot;');
}

Friday, June 25, 2010

Set the account lookup when new contact is created from the Contact lookup new button in Account form in MS CRM 4.0

function getAccountLookup()
{
try
{
var stringXml = window.opener.document.getElementById("fetchxml").value;

xmlDoc=new ActiveXObject("Microsoft.XMLDOM");
xmlDoc.async="false";
xmlDoc.loadXML(stringXml)

var name = xmlDoc.selectNodes('fetch/entity/filter/condition')[1].attributes[2].value;
var id = xmlDoc.selectNodes('fetch/entity/filter/condition')[1].attributes[4].value;

//Create an array to set as the DataValue for the lookup control.
var lookupData = new Array();

//Create an Object add to the array.
var lookupItem= new Object();

//Set the id, typename, and name properties to the object.
lookupItem.id = id;
lookupItem.typename = 'account';
lookupItem.name = name;

// Add the object to the array.
lookupData[0] = lookupItem;

// Set the value of the lookup field to the value of the array.
crmForm.all.parentcustomerid.DataValue = lookupData;

}
catch (e)
{}
}

Remove Add Existing Button From CRM Iframe in MS CRM 4.0

/* _MBtoplocAssocOneToMany2contactcustomeraccounts is the Id of the AddExisting button appearing in CRM grid. this id can be find out using IE developer tool bar */

function RemoveAddExistingFromIframe()
{
var iFrame1 = null;
iFrame1 = crmForm.all.IFRAME_Test;
var iDoc1 = iFrame1.contentWindow.document;
iFrame1.attachEvent( "onreadystatechange" , Ready1);
RemoveWhiteSpace(iFrame1);
}

function Ready1()
{

var iFrame1 = crmForm.all.IFRAME_Test;
var iDoc1 = iFrame1.contentWindow.document;
if(iDoc1.getElementById("_MBtoplocAssocOneToMany2contactcustomeraccounts") != null)
iDoc1.getElementById("_MBtoplocAssocOneToMany2contactcustomeraccounts").style.display = "none";
}


function RemoveWhiteSpace(iframe)
{
try
{
var IFRAME_test = iframe;
IFRAME_test.onreadystatechange = function ()
{
if( IFRAME_test.readyState != 'complete' )
return;
IFRAME_test.style.border = "0px";
var IframeWindo = IFRAME_test.contentWindow;
IframeWindo.document.body.scroll = "no";
IframeWindo.document.body.childNodes[0].rows[0].cells[0].style.padding = "0px";
}
}catch (e)
{alert('Error : '+e);}
}

Hide CRM form Button/menu/sort cuts/isv buttons in MS CRM 4.0

function HideISVButtons()
{

var toolBar = document.getElementById('mnuBar1');
if (toolBar != null && toolBar.rows.length > 0 && toolBar.rows[0].cells.length > 0)
{
try
{

var toolBarItems = toolBar.rows[0].cells[0].getElementsByTagName('li')
if (toolBarItems != null && toolBarItems.length > 0) {
for (var i = 0; i < toolBarItems.length; i++) {
var toolBarbuttonName = toolBarItems[i].getAttribute('title');
switch (toolBarbuttonName) {
case "Attach a File":
toolBarItems[i].style.display = 'none';
toolBarItems[i - 1].style.display = 'none';
break;
case "Print Preview":
toolBarItems[i].style.display = 'none';
break;
case "Actions":
toolBarItems[i].style.display = 'none';
toolBarItems[i - 1].style.display = 'none';
break;
break;
case "Follow Up":
toolBarItems[i].style.display = 'none';
toolBarItems[i - 1].style.display = 'none';
break;
case "Test ISV Button":
toolBarItems[i].style.display = 'none';
toolBarItems[i - 1].style.display = 'none';
toolBarItems[i + 1].style.display = 'none'; break;
}
}
}
}
catch (e)
{ }
}
}

Advanced find view in an IFRAME in CRM from in MS CRM 4.0

// Fetch xml for the data we want to show in a CRM grid

fetchXml = "<fetch version='1.0' output-format='xml-platform' mapping='logical' distinct='true'>"+
"<entity name='opportunity'>"+
"<attribute name='name'/>"+
"<attribute name='createdon'/>"+
"<attribute name='ownerid'/>"+
"<attribute name='new_finalstage'/>"+
"<attribute name='opportunityid'/>"+
"<order attribute='name' descending='false'/>"+
"<filter type='and'><condition attribute='statecode' operator='eq' value='0'/></filter>"+
"</entity></fetch>";

/* Layout of the adv find Grid
In object - is the objecttypecode of the result entity
jump - is the name of the primary column in the result view */

var layoutXml = ""+
"<grid name='resultset' object='3' jump='name' select='1' icon='1' preview='1'>"+
"<row name='result' id='opportunity'>"+
"<cell name='name' width='230' />"+
"<cell name='createdon' width='80' />"+
"<cell name='ownerid' width='120' />"+
"<cell name='new_finalstage' width='160' />"+
"</row>"+
"</grid>";

/* the main method to retrieve and bind the data to the CRM Grid according to the fetch XML and Layout XML
IFRAME_TEST- an IFRAME to show the advance find view
opportunity – is the main entity name
fetchXml – the fetchXml query we want to retrieve from CRM
layoutXml – the layout to show the retrieved data
name – sorting of records in CRM advanced find grid
false – sort order Descending
{350D0AA8-3EF5-496B-A714-15B2DE896D20} – advance find view id for the same entity (opportunity) */

EmbedAdvancedFindView("IFRAME_TEST", "opportunity", fetchXml, layoutXml, "name", "false", "{350D0AA8-3EF5-496B-A714-15B2DE896D20}");

// to remove the toolbar items from the advance find grid
var iFrame1 = null;
iFrame1 = crmForm.all.IFRAME_TEST;
var iDoc1 = iFrame1.contentWindow.document;
iFrame1.attachEvent( "onreadystatechange" , Ready1);
RemoveWhiteSpace(iFrame1);


function Ready1(){
try{
var iFrame = crmForm.all.IFRAME_TEST;
var iDoc1 = iFrame.contentWindow.document;
if(iDoc1.getElementById("gridMenuBar") != null)
iDoc1.getElementById("gridMenuBar").style.display = "none";
}catch (e)
{}
}


function EmbedAdvancedFindView(iFrameId, entityName, fetchXml, layoutXml, sortCol, sortDescend, defaultAdvFindViewId) {
try {

var iFrame = document.getElementById(iFrameId);
var httpObj = new ActiveXObject("Msxml2.XMLHTTP");
var url = "/" + ORG_UNIQUE_NAME + "/advancedFind/fetchData.aspx";

var params = "FetchXML=" + fetchXml
+ "&LayoutXML=" + layoutXml
+ "&EntityName=" + entityName
+ "&DefaultAdvFindViewId=" + defaultAdvFindViewId
+ "&ViewType=1039" // According to Michael Hohne over at Stunnware
+ "&SortCol=" + sortCol
+ "&SortDescend=" + sortDescend;

httpObj.Open("POST", url, true);

httpObj.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
httpObj.setRequestHeader("Content-length", params.length);

httpObj.onreadystatechange = function() {
if (httpObj.readyState == 4 && httpObj.status == 200) {
var doc = iFrame.contentWindow.document;
iFrame.src = null;
doc.open();
doc.write(httpObj.responseText);
doc.close();

doc.body.style.padding = "0px";
doc.body.style.backgroundColor = "#eaf3ff";
}
}
httpObj.send(params);
}
catch (e) {
}
}

// to expand the adv find grid to full width
function RemoveWhiteSpace(iframe)
{
var IFRAME_test = iframe;
IFRAME_test.onreadystatechange = function ()
{
if( IFRAME_test.readyState != 'complete' )
return;
IFRAME_test.style.border = "0px";
var IframeWindo = IFRAME_test.contentWindow;
if(IframeWindo.document.body.childNodes[0]!=null){
if(IframeWindo.document.body.childNodes[0].rows!=null){
IframeWindo.document.body.scroll = "no";
IframeWindo.document.body.childNodes[0].rows[0].cells[0].style.padding = "0px";
}
}
}
}

Thursday, June 24, 2010

Xmlencode the text in fetchXML in Jscript in MS CRM 4.0

While passing text as a parameter in fetchXml in CRM OnLoad/OnSave/OnChange event Jscript, it required to xmlencode the text before use the same as parameter.
This is because the fetchXml contains “&” or single quote(‘) is not executed in Jscript CRM service call.


function xmlencode(string) {
return string.replace(/\&/g,'&'+'amp;').replace(//g,'&'+'gt;').replace(/\'/g,'&'+'apos;').replace(/\"/g,'&'+'quot;');
}

Refresh a CRM grid on the CRM Form in MS CRM 4.0

try
{
var _locAssocObj = locAssocObj;
locAssocObj = this.locAssocObj;

//fucntion definition for overloading the N:N Grid association
this.locAssocObj = function(iType, sSubType, sAssociationName, iRoleOrdinal) {
_locAssocObj(iType, sSubType, sAssociationName, iRoleOrdinal);
switch (sAssociationName) {
case "new_new_opportunity_systemuser":
crmForm.all.IFRAME_OpportunityUser.contentWindow.document.all.crmGrid.Refresh();
break;
}
}

} catch (e)
{ }


“sAssociationName” is the relationship name (we can find this in entity customization).
Here there is an N:N relationship in between Opportunity and SystemUser named “new_new_opportunity_systemuser”.
And the system user grid is there on the CRM. On addition/removal of any entry in the user list will refresh the corresponding grid.

Set Focus to a field in CRM form in MS CRM 4.0

function SetFocustoaField()
{
var oField = crmForm.all.new_name;
oField.onblur = function() {
oField.SetFocus();
oField.onblur = null;
}
oField.SetFocus();
}

Call External JS file in CRM from OnLoad/OnSave/OnChange event in MS CRM 4.0

Take an example. I have a JS file named “Entity_OnLoad.js” in “ISV/Org_Name/JavaScript” folder. There is a method named “CommonAction” in “Entity_OnLoad.js” file.

With the help of following Jscript we can call the “CommonAction” method from “Entity_OnLoad.js” in the OnLoad/OnSave/OnChange event of the CRM form.


var netRequest = new ActiveXObject("Msxml2.XMLHTTP");
netRequest.open("GET", "/ISV/Org_Name/JavaScript/Entity_OnLoad.js", false);
netRequest.send(null);
eval(netRequest.responseText);

CommonAction();

Sunday, March 14, 2010

Trigger N:N Association event and Dassiciation event in CRM Plugin in MS CRM 4.0

-- ===================================================================================================
-- Enable Associate and Disassociate Plug-in Events
-- execute the following query to CRM database, it will add two entries in SdkMessageFilterBase
-- 'DisassociateEntities' and 'AssociateEntities' from SdkMessageBase which is not listed
-- --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
USE CrmDev_MSCRM
GO

-- Find the deployments SDK Filter ID for the
-- Associate and Disassociate Entity SDK Messages
DECLARE @DisassociateEntitiesFilterId uniqueidentifier
DECLARE @AssociateEntitiesFilterId uniqueidentifier
SET @DisassociateEntitiesFilterId = (SELECT SdkMessageId FROM SdkMessageBase WHERE [Name] = 'DisassociateEntities')
SET @AssociateEntitiesFilterId = (SELECT SdkMessageId FROM SdkMessageBase WHERE [Name] = 'AssociateEntities')

-- Enable the Associate and Disassociate Filters to be valid for custom processing
-- Custom Processing means "you register plug-ins against it"
-- Note: We only do this for the "generic" (OTC == 0) case, just to be safer
UPDATE SdkMessageFilterBase SET IsCustomProcessingStepAllowed = 1 WHERE SdkMessageId = @DisassociateEntitiesFilterId AND PrimaryObjectTypeCode = 0
UPDATE SdkMessageFilterBase SET IsCustomProcessingStepAllowed = 1 WHERE SdkMessageId = @AssociateEntitiesFilterId AND PrimaryObjectTypeCode = 0
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
The above query will enable the 'DisassociateEntities' and 'AssociateEntities' message in the plugin registration tool. While registering the plugin select the entity name as ‘none’

While executing the plugin you will be getting four parameter as input parameters from the plugin context along with the other properties :

1. Related Entity1 guid and entity name
2. Related Entity2 guid and entity name
3. Relation hsip name (nothing but intersect hidden N:N entity name)
4. Optional parameter.

Using these value you can implement you logic.

Sample Code for N:N relationship with a custom entity and Sytem User:

public void Execute(IPluginExecutionContext context)
{
try
{
crmservice = context.CreateCrmService(true);

if (context.MessageName == "AssociateEntities")
{

if (context.InputParameters.Properties["RelationshipName"].ToString() == "new_new_customentity_systemuser")
{
string oId = string.Empty;
string SharedUserId = string.Empty;

oId = (context.InputParameters.Properties["Moniker1"] as Moniker).Id.ToString();

SharedUserId = (context.InputParameters.Properties["Moniker2"] as Moniker).Id.ToString();

// write you logic here

}
}

}
catch (System.Web.Services.Protocols.SoapException ex)
{
LogWriter.LogInfo(ex.ToString());
}

catch (Exception ex)
{
LogWriter.LogInfo(ex.ToString());
}
}

Note : As we have defined 'none' as the entity name while registering the plugin, so this plugin will get triggered when ever user will do add existing or romove existing, for any entity. So while writing the logic relationship name is required to identify from where plugin has been triggered.

Referance : http://consulting.ascentium.com/blog/crm/Post533.aspx

Friday, March 12, 2010

Disable CRM form in MS CRM 4.0

Here is the JScript to Disable all the fields/attributes of the CRM From.

function DisableForm() {
var iLen = crmForm.all.length;
for (i = 0; i < iLen; i++) {
crmForm.all[i].Disabled = true;
}
}

HIde Left Nav Bar of CRM from in MS CRM 4.0

Here is the JScript to hide the left navigation area (completly) of any CRM form.

document.all.crmNavBar.parentElement.style.display = "none";
document.all.tdAreas.colSpan = 2;

Maximize the CRM form in MS CRM 4.0

Here is the JScript to maximise the CRM form.

window.moveTo(0, 0);
window.resizeTo(screen.availWidth, screen.availHeight);