, , ,

Hello Everyone,

Today I will show you how to create a Personalized Auto Number for an Entity. I know you must have already gone through various Auto Number Plugins. But when I talk about Personalized ; Its based on a certain condition with the Auto-Number Format set as a number with Left Padding with Digits(0) & attached to a Prefix.

To begin with : Firstly, I created an Auto-Number Entity with Attributes like Name, Prefix and Number.


Then I wrote a simple plugin which would check for the specific condition to meet and then only the Auto Number is assigned to that particular Account. ( In my case the specific condition was to check whether the Account is Retail Client or not through a check-box)

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

using Microsoft.Xrm.Sdk;
using Microsoft.Xrm.Sdk.Client;
using Microsoft.Xrm.Sdk.Query;
using Microsoft.Xrm.Sdk.Messages;
using Microsoft.Xrm.Sdk.Discovery;
using Microsoft.Crm.Sdk.Messages;
using System.ServiceModel;

namespace AutoNumber
    public class Class1:IPlugin
        IOrganizationService service;
        public void Execute(IServiceProvider serviceProvider)
            IPluginExecutionContext context = (IPluginExecutionContext)serviceProvider.GetService(typeof(IPluginExecutionContext));
            IOrganizationServiceFactory serviceFactory = (IOrganizationServiceFactory)serviceProvider.GetService(typeof(IOrganizationServiceFactory));
            IOrganizationService service = serviceFactory.CreateOrganizationService(context.UserId);

            if (context.InputParameters.Contains("Target") && context.InputParameters["Target"] is Entity)
                Entity entity = (Entity)context.InputParameters["Target"];

                if (entity.LogicalName == "account")
                    if (entity.Contains("new_isretail"))
                        if (((Boolean)entity.Attributes["new_isretail"]) == true)
                                var fetchXml = "<fetch version='1.0' output-format='xml-platform' mapping='logical' distinct='false'>";
                                fetchXml += "<entity name='new_autonumber'>";
                                fetchXml += "<attribute name='new_autonumberid' />";
                                fetchXml += "<attribute name='new_prefix' />";
                                fetchXml += "<attribute name='new_number' />";
                                fetchXml += "<filter type='and'>";
                                fetchXml += "<condition attribute='new_name' operator='eq' value='" + entity.LogicalName + "' />";
                                fetchXml += "</filter>";
                                fetchXml += "</entity>";
                                fetchXml += "</fetch>";
                                var result = service.RetrieveMultiple(new FetchExpression(fetchXml));
                                if (result.Entities.Count > 0)
                                    Guid AutoNumberId = ((Guid)result.Entities[0].Attributes["new_autonumberid"]);
                                    String Prefix = ((String)result.Entities[0].Attributes["new_prefix"]);
                                    String Number = ((String)result.Entities[0].Attributes["new_number"]);

                                    Int32 No = Convert.ToInt32(Number);
                                    No = No + 1;

                                    String ACCcode = Prefix + (Convert.ToString(No)).PadLeft(6, '0');

                                    ColumnSet attributes1 = new ColumnSet(new string[] { "accountid", "new_accountno" });
                                    Entity acc = service.Retrieve("account", entity.Id, attributes1);
                                    if ( !(acc.Contains("new_accountno")) ) // To check if AccountNo doesnot already contain any data.  
                                        acc.Attributes["new_accountno"] = ACCcode;

                                        ColumnSet attributes2 = new ColumnSet(new string[] { "new_number" });
                                        Entity ano = service.Retrieve("new_autonumber", AutoNumberId, attributes2);
                                        ano.Attributes["new_number"] = Convert.ToString(No);

                            catch (Exception ex)
                                throw new InvalidPluginExecutionException("An error occured in plugin. " + ex, ex);




I registered the above plugin on Create message of the Account with execution pipeline stage as ‘Post-Operation’. And on Update message of the Account with Filtering Attributes set to ‘new_isretail’ and execution pipeline stage as ‘Post-Operation’. So that even when a existing account is updated to Retail Client then also an Account No is given to it.


In my above code I used the following:

Entity acc = service.Retrieve("account", entity.Id, attributes1);
if ( !(acc.Contains("new_accountno")) )  // To check if AccountNo doesnot already contain any data.

Retrieve only fetches those columns which contains data and have been updated. So in case of saving a new account, the Account number will definitely be empty and the condition will be true. But In case of account update with field IsRetail, Account No already contains a data during update then this plugin will move out to else condition and wouldn’t update autonumber on update of the check-box ‘IsRetail’ .


In the following way Autonumber entity can be used to set Autonumber for any entity with any set of conditions and different formats. You would just need to tweak the plugin code a bit.


Hope that would be Helpful.

Thanks !!!