Home

How to execute a Workflow from Plugin in Microsoft Dynamics CRM 2011

webmaster's picture

Este es uno de los casos más complejos de resolver en Microsoft Dynamics CRM 2011, partiendo de la base que un Workflow diseñado para una entidad no puede ser llamado desde otro workflow como un proceso secundario al cual no pertenece, encima si este workflow se tiene que ejecutar a la espera de algunos parámetros de la entidad anterior. Bueno un poco complicao de explicar técnicamente; pero a nosotros nos surgió el problema y acudimos a nuestro ingenio para resolverlo mediante el diseño de un plugin que se disparase en la actualización de la entidad origen y este llamase al workflow de la entidad destino correspondiente pasandole los parámetros necesarios para su ejecución.

En nuestro proyecto de Control de gastos de usuarios, cuando un usuario da de alta a un gasto, el Administrador del sistema, recibe una actividad de tipo tarea, con la notificación que tiene un gasto que aprobar, ya que según el sistema solo el está autorizado a Aprobar dicho gasto y en dicha tarea se encuentra la referencia al gasto que se ha dado de alta.


Pulse en la imagen para ampliar

¿Como automatizar el cierre de la tarea cuando el gasto se apruebe?

Diseñamos primeramente un workflow desde Area de Navegación en el Centro de procesos - Procesos y le llamamos CloseTaskAfterApprobalFees con la siguiente definición:


Pulse en la imagen para ampliar

Los datos mas importantes del workflow son los siguientes:

  1. Que va ser un proceso a petición: Por que va a ser llamado desde otro workflow a peticion del usuario. No es automático. Véase como en la parte de Iniciar a: se encuantra desmarcada.
  2. Adjudicado a la Entidad Tarea y de Categoría. Flujo de trabajo
  3. Los pasos a seguir son:
  • Comprobar el estado del gasto: Se verifica el campo "Referente a" que contiene la referencia a la entidad Gastos y dentro de el comprobar si el campo Aprobado = Si
  • Complatar la tarea: Pasa la tarea al estado "Completada" en caso de que al paso anterior se cumpla.

Una vez creado el workflow, se Activa, para que este disponible en el sistema. Arriba aparece  Desactivar porque ya ha sido activado. En caso de que diseñe el workflow desde una solución deberá pubicar los cambios hechos para que este de la misma forma disponible en el sistema.

Posteriormente diseñamos el Plugin llamado "CrmVerifyTask" desde Visual Studio 2012 como herramienta habitual, como un nuevo projecto de teniendo en cuenta algunos aspectos importantes como son:

  1. Proyecto de tipo: Microsoft Dynamics CRM 2012 Plugin. Esto conlleva la asignacion de las librerias necesarias del SDK.
  2. Confeccionamos una nueva firma para nuestro PlugIn en las propiedades del proyecto.
  3. Realizamos una conexion al servidor mediante la herramienta Conectar a Dynamics CRM Server para taernos el esquema de entidades de nuestra solución o de la solución predeterminada.
  4. A través del botón derecho sobre las Entidades del Explorador de Soluciones CRM escogemos Generate Wrapper que nos creará un fichero Entity.cs  con la definición de todas las clases del CRM para poder realizar consultas de tipo EarlyBound.
  5. Por ultimo generamos en la clase primaria el código necesario para conectarnos que publicamos mas abajo con los comentarios correspondientes para su entendimiento.


Pulse en la imagen para ampliar

 

El código del Plugin:

using System;
using Microsoft.Xrm.Sdk;
using Microsoft.Xrm.Sdk.Query;
using Entities;
using Microsoft.Crm.Sdk.Messages;  // Usa el Name espace incorporado con todas las Entities.
using System.Linq;
 
namespace CrmVerifyTask
{
    // Nombre:  CrmVerifyTask
    // Description: Lanza el WorkFlow CloseTaskAfterApprobalFees desde la entidad new_gastos
 
    public class CrmVerifyTask : IPlugin
    {
        #region Execute // Metodo inicial obligatorio para las ejecuciones del plugin
 
        public void Execute(IServiceProvider serviceProvider)  // Cuando se realice la ejecución CRM nos devuelve un IServiceProvider
        {
            // Dentro del recogemos un objeto que es el de tipo IPluginExecutionContext
            IPluginExecutionContext context = (IPluginExecutionContext)serviceProvider.GetService(typeof(IPluginExecutionContext));
 
            // El factory sirve para recoger elservicio de CRM y poder realizar las operaciones de mantenimiento 
            IOrganizationServiceFactory factory = (IOrganizationServiceFactory)serviceProvider.GetService(typeof(IOrganizationServiceFactory));
            IOrganizationService service = factory.CreateOrganizationService(context.UserId); // Muy iimportante que se ejecute con el usuario que está autenticado
 
            // El ITracingService nos sirve para añadir trazas al pluing para depurar los errores.
            ITracingService tracingService = (ITracingService)serviceProvider.GetService(typeof(ITracingService));
 
            if (context.InputParameters.Contains("Target") && context.InputParameters["Target"] is Entity)
            {
                // Obtain the target entity from the input parameters.
                Entity entity = (Entity)context.InputParameters["Target"];
 
                // Verify that the target entity represents an new_gastos activity. 
//If not, this plug-in was not registered correctly.
                if (entity.LogicalName != "new_gastos")
                    return;
 
                try
                {
                    // To take de Id of the actual Entity and process to get the Id of the relation task
                    Guid IdTask = new Guid();
                    ServiceContext svcContext = new ServiceContext(service);
                    try {
                        var query = from tarea in svcContext.TaskSet
                                    where (Guid)tarea.RegardingObjectId.Id == entity.Id
                                    select new
                                    {
                                        Idtask = tarea.Id
                                    };
                        foreach (var reg in query)
                        {
                            IdTask = reg.Idtask;
                        }
                    }
                    catch (Exception ex) { string error = ex.ToString(); }
 
                    //Declaramos la variable que ejecuta el workflow
                    ExecuteWorkflowRequest req = new ExecuteWorkflowRequest();
 
                    //specify the guid of the workflow to execute.
                    req.WorkflowId = new Guid("763EB1C5-8D4D-43DC-89C9-FEC15B0A459C"); 
                    //specify the guid of the related entity instance
                    req.EntityId = IdTask ;
                    ExecuteWorkflowResponse resp = (ExecuteWorkflowResponse)service.Execute(req);
                }
 
                catch (Exception ex)
                {
                    tracingService.Trace("CrmVerifyTask: {0}", ex.ToString());
                    throw;
                }
            }
 
        }
        #endregion Execute
    }
}

Una vez codificado nuestro plugin, pasamos a la fase de registro con la herramienta del SDK PlugIn Registration Tool. Con esta herramienta, después de haber realizado la conexión con el CRM 2011, añadimos la dll creada desde Visual Estudio y elejimos la form en que vamos a almacenarla.

Pulse en la imagen para ampliar

Los datos más importantes en la fase del registros están en la definición del paso que hay que añadir a continuación del registro, ya que éste debe estar definido en la operación Update de la entidad y que se ejecute de forma Asincrona en el Server.


Pulse en la imagen para ampliar

De esta forma cuando el usuario Administrador del sistema apueba los gastos, todas las tareas relacionadas con los mismos se completan de forma automática y desaparecen de la lista de tareas pendientes pasando al estado de completadas.

Pulse en la imagen para ampliar
 

 

Fuente: 

Centro Práctico de LEMURSOLUTION & Knowledge Base de Microsoft Dynamicsn CRM 2011

Contacto: 
webmaster