[VS2008 – WWF – MOSS 2007] ¿Cómo crear tareas paralelas en MOSS 2007 desde Visual Studio 2008 ?

Introducción

En  un artículo anterior publiqué cómo crear una tarea en MOSS 2007, en este artículo aprenderá cómo crear tareas paralelas en MOSS 2007 utilizando Visual Studio 2008 Team Developer, Visual Studio 2008 nos permite crear de manera sencilla (al estilo Microsoft) flujos de trabajo para SharePoint, para esto disponemos de plantillas de proyecto al momento de empezar con la creación del mismo, en Microsoft Office SharePoint 2007 (MOSS 2007) podemos crear tareas en serie o en paralelo, las mismas que para crearlas las podemos hacer utilizando diferentes herramientas disponibles en el toolbox de Visual Studio 2008, en esta ocasión utilizaremos el replicator para la creación de las actividades en paralelo.

Les recomiendo leer el artículo anteriormente mencionado y descargar su código ya que reutilizaremos el ejemplo anterior para la creación de las tareas. El código fuente del presente artículo lo pueden descargar de aquí: 

Descargar código Fuente.

Software Requerido

  • Windows Server 2003 o superior
  • Microsoft Office SharePoint 2007 (instalación stand alone)
  • Visual Studio 2008 Team Developer

  

Desarrollo

Empiece abriendo Visual Studio 2008 y agregando un nuevo proyecto a la solución anterior.

001

De la lista de Tipos de Proyectos seleccione Workflow y luego de la lista de plantillas SharePoint 2007 Sequential Workflow, le asigna un nombre a su proyecto y de clic en Ok.

002

Visual Studio 2008 iniciará un asistente, el cual en esta primera ventana deberá asignarle el nombre  de su flujo de trabajo que desea que aparezca en SharePoint, e ingresar la url del sitio sobre el cual va a publicar el flujo de trabajo, Visual Studio 2008 en plataformas de 32 bits le permite publicar y hacer debug de sus flujos de trabajo para MOSS 2007, para lo cual utilizará la url proporcionada en este paso.

003

Si usted desea puede marcar para que automáticamente se asocie el flujo de trabajo que va a desarrollar con una librería en particular, caso contrario lo puede realizar manualmente utilizando comandos. Para la asociación automática debemos tener claro que significa cada elemento listado en este paso del asistente. El flujo de trabajo se debe asociar a una lista, esta lista será quien inicie el flujo de trabajo bajo ciertas condiciones, la lista de historial me permitirá almacenar toda la información relacionada al flujo de trabajo, por ejemplo: cuando inicio el flujo, cierta actividad, cuanto terminó, quién la terminó, etc., por último tenemos que seleccionar la lista de tareas, en esta lista el flujo de trabajo creará las tareas que nosotros le indiquemos. Antes de continuar y una vez entendido lo anterior pensemos en el siguiente escenario: Tenemos una librería de documentos que cada vez que se modifique un documento este deba ser aprobado por la persona X, persona Y o persona Z (esto implica que cualquiera de dichos usuarios puede aprobar el documento, es decir, estamos hablando de un flujo de aprobación en paralelo), para que dichos usuarios se enteren de que deben aprobar el documento debemos crear tareas y asignárselas para esto utilizaremos la lista de tareas.

004

En este paso final del asistente debemos seleccionar cuando queremos que el flujo de trabajo se inicie, basándonos en el ejemplo anterior debería seleccionar cuando el elemento cambie, pero en este caso yo quiero iniciar el flujo manualmente, razón por la cual selecciono sólo la primera acción.

005

Una vez terminado el asistente se abrirá el diseñador del flujo, recuerden que para la creación de una tarea utilizaremos el ejemplo publicado en el artículo anterior, por lo cual debemos a este proyecto agregar la referencia al mismo.

006 

En la ventana de referencias seleccione de proyectos BasicTaskActivity.

007

En ese momento en el toolbox veremos el componente WssTaskActivity, pero antes de agregarlo debemos insertar en el flujo de trabajo el componente que realizará la creación de las tareas en paralelo, para lo cual seleccionen el componente replicator y llévenlo hacia el área de trabajo, luego seleccionen WssTaskActivity e insértenlo dentro del replicator.

 

008

La siguiente es la vista del flujo de trabajo con el replicator insertado. Le damos doble clic sobre el componente onWorkflowActivated1, para proceder a inicializar variables.

009

Una vez realizado lo anterior, vamos al código del flujo de trabajo y defina las siguientes variables públicas:

//Contendrá la lista de aprobadores.
public IList approversList;
//Bandera que se utilizará para determinar si la tarea actual
//fue completada o no, por defecto es falso.
public bool isActualTaskCompleted = false;
 

