WorkFlow de aprobación para Sharepoint 2007 paso a paso

Hace días que estoy viendo cómo armar este artículo y mostrar cómo hacer un WorkFlow para Sharepoint 2007 utilizando Visual Studio 2005, las extensiones de WorkFlow Foundation y las extensiones para Windows Sharepoint Services, pensé mostrar un WorkFlow de aprobación para varios usuarios, donde la tarea de aprobación fuese asignada a mas de un aprobador, pero analizando me di cuenta que eso podía ser el final de todo esto y entonces decidí crear una serie de artículos que mostraran como hacer un WorkFlow paso a paso y luego ir añadiendo funcionalidades.

Para poder realizar este WorkFlow vamos a necesitar tener un ambiente de desarrollo montado de la siguiente forma, en mi caso tengo una maquina virtual con todo instalado y es la que utilizo para desarrollar soluciones para Sharepoint 2007.

1)      Windows 2003 cualquier versión con SP1 instalado.

2)      SQL Server 2005 con SP1 instalado. También podemos utilizar SQL Express 2005

3)      Framework 3.0. Necesitamos las extensiones de WorkFlow Foundation.

4)      Sharepoint 2007.

5)      Visual Studio 2005 cualquier versión.

6)      Extensiones de Windows Sharepoint Services

7)      Infopath 2007 para realizar los formularios.

Bien una vez tenemos el ambiente montado y configurado, lo que demos hacer es ponernos a construir el WorkFlow. Para lo cual abrimos el Visual Studio 2005 y creamos un nuevo proyecto basándonos en la plantilla instalada. El WorkFlow que vamos a crear en este caso es uno secuencial, en un próximo artículo vamos a crear un WorkFlow de estado. En la imagen 1 vemos la pantalla de creación de proyectos de Visual Studio donde seleccionamos el templete y le ponemos un nombre.

Imagen 1

1_Visual_Studio_Template

Una vez que tenemos creado el proyecto el Visual Studio se tiene que ver como en la imagen 2, el proyecto creado, nuestro WorkFlow creado y al abrir el mismo nos encontramos con una única actividad que nos crea el template de proyecto, la actividad  “OnWorkflowActivated” la cual es invocada cuando se inicia el WorkFlow y la podemos utilizar para inicializar propiedades, conectarnos algún repositorio de datos para extraer información.

Imagen 2
2_Workflow_Abierto

Lo que debemos hacer ahora es configurar nuestro WorkFlow, lo primero que vamos hacer es crear un “CorrelationToken”, esto es necesario para que la actividad quede vinculada a nuestro WorkFlow y el árbol de mensajes del WorkFlow quede cargado. Para realizar esto seleccionamos la actividad “OnWorkflowActivated” y en el cuadro de propiedades escribimos un nombre para la propiedad “CorrelationToken” y seleccionamos cual es la actividad padre, en este caso seleccionamos el propio WorkFlow debido a que es nuestra primera actividad, en la imagen 3 vemos como nos debería quedar cargada.

Imagen 3
3_Correlation_Token_OnActiveted

Lo próximo que debemos configurar es la propiedad “WorkflowProperties” de la actividad “OnWorkflowActivated”, la cual nos permitirá acceder a datos de donde está corriendo el WorkFlow como ser el Site, Web, List, Item al que está asociado, etc. Para ellos seleccionamos la actividad, y en el cuadro de propiedades vamos a ver la propiedad “WorkflowProperties” y presionamos el botón “…” que aparece para que se nos despliegue una ventana donde vamos a crear el valor para la misma. Esta ventana tiene dos pestañas, en una podemos seleccionar las propiedades que ya estén creadas como lo muestra la imagen 4 y en la otra pestaña podemos crear una nueva propiedad como lo muestra la imagen 5. Nosotros vamos a crear una nueva propiedad, para lo cual introducimos un nombre y presionamos OK. En este caso vamos a crear un atributo de nuestro WorkFlow y no una propiedad.

Imagen 4
4_WorkFlowProperties

Imagen 5
5_WorkFlowProperties_Bind

Una vez creado el atributo el mismo quedara cargado en la actividad y ahora vamos a crear nuestro WorkFlow de aprobación. Para ello vamos a crear 3 actividades que son de las extensiones de Windows Sharepoint Services, estas actividades, nos permitirán crear una nueva tarea de aprobación para el o los usuarios que se designen, esperar que el mismo acceda a la tarea, la aprueba o rechace y por ultimo darla por completada, las actividades que usaremos son las siguientes:

1)      CreateTask Activity: Esta actividad creara una tarea para un usuario determinado en la lista de tareas asociada al WorkFlow.

2)      OnTaskChange Activity: Esta tarea se quedara esperando que el usuario modifique la misma, o sea la apruebe o la rechace.

3)      CompleteTask Activity: Esta tarea completara la misma de forma automática.

Lo que haremos es colocar una actividad adicional en nuestro WorkFlow, esta actividad actuara como contenedora de las tres actividades mencionadas anteriormente y esto se debe a que las 3 tareas deben tener el mimo “CorrelationToken”. Así que vamos a agregar una “SecuentialActivity” para englobar a las otras 3 actividades mencionadas, la imagen 6 nos muestra cómo nos debería quedar nuestro WorkFlow después de agregar todas las actividades descriptas.

Imagen 6
6_WorkFlow

La siguiente tabla muestra cómo debemos configurar las propiedades de cada una de las actividades recién agregadas:

CreateTask:

Name: CreateTaskApproval

CorrelationToken: CreateTaskCorrelationToken

OwnerActivityName: ApprovalActivity

TaskID: CreateTaskApproval_TaskId. Para configurar esta propiedad utilizaremos la ventana mostrada en las imagenes 4 y 5. Crearemos un atributo nuevo y lo asignaremos al WorkFlow.

TaskProperties: CreateTaskApproval_TaskProperties. Para configurar esta propiedad también utilizaremos la ventana mostrada en las imágenes 4 y 5.  Crearemos un atributo nuevo y lo asignaremos al WorkFlow.

OnTaskChange:

Name: TaskChangedApproval

CorrelationToken: CreateTaskCorrelationToken. Seleccionamos el mismo creado para la actividad “CreateTask” puesto que deben ser iguales. Esto se debe a que es una unidad atómica de trabajo.

AfterProperties: TaskChangedApproval_AfterProperties. Para configurar esta propiedad utilizaremos la ventana mostrada en las imágenes 4 y 5, pero en vez de crear un atributo vamos a crear un property. Esta propiedad nos servirá para recuperar el valor modificado de una columna de la lista..

BeforeProperties: TaskChangedApproval_BeforeProperties. Para configurar esta propiedad utilizaremos la ventana mostrada en las imágenes 4 y 5, pero en vez de crear un atributo vamos a crear un property. Esta propiedad nos servirá para recuperar el valor original de una columna de la lista.

TaskID: CreateTaskApproval_TaskId. Para configurar esta propiedad utilizaremos la ventana mostrada en las imagenes 4 y 5, pero en vez de crear una nueva, lo que haremos es seleccionar el atributo creado en la actividad “CreateTask, dado que estas actividades deben tener el mismo TaskId para que queden asociadas.

CompleteTask:

Name: CompleteTaskApproval

CorrelationToken: CreateTaskCorrelationToken. Seleccionamos el mismo creado para la actividad “CreateTask” puesto que deben tener el mismo. Esto se debe a que es una unidad atómica de trabajo.

TaskID: CreateTaskApproval_TaskId. Para configurar esta propiedad utilizaremos la ventana mostrada en las imagenes 4 y 5, pero en vez de crear una nueva, lo que haremos es seleccionar el atributo creado en la actividad “CreateTask, dado que estas actividades deben tener el mismo TaskId para que queden asociadas.

TaskOutcome: Cargaremos un texto que se mostrara en la ventana del WorkFlow una vez que el mismo termine.

Una vez configuradas todas las propiedades del WorkFlow el mismo nos tiene que quedar como se muestra en la imagen 7 y ahora lo que vamos hacer colocar el código para asociar al usuario.

Imagen 7
7_WorkFlow_Configurado

Para este ejemplo lo que vamos hacer es siempre asignarle el mismo usuario, así que cada vez que se cree una tarea se le asignara un único usuario. Podemos colocar el código necesario para sacar los aprobadores de cualquier repositorio de datos o cargarlos cuando el WorkFlow se instancie. Para este primer artículo vamos a mostrar como cargarlo, en los siguientes vamos a construir un formulario que nos permitirá seleccionar los usuarios aprobadores al iniciarse el WorkFlow. Todas las actividades contienen una serie de eventos que nosotros podemos programar y que los mismos serán disparados cuando las tareas sean invocadas. En este ejemplo solo vamos a codificar el evento “MethodInvoking” de la actividad “CreateTask” y en la imagen 8 vemos como asociar el método que va a manejar dicho evento.

Imagen 8
8_MethodInvoking

En la sección 1 vemos el código para el método asociado al evento “MethodInvoking” recién creado y en el cual cargamos todas las propiedades de la tarea.

Sección 1

private void CreateTaskApproval_MethodInvoking(object sender, EventArgs e)

{

 CreateTaskApproval_TaskId = Guid.NewGuid();

 CreateTaskApproval_TaskProperties.TaskType = 0;

CreateTaskApproval_TaskProperties.AssignedTo = "sidom\fabiani";

CreateTaskApproval_TaskProperties.Title = "Tarea de aprobación para Fabian";

CreateTaskApproval_TaskProperties.Description = "Fabian debe aprobar esta tarea";

CreateTaskApproval_TaskProperties.SendEmailNotification = false;

}

Una vez que tenemos creado nuestro WorkFlow lo que tenemos que hacer es crear un formulario para aprobar o rechazar la tarea. En esta versión lo vamos hacer utilizando Infopath y el formulario lo único que tendrá será un botón para aprobar y otro para rechazar la tarea asignada al usuario. En la imagen 9 vemos el formulario creado.

Imagen 9
9_Formulario_Infopath

Una vez creado lo que tenemos que hacer es configurar el botón “Aprobar”, para lo cual vamos hacer una regla para enviar a nuestro Workflow que la tarea fue aprobada. En la imagen 10 vemos como la regla creada para el botón “Aprobar”.

 

Imagen 10
10_ReglaFormularios_Infopath

 

Por último vamos a configurar las opciones del formulario y a publicarlos en nuestro servidor de Sharepoint para que quede disponibl. Para ello en Infopath accedemos a las opciones del formulario en la opción “Herramientas” y aplicamos las siguientes configuraciones:

1) En la sección Examinar seleccionamos el idioma de nuestro formulario, en este caso Ingles puesto que el Sharepoint está en Ingles.

2) En la sección Compatibilidad seleccionamos el Checkbox “Diseñe una plantilla de formulario que se pueda abrir en el Explorador” esto nos permitirá abrir este formulario Infopath como una página Web y no necesitaremos tener Infopath instalado en la maquina cliente y en el cuadro de texto “Especifique la dirección URL…” cargamos la dirección URL del servicio Web de FormsServices, tal cual se muestra así (debe sustituir los valores correctos correspondientes a su servidor) http://<servidor>:<puerto>/_vti_bin/FormsServices.asmx. Una vez que aceptemos los cambios realizados Infopath intentara conectarse con el servidor Sharepoint y de ser necesario le deberemos proporcionar las credenciales correctas para que se conecte y nos valide el formulario.

Una vez configurado, lo que debemos hacer es publicarlo, para realizar esto accedemos a la opción de publicar del formulario Infopath presionando “Archivo” y después “Publicar”. Se nos abrirá un Wizard para realizar la publicación, en el primer paso vamos a seleccionar la opción “En un servidor de Sharepoint con o sin Infopath Forms Services”, en el segundo paso cargamos la URL de nuestro portal Sharepoint (http://<servidor>:<puerto>/), en el tercer paso seleccionamos al última opción del mismo “Plantilla de formulario aprobada por el administrador”, en el cuarto paso seleccionamos una ruta de red en el servidor donde colocaremos el formulario (En este punto vamos a colocar el formulario dentro de la carpeta “FeatureFiles “ que se encuentra en “DeploymentFiles” dentro de la raíz de nuestro proyecto y le vamos asignar un nombre, para nuestro ejemplo le asignamos “FormApprovalTaskBlog.xsn”. Nos debería quedar así “\<servidor><ruta al proyecto> DeploymentFilesFeatureFilesFormApprovalTaskBlog.xsn”), en el quinto paso damos siguiente (No vamos a crear ninguna columna personalizada para asociar a nuestro WorkFlow) y por último presionamos el botón publicar.

Ahora debemos configurar los archivos XML de configuración y realizar nuestro deploy del Workflow. Cada vez que creamos un proyecto utilizando el template de WorkFlow se nos agregan una serie de archivos XML y Bat que nos facilitaran la tarea de realizar la instalación de nuestro Workflow. En la imagen 11 vemos la estructura de archivos creada por el template de proyectos una vez creado el mismo y que a continuación detallaremos.

Imagen 11
11_Estructura_Archivos

Feature.xml: este archivo se utiliza para crear un feature en nuestro portal Sharepoint y asociar el Workflow, el cual podremos utilizar en cualquier sitio de la colección de sitios.

Workflow.xml: Este archivo declara el WorkFlow y asocia los formularios Infopath creados al mismo.

PostBuildActions.bat: Este bat es invocado por Visual Studio y realiza la instalación del Feature en nuestro Sharepoint, lo activa, instala el Assembly en al GAC y realiza un IISRESET para que los cambios sean tenidos en cuenta. Lo único que debemos hacer es editarlo y cambiar la dirección URL “http://localhost” por la dirección URL de nuestro sitio “http://<servidor>:<puerto>/”

Unistall.bat: Este archivo desinstala y desactiva el feature de nuestro portal. Lo único que debemos hacer es editarlo y cambiar la dirección URL “http://localhost” por la dirección URL denuestro sitio “http://<servidor>:<puerto>/”

Todos los demás valores utilizados por estos dos archivos Bat son pasados en el Visual Studio una vez que se termine la compilación del proyecto. En la imagen 12 vemos la pantalla de propiedades del proyecto en el Visual Studio. Si queremos que el WorkFlow sea instalado una vez terminemos de complicar debemos indicarlos colocando la palabra “DEPLOY” en el cuadro de texto “Post-Build envent command line” y si no queremos que el WorkFlow sea instalado después que terminamos de complicar colocamos la palabra “NODEPLOY” para seguir trabajando en el mismo y no se produzca una instalación cada vez que compilamos.

Imagen 12
12_Porpiedades_VisualStudio

En la sección 2 vemos el código completo para el archivo “feature.xml” y en la sección 3 vemos el código completo para el archivo “workflow.xml”.

Sección 2

<Feature Id="A93B9917-3038-4aea-8C5F-01A0F78DA4A6"

Title="Simple Approval WorkFlow"

Description="This feature is a simple approval workflow."

Version="12.0.0.0"

Scope="Site"

ReceiverAssembly="Microsoft.Office.Workflow.Feature, Version=12.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c"

ReceiverClass="Microsoft.Office.Workflow.Feature.WorkflowFeatureReceiver" xmlns="http://schemas.microsoft.com/sharepoint/">

<ElementManifests>

<ElementManifest Location="workflow.xml" />

</ElementManifests>

<Properties>

<Property Key="GloballyAvailable" Value="true" />

<!– Value for RegisterForms key indicates the path to the forms relative to feature file location –>

<!– if you don’t have forms, use *.xsn –>

<Property Key="RegisterForms" Value="*.xsn" />

</Properties>

</Feature>

El archivo feature.xml define la funcionalidad dentro de Sharepoint y asocia el archivo “workflow.xml” que es el que tiene toda la definición del WorkFlow. Básicamente nosotros debemos colocarle un guid para el ID, un nombre y una descripción, las demás propiedades las podemos dejar como nos la genera el template de proyecto del Visual Studio.

Sección 3

<Elements xmlns="http://schemas.microsoft.com/sharepoint/">

<Workflow

Name="Simple Approval WorkFlow"

Description="This simple approval workflow."

Id="45229254-E7C9-4846-8D49-D28AF6A88315"

CodeBesideClass="Siderys.Blog.SimpleApprovalWorkFlowInfopathForms"

CodeBesideAssembly="Siderys.Blog.Workflow.SimpleApprovalWorkFlowInfopathForms. SimpleApprovalWorkFlow, Version=1.0.0.0, Culture=neutral, PublicKeyToken=a82cbe50b3eab825"

StatusUrl="_layouts/WrkStat.aspx"

TaskListContentTypeId="0x01080100C9C9515DE4E24001905074F980F93160"

ModificationUrl="_layouts/ModWrkflIP.aspx">

<Categories/>

<!– Tags to specify InfoPath forms for the workflow; delete tags for forms that you do not have –>

<MetaData>

<Task0_FormURN>urn:schemas-microsoft-com:office:infopath:FormApprovalTaskBlog:-myXSD-2008-01-04T13-20-14</Task0_FormURN>

<StatusPageUrl>_layouts/WrkStat.aspx</StatusPageUrl>

</MetaData>

</Workflow>

</Elements>

En el archivo “workflow.xml” define al WorkFlow que acabamos de crear y en este archivo debemos cargar el Assembly del WorkFlow (el Assembly debe estar firmado con un Strong Name) para ello usamos la propiedad “CodeBesideAssembly”, en la propiedad “CodeBesideClass” declaramos el espacio de nombre y la clase donde esta codificado y en la propiedad “Task0_FormURN” declaramos el formulario Infopath creado, para obtener el valor para dicha propiedad abrimos el formulario Infopath utilizando Infopath 2007 en las propiedades del mismo copiamos el valor que se encuentra en la caja de texto “Id”. Podemos declarar varios formularios Infopath, tantos como necesitemos, lo único que tenemos que variar de esta propiedad es el nombre, por ejemplo si quisiéramos colocar otro formulario la propiedad debería llamarse “Task1_FormURN” y así sucesivamente. Para asociar el formulario a nuestro WorkFlow lo hacemos utilizando la propiedad “TaskType” que se encuentra en la propiedad “TaskProperties” creada para nuestra actividad “CreateTaskApproval”, en la sección 1 podemos ver la asignación de esta propiedad.

Una vez instalado nuestro WorkFlow lo que debemos hacer es asociarlo a la lista que deseamos tener aprobación de elementos. Para configurar el WorkFlow debemos acceder a la configuración de WorkFlow de la lista y presionar “Agregar WorkFlow”. En la pantalla de configuración seleccionamos nuestro WorkFlow de la lista disponible de WorkFlows, le colocamos un nombre, la lista de tareas donde vamos a estar creando las tareas, la lista histórica de movimientos y como queremos que el WorkFlow se inicialice. En la imagen 13 vemos como debería quedarnos configurado una vez cargado todos los valores y al terminar presionamos el botón Ok que asociara nuestro WorkFlow a la lista.

Imagen 13
13_WorkFlow_Asociado

Ahora tenemos asociado el WorkFlow, lo próximo que debemos hacer es crear un elemento en la lista y el WorkFlow se dispara dado que lo configuramos para que se inicie al crear un elemento. En la imagen 14 vemos como después de crear un elemento en la lista la instancia del WorkFlow está en progreso.

Imagen 14
14_Instancia_Corriendo

Una vez creado podemos acceder a la lista de tareas y nos encontramos con una nueva tarea creada y asignada al usuario que cargamos dentro del WorkFlow, al seleccionar la misma se nos abrirá el formulario Infopath asociado para que aprobemos o rechacemos la tarea, en la imagen 15 vemos el formulario abierto.

Imagen 15
15_Formulario_Infopath

Cuando el WorkFlow termina podemos acceder a la historia de la ejecución, para eso seleccionamos el link “Completado”, que se encuentra en el elemento que acabamos de aprobar y accedemos a la pantalla de estado de la instancia del WorkFlow que acabamos correr. En dicha pantalla, ver imagen 16, veremos cómo se fue ejecutando nuestro WorkFlow de aprobación y veremos el mensaje cargado en la propiedad “TaskOutcome” de la actividad CompteTask.

Imagen 16
16_Estado_WorkFlow

La idea de este artículo fue mostrar como armar un WorkFlow simple de aprobación, paso a paso y explicando cómo vamos creando y configurando el mismo. En el próximo articulo vamos hablar de cómo podemos utilizar formularios de aprobación hechos en Asp.Net, para llevar a cabo esto, vamos a utilizar un AddIn que me recomendó un amigo Haaron Gonzalez y que se puede descargar de Codeplex y buscaremos no depender de Forms Services e Infopath.