WSS 3.0 & MOSS: Creación de un workflow de máquina de estados!

Habitualmente cuando se realizan ejemplos de workflows de Windows Workflow Foundation (WF) se suele recurrir al diseño y creación de workflows de tipo secuencial. Ahora bien, cómo sin duda sabéis, WF habilita la creación de workflows de máquina de estados, mucho más flexibles y capaces de modelar un espectro más amplio de procesos que los workflows de tipo secuencial sobre todo en lo que a la interacción humana se refiere.


Por otro lado, Windows Sharepoint Services 3.0 (WSS 3.0) y Microsoft Office Sharepoint Server 2007 (MOSS) son las plataformas y tecnologías que ofrece Microsoft para la colaboración y gestión de la información en los equipos de trabajo de una organización, y un conjunto de aplicaciones que mejoran la eficacia de las organizaciones permitiendo la colaboración y gestión de la documentación, aplicando flujos de trabajo con Windows Workflows Foundation, integra un potente motor de búsquedas, gestión de portales, publicación web, integración con Business Intelligence, etc. Por definición, tanto WSS 3.0 como MOSS son herramientas en la que los workflows de máquina de estados encajan a la perfección por estas características de flexibilidad y mayor interacción que hemos comentado. En este post vamos a detallar cómo crear un workflow de máquina de estados para ser desplegado y utilizado en WSS 3.0 & MOSS. Empecemos.


Creación del workflow


El workflow que vamos a crear es realmente sencillo y se compone de tres estados. Este workflow tiene la siguiente funcionaliad: al detectar que se crea un documento en una biblioteca de documentos genera una tarea en la lista de tarea , y que si el documento original sufre alguna modificación. el workflow se “despierta” y actualiza las tareas generadas inicialmente.


El primer paso es crear el proyecto de workflow para Sharepoint en el entorno de Visual Studio 2005 (ya vimos que con Visual Studio 2008 todo es mucho más automático, los pasos en este entorno serían los ya comentados). En este caso tenemos que seleccionar dentro de los proyectos de tipo Sharepoint la plantilla State Machine Workflow Library.






image Workflow_State_Machine_1

Una vez creado el proyecto, vemos que en la superficie de diseño ya tenemos un estado inicial (al igual que ocurre con los workflows de tipo secuenciales y la actividad OnWorkflowActivated): WorkflowInitialState. Por lo tanto, tendremos que añadir dos nuevos estados. El primero de estos estados se encargará de la generación de la tarea, así como de la detección de cambios en el elemento que provocó la generación de la misma. El segundo de los estados es el estado de fin del workflow. Para añadir un nuevo estado al workflow, hacemos clik con el botón derecho del ratón y seleccionamos la opción Add State. Repetimos la operación para añadir el segundo estado a la superficie de diseño:






Workflow_State_Machine_3 Workflow_State_Machine_4

Una vez que hemos añadido los estados, el siguiente paso consiste en dotarles de capacidad lógica añadiendo las actividades (propias de WF o de Sharepoint) necesarias. Para añadir estas actividades a un estado del workflow basta con arrastrarlas desde la toolbox del diseñador al estado. En mi caso, el estado 1 se compondrá de 1 actividad de tipo StateInitializationActivity, 2 actividades de tipo EventDrivenActivity, y 1 actividad de tipo StateFinalizationActivity. Cada una de ellas se encargará de responder a los eventos respectivos de creación de una tarea al crearse un ítem en la biblioteca de documentos, modificación de la tarea (para marcarla como completada, especificar un % de completado,…), detectar que se ha producido un cambio en las propiedades del documento que desencadenó el workflow y finalmente detectar que se ha completado el estado y se puede hacer la transición al estado final del workflow.






Workflow_State_Machine_4 Workflow_State_Machine_6