En este ejemplo quemaremos en el código la lista de aprobadores, pero debemos tener en cuenta que los aprobadores los podemos obtener de cualquier objeto.

 

private void onWorkflowActivated1_Invoked(object sender, ExternalDataEventArgs e)
{
   approversList = new ArrayList();
   approversList.Add("igec\ffagas");
   approversList.Add("igec\user1a");
   approversList.Add("igec\user2a");
}

Una vez inicializada la lista de aprobadores regresamos a la vista de diseño del flujo de trabajo y procedemos a configurar las propiedades del replicator, lo primero que debemos hacer es vincular la variable approversList con la propiedad InitialChildData, el replicator utilizará esta lista para la creación de las actividades, veamos al replicator como un foreach, lo que implica que no debemos programar el avance al siguiente elemento de la lista, el replicator permite dos tipos de iteraciones en serie o en paralelo, por defecto está en serie, procedamos a cambiarlo a paralelo.

010

Luego, procedemos a programar los siguientes métodos del replicator, para lo cual en la lista de propiedades ingrese el nombre del método y enter, automáticamente el VS abrirá la vista de código del flujo:

 

private void ParallelChildInitialized(object sender, ReplicatorChildEventArgs e)
{
  /* Debemos hacer un cast de la actividad que está actualmente instanciada

con la actividad que creamos en el proyecto anterior, para

poder tener acceso

a las propiedades públicas de la misma. Estas propiedades

nos permitirán asignar a un usuario,

     la descripción, título, ID (es un GUID), y el campo de estado de la tarea.
  */
  //Recuerde que los usuarios a los que se va a asignar la tarea se encuentran en la lista,
  //entonces debe hacer referencia al dato actualmente instanciado y asignarselo al campo público de la actividad.
  (e.Activity as BasicTaskActivity.WssTaskActivity).strAsignadoA = e.InstanceData.ToString();
  (e.Activity as BasicTaskActivity.WssTaskActivity).strDescripcion = "Demo Tarea Paralelas";
  (e.Activity as BasicTaskActivity.WssTaskActivity).strTitulo = "Demo Tarea Paralela";
  (e.Activity as BasicTaskActivity.WssTaskActivity).taskId = Guid.NewGuid();

// Para obtener información de una columna de sharepoint la debemos instanciar por su GUID,

para lo cual utilizaremos las propiedades del flujo,

// instanciamos la lista de tareas, luego sus campos y le pasamos como

parametro el nombre que se muestra en sharepoint

// en este caso me interesa conocer la información del campo estado, y obtengo su ID (GUID)

que utilizará el WssTaskActivity para obtener la información

  // del estado actual de la tarea 

(e.Activity as BasicTaskActivity.WssTaskActivity).idCampoEstado =

workflowProperties.TaskList.Fields["Estado"].Id;

}

 

 private void ParallelChildCompleted(object sender, ReplicatorChildEventArgs e)
        {

// Validamos cada vez que se complete una actividad hija del

replicator el estado actual de la tarea

// si la tarea fue completada, cambiamos el estado de la

variable isActualTaskCompleted a True.

            if ((e.Activity as BasicTaskActivity.WssTaskActivity).esTareaCompletada)
            {
                this.isActualTaskCompleted = true;
            }
        }

 


/*Este método corresponde a la condición del replicator,

debe seleccionar en el tipo de condición (Until Condition)

código, y luego insertar el siguiente método, y le asignamos

el valor de la variable this.isActualTaskCompleted, con esto

cuando un usuario complete la tarea el flujo terminará.
*/
private void ParallelTasksNotCompleteCondition(object sender, ConditionalEventArgs e)
        {
            e.Result = this.isActualTaskCompleted;
        }

Una vez realizado lo anterior, compilamos y ejecutamos el flujo de trabajo, esto le abrirá un navegador y deberá inicializar el flujo manualmente:

011 

De la lista de flujos de trabajo seleccionamos el que acabamos de publicar y le aparecerá que la operación de inicialización está en proceso.

012

 

A continuación en el estado del flujo de trabajo veremos que se ha creado las tareas para los usuarios que configuramos en la lista

 

013

Seleccionamos cualquiera de ellas y editamos su estado

014

Seleccionamos completada. (Tenga en cuenta que si su sharepoint está en español deberá cambiar el código de la tarea personalizada), por lo siguiente:

 

private void cambiaTarea_Invoked(object sender, ExternalDataEventArgs e)
        {

string estado =

cambiaTarea_AfterProperties1.ExtendedProperties[idCampoEstado].ToString();

            if (estado != null)
            {
                if (estado.Equals("Completada"))
                    this.esTareaCompletada = true;
            }
        }

015

Luego de completar la tarea el flujo aparecerá con un estado ya no en curso sino en Finalizado.

016