Rechercher dans ce blog

dimanche 7 septembre 2014

Numérotation automatique par workflow : Activité de workflow personnalisée

Suite de l'article : Numérotation automatique par workflow temps réel vs Plugin

Rappel de l'article précédent :
La numérotation automatique par workflow est facilement paramétrable mais son impact sur la création d'enregistrement est plus important qu'un plugin (120 % en plus).

Dans cet article, nous allons créer une activité de workflow personnalisée pour réduire le temps de traitement du workflow tout en gardant la flexibilité de paramétrage du workflow.

1/ Créer une entité Counter avec les attributs :
  • Name : Chaîne de caractères
  • Prefix : Chaîne de caractères
  • Number : Décimal
  • Number Length : Décimal
  • Suffix : Chaîne de caractères

2/ Créer l'activité de Workflow personnalisé.

En paramètre d'entrée, l'enregistrement Counter correspondant à la numérotation d'une entité.
En paramètre de sortie, la numérotation générée.

namespace AutoNumberingWorkflowActivity
{
    using System;
    using System.Activities;
    using System.ServiceModel;
    using System.Text;
    using Microsoft.Xrm.Sdk;
    using Microsoft.Xrm.Sdk.Messages;
    using Microsoft.Xrm.Sdk.Query;
    using Microsoft.Xrm.Sdk.Workflow;

    public sealed class AutoNumbering : CodeActivity
    {
        /// 
        /// Executes the workflow activity.
        /// 
        /// The execution context.
        protected override void Execute(CodeActivityContext executionContext)
        {
            // Create the tracing service
            ITracingService tracingService = executionContext.GetExtension();

            if (tracingService == null)
            {
                throw new InvalidPluginExecutionException("Failed to retrieve tracing service.");
            }

            tracingService.Trace("Entered Class1.Execute(), Activity Instance Id: {0}, Workflow Instance Id: {1}",
                executionContext.ActivityInstanceId,
                executionContext.WorkflowInstanceId);

            // Create the context
            IWorkflowContext context = executionContext.GetExtension();

            if (context == null)
            {
                throw new InvalidPluginExecutionException("Failed to retrieve workflow context.");
            }

            tracingService.Trace("Class1.Execute(), Correlation Id: {0}, Initiating User: {1}",
                context.CorrelationId,
                context.InitiatingUserId);

            IOrganizationServiceFactory serviceFactory = executionContext.GetExtension();
            IOrganizationService service = serviceFactory.CreateOrganizationService(context.UserId);

            try
            {

                //Create a request
                RetrieveRequest _retrieveRequest = new RetrieveRequest();
                _retrieveRequest.ColumnSet = new ColumnSet(new string[] { "new_prefix", "new_number","new_numberlength","new_suffix" });
                _retrieveRequest.Target = Counter.Get(executionContext);

                //Execute the request
                RetrieveResponse _retrieveResponse = (RetrieveResponse)service.Execute(_retrieveRequest);

                //Retrieve the Counter Entity
                Entity _counterRecord = _retrieveResponse.Entity as Entity;

                StringBuilder _sbuilder = new StringBuilder();
                if (_counterRecord.Contains("new_prefix"))
                {
                    _sbuilder.Append((String)_counterRecord["new_prefix"]);
                    _sbuilder.Append("-");
                }
                if (_counterRecord.Contains("new_numberlength"))
                {
                    _sbuilder.AppendFormat(String.Concat("{0:D", (int)(Decimal)_counterRecord["new_numberlength"], "}"), (int)(Decimal)_counterRecord["new_number"]);
                }
                else 
                {
                    _sbuilder.AppendFormat("{F0}",(Decimal)_counterRecord["new_number"]);
                }
                if (_counterRecord.Contains("new_suffix"))
                {
                    _sbuilder.Append("-");
                    _sbuilder.Append((String)_counterRecord["new_suffix"]);
                }

                //Set the variable
                Number.Set(executionContext, _sbuilder.ToString());

                //Increment
                decimal _value = (Decimal)_counterRecord["new_number"];

                Entity _updateCounter = new Entity("new_counter");
                _updateCounter.Id = _counterRecord.Id;
                _updateCounter["new_number"] = _value + 1;
                service.Update(_updateCounter);


            }
            catch (FaultException e)
            {
                tracingService.Trace("Exception: {0}", e.ToString());

                // Handle the exception.
                throw;
            }

            tracingService.Trace("Exiting Class1.Execute(), Correlation Id: {0}", context.CorrelationId);
        }

        [RequiredArgument]
        [Input("Select Counter Record")]
        [ReferenceTarget("new_counter")]
        public InArgument Counter { get; set; }

        [Output("Number")]
        public OutArgument Number { get; set; }

    }
}

3/Importer cette assembly dans la solution.

4/Création du workflow.

La première étape permet de renseigner l'enregistrement pour la numérotation.
 La seconde étape modifie l'attribut sur l'enregistrement cible avec le champ retourné par l'activité de workflow.
Après activation du workflow, voici les tests.


Tableau de comparaison pour un chargement de 100 enregistrements par la méthode CreateRequete.

Type de compteurDurée en msRemarque
Workflow temps réel7583Impossible de définir la longueur du nombre incrémental
Plugin3450Trop spécifique à l'entité cible
Activité de workflow5060Paramétrable à souhait

L'utilisation d'une activité de workflow personnalisé permet de réduire le temps d'exécution de 30 %. De plus, le paramétrage du compteur est plus souple et permet d'ajouter une numérotation automatique sur n'importe quelle entité. Le prochain article décrira les différentes possibilités de numérotation.

Aucun commentaire:

Enregistrer un commentaire