Una vez que ya tenemos los estados del workflow y sus correspondientes niveles hijos (actividades que acabamos de añadir), el siguiente paso consiste en especificar los estados de inicio y fin del worlflow a través de las correspondientes propiedades y establecer las transiciones entre estados:



  • Para especificar que un estado sea el estado final del workflow, lo seleccionamos y en el menú contextual (botón derecho del ratón) hacemos clic sobre la opción Set As Completed State.
  • Para el estado inicial se sigue la misma idea, pero seleccionando la opción Set As Initial State para el estado que queramos que sea el de inicio del workflow.
  • Para definir las transacciones, tenemos dos posibilidades:

    • De manera visual y seleccionando el nivel hijo dentro de un estado que vaya a ser origen o destino de la transición y cuando en el límite de la misma aparezca el símbolo image , arrastramos hasta el siguiente estado con la que queremos definir la transición. En mi caso, siguiendo este procedimiento, he enlazado la actividad onWorkflowActivated del estado inicial (InitialState) con el segundo estado del workflow…¿y esta transición en que se traduce? Pues si hacéis doble clic sobre el estado inicial varéis que el diseñador de workflows ha añadido a continuación de la actividad onWorkflowActivated una actividad de tipo SetStateActivity que es la responsable de que la transición entre estados tenga lugar.
    • De nuevo de manera visual, pero controlando como se realiza la transición en función de definir una cierta condición. Esta técnica la vamos a utilizar para modelar la transición entre el estado intermedio y el definido como final de nuestro workflow:

      • Hacemos doble clic sobre la actividad desde la que produce la transición (en este caso on TaskChanged).
      • A continuación de la actividad anterior añadimos una actividad de tipo IfElseActivity, que configuramos de manera que en la primera rama situamos una actividad de tipo SetStateActivity que es la que nos permitirá definir la transición del estado actual al destino. Para definir esta transición especificamos que el valor de la propiedad TargetStateName sea CompletedState (que es el último estado del workflow de máquina de estados que estamos construyendo).

Tras realizar los pasos anteriores, tendremos definidas las correspondientes transiciones entre los estados que hemos definido en el workflow.







Workflow_State_Machine_7 Workflow_State_Machine_9 Workflow_State_Machine_10

Configurando los niveles hijos


Hasta ahora hemos diseñado e implementado de manera visual el workflow de máquinas de estados a partir de crear una serie de estados y unas transiciones entre los mismos. como hemos visto, cada estado se compone de una serie de actividades (niveles hijos) que tienen que ser configurados de manera adecuada. En particular, para el workflow creado hay que realizar las siguientes configuraciones:



  • Estado InitialState, Actividad onWorkflowActivated, tenemos que configurar la propiedad CorrelationToken. Especificamos para la misma workflowToken (por defecto aparecerá esta).
  • Estado TaskCreatedState, para el que realizamos las siguientes configuraciones:

    • Hacemos doble clic sobre la actividad InitTaskCreatedState y añadimos a continuación de esta una actividad de tipo CreateTask con las siguientes propiedades:

      • CorrelationToken, especificamos como valor taskToken.
      • MethodInvoking, especificamos InitCreateTask.
      • TaskID, que se configura a partir de la definición de una propiedad (taskID) o campo de la clase que representa el workflow. Se podrá definir de manera visual (a través de la ventana de definición, de la que se detalla un ejemplo debajo) o directamente en código.
      • TaskProperties, que configuramos con otra nueva propiedad denominada taskProperties (creada con el mismo mecanismo seguido para taskID).

Workflows_VS_6




    • Para la actividad onTaskChanged (que es de tipo EventDriven) realizamos las siguientes configuraciones:

      • Añadimos una actividad de tipo onTaskChanged encima de la actividad IfElse que gobierna la transición al estado final del workflow. Esta actividad la configuramos del siguiente modo:

        • Especificamos como taskToken como valor para la propiedad CorrelationToken.
        • Especificamos taskID como valor para la propiedad TaskID.
        • Creamos un nuevo campo denominado afterProps (siguiendo el procedimiento visual comentado) para asignarlo a la propiedad AfterProperties.

      • Especificamos la condición para la actividad IfElse. En este caso vamos a definir una condición de tipo declarativo (Declarative Rule Condition) con la siguiente expresión: onTaskChanged1.AfterProperties.PercentCompleted==1, es decir, para poder realizar la transición al estado final es necesario que el usuario complete la tarea al 100 %.


