Showing posts with label autonumber. Show all posts
Showing posts with label autonumber. Show all posts

Monday, September 10, 2012

Set Auto numbering Format CRM 2011

You can control the prefix and suffix to certain extent for system entities in CRM 2011.
Navigate to Settings ->Administration ->Auto-Numbering.


Note: This option is available only for system entities. If you want to use autonumbering for custom entities or use a different format for system entities, refer to this post "Auto number in CRM 2011"

Tuesday, March 20, 2012

Auto number Plugin

Thanks to Atif for the inspiration




Heltall - whole number
En linje med tekst -single line of text


Open visual studio 2010
Create a new project for classlibrary


Add referenced to the below DLLs
microsoft.crm.sdk.proxy
microdsoft.xrm.sdk
System.Runtime.Serialization





You can find these dlls in the SDK\bin folder. Dowload the SDK from microsoft website



 

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


namespace AutoNumber
{
    public class AutoNumberPlugin : IPlugin
    {
        public void Execute(IServiceProvider serviceProvider)
        {
            System.Threading.Mutex mtx = null;
            String debugText = "Inside Execute \n";
            try
            {
                Microsoft.Xrm.Sdk.IPluginExecutionContext context = (Microsoft.Xrm.Sdk.IPluginExecutionContext)
                    serviceProvider.GetService(typeof(Microsoft.Xrm.Sdk.IPluginExecutionContext));
                if (context.InputParameters.Contains("Target") &&
                context.InputParameters["Target"] is Entity)
                {
                    Entity entity = (Entity)context.InputParameters["Target"];
                    debugText = debugText + "Inside if loop - targe \n";

                    IOrganizationServiceFactory serviceFactory = (IOrganizationServiceFactory)serviceProvider.GetService(typeof(IOrganizationServiceFactory));
                    IOrganizationService service = serviceFactory.CreateOrganizationService(context.UserId);

                    string fetchXml = @"<fetch mapping='logical'>
                                                <entity name='ssb_autonumber'><all-attributes/>
                                                    <filter type=""and"">
                                                            <condition attribute=""ssb_entityname"" operator=""eq"" value='" + entity.LogicalName + "'" + " /></filter></entity></fetch>";


                    string mutextName = string.Format("{0}{1}", entity.LogicalName, "Autonumber");
                    mtx = new System.Threading.Mutex(false, mutextName);

                    mtx.WaitOne();

                    //get hold on the mutex and only release it after update was done ot the ssb_counter entity
                    // not sure if this will work in a multi server environment
                    debugText = debugText + "Before executing fetch \n";
                    EntityCollection result = service.RetrieveMultiple(new FetchExpression(fetchXml));
                    debugText = debugText + "After executing fetch \n";
                    string nextIncrementNumber = string.Empty;
                    if (result.Entities.Count == 1)
                    {
                        debugText = debugText + "inside the if loop - enitities \n";
                        //retrieve the counter
                        Entity autoNumber = result.Entities[0];
                        if (!autoNumber.Attributes.Contains("ssb_counter"))
                            throw new InvalidPluginExecutionException("ssb_counter must contain a value");
                        if (!autoNumber.Attributes.Contains("ssb_incrementunit"))
                            throw new InvalidPluginExecutionException("ssb_incrementunit must contain a value");
                        debugText = debugText + "get values \n";
                        int counter = Int32.Parse(autoNumber.Attributes["ssb_counter"].ToString());
                        int incrementUnit = Int32.Parse(autoNumber.Attributes["ssb_incrementunit"].ToString());
                        string prefix = autoNumber.Attributes.Contains("ssb_prefix") ? autoNumber.Attributes["ssb_prefix"].ToString() : string.Empty;
                        string prefixSeparator = autoNumber.Attributes.Contains("ssb_prefixseparator") ? autoNumber.Attributes["ssb_prefixseparator"].ToString() : string.Empty;
                        string suffix = autoNumber.Attributes.Contains("ssb_suffix") ? autoNumber.Attributes["ssb_suffix"].ToString() : string.Empty;
                        string suffixseparator = autoNumber.Attributes.Contains("ssb_suffixseparator") ? autoNumber.Attributes["ssb_suffixseparator"].ToString() : string.Empty;
                        string numberFormatter = autoNumber.Attributes.Contains("ssb_numberformatter") ? autoNumber.Attributes["ssb_numberformatter"].ToString() : string.Empty;
                        string fieldToUpdate;
                        if (autoNumber.Attributes.Contains("ssb_entityautonumberfield"))
                            fieldToUpdate = autoNumber.Attributes["ssb_entityautonumberfield"].ToString();
                        else
                            throw new InvalidPluginExecutionException("ssb_entityautonumberfield should not be emplty");
                        debugText = debugText + "before calling buld number \n";
                        nextIncrementNumber = BuildAutoNumber(prefix, prefixSeparator,
                            suffix, suffixseparator, counter, incrementUnit, numberFormatter);
                        debugText = debugText + "after calling build number \n" + nextIncrementNumber;
                        //increment the autonumber entity
                        //and update it to record the counter
                        debugText = debugText + "before calling update (autonumber)\n";
                        autoNumber.Attributes["ssb_counter"] = counter + incrementUnit;
                        service.Update(autoNumber);

                        debugText = debugText + "before calling update (entity) \n";
                        entity.Attributes.Add(fieldToUpdate, nextIncrementNumber);
                        //entity.Attributes[fieldToUpdate] = nextIncrementNumber;
                        // service.Update(entity);

                    }
                }
            }
            catch (Exception ex)
            {
                if (mtx != null)
                {
                    mtx.ReleaseMutex();
                    mtx = null;
                }

                // throw new InvalidPluginExecutionException("An error occured in Autonumber plugin", ex);
                throw new InvalidPluginExecutionException("An error occured in Autonumber plugin" + ex + "\n" + debugText);

            }
            finally
            {
                debugText = null;
                if (mtx != null)
                    mtx.ReleaseMutex();
            }
        }

        private string BuildAutoNumber(string prefix, string prefixSeparator, string suffix, string suffixSeparator, int counter, int incrementUnit, string numberFormatter)
        {
            bool hasPrefix = false, hasSuffix = false;

            string returnNumber = string.Empty;

            if (!string.IsNullOrEmpty(prefix))
            {
                hasPrefix = true;
            }
            if (!string.IsNullOrEmpty(suffix))
            {
                hasSuffix = true;
            }
            counter = counter + incrementUnit;
            returnNumber = (hasPrefix ? prefix + prefixSeparator : "") + counter.ToString(numberFormatter) + (hasSuffix ? suffixSeparator + suffix : "");


            return returnNumber;


        }
    }
}

Build your plugin
then use the plugin registration tool to register your plugin in the create event - preoperation step