Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles
(untagged)

Autonumbering in Dynamics CRM 2011

0.00/5 (No votes)
22 May 2011 1  
Learn how to create an autonumber system for custom entities in Dynamics CRM 2011.

Introduction

Out of the box, Dynamics CRM 2011 doesn't provide the functionality to create an autonumber on custom entities; this article describes my proposed solution to this.

For this demo code, we will create an autonumber required application called TracknTrace (new_trackntrace).

Prerequisites

Dynamics CRM 2011 SDK.

Create a provider for the solution, mine was named XRM with a prefix xrm. If you choose the default provider, you will have it prefixed as new, and all entities will be new_ instead of xrm_ as I have used here.

Creating the entities

The AutoNumber entity

First, create the AutoNumbering Entity as shown below:

counterEntity.png

Then create the field for holding the Counter value:

counterFields.png

The last thing to do for this entity is to add the Counter field to the form:

counterForm.png

Create a new entity in the AutoNumbering entity with the name CaseCounter and 0 in counter; this will hold the value for the incremental part of the plug-in.

counterEntity.png

The TrackNTrace Entity

Create the TrackNTrace entity:

ttEntity.png

Create the two fields; a thing to note here is xrm_SubTTNumber is a lookup on the TrackNTrace entity for looking up the parent TrackNTrace number to create a sub TT on.

ttFields.png

Last, add the two fields to the form of the TrackNTrace entity. I have added the TrackNTrace Number to the Header of the form, so nobody is able to change it, since we want all TrackNTrace numbers to be system generated.

ttForm.png

Now we have the entities ready, and we're ready to start coding.

The code

The TrackNTrace entity class

Open a command line and browse to your crm2011sdk\bin folder.

command.png

This will create the TTEntities.cs class which will hold the entities from your XRM solution, including the newly added xrm_AutoNumbering and xrm_TrackNTrace.

The creation of the plug-in

Open Visual Studio and create a new Class Project.

Add Microsoft.crm.sdk.proxy.dll and microsoft.xrm.sdk.dkk from the SDKFolder\bin folder. Add System.Runtime.Serialization from the .NET list in "Add Reference". It should look like this:

ClassProject.png

Add the newly generated TTEntities.cs to the project. By default, this will be located in the SDKFolder\bin folder.

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

namespace AutoNumber
{
  public class AutoNumber : IPlugin
  {
    public void Execute(IServiceProvider serviceProvider)
    {
      var context = (IPluginExecutionContext)serviceProvider.GetService(
                        typeof(IPluginExecutionContext));
      IOrganizationServiceFactory factory = 
        (IOrganizationServiceFactory)serviceProvider.GetService(
         typeof(IOrganizationServiceFactory));
      ITracingService tracingService = 
        (ITracingService)serviceProvider.GetService(typeof(ITracingService));

      if (context.InputParameters.Contains("Target") && 
          context.InputParameters["Target"] is Entity)
      {
            // Obtain the target entity from the input parmameters.
            Entity entity = (Entity)context.InputParameters["Target"];
            //Verify that the target entity represents an account.
            // If not, this plug-in was not registered correctly.
            if (entity.LogicalName == "xrm_trackntrace")
            {
                // An accountnumber attribute should not already exist because
                // it is system generated.

                if (entity.Attributes.Contains("xrm_ttnumber") == false)
                {
                    IOrganizationService service = 
                      factory.CreateOrganizationService(context.UserId);
                    OrganizationServiceContext orgContext = 
                      new OrganizationServiceContext(service);
                    if (entity.Attributes.Contains("xrm_subttnumber") == true)
                    {
                        var ttGuid = ((EntityReference)entity["xrm_subttnumber"]).Id;
                        //Grab case to create subcase on
                        var subTT = (from CN in orgContext.CreateQuery<xrm_trackntrace>()
                            where CN.Id == ttGuid
                            select CN).First();

                            //Check for existing sub TT numbers
                            var checkForCounter = 
                              from entry in orgContext.CreateQuery<xrm_autonumbering>()
                              where entry.xrm_name == subTT.xrm_TTNumber
                              select entry;
                            int i = 0;
                            foreach (var t in checkForCounter)
                            {
                                i++;
                            }
                            //if sub tt doesnt exist, create counter for sub tt
                            if (i == 0)
                            {
                                var counter = new xrm_autonumbering()
                                {
                                    xrm_name = subTT.xrm_TTNumber,
                                    xrm_Counter = 0
                                };
                                orgContext.AddObject(counter);
                                orgContext.SaveChanges();
                            }
                            // read from sub tt and tt number and set
                            // this number as TTNUBMER - SUBTTNUMBER on the form. Save changes
                            var subCounter = checkForCounter.First();
                            var sub = subCounter.xrm_Counter + 1;
                            var main = subTT.xrm_TTNumber;
                            entity.Attributes.Add("xrm_ttnumber", main + "-" + sub.ToString());

                            subCounter.xrm_Counter = sub;
                            orgContext.UpdateObject(subCounter);
                            orgContext.SaveChanges();
                        }
                        else
                        {
                            //if no sub tt has been selected create new, grab counter
                            //from CaseCounter entry and add 1, save after this
                            var query = from CN in orgContext.CreateQuery<xrm_autonumbering>()
                                where CN.xrm_name == "CaseCounter"
                                select CN;
                            foreach (var entry in query)
                            {
                                var t = entry.xrm_Counter + 1;
                                entity.Attributes.Add("xrm_ttnumber", t.ToString());
                                entry.xrm_Counter = t;
                                orgContext.UpdateObject(entry);
                                orgContext.SaveChanges();
                            }
                        }
                    }
                }
                else
                {
                    throw new InvalidPluginExecutionException(
                       "TrackNTrace Number can only be set by the system.");
                }
            }
        }
    }
}

The source code and the CRM 2011 solution are in the Zip file.

Disclaimer

The code might not be the most beautiful and aesthetic ever seen, but it works and it will give you an idea of how to accomplish this task.

History

  • 11 May 2011 - Initial release.
  • 22 May 2011 - Smaller typo update.

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here