"тнιѕ вℓσg ¢συℓ∂ ѕανє уσυя мσηєу ιƒ тιмє = мσηєу" - ∂.мαηנαℓу

Saturday, 4 February 2012

Duplicate Detection in CRM 2011 --- Pitfalls



As you all know Duplicate Detection is a very good feature in Dynamics CRM 2011. But there are some useful tips to be remembered.


Lets consider a scenario.


Imagine that a user Mr.Derek would like to import some data into CRM 2011


Data Import feature in CRM 2011 is explained here http://crmdm.blogspot.com/2011/04/how-to-import-data-into-crm-2011.html


So Derek sets the 'Allow Duplicates' to No as shown below.




But please remember that the above option works based on the duplicate detection settings and duplicate detection rules defined.



Sadly, after the import Derek found duplicates. What could be the reason for this?

  There is a pitfall related to duplicate detection rules. As you all know, the duplicate detection rule must be in a published state if that has to be valid.
So in our case Derek was for sure that he published all the duplicate detection rules after defining them. But from his investigation, he finds that the state of the duplicate detection rule was turned automatically into unpublished later. And this is the pitfall.




Now the very important thing how does it happens ? How and Why the state of a duplicate detection rule turns from published to unpublished ?


We found the very useful information from a blog.
"By design, whenever any entity metadata is changed all duplicate rules associated with that entity are unpublished"
Here is reference for the above information.
Ref: http://www.madronasg.com/blog/duplicate-detection-rules-automatically-unpublished


Note: In simple words, whenever we do a release (importing solution to Test OR QA OR Production) if there is any change for an entity, say  for contact entity then the duplicate detection rule for contact would turn into unpublished state. So after importing a solution we need to make sure that the duplicate detection rules are in published state. This check could be done either manually or through scripts.


Hope this helps you !









Tuesday, 17 January 2012

Latest SDK for CRM 2011

             Microsoft released the latest SDK for CRM 2011 ( version 5.0.9  Dated 16.01.2012) . It could be downloaded from the following link.


http://www.microsoft.com/download/en/details.aspx?id=24004



Tuesday, 10 January 2012

eXtremeCRM 2012 Berlin

eXtremeCRM 2012 Berlin


One of our Colleagues ( Mr. Sebastian ) would be a speaker at this great event.

Hats off you Seb ! Wish you good luck !

Lets listen to his words,

"eXtremeCRM in 2012 is going to be held in Berlin and again I have a privilege to be invited as speaker. What I like about that  conference, well  eXtremeCRM is great event , deep technical readiness on Microsoft Dynamics CRM 2011 a lot of content delivered by Microsoft product team, and technical experts within the channel, not enough new track is coming Practice Leaders Summit. Now a bit about myself, I’ll  present definitely more about Azure + XRM  working together a lot of new content in comparison to event in Prague and also some new session about SharePoint 2010 + XRM, details will be soon published on eXremeCRM website. There is still a time to register so don’t miss it and see you in Berlin" -- Mr. Sebastian

Further details could be found from his blog

OR From eXtremeCRM website


Tuesday, 3 January 2012

How to override System Ribbon Button in CRM 2011 ( Display / Enable Rule to System Ribbon Button in CRM 2011)

This post would shed light on the following.
How to override System Ribbon Button in CRM 2011 ( Display / Enable Rule to System Ribbon Button in CRM 2011)?
How to show / hide a system button based on a value on the form?


In CRM 2011, it is possible to override the System ribbon button functionality. Also we could apply Enable / Disable Rule Display / Hide Rule to the existing System Ribbon button.
In order to grasp this quickly, lets consider a scenario.


As we all know, there is a Deactivate system ribbon button on the Account form.
Suppose we would like to Enable / Disable this button based on a value on the Account form. To make it simple, lets consider the City field. 
For instance, if the city is London, then Deactivate system button should be enabled. Also we should be able to fire our custom javascript when the Deactivate System button gets clicked. This sample could take you through very useful scenarios.


There is a key to unlock the door here. what is that key ? Lets see.


If you refer the SDK, you could find the following folder and file


sdk\resources\exportedribbonxml\accountribbon.xml


Lets find out our System Deactivate button.


Please Note: We don't need to write the following piece of code. This is just an easy way to refer and then to find the key from SDK.
<Button Id="Mscrm.Form.account.Deactivate" ToolTipTitle="$Resources:Ribbon.HomepageGrid.account.Record.Status.Deactivate" ToolTipDescription="$Resources(EntityPluralDisplayName):Ribbon.Tooltip.Deactivate" Command="Mscrm.Form.Deactivate" Sequence="60" Alt="$Resources:Ribbon.HomepageGrid.account.Record.Status.Deactivate" LabelText="$Resources:Ribbon.HomepageGrid.account.Record.Status.Deactivate" Image16by16="/_imgs/ribbon/deactivate16.png" Image32by32="/_imgs/ribbon/Deactivate_32.png" TemplateAlias="o2" />


Now can you guess what's the key in this? Its nothing but the Command.


The only key thing we need to override the System Ribbon button is to know the command value. Rest is as easy as we open a door with a valid key. We need to write the CommandDefinition as shown below.




Please make sure that the code is written under right parent tags.



          <CommandDefinition Id="Mscrm.Form.Deactivate">
            <EnableRules>
              <EnableRule Id="Mscrm.Form.account.Deactivate.EnableRule"></EnableRule>
            </EnableRules>
            <DisplayRules></DisplayRules>
            <Actions>
              <JavaScriptFunction Library="$webresource:ap_DeactivateOverride.js" FunctionName="DeactivateOverride" />
            </Actions>
          </CommandDefinition>




Also the enable rule under rule definitions as show in the above picture.

         <EnableRule Id="Mscrm.Form.account.Deactivate.EnableRule">
              <ValueRule Field="address1_city" InvertResult="false" Value="London"/>
            </EnableRule>


Here we go.


Scenario1: City value is not London -- Deactivate Button got disabled.






Scenario2: City value is London -- Deactivate Button got enabled.



Scenario3: City value is London -- Deactivate Button was clicked by the user. (alert from custom js function)




As this is my first post in 2012,

"тнєяє ѕнαℓℓ вє ѕнσωєяѕ σƒ вℓєѕѕιηg тσ уσυ αℓℓ ιη тнє вℓσωιηg ƒℓσωєя -2012"














Monday, 19 December 2011

How to Update records of a Sub-grid in CRM 2011 using OData JSON JQuery

How to Update records of a Sub-grid in CRM 2011 using OData  JSON JQuery:


Lets get the ball rolling.


Odata :"The Open Data Protocol (OData) is a Web protocol for querying and updating data that provides a way to unlock your data and free it from silos that exist in applications today" Ref: http://www.odata.org/


JSON: "JSON (JavaScript Object Notation) is a lightweight data-interchange format. It is easy for humans to read and write." Ref: http://www.json.org/


JQuery: Its used to simplify AJAX interactions


Let's consider a scenario.
On Account form we have a sub-grid. This would display the Public Relations Budgets of a company. The user could view  and select these budgets and when he / she clicks the Verify button on the ribbon, the Budget records would be updated with the following field values


Verified On --- Current Date Time
Verified By --- Logged in User.


Note: The Verify Budget button would be enabled only if the user selects one record.


Lets see how we could do this using the combination of OData, JSON and JQuery in CRM 2011


Verify Budget button in disabled state-- No records are selected in the sub-grid.




Verify Budget button in enabled state-- One record is selected in the sub-grid.



In order to achieve our target we should have js files for jquery and json. This could be easily downloaded from various resources. Nevertheless, the best way would be to get this from SDK. 
If you have latest SDK, you could find the following folder.

sdk\samplecode\js\restendpoint\jqueryrestdataoperations\jqueryrestdataoperations\scripts
The following js files were used for this example. 
jquery1.4.1.min
json2


As you all know, firstly these two js files should be added as webresources.


We need to add these to the form library of Account form as shown below.




The simplest way to understand the above stuff is to bring back the concept of header files or Library into your mind. After this step, we could use JSON notations and JQuery syntaxes whenever required.


Now lets think about the Verify Budget Button. Here is the skeleton of Verify Budget Button.
Note: Even though we are on the Account form, the following ribbondiffxml has to be added under the Budget entity ( Remember that items of Sub-grid belongs to Budget entity)




For your convenience, I have pasted the code below.



<RibbonDiffXml>
        <CustomActions>
          <CustomAction Id="Mscrm.SubGrid.ap_budget.verify" Sequence="60" Location="Mscrm.SubGrid.ap_budget.MainTab.Management.Controls._children">
            <CommandUIDefinition>
              <Button Id="Mscrm.SubGrid.ap_budget.verifybutton" TemplateAlias="o1" Image16by16="$webresource:ap_btn.png" Image32by32="$webresource:ap_btn.png" 
                      LabelText="$LocLabels:Mscrm.SubGrid.ap_budget.verify.LabelText" ToolTipTitle="$LocLabels:Mscrm.SubGrid.ap_budget.verify.Tooltip" 
                      ToolTipDescription="$LocLabels:Mscrm.SubGrid.ap_budget.verify.TooltipDescription" Command="Mscrm.SubGrid.ap_budget.verify.Command" />
            </CommandUIDefinition>
          </CustomAction>
          <HideCustomAction HideActionId="Mscrm.SubGrid.ap_budget.Edit.HideId" Location="Mscrm.SubGrid.ap_budget.Edit" />
          <HideCustomAction HideActionId="Mscrm.SubGrid.ap_budget.Delete.HideId" Location="Mscrm.SubGrid.ap_budget.Delete" />
          <HideCustomAction HideActionId="Mscrm.SubGrid.ap_budget.Deactivate.HideId" Location="Mscrm.SubGrid.ap_budget.Deactivate" />
          <HideCustomAction HideActionId="Mscrm.SubGrid.ap_budget.Activate.HideId" Location="Mscrm.SubGrid.ap_budget.Activate" />
          <HideCustomAction HideActionId="Mscrm.SubGrid.ap_budget.BulkDelete.HideId" Location="Mscrm.SubGrid.ap_budget.BulkDelete" />
        </CustomActions>
        <Templates>
          <RibbonTemplates Id="Mscrm.Templates"></RibbonTemplates>
        </Templates>
        <CommandDefinitions>
          <CommandDefinition Id="Mscrm.SubGrid.ap_budget.verify.Command">
            <EnableRules>
              <EnableRule Id="Mscrm.SubGrid.ap_budget.verify.EnableRule"></EnableRule>
            </EnableRules>
            <DisplayRules></DisplayRules>
            <Actions>
              <JavaScriptFunction Library="$webresource:ap_verify.js" FunctionName="VerifyBudget" />
            </Actions>
          </CommandDefinition>
        </CommandDefinitions>
        <RuleDefinitions>
          <TabDisplayRules />
          <DisplayRules />
          <EnableRules>
            <EnableRule Id="Mscrm.SubGrid.ap_budget.verify.EnableRule">
              <SelectionCountRule AppliesTo="SelectedEntity" Minimum="1"></SelectionCountRule>
            </EnableRule>
          </EnableRules>
        </RuleDefinitions>
        <LocLabels>
          <LocLabel Id="Mscrm.SubGrid.ap_budget.verify.LabelText">
            <Titles>
              <Title languagecode="1033" description="Verify Budget" />
            </Titles>
          </LocLabel>
          <LocLabel Id="Mscrm.SubGrid.ap_budget.verify.Tooltip">
            <Titles>
              <Title languagecode="1033" description="Verify Budget" />
            </Titles>
          </LocLabel>
          <LocLabel Id="Mscrm.SubGrid.ap_budget.verify.TooltipDescription">
            <Titles>
              <Title languagecode="1033" description="Verify Budget" />
            </Titles>
          </LocLabel>
        </LocLabels>
      </RibbonDiffXml>


Now lets traverse through JS code.
Please note the comments along with the code.
function VerifyBudget()
{


    var gridControl = document.getElementById("PubilcRelationsBudget").control;
    var ids = gridControl.get_selectedIds(); // Get the selected Ids of Sub-Grid
    for (i = 0; i < ids.length; i++)
 {


        var budgetToVerify= new Object(); // object to be sent to CRM
        var currentDate = new Date();
        var formatDate = new Date(currentDate);
        budgetToVerify.ap_verifiedon = formatDate;
        budgetToVerify.ap_verifiedby = { Id: Xrm.Page.context.getUserId(), Name: "", LogicalName: "systemuser" };  // You could keep the name empty in this case
        var jsonEntity = window.JSON.stringify(budgetToVerify);


        var ODataPath = Xrm.Page.context.getServerUrl() + "/XrmServices/2011/OrganizationData.svc/ap_budgetSet";
        var id = ids[i].replace("{", "").replace("}", "");
//AJAX Call using JQuery syntax. Please note the type--POST. To post something to CRM
//To update a record you must pass GUID which is the identifier of the record.
//For retrieval type would be GET
        $.ajax({
            type: "POST",
            contentType: "application/json; charset=utf-8",
            datatype: "json",
            data: jsonEntity,
            url: ODataPath + "(guid'" + id + "')",
            beforeSend: function (XMLHttpRequest) {
                XMLHttpRequest.setRequestHeader("Accept", "application/json");
                XMLHttpRequest.setRequestHeader("X-HTTP-Method", "MERGE");
            },
            success: function (data, textStatus, XmlHttpRequest) {
// Refresh the Sub-Grid to reflect the changes.


                document.getElementById("PubilcRelationsBudget").control.refresh();
            },
            error: function (XMLHttpRequest, textStatus, errorThrown) { }
        });


    }
}







Here is your pie.




























Tuesday, 13 December 2011

How to refresh a Sub-Grid in CRM 2011 using Javascript

Code Snippet:
gridControl = Xrm.Page.ui.controls.get("yourSubGridName");
gridControl.refresh();
Alternatively, you could use the following.
document.getElementById("yourSubGridName").control.refresh();

Monday, 12 December 2011

How to retrieve the Selected Record Ids of a Sub Grid in CRM 2011 using javascript

How to retrieve the Selected Record Ids of a Sub Grid in CRM 2011 using javascript
Code Snippet:
    var gridControl = document.getElementById("yourSubGridName").control;
    var ids = gridControl.get_selectedIds();