Saturday, June 22, 2013

Some things to be prepared of in the next big Release of Microsoft Dynamics CRM

Do visit the below link to know more about the changes as part of the next big release.

1. Removal of the 2007 Endpoint and Legacy Features
2. Removal of JavaScript Form Scripting Support for Microsoft Dynamics CRM 4.0 Objects and Functions
3. Changes to the Document Object Model (DOM)
4. Removal of Some Ribbon Controls
5. Microsoft Lync Presence Not Supported
6. Removal of Workplace and Personalization Options for New Customers
7. Duplicate Detection during Record Create and Update Operations Not Supported

To know more about, please do visit this: 
  • http://msdn.microsoft.com/en-us/library/dn281891.aspx
  • http://technet.microsoft.com/en-us/library/dn265924.aspx


Microsoft Dynamics CRM SDK 5.0.16 Released.


SDK 5.0.16 Released.


Things to know about the new release: You could view this in the downloaded SDK:

New and updated topics
Description of changes
Microsoft_Dynamics_CRM_2011_SDK_Readme.htm
Updated the readme for this version of the SDK package.
Active Directory and Claims-Based Authentication
Authenticate Office 365 Users with Microsoft Dynamics CRM Online Web Services
OrganizationServiceProxy
DiscoveryServiceProxy
Updated these topics to remove the restriction on using the service proxy classes when authenticating with the Microsoft online services identity provider of Microsoft Dynamics CRM Online. You can now use these proxy classes with all deployment types and identity providers.
BulkDeleteRequest
BulkDetectDuplicatesRequest
Added in Remarks that you can run the bulk delete job or bulk detect duplicates job daily or without recurrence.
Create, Export, or Import an Unmanaged Solution
Create, Install, and Update a Managed Solution
Added a note to these topics saying “Installing a solution can interfere with normal system operation. We recommend that you schedule solution imports when it’s least disruptive to users.”
Form XML Reference
The following FormXml elements have been updated to indicate that they are for internal use only: (FormXml), (FormXML), (FormXml), and (FormXml). These elements are used only in a quick form, which is not customizable. These elements will be removed from the schema in the next major release.
Handle Exceptions in Plug-Ins
Clarified how plug-in exceptions are handled and where error message are written or displayed.
Introduction to Activity Feeds
Corrected the maximum number of characters in the posts created programmatically. The correct value is 2000 characters.
Introduction to Solutions
Added the Enterprise Solution Lifecycle Management section introducing the ALM for Microsoft Dynamics CRM 2011: CRM Solution Lifecycle Management white paper.
Open Forms, Views, Dialogs and Reports with a URL
Appended to an existing note to include:
Microsoft Dynamics CRM forms are not designed to be opened as dialogs using either showModalDialog or showModelessDialog.
Uninstall or Delete a Solution
Added an Access the Solutions List with a URL section.
What’s Changing in the Next Major Release
Added a new topic to provide information about what is changing in the next major release of Microsoft Dynamics CRM.
Write Custom Code for Microsoft Dynamics CRM for Outlook
GoOffline
GoOnline
Added a note that these methods cannot be used in a plug-in because they cause a UI interaction with the user.
Xrm.Page.data.entity Attribute Methods
Added a missing getFormat return value: textarea.
Xrm.Page.ui Control Methods
Added a remark to the addCustomView method to show that this method does not work with Owner lookups.
Xrm.Utility Reference
Corrected an error for the openEntityForm method. This method returns a Boolean value rather than a window object.
                                                         

Thursday, February 28, 2013

Rollup 12 :- Pricelist Item error on Opportunity screen

In the latest roll-up 12 updates, I found an error message displaying on the opportunity screen for the missing price list. If your business not making use of the price list item an OOTB feature, one of the solution you can make use of to suppress the error message, is  by updating a price List Item using a Retrieve plugin. Keep in mind this needs to be configured as a Pre-event stage in the Plugin configuration tool. 

Code sample:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Xrm.Sdk;
using Microsoft.Xrm.Sdk.Query;

namespace Opportunity
{
    public class SetDefaultPriceList : IPlugin
    {
        public void Execute(IServiceProvider sp)
        {
            //--Trigger: Retrieve Message of opportunity
            //--Stage: Pre
            //--Method: Synchronous
            //--Filter Attributes: none
            //--Pre Attributes: none
            //--Post Attributes: none
            //--Description: Setting the the default PriceList value.
            //--Author: Chaitanya

            var tracer = (ITracingService)sp.GetService(typeof(ITracingService));
            var context = (IPluginExecutionContext)sp.GetService(typeof(IPluginExecutionContext));

            if (context.MessageName == "Retrieve" && context.PrimaryEntityName == "opportunity")
            {
                var factory = (IOrganizationServiceFactory)sp.GetService(typeof(IOrganizationServiceFactory));
                IOrganizationService service = factory.CreateOrganizationService(null);

                Guid priceListId = Guid.Empty;

                var priceListsEntity = GetDefaultPriceLevel(service);
                if(priceListsEntity.Entities.Count > 0)
                    if(priceListsEntity.Entities[0].Attributes.Count > 0)
                        if(priceListsEntity.Entities[0].Attributes.Contains("pricelevelid"))
                            priceListId = (Guid)priceListsEntity.Entities[0].Attributes["pricelevelid"];
                   if(priceListId != Guid.Empty)
                   {
                       var opportunity = new Entity(context.PrimaryEntityName) { Id = context.PrimaryEntityId };
                       opportunity.Attributes.Add("pricelevelid", new EntityReference("pricelevel",priceListId));
                       service.Update(opportunity);
                   }
            }
        }

        private static EntityCollection GetDefaultPriceLevel(IOrganizationService service)
        {
            var cols = new ColumnSet("pricelevelid", "name");
            var filter = new FilterExpression { FilterOperator = LogicalOperator.And };
            filter.AddCondition(new ConditionExpression("name", ConditionOperator.Equal, new object[] { "Default Price List" }));

            var query = new QueryExpression
            {
                ColumnSet = cols,
                Criteria = filter,
                EntityName = "pricelevel"
            };
            return service.RetrieveMultiple(query);
        }
    }
}
One more thing to keep in mind, Before running this code, you should have a "Default Price List" created with the same name. 

Hope this helps, 
Chaitanya...

Saturday, February 23, 2013

XRM Utility

Some quick tips on the javascript utilities:

for any reason, if the dashboard is clumsy in the real esate in displaying grid and charts, we can provide a button to view in a new tab by exploding or opening the web resource in a new tab.

Code sample:


//HTML Web Resource
Xrm.Utility.openWebResource(
    webResourceName
  ,
    webResourceData
  ,
    width
  , 
    height
  )

//Example 
//Open an HTML web resource named “new_webResource.htm”
Xrm.Utility.openWebResource("new_webResource.htm");

//Open an HTML web resource, setting the height and width
Xrm.Utility.openWebResource("new_webResource.htm", null, 500,700);

//Open an HTML web resource with the parameters expected by HTML web resources
Xrm.Utility.openWebResource("new_webResource.htm?typename=account&userlcid=1033");

//Entity Form:
Xrm.Utility.openEntityForm(
    name
  ,
    id
  ,
    parameters
  )
  
//Example
//Open a new account record
Xrm.Utility.openEntityForm("account");

//Open an existing account record
Xrm.Utility.openEntityForm("account","B85N0252-GHT8-U111-997C-99055D8A8410");

Hope this helps,
Chaitanya...

Monday, January 21, 2013

Execute Multiple Request (Rollup 12 - SDK 5.0.13)

Today, I have used the latest SDK 5.0.13 DLL to take advantage of "ExecuteMultipleRequest" for one of the bulk create and update scenario. This is really a nice SDK message for dealing with loads of data. It drastically improved the overall performance. This is mainly used for Bulk Creating, Updating and Deleting the records.
 
ExecuteMultipleRequest accepts an input collection of message Requests, executes each of the message requests in the order they appear in the input collection, and optionally returns a collection of Responses containing each message’s response or the error that occurred. Each message request in the input collection is processed in a separate database transaction.

@Developers, This is a very helpful message inclusion in the December 2012 Service updates (Rollup 12).

Here are the detailed steps with code snippet:

Create Scenario:
  • Create an Entity Collection object to hold multiple entity records.
  • Call the ExecuteMultipleRequest as in the below code snippet.
 
//Class level variable
private static EntityCollection _accountCollection = null;

//Create an instance of an entity collection
_accountCollection = new EntityCollection();

//Account object, You can use a for loop to add entity object to a collection.
for (int i = 0; i < 10; i++)
{
   var accountEntity = new Entity { LogicalName = "account" }; 
   accountEntity.Attributes.Add("name", "Test Account");

   /************************************************************/
   //accountId is a GUID of an account used only on UPDATE
     accountEntity.Attributes.Add("accountid", accountId);
   /************************************************************/

   accountEntity.Attributes.Add("accountnumber", "10010010");

   //Add an account entity to an entity collection
  _accountCollection.Entities.Add(accountEntity);
}

//Create
ExecuteCreateMultipleRequest(service, _accountCollection, tracer)

//Update : Note an entity collection records to have a GUID
ExecuteUpdateMultipleRequest(service, _accountCollection, tracer)


/// 
/// Latest SDK Message for Multiple record create
/// 
/// 
/// 
/// 
private static void ExecuteCreateMultipleRequest(IOrganizationService service, EntityCollection input, ITracingService tracer)
{
 // Create an ExecuteMultipleRequest object.
 var requestWithResults = new ExecuteMultipleRequest()
 {
  // Assign settings that define execution behavior: continue on error, return responses. 
  Settings = new ExecuteMultipleSettings()
  {
   ContinueOnError = false,
   ReturnResponses = true
  },
  // Create an empty organization request collection.
  Requests = new OrganizationRequestCollection()
 };

 tracer.Trace("Survey Entity Count" + input.Entities.Count);

 // Add a CreateRequest for each entity to the request collection.
 foreach (var entity in input.Entities)
 {
  var createRequest = new CreateRequest { Target = entity };
  requestWithResults.Requests.Add(createRequest);
 }

 // Execute all the requests in the request collection using a single web method call.
 var responseWithResults = (ExecuteMultipleResponse)service.Execute(requestWithResults);
}

/// 
/// Latest SDK Message for Multiple record update
/// 
/// 
/// 
/// 
private static void ExecuteUpdateMultipleRequest(IOrganizationService service, EntityCollection input, ITracingService tracer)
{
 // Create an ExecuteMultipleRequest object.
 var requestWithResults = new ExecuteMultipleRequest()
 {
  // Assign settings that define execution behavior: continue on error, return responses. 
  Settings = new ExecuteMultipleSettings()
  {
   ContinueOnError = false,
   ReturnResponses = true
  },
  // Create an empty organization request collection.
  Requests = new OrganizationRequestCollection()
 };

 tracer.Trace("Survey Entity Count" + input.Entities.Count);

 // Add a CreateRequest for each entity to the request collection.
 foreach (var entity in input.Entities)
 {
  var updateRequest = new UpdateRequest { Target = entity };
  requestWithResults.Requests.Add(updateRequest);
 }

 // Execute all the requests in the request collection using a single web method call.
 var responseWithResults = (ExecuteMultipleResponse)service.Execute(requestWithResults);
}
 
The same steps would also work on Update, Delete and any other CRM requet messages.
 
In order to use the above code, you should download the latest 2011SDK_5.0.13 SDK from the below link and use the microsoft.xrm.sdk.dll available in the SDK bin folder. 
 
 
You can use them from Custom .NET application and also, from the Plugins. The Plugin's would give you better performace than running it from a custom .net application.
 
Let me know, if you have any specific scenario's in Multiple records creation/Updation/deletion?
 
I truly love this feature, this opens up a lot of opportunities in building some custom components in CRM. Just great!!!
 
Hope this helps,
Chaitanya...

Thursday, January 10, 2013

Javascript Debugging

I know, this is known to many of us, just incase any one hits a roadblock on debugging the Javascript, here are some of the good links to get started.

Java Script Debugging with the Developer Tools (F12):
http://msdn.microsoft.com/en-us/library/dd565625(VS.85).aspx

CRM 2011 Debugging:
http://social.technet.microsoft.com/wiki/contents/articles/3…

CRM Javascript Debugging in IE8:
http://www.furnemont.eu/2010/06/how-to-series-easily-debug-y…

Thanks,
Chaitanya...

Tuesday, January 8, 2013

CRM 2011 SDK 5.0.13 Released.