image




    • Para la actividad onWorkflowItemChanged (que responde a cambios en el ítem que desencadeno el workflow), realizamos los siguientes pasos:

      • Añadimos una actividad de tipo onWorkflowItemChanged, para la que especificamos que su correlation token sea workflow token.
      • Añadimos una actividad de tipo Code especificando que el método invocado sea updateDueDates().
      • Añadimos una actividad de tipo UpdateTask (responsable de actualizar las tareas si se ha producido un cambio en los ítems a partir de las cuales se generaron) en la que especificamos:

        • Propiedad CorrelationToken=taskToken.
        • Propiedad TaskID=taskID.
        • Propiedad AfterProperties, creamos un nuevo elemento denominado taskProperties.

  • Estado CompletedState, en este caso añadimos una actividad de tipo CompleteTask, configurando las propiedades:

    • CorrelationToken=taskToken.
    • TaskID=taskID.

Codificando los manejadores


Una vez configurados los niveles hijos de cada estado, tenemos que codificar los manejadores que hayamos especificado en los correspondientes niveles hijos. En nuestro caso:



  • Método InitCreateTask(), inicializamos la propiedad taskID y definimos algunas de las propiedades propias del objeto taskProperties…en concreto el usuario al que asignaremos la tarea y el título de la misma.




        private void InitCreateTask(object sender, EventArgs e)        {            this.taskID = Guid.NewGuid();            this.updateDueDates(null, null);            this.taskProperties.AssignedTo = “litwaredemo\Administrator”;            this.taskProperties.Title = “Documento a revisar”;        }


  • En el método updateDueDates() lo que hacemos es actualizar la fecha de creación de la tarea a partir de añadirle un número aleatorio entre 5 y 15 días (suponemos que este es un requerimiento de negocio).




        private void updateDueDates(object sender, EventArgs e)        {           Random rand = new Random();           this.taskProperties.DueDate=               DateTime.Now.AddDays(rand.Next(5,15));        }

Sin más, firmamos el proyecto para que el ensamblado que se genere sea seguro y se pueda desplegar en WSS 3.0 / MOSS y compilamos para asegurarnos de que no hay ningún error.


Despliegue y prueba del workflow


Aunque ya comentamos en un post previo la técnica de despliegue de workflows (aunque con Visual Studio 2008 esta tarea se simplifica), vamos a recordar los pasos esenciales:



  • El workflow lo desplegaremos como una feature de Sharepoint, por lo que tendremos que crear el correspondiente archivo XML de definición de la misma:




<?xml version=”1.0″ encoding=”utf-8″?><Feature  Id=”BD2F0F08-8295-4543-9005-1C051CA8E7C5″          Title=”Ejemplo de Workflow Máquina de Estados en VS”          Description=”Ejemplo de workflow de máquina de estados.”

          Version=”1.0.0.0″ 

          Scope=”Site” xmlns=”http://schemas.microsoft.com/sharepoint/”>                <ElementManifests>                               <ElementManifest Location=”workflow.xml” />                </ElementManifests>                <Properties>                               <Property Key=”GloballyAvailable” Value=”true” />                </Properties></Feature>


  • Tenemos que definir el correspondiente manifiesto que describe el workflow:




<?xml version=”1.0″ encoding=”utf-8″ ?><Elements xmlns=”http://schemas.microsoft.com/sharepoint/”>                        <Workflow                                                Name=”Ejemplo de Workflow Máquina de Estados en VS”                                                Description=”Ejemplo de workflow de máquina de estados.”                                                Id=”A9824E24-3608-4504-A09B-323A492714BB”                                                CodeBesideClass=”ResetTaskWorkflow.Workflow1″

                                                CodeBesideAssembly=”ResetTaskWorkflow, Version=1.0.0.0,

                                               Culture=neutral, PublicKeyToken=31d35b2bfb1b9654″>                                               <Categories/>

                                               <MetaData>


                                               <StatusPageUrl>

                                                           _layouts/WrkStat.aspx</StatusPageUrl>                                               </MetaData>                        </Workflow></Elements>


  • Crearnos un script .bat en el que especificaremos los correspondientes comandos para copiar el assembly en la gac, copiar los XML, activar e instalar la feature en los correspondientes directorios dentro del directorio 12 del servidor donde tengamos instalado Sharepoint.
  • Nos vamos al site collection dónde vamos a utilizar el workflow y activamos la feature desde la galería de features del site collection.

Workflow_State_Machine_15


Probando el workflow


Para probar el workflow, simplemente desde las settings de una biblioteca de documentos de nuestro site collection especificamos que queremos utilizar el workflow que acabamos de desplegar, indicando para ello el nombre de la instancia, la lista de tareas en la que se van a a generar tareas y el modo de arranque (en este caso automático y cuando se cree un nuevo ítem):







Workflow_State_Machine_16 Workflow_State_Machine_17 Workflow_State_Machine_18

Una vez que hemos asociado el workflow a una biblioteca de documentos, para comprobar que la máquina de estados funciona como se espera:



  • Creamos o subimos un documento en la biblioteca, de manera que el workflow se iniciará y en la vista de listado de documentos de la biblioteca aparecerá una nueva columna con el nombre de la instancia del workflow y con valor In Progress (se ha creado una tarea que está pendiente de ser completada).
  • Si nos vamos a la lista de tareas, veremos que efectivamente se ha creado una tarea y que el estado de la misma es Not Started.
  • Volvemos a la biblioteca de documentos y cambiamos uno de los metadatos del elemento que desencadeno el arranque de la instancia al workflow.






Workflow_State_Machine_19 Workflow_State_Machine_20 Workflow_State_Machine_22


  • Si volvemos a la lista de tareas, veremos que la columna Due Date presenta un valor distinto al inicial. El workflow ha cumplido con su cometido, a actualizado esta columna al detectar que se había cambiado el ítem origen de la biblioteca de documentos responsable del inicio de la instancia del workflow.
  • Modificamos ahora la tarea y especificamos que el campo % Completed tenga un valor 100…si lo hemos hecho bien, esto significa que el workflow tiene que concluir y por lo tanto la columna de estado del workflow en la biblioteca debería tener el valor Completed…y así es!





Workflow_State_Machine_21 Workflow_State_Machine_23

 


Y hasta aquí llega este post en el que os queríamos contar como construir un workflow de máquina de estados para Sharepoint. Os podéis descargar el proyecto del workflow de este enlace. Esperamos que os haya resultado interesante.

Publicado por

Juan Carlos González

Juan Carlos es Ingeniero de Telecomunicaciones por la Universidad de Valladolid y Diplomado en Ciencias Empresariales por la Universidad Oberta de Catalunya (UOC). Cuenta con más de 12 años de experiencia en tecnologías y plataformas de Microsoft diversas (SQL Server, Visual Studio, .NET Framework, etc.), aunque su trabajo diario gira en torno a SharePoint & Office 365. Juan Carlos es MVP de Office Servers & Services desde 2015 (anteriormente fue reconocido por Microsoft como MVP de Office 365 y MVP de SharePoint Server desde 2008 hasta 2015), coordinador del grupo de usuarios .NET de Cantabria (Nuberos.Net, www.nuberos.es), co-fundador y coordinador del Grupo de Usuarios de SharePoint de España (SUGES, www.suges.es), así como co-director de la revista gratuita en castellano sobre SharePoint CompartiMOSS (www.compartimoss.com). Hasta la fecha, ha publicado 8 libros sobre SharePoint & Office 365 y varios artículos en castellano y en inglés sobre ambas plataformas.

24 comentarios en “WSS 3.0 & MOSS: Creación de un workflow de máquina de estados!”

  1. Hola Juan Carlos!!!!!
    Menos mal que alguien publica algo en castellano sobre la creación de workflows, porque hay muy poca documentación sobre el tema, y menos aún sobre los problemas habituales que te puedes encontrar. Sería un interesante tema de artículo también.
    Un abrazo!!!
    Fabián

  2. Buenos días, ante todo felicitaros por el articulo publicado, pero me gustaria saber si es posible utilizar una lista distinta de Taks, es decir, poder mandar las tareas a una lista de un sitio en concreto.
    Un saludo y gracias.

  3. Buenos días Diego,
    Gracias a tí y a Fabían por leer nuestros posts..respecto a lo que preguntas, claro que puedes utilizar una lista distinta de Tasks. De hecho, cuando asocias el workflow a una lista o una librería de documentos tienes un desplegable en el que aparecen las listas de tipo Tasks que tienes en el site…esto implica que la lista de tareas tiene que estar en el mismo site en el que reside la lista o biblioteca a la que vas a asociar el workflow. Si lo que quieres es que la tarea se cree en un sitio distinto, entonces tendrás que hacerlo de otro modo y sin utilizar la actividad CreateTask….en este caso yo utilizaría la actividad Code y en su manejador escribiría el código necesario para crear la tarea…personalmente creo que hay que usar CreateTask y que las tareas se creen en una lista de tareas que reside en el mismo site dónde está la lista o librería a la que asocias el workflow.

    Un saludo

    JC

  4. Hola la verdad es que recien inicio en esto de la programacion con wwf agradeceria si me pudieran indicar con que puedo empezar, la implementacion la haria en webpages ASP.Net, cualquier informacion gracias.

  5. Hola Vanesa,
    Un buen ejemplo de como utilizar workflows de WF en aplicaciones ASP.NET lo puedes encontrar en el sitio de WF. En concreto, en este enlace puedes encontrar un ejemplo de aplicación ASP.NET en la que el flujo de navegación es realizaco con un workflow:
    http://wf.netfx3.com/files/13/default.aspx

    Para partir de cero con WF, tienes la página oficial de MSDN para empaparte bien del tema:

    http://msdn2.microsoft.com/en-us/netframework/aa663328.aspx

    Aquí tienes todos los recursos sobre WF…

    Espero haber respondido a tu pregunta.

    Un saludo

    JC’s

  6. Hola JC pues si bien eh visto ya tus enlaces, te lo agradezco; ahora solo es encontrar el principio para comenzar, por lo que veo es bastante amplio esta herramienta, gracias y si se me atora algo creo volvere a molestarte.

  7. Hola;

    Eh estado trabajando con algunos de los servicios que el wf ofrece como lo son el de persistence y tracking orientados a sql server, mi pregunta es: que tipo de informacion es la que guardan estas tablas (las que se crean con los scripts que vienen en el framework 3) se usar estos servicios programaticamente, pero no se si haya alguna descripcion de las tablas y/o campos en algun sitio ya que eh buscado y no eh tenido exito en este contexto, agradeceria si me pudieran ayudar ya que puede ayudarme esa informacion que se guarda para el desarrollo de alguna aplicacion. Gracias por su atencion y espero su amable respuesta.

  8. Buenas Danna,
    Pues por ejemplo, sobre el servicio de tracking ya escribí algo hace tiempo:
    http://geeks.ms/blogs/ciin/archive/2007/02/05/comenzando-con-wf-paso-de-datos-y-runtime-services.aspx

    Como se comenta en el post, este servicio permite monitorizar permite monitorizar y realizar un seguimiento de los workflows en ejecución…por lo que necesita guardar este tipo de información. La parte del servicio de tracking del post está basada en el SDK de WF…y para entender mejor la info guardada, pues lo mejor es hacer un ejemplo como el del post, hacer que tu workflow se ejecute varias veces y luego con T-SQL analizar la info que se va almacenando…más enlaces sobre los servicios de WF:
    http://msdn.microsoft.com/msdnmag/issues/07/03/Foundations/Default.aspx?loc=es

    Espero haber resuelto tus dudas!

    Saludos

    JC’s

  9. Hola, muy buen post, para aprender a crear WF desde el inicio. Tengo una sola duda, que por favor me la pudiesen aclarar. Es posible modificar los Workflows que trae por defecto MOSS 2007, como el WF de aprobación. Esto es, por que necesito modificar un tema muy pequeño, que es quitar los botones de aprobación y rechazo, cuando un usuario abre una tarea que va con copia a él (CC). No se si fui explicito. Por favor agradezco su respuesta. Mi correo es ezambranoa@gmail.com.

    Saludos cordiales,
    Ernesto.

  10. Hola Ernesto,
    Si que se pueden modificar los workflows que trae por defecto MOSS 2007, pero no es recomendable ni tampoco una buena práctica. Ahora bien, lo que quieres hacer es sencillo. Lo que tienes que hacer es personalizar el formulario de aprobar/rechazar tarea para oculatar estos botonones. Esto lo tienes que hacer con SD 2007…y aquí tengo una pregunta para tí, ¿Cómo se va a completar el workflow si ocultas estos botones?

    Un saludo

    JC’s

  11. Hola Juan Carlos, Gracias por tu respuesta. Lo que pasa que estos botones aparecen a los usuarios que van con copia, utilizando el WF de Aprobación, no el de 3 estados. Lo que necesito que estos usuarios copiados (CC), no puedan aprobar ni rechazar el flujo, que solo les llegue informativo, y en este momento lo hace de esta forma.

  12. Hola de nuevo Ernesto, creo que no entiendo bien tu problema. Acabo de probar el workflow de aprobación de MOSS y sólo pueden aprobar el documento los usuarios que hayas especificado en la sección de aprobadores. Los que van en CC reciben un e-mail, pero no se genera una tarea qe tenga que aprobar…explica mejor tu problema para entender que te pasa exactamente.

    Un saludo

    JC’s

  13. Muy interesante tu post amigo, yo apenas estoy empezando con el Windows WF, tengo una pregunta: ¿Cómo le hago para volvera publicar mi wf?, por ejemplo: sí al momento de procesarlo me doy cuanta que tengo un error en la logica, entonces lo modifico en el VStudio y para publicarlo, ¿Cómo le hago?, ¿se siguen los mismos pasos con los mismos datos(Feature Id, Manifiesto Id, PublicKeyToken, Version)?

    De antemano te doy las gracias.

  14. Hola Antonio,
    Efectivamente, todo se queda igul…lo que tendrás que hacer es en el install.bat que te despliega la feature:
    – Copiar de nuevo los ensamblados en la GAC
    – Desactivar la feature.
    – Desinstalar la feature.
    – Instalar la feature.
    – Activar la feature.

    Un saludo

    JC’s

  15. Hola Antonio,
    Para depurar el workflow tienes que utilizar la opción de depuración del mismo atachando Visual Studio a los worker process de SharePoint.

    Un saludo

    JC’s

  16. Hola Juan Carlos… muy bueno el post. Tengo algunas dudas en su implementación.

    El CompletedState se ve en la imagen que queda vacío al crearlo. Más tarde en la sección “Configurando los niveles hijos” se indica que para este estado “añadimos una actividad de tipo CompleteTask…”. Al intenar agregar una CompleteTask, Visual Studio no me lo permite.

    Entonces pensé “Ok… debo asignar primero un stateInitialization, eventDriven o stateFinalization, y dentro de él agregar el CompleteTask”, pero tampoco me permite agregar ninguno de los tres.

    ¿Que estoy haciendo mal?

    Saludos,

    Nicolás

  17. Hola Nicolás,
    Pues no sé porque no te deja agregar la actividad…en teoría,dado un estado deberías poder agregar cualquier tipo de actividad.

    Un saludo

    JC’s

  18. Hola Juan Carlos…

    Solo posteo para aclarar este punto que finalmente resolví (o mas bien se resolvió solo).

    No fue necesario agregar la actividad CompleteTask en el estado final (que de hecho nunca me permitió agregar). O bien dejo que sea responsabilidad del usuario marcarla como completa, o coloco la actividad antes de salir del estado anterior.

  19. Juan Carlos:

    Es posible tener toda mi logica de los Workflow definidas en una BD SQL Server 2005 (pasos,reglas y acciones) utilizarlas en WSS para hacer los Workflow personalizados?

    Saludos

  20. Hola Francisco,
    Me imagino que la idea bajo esto sea el definir una especie de diseñador de workflows en SharePoint….por poder seguramente se pueda, aunque no me parece la opción más idonea.

    Un saludo

    JC’s

  21. Hola, necesito crear un flujo de trabajo con las siguientes características:
    El usuario que inicie el flujo puede asignar el documento a varios usuarios a la vez, para que estos le aprueben el documento, para darle una indicacion de hacer algún cambio en el documento, o para que tenga conocimiento de la información contenida en el documento, esto se debe crear paralelamente.
    Por su parte los usuario afectados por el iniciador, deben tener las mismas opciones que el anterior.
    Es como si el flujo se dividiera en varios caminos por el que transita el documento al mismo tiempo.
    Esto se pudiera hacer?

  22. Hola Isabel,
    El escenario que planteas es perfectamente implementable con un flujo de trabajo de SharePoint 2007 (tb 2010) modelado pòr medio de Visual Studio. La parte más complicada del flujo es la interacción con el usuario por medio de formularios.

    Saludos!

Deja un comentario

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *