Rechercher dans ce blog

Suivez-moi par Email

Affichage des articles dont le libellé est Workflow. Afficher tous les articles
Affichage des articles dont le libellé est Workflow. Afficher tous les articles

dimanche 7 septembre 2014

Numérotation automatique par workflow : Différents paramétrages possibles

Suite de l'article : Numérotation automatique par workflow : Activité de workflow personnalisée

Rappel :
Dans l'article précédent, nous avons créé une activité de workflow personnalisée pour générer une numérotation automatique. Dans cette article, nous allons décrire les différents paramétrages possibles de numérotation.

1/ Préfixe-000001-Suffixe

Paramétrage :
 Résultat :

2/ 000001-Suffixe

Paramétrage :
 Résultat :

3/ Préfixe-000001

Paramétrage :
 Résultat :


4/ 000001

Paramétrage :
 Résultat :


5/ Modification de la taille du numéro incrémental

Paramétrage :

Résultat :

Paramétrage :
 Résultat :

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.

samedi 6 septembre 2014

Numérotation automatique par workflow temps réel vs Plugin

Je me suis inspiré de l'article : Auto-Numbering with CRM Workflows: Real-Time vs. Asynchronous.

1/ Création d'une entité Compteur. On ajoute les attributs :
  • Entité : Chaîne de caractères
  • Préfixe : Chaîne de caractères
  • Numéro : Décimal
  • Suffixe : Chaîne de caractères
 
 Ce qui donne :

2/ Création d'une relation 1:N entre l'entité où l'on souhaite la numérotation (dans cet exemple, elle se nomme Maison) et l'entité compteur.

3/ Création du Workflow temps réel
La première étape permet de lier l'enregistrement à l'enregistrement Compteur.
 La seconde étape renseigne le numéro.
La dernière étape incrémente la valeur au niveau du compteur.
4/ Activer le workflow et regardons les résultats après des essais d'import de fichier.

 Comparons maintenant les performances d'intégration de données entre la numérotation automatique par workflow temps réel et par plugin avec un chargement de 100 enregistrements importés en utilisant la fonction CreateRequest.

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

Pour réaliser un compteur générique qui possèdent à la fois un impact minimum sur le chargement de données et tout en ayant un paramétrage aisé, il faut donc utiliser une activité de workflow personnalisée appelée depuis un workflow temps réel. Ce sera le sujet du prochain article.

mardi 20 août 2013

Workflow : Prévenir le responsable de comptes qu'une note a été ajoutée

Un responsable de compte doit être au courant des événements affectant ses comptes par d'autres intervenants. L'article se focalise sur la création d'une note.

Pour répondre à cette problématique, nous allons créer un workflow pour prévenir le responsable de compte qu'une note a été ajoutée à un de ses comptes.

Créer un Processus de catégorie Workflow sur l'entité Note.