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










6 comments:

Terry A. said...

Outstanding - this worked perfect for me. Thank you very much for your effort here!

Terry - Indianapolis IN

Terry A. said...
This comment has been removed by the author.
Unknown said...

cant seem to figure out the steps following "then use the plugin registration tool to register your plugin" everything is in a different language than English in the images.

Unknown said...

i have been going nuts trying to figure out what "ssb_arrangement" is????? (in english)

if someone could help me out, i would greatly appreciate it

Awad said...

"ssb_arrangement" is the entity schema name on which you want to generate the Auto Number

samali said...

I wish to show some appreciation to you just for rescuing me from this difficulty. Just after surfing throughout the search engines and obtaining opinions which were not pleasant, I believed my entire life was done. Living without the solutions to the problems you’ve solved by way of this review is a serious case, and the ones that would have in a wrong way affected my entire career if I had not come across your blog. Your actual natural talent and kindness in handling the whole lot was important. I’m not sure what I would have done if I hadn’t discovered such a point like this. It’s possible to at this time look forward to my future. Thanks for your time so much for this specialized and result oriented guide. I won’t think twice to propose the blog to anybody who ought to have guide on this topic.
best ios development