Sunday, September 18, 2011

How to create an email activity using REST Endpoints in CRM2011


How tough it can be to create an activity using code? It sounds very easy but there are few issues, if you are using REST Endpoints.

REST Endpoints do not support all the CRM data types. One of those data type is PartyList. PartyList is very important to create most of the activity like emails, appointments, phone calls etc.

To set the value of the PartyList field you need an array of PartyLists as you can have more than value for those fields. For e.g you can have more than one recipient for an email or you can have more than resource for an appointment.

As I mentioned earlier, REST Endpoints do not support PartyList, So its is impossible to assign value to these fields. If you look at DataSet returned by the Rest Endpoints, It looks like they are treating PartyList fields like string fields.

image

These values does not even return the guid or name of the PartyList entity. if you look at sender field in the screen shot above, it does not have guid or the name of the system user who sent this email.
I tried the same using following code:

email.Sender="crm2011@emailops.com.au";
var partlistcollection = new Array(); //tried to create an array of PartyLists

partlistcollection[0] = {Id: "8384E684-7686-E011-8AF0-00155D32042E",LogicalName: "contact",Name: "Amreek Singh"};
email.ToRecipients=JSON.stringify(partlistcollection);

But it did not work, if you pass a string value to the PartyList fields, You won’t get any error message but you won’t see any value in those fields on a created entity. 

Now here is the solution. You need to create an activity (in this case it’s  an email) first and then create a PartyList entity and link it back to the created activity.

function CreateEmail() {
alert("CreateEmail Begin");

var email = new Object();
email.Subject = "Sample Email Using REST";
SDK.JScriptRESTDataOperations.Create(email, "Email", EmailCallBack, function (error) { alert(error.message); });
}

// Email Call Back function
function EmailCallBack(result)
{
var activityParty=new Object();
// Set the "party" of the ActivityParty // EntityReference of an entity this activityparty relatated to. 
activityParty.PartyId = {
  Id: "8384E684-7686-E011-8AF0-00155D32042E",//replace this with the contactid from your system.
  LogicalName: "contact"
};
// Set the "activity" of the ActivityParty
// EntityReference.
activityParty.ActivityId = {
  Id: result.ActivityId, 
  LogicalName: "email"
};
// Set the participation type (what role the party has on the activity).
activityParty.ParticipationTypeMask = { Value: 2 }; // 2 mean ToRecipients
SDK.JScriptRESTDataOperations.Create(activityParty, "ActivityParty",ActivityPartyCallBack , function (error) { alert(error.message); });
}

function ActivityPartyCallBack(reuslt)
{
alert("Process Completed");
}

activityParty.ParticipationTypeMask = { Value: 2 }; is very important as it will specify if this PartList is sender/recipient/resource etc  of the activity.

Here is the link to complete list of activityParty.ParticipationTypeMask click here.
For this sample, I have used the generic REST CRUD data operations library created by Jim Daly.
Add references to following Java Script  web resources to try the solution.
  • SDK.JScriptRESTDataOperations
  • JSON2
Here is the link to unmanaged solution RESTEmailSolution_1_0
  • I hope this helps.

Tuesday, September 6, 2011

How to change the maximum no. of controls on CRM2011 Dashboards

The maximum number of controls allowed on CRM2011 dashboards are 6. You cannot put the more than 6 graphs/charts/iframes/webresources etc. on the dashboard.
This setting is applied to the server not a organisation setting. So you cannot change this setting for CRM Online but you can change this for an on-premise installation.
There are two ways to do it.
  1. Using Deployment Web Service (http://myservername/xrmdeployment/2011/deployment.svc)
  2. Using Window Power Shell
Windows Power Shell Option is the easiest one.
  • Open the Windows Power Shell
  • Add the Microsoft Dynamics CRM PowerShell snap-in using
Add-PSSnapin Microsoft.Crm.PowerShell
you may get the message saying something like “Add-PSSnapin : Cannot add Windows PowerShell snap-in Microsoft.Crm.PowerShell because it is already added.” It is okay.
  • Run the following 3 command
$setting = Get-CrmSetting -SettingType DashboardSettings
$setting.MaximumControlsLimit = 7 (// you can change this number)
Set-CrmSetting -Setting $setting
Here is my screen shot with 7 charts.
    Charts

Monday, August 29, 2011

CRM2011 User Settings Utility

Hi Guys, I have created this CRM2011 utility tool that will help administrators to update personal settings of multiple users with  just few clicks. This is also my first codeplex project. Here is the link http://crm2011usersettings.codeplex.com.
Please leave feedback and suggestions.
Utility



Thanks

Tuesday, August 2, 2011

Enable/Disable Out of Box buttons (Sub Grid) based on a custom rule in crm 2011

You may have read millions of blogs on this topic. Here is my attempt.

Scenario:

We have an entity with “Many to One relationship” to multiple entities. We want to disable “Add Existing” button on subgrids of some of those entities.
In this example, I am disabling a “Add Existing Contact” button for all the entities except account. I am modifying the ribbon of contact entity.

Steps: There are 3 major steps to accomplish this solution

  1. JavaScript web resource
  2. Button id and command definition of the button we want to disabale/enable.
  3. Modify the ribbon definition of the entity ribbon.
Here are steps the steps in detail

Step 1: Javascript WebResource

  • Create a new javascript webresource with name new_CustomRule.js and add the following lines in it.
function HideExisting( PrimaryEntityTypeCode)
 {
  if (PrimaryEntityTypeCode ==1)
        {
        return true;
         }
         else
         {
          return false;
          }
 }
  • Save the webresource and publish it.
The HideExisting function is checking value of PrimaryEntityTypeCode parameter passed to it. If the PrimaryEntityTypeCode is 1(account) the function will return true otherwise it will return false.The function will enable the “Add Existing Contact” if it is on account form but disable the button on any other entity form.

Step 2: Getting the button id/s and command definitions of the button/s


  • If you don’t have CRM2011 SDK, download one. Go to location sdk\samplecode\cs\client\ribbon\exportribbonxml in SDK.

  • If you are using system entity and it’s ribbon has not been modified before, click on exportedribbonxml folder and open up the ribbon of your entity.

  • If you are working with a custom entity or with the system entity whose ribbon has been modified, open the exportribbonxml solution in Visual studio. If you are using a custom entity enter your entity name in ExportRibbonXml.cs in the following section.

image



  • Run the program and it will generate the ribbon definitions for the all the entities mentioned in the program.
  • Open the entity ribbon from exportedribbonxml folder and search for the button you are interested in. We are looking for “AddExisting” buttons in this case scenario. we need the whole <Buttons>tags for this solution

image

AddExistingStandard button is used when we embed a grid on the form and AddExistingAssoc is used when we click on native left navigation link. Look at “Command” name in the button tags above. We need the command definitions for these commands.

Step 3: Modify the Ribbon definition of Contact entity

  • Create a new solution in CRM, add contact entity to the solution and export the solution.

  • Open the customization file from the exported solution and look for <RibbonDiffXML> . It will look like following. We are making changes to 3 areas of the definition highlighted in red.
<RibbonDiffXml>
        <CustomActions />         
        <Templates>
               <RibbonTemplates Id=“Mscrm.Templates“></RibbonTemplates>
        </Templates>
        <CommandDefinitions />
        <RuleDefinitions>
       <TabDisplayRules />
       <DisplayRules />
       <EnableRules />
       </RuleDefinitions>
       <LocLabels />
</RibbonDiffXml>
  • Repalce the <CustomActions /> with
 <CustomActions>
            <CustomAction Id="AddExistingCustomAction"  Location="Mscrm.SubGrid.contact.AddExistingAssoc"  Sequence="40">
              <CommandUIDefinition>
                <Button Id="Mscrm.SubGrid.contact.AddExistingAssoc"  Command="Mscrm.AddExistingRecordFromSubGridAssociated"  Sequence="40" LabelText="$Resources(EntityDisplayName):Ribbon.SubGrid.AddExisting" Alt="$Resources(EntityDisplayName):Ribbon.SubGrid.AddExisting" Image16by16="/_imgs/ribbon/AddExistingStandard_16.png" Image32by32="/_imgs/ribbon/AddExistingStandard_32.png" TemplateAlias="o1" ToolTipTitle="$Resources(EntityDisplayName):Mscrm_SubGrid_EntityLogicalName_MainTab_Management_AddExistingAssoc_ToolTipTitle" ToolTipDescription="$Resources(EntityDisplayName):Mscrm_SubGrid_EntityLogicalName_MainTab_Management_AddExistingAssoc_ToolTipDescription" />
              </CommandUIDefinition>
            </CustomAction>
            <CustomAction Id="AddExistingCustomAction2"  Location="Mscrm.SubGrid.contact.AddExistingStandard"  Sequence="40">
              <CommandUIDefinition>
                <Button Id="Mscrm.SubGrid.contact.AddExistingStandard" Command="Mscrm.AddExistingRecordFromSubGridStandard" Sequence="30" LabelText="$Resources(EntityDisplayName):Ribbon.SubGrid.AddExisting" Alt="$Resources(EntityDisplayName):Ribbon.SubGrid.AddExisting" Image16by16="/_imgs/ribbon/AddExistingStandard_16.png" Image32by32="/_imgs/ribbon/AddExistingStandard_32.png" TemplateAlias="o1" ToolTipTitle="$Resources(EntityDisplayName):Mscrm_SubGrid_EntityLogicalName_MainTab_Management_AddExistingStandard_ToolTipTitle" ToolTipDescription="$Resources(EntityDisplayName):Mscrm_SubGrid_EntityLogicalName_MainTab_Management_AddExistingStandard_ToolTipDescription" />
              </CommandUIDefinition>
            </CustomAction>
 </CustomActions>
We need a <CustomAction> to change the behaviour of the button. Make sure location property of <CustomAction> tag is exactly the same as Id property of <Button> tag.
The <Button >tags has been copied from contactribbon file from exportedribbonxml folder mentioned in step 2.
  • Repalce the <CommandDefinitions /> with the command definition from contactribbon file from step 2.
<CommandDefinitions>
            <CommandDefinition Id="Mscrm.AddExistingRecordFromSubGridStandard">
              <EnableRules>
                <EnableRule Id="Mscrm.AppendToPrimary" />
                <EnableRule Id="Mscrm.EntityFormIsEnabled" />
                <EnableRule Id="Mscrm.AddExistingCustomRule" />
              </EnableRules>
              <DisplayRules>
                <DisplayRule Id="Mscrm.ShowForOneToManyGrids" />
                <DisplayRule Id="Mscrm.AppendToPrimary" />
                <DisplayRule Id="Mscrm.AppendSelected" />
                <DisplayRule Id="Mscrm.CanWriteSelected" />
              </DisplayRules>
              <Actions>
                <JavaScriptFunction FunctionName="Mscrm.GridRibbonActions.addExistingFromSubGridStandard" Library="/_static/_common/scripts/RibbonActions.js">
                  <CrmParameter Value="SelectedEntityTypeCode" />
                  <CrmParameter Value="SelectedControl" />
                </JavaScriptFunction>
              </Actions>
            </CommandDefinition>
            <CommandDefinition Id="Mscrm.AddExistingRecordFromSubGridAssociated">
              <EnableRules>
                <EnableRule Id="Mscrm.AppendPrimary" />
                <EnableRule Id="Mscrm.AppendToPrimary" />
                <EnableRule Id="Mscrm.EntityFormIsEnabled" />
                <EnableRule Id="Mscrm.AddExistingCustomRule" />
              </EnableRules>
              <DisplayRules>
                <DisplayRule Id="Mscrm.ShowForManyToManyGrids" />
                <DisplayRule Id="Mscrm.AppendPrimary" />
                <DisplayRule Id="Mscrm.AppendToPrimary" />
                <DisplayRule Id="Mscrm.AppendSelected" />
                <DisplayRule Id="Mscrm.AppendToSelected" />
                <DisplayRule Id="Mscrm.CanWriteSelected" />
              </DisplayRules>
              <Actions>
                <JavaScriptFunction FunctionName="Mscrm.GridRibbonActions.addExistingFromSubGridAssociated" Library="/_static/_common/scripts/RibbonActions.js">
                  <CrmParameter Value="SelectedEntityTypeCode" />
                  <CrmParameter Value="SelectedControl" />
                </JavaScriptFunction>
              </Actions>
            </CommandDefinition>
          </CommandDefinitions>

The only thing we changed in the commandefinition is the <EnableRule> highlighted in Blue.
<EnableRule Id="Mscrm.AddExistingCustomRule" />

  • Now I need to define this rule. Change the <EnableRules /> with
<EnableRules>
      <EnableRule Id="Mscrm.AddExistingCustomRule">
       <CustomRule FunctionName="HideExisting" Library="$webresource:new_CustomRule.js" Default="false" >
          <CrmParameter Value="PrimaryEntityTypeCode" />
        </CustomRule>
      </EnableRule>
 </EnableRules>
In the <CustumRole> I am calling a function HideExisting from webresource CustomRule.js mentioned in step 1. The default return value for this function false.The <CustomRule> is also passing PrimaryEntityTypeCode as parameter to HideExisting function If the function return true, the system will enable the “Add Existing Contact” button otherwise it will be disable the button.

  • Save the file and overwrite the Customization file in your exported solution zip file with this file.
  • Import the solution zip file and publish it. It’s done.
Note: If your solution is not working. The reason may be, when you click on left navigation or click on subgrid on the form the javascript starts loading. But it won’t call the function. But if you click on some other option and come back it will work the second time.This problem has been fixed in Rollup 2 . I spent 2 days to sort this out.
Install rollup 2 and you are good to go.

Sunday, July 17, 2011

Step by Step - Hiding “Add Existing” button in CRM 2011

In MSCRM 4.0, hiding the “Add Existing” button was a very common request. This blog will show how to do this in CRM 2011. When we click on associated record link in left navigation of an entity form, we can see a "Add Existing" button on the ribbon. To hide this button we need to modify the ribbon of the associated entity.
The following screen shot is of an account entity. If we click on "Contacts" on left navigation, we can see the "Add Existing Contact" button on the ribbon. To hide this button we need to modify the ribbon of the contact entity.
image
Here are the steps
  • Create a new solution.
  • Add the contact entity to the solution. Do not include any required components or dependent components to the solution.
  • Export the solution and unzip the solution file.
  • Open the customizations file and look for “<RibbonDiffXml>” tag.
  • Replace the <CustomActions /> with
<CustomActions>
  <HideCustomAction Location="Mscrm.SubGrid.contact.AddExistingAssoc" HideActionId="Mscrm.SubGrid.contact.AddExistingAssoc.HideAction" />
  <HideCustomAction Location="Mscrm.SubGrid.contact.AddExistingStandard" HideActionId="Mscrm.SubGrid.contact.AddExistingStandard.HideAction" />
</CustomActions>
  • Save the file.
  • Replace the customizaions.xml file in your zip solution with this file.
  • Import the solution and publish the changes.
Note: Replace the highlighted "contact” text with your entity name. It can be “opportunity” or a custom entity like “new_entity” etc.

Good day…………..

Wednesday, June 29, 2011

CRM 2011 Postcode Lookup Solution Version 1.0

I have created this postcode lookup solution. You can download the managed solution from here. The name of the solution file is PostCodeSolution_1_0_managed. The solution consists of 4 files

  • new_Json2.js (Javascript webresource)
  • new_PostCodeScript(Javascript webresource)
  • new_postcode(custom entity to store postcode information)
  • new_SuburbOptions (HTML webresource)

How does it work:

  • User enters the postcode on postal code field and onchange event of the field, the solution will retrieve postcode records related to entered postcode.
  • If there is a record related to entered postcode, the solution will populate the state, suburb and country fields for you.
  • If there are more than one records related to entered postcode, solution will prompt you to select the appropriate entry.

In the following screen shot, I entered 2000 in postal code field and system prompt to pick the relevant city/suburb.

image

Pros:

  • Clean data entry: The solution will help to minimise data entry errors in address fields.
  • Don’t need to create custom picklist state/or country attributes.
  • Using built-in address fields means, don’t need to modified some of the built-in reports.

Cons:

  • The solution is working only address1_postalcode attribute of an entity. It can work on account , contact or any other entity that has built in address fields.
  • The solution is hard coded to fill built in adress1_city, address1_stateorprovince, address1_country fields only.

Version 2.0 :

I will release version 2.0 soon, which will not use hard coded attributes.

Installation Directions:

  1. Install the postcode solution.
  2. Open the account or contact entity form in customisation mode.
  3. Double click on Postal Code attribute.
  4. Add new_Json2.js and new_PostCodeScript to form libraries.
  5. Call loadPostCodeRequest function from new_PostCodeScript.Save the changes and publish them.

image





















6. Import the Postcodes.

image

  • Import the file into new_postcode entity.

    Note: You can download the US postal Codes from US ZIP CODES.

    You are good to go.

    Feedback please.

Thursday, June 16, 2011

Tips for using REST endpoints in CRM 2011(Rest endpoints browser)

Using REST endpoints with json2 are the simplest way to retrieve data in CRM 2011. The code is clean and simple. Here is a sample retrieve request

retrieveAccountsReq.open("GET", getRESTUrl() +

"/new_postcodeSet?$top=20&$select=new_name,new_Country,new_Suburb,new_State,new_postcodeId&$filter=new_name
eq ('"
+ postcode + "')", true);


The above request is used to retrieve the custom entity (new_postcode) dataset where new_name is equal to postcode.

The result will look like this
image
To get the fieldnames for an entity you can use http://servername:portnumber/organization name/XRMServices/2011/OrganizationData.svc/entitySet

The result will look like this

image

You can even paste the query in the browser and check the result of the query. The following query will display all the records with postcode 2010.

http://tcrm2010:5555/CRM/XRMServices/2011/OrganizationData.svc/new_postcodeSet?$select=new_name,new_Country,new_Suburb,new_State,new_postcodeId&$filter=new_name

The result will look like this

image

Conclusion

REST endpoints are the best way to retrieve data on client site. You can even see the result of the query in the browser.

Happy Programming……..