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:
Then create the field for holding the Counter value:
The last thing to do for this entity is to add the Counter field to the form:
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.
The TrackNTrace Entity
Create the TrackNTrace entity:
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.
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.
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.
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:
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)
{
Entity entity = (Entity)context.InputParameters["Target"];
if (entity.LogicalName == "xrm_trackntrace")
{
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;
var subTT = (from CN in orgContext.CreateQuery<xrm_trackntrace>()
where CN.Id == ttGuid
select CN).First();
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 (i == 0)
{
var counter = new xrm_autonumbering()
{
xrm_name = subTT.xrm_TTNumber,
xrm_Counter = 0
};
orgContext.AddObject(counter);
orgContext.SaveChanges();
}
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
{
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.