Árvore de páginas

Índice


Personalización de Workflow:

Propiedades Extensión

Las propiedades de extensión contienen información especial que pueden alterar el comportamiento patrón del proceso en algún punto. Se debe utilizar principalmente durante la fase de personalización o debe contener "flags" especiales que modifiquen alguna lógica interna (sólo en casos especiales).

El registro de propiedades de la extensión del proceso es realizado por Fluig Studio, siendo necesario que el diagrama del proceso ya esté creado. Para registrar un nuevo atributo, es necesario abrir el proceso para la edición y en la visión 'Properties' acceder a la pestaña extensión:



Se deben utilizar los botones Agregar nuevo Atributo, para agregar una propiedad de extensión. A continuación indicaremos el formulario para crear un nuevo atributo.

En este ejemplo, crearemos actividades automáticas personalizadas.


 

En la siguiente imagen se puede visualizar el atributo agregado, definiendo a las actividades 2 y 4 (separados por comas) como las actividades automáticas del proceso.

Eventos del Processo

Los eventos de un proceso son un conjunto de scripts cargados por la API de workflow Estos scripts se desarrollan con el uso del lenguaje JavaScript y se utilizan a lo largo de la ejecución del proceso en momentos predeterminados, como por ejemplo, la creación de la solicitud del proceso o el ingreso a una nueva actividad.

La implementación de los eventos del proceso es llevada a cabo por Fluig Studio, siendo necesario que ya exista un proyecto Fluig con al menos un diagrama de proceso. 

Para crear un nuevo evento del proceso, haga clic con el botón derecho del ratón en el proyecto, acceder a la opción New y luego la opción Other. En el asistente abierto, seleccionar la opción "Script Evento Workflow", presente en la carpeta Fluir, y luego haga clic en el botón Next. En la nueva ventana seleccionar qué evento será creado y relacionarlo a un proceso ya existente. Para terminar, haga clic en el botón Finish:




En todos los eventos del proceso es posible obtener informaciones de la API de Workflow. Cada evento posee acceso al handle de la API de workflow a través de la variable global hAPI. Los siguientes métodos se a través de la hAPI:

MétodoEspecificação
getCardValue("nomeCampo")

Permite acceder al valor de un espacio del formulario del proceso, donde:

  • nombreEspacio: nombre del espacio del formulario.
setCardValue("nomeCampo", "valor")

Permite definir el valor de un espacio del formulario del proceso, donde:

  • nombreEspacio: nombre del espacio del formulario;
  • valor: valor a definir para el espacio del formulario.
setAutomaticDecision(numAtiv, listaColab, "obs")

Permite definir el flujo de salida de una actividad de manera automática, donde:

  • númActiv: número de la actividad destino;
  • listaColab: lista (del tipo String) de los usuarios que recibirán la tarea;
  • obs: observación de la tarea;
getActiveStates()Responde con una lista de las actividades actividades del proceso.
getActualThread(numEmpresa, numProcesso, numAtiv)

Responde con el thread de la actividad que está activa, recordando que en caso de actividades paralelas, responde 0,1,2 y así sucesivamente.

  • númEmpresa: número de la empresa;
  • númProceso: número de la solicitud;
  • númActiv: número de la actividad.
Ejemplo de uso para esta función:


function afterTaskCreate(colleagueId) {
    var nrPróxActividad = getValue("WKNextState");
    if (nrPróxActividad == "5"){ //actividad entre paralelas
 
		var fecha = new Date();
		var númEmpresa = getValue("WKCompany");
	
		//Establecer el día, mes (Enero es 0) y año
		fecha.setDate(20);
		fecha.setMonth(10);
		fecha.setFullYear(2010);
	   
		// Recupera el número de la solicitud
		var númProceso = getValue("WKNumProces");
	
		// Establecer el plazo para las 14:00
		hAPI.setDueDate(númProceso, hAPI.getActualThread(númEmpresa, númProceso, nrProxActividad), colleagueId, fecha, 50400);
	}
}
setDueDate(numProcesso, numThread, "userId", dataConclusao, tempoSeg)

Permite alterar el plazo de finalización para una determinada actividad del proceso, donde:

  • númProceso: número de la solicitud;
  • númThread: número del thread (normalmente 0, cuando no se utilizan actividades paralelas);
  • userId: el usuario responsable por la tarea;
  • fechaFinalización: la nueva fecha de finalización;
  • tiempoSeg: tiempo que representa la nueva hora de finalización, calculado en segundos después de la media noche.

Recomendamos la utilización de este método en el evento afterTaskCreate, ya que se ejecutará después de la creación de la tarea. Ejemplo:

function afterTaskCreate(colleagueId) {
	var fecha = new Date();
	
	//Establecer el día, mes (Enero es 0) y año
	fecha.setDate(20);
	fecha.setMonth(10);
	fecha.setFullYear(2010);
	   
	// Recupera el número de la solicitud
	var proceso = getValue("WKNumProces");
	
	// Establecer el plazo para las 14:00
	hAPI.setDueDate(proceso, 0, colleagueId, fecha, 50400);
}
transferTask(transferUsers, "obs", int numThread)

Transferir una tarea de un usuario a otro(s) usuario(s).

  • transferUsers: lista (del tipo String) de usuarios;
  • obs: la observación;
  • numThread: secuencia del thread, en caso de actividades paralelas.
transferTask(transferUsers, "obs")

Transferir una tarea de un usuario a otro(s) usuario(s). Este método no puede utilizarse en procesos con actividades paralelas:

  • transferUsers: lista (del tipo String) de usuarios;
  • obs: la observación.
startProcess(processId, ativDest, listaColab, "obs", completarTarefa, valoresForm, modoGestor)

Inicia una solicitud workflow, donde:

  • processId: código del proceso;
  • activDest: actividade de destino;
  • listaColab: lista (del tipo String) de usuarios;
  • obs: texto de la observación;
  • completarTarea: indica si se debe completar la tarea (true) o solamente guardar (false);
  • valoresForm: um Mapa con los valores del formulario del proceso;
  • modoGestor: acceso como gestor del proceso (true/false).

Responde con un mapa con información de la solicitud creada. Entre ellas, el iProcess que es el número de la solicitud creada.

setColleagueReplacement(userId)

Establecer un usuario sustituto, donde:

  • userId: código del usuario sustituto.
setTaskComments("userId", numProcesso,  numThread, "obs")

Define una observación para una determinada tarea del proceso, donde:

  • userId: usuario responsable por la tarea;
  • númProceso: número de la solicitud de proces;
  • númThread: es el número del thread (normalmente 0, cuando no se utilizan actividades paralelas);
  • obs: la observación.
getCardData(numProcesso)

Retorna um Mapa com todos os campos e valores do formulário da solicitação.

  • numProcesso: número da solicitação de processo.
getAdvancedProperty("propriedade")

Responde con un Mapa con todos los espacios y valores del formulario de la solicitud.

  • númProceso: número de la solicitud del proceso;
calculateDeadLineHours(data, segundos, prazo, periodId)

Calcula un plazo a partir de una fecha basada en el expediente y feriados registrados en el producto informando el plazo en horas.

  • fecha: Fecha inicial (tipo Date);
  • segundos: Cantidad de segundos después de la media noche:
  • plazo: Plazo que se aplicará en horas (tipo int);
  • periodId: Código de Expediente.  

Devolución: Array de objeto, donde la primera posición del array es la fecha y la segunda, la hora.

Ejemplo:

function afterTaskCreate(colleagueId) {
   	var fecha = new Date();
   	//Calcula el plazo
   	var obj = hAPI.calculateDeadLineHours(fecha, 50000, 2, "Default");
	var dt = obj[0];
	var segundos = obj[1];
   	//Recupera el número de la solicitud
   	var proceso = getValue("WKNumProces");
   	//Modifica el plazo del proceso
	hAPI.setDueDate(proceso,0,colleagueId, dt, segundos);
}
calculateDeadLineTime(data, segundos, prazo, periodId)

Calcula un plazo a partir de una fecha basada en el expediente y feriados registrados en el producto informando el plazo en minutos.

  • fecha: Fecha inicial (tipo Date);
  • segundos: Cantidad de segundos después de la media noche:
  • plazo: Plazo que se aplicará en minutos (tipo int);
  • periodId - Código de Expediente

Devolución: Array de objeto, donde la primera posición del array es la fecha y la segunda, la hora.

 Ejemplo:

function afterTaskCreate(colleagueId) {
	var fecha = new Date();
	//Calcula el plazo
	var obj = hAPI.calculateDeadLineTime(fecha, 50000, 120, "Default");
	var dt = obj[0];
	var segundos = obj[1];
	//Recupera el número de la solicitud
	var proceso = getValue("WKNumProces");
	//Modifica el plazo del proceso
	hAPI.setDueDate(proceso,0,colleagueId, dt, segundos);
}
getUserTaskLink(numAtiv)

Permite buscar el link para ejecutar una determinada actividad, y utilizarlo, por ejemplo, para enviar un correo electrónico con un template personalizado.

  • númAtiv: número de la actividad
Devolución: link para ejecutar la solicitud.


Atención

Este método no responde el link a las actividades que aún no se crearon, es decir, no se puede utilizar en eventos como afterTaskComplete(colleagueId,nextSequenceId,userList) para obtener el link de la actividad con "nextSequenceId".

 Ejemplo:

function afterTaskCreate(colleagueId) {
	var sequenceId = getValue ("WKCurrentState");
	if (sequenceId == 2) {
		var destinatarios = new java.util.ArrayList();
		destinatarios.add(colleagueId);
 
		var parámetros = new java.util.HashMap();
		parámetros.put("WDK_CompanyId", getValue("WKCompany"));
		parámetros.put("WDK_TaskLink", hAPI.getUserTaskLink(sequenceId));
 
		notifier.notify(getValue("WKUser"), "tplPersonalizado", parámetros, destinatarios, "text/html");	
	}
}



En los eventos existe la posibilidad de integrar los servicios de datos. Dichos servicios pueden ser WebServices, AppServer Progress® e Dataset.

Se debe configurar previamente el acceso al WebServices o AppServer Progress ® en el directorio de servicios. Para más detalles consulte en Integración con Aplicaciones Externas , en el capítulo "Accediendo a WebServices a partir del Fluig"

Indicamos a continuación un ejemplo respecto a cómo ejecutar el WebService de Colleague para crear un usuario en el Fluir después de ejecutar una tarea:

function afterTaskComplete(colleagueId, nextSequenceId, userList) {
	
	if (nextSequenceId == 2) {
		//Busca el webservices de Colaborador
		var colleagueServiceProvider = ServiceManager.getServiceInstance("Colleague");
		var colleagueServiceLocator = colleagueServiceProvider.instantiate("com.totvs.technology.ecm.foundation.ws.ECMColleagueServiceService");
		var colleagueService = colleagueServiceLocator.getColleagueServicePort();
	
		//Crea el ColleagueDto – Verificar la lista de métodos en la visualización del servicio
		var colleagueDto = colleagueServiceProvider.instantiate("com.totvs.technology.ecm.foundation.ws.ColleagueDto");
		colleagueDto.setCompanyId(1);
		colleagueDto.setColleagueId("prueba");
		colleagueDto.setColleagueName("Usuario Prueba");
		colleagueDto.setActive(true);
		colleagueDto.setVolumeId("Default");
		colleagueDto.setLogin("prueba");
		colleagueDto.setMail("[email protected]");
		colleagueDto.setPasswd("prueba");
		colleagueDto.setAdminUser(false);
		colleagueDto.setEmailHtml(true);
		colleagueDto.setDialectId("pt_BR");
		
		//Crea el colleagueDtoArray y agrega
		var colleagueDtoArray = colleagueServiceProvider.instantiate("com.totvs.technology.ecm.foundation.ws.ColleagueDtoArray");
		colleagueDtoArray.getItem().add(colleagueDto);
	
		var result = colleagueService.createColleague("adm", "adm",  1, colleagueDtoArray);
		log.info("Result: " + result);
	}
}


Los siguientes eventos son efectuados por la API de Workflow:

Evento
Descripción
Parámetros
afterCancelProcess

Se produce después de la cancelación de la solicitud.

  • Usuario corriente (String);
  • Número del proceso (Integer).
afterProcessCreate

Ocurre luego de la creación de un nuevo evento.


Observación: En caso de ejecutar este evento en subproceso, no será posible definir o recuperar datos de la ficha anexada al subproceso, ya que en esta situación aún no ha sido creada la ficha.

  • Número del nuevo proceso (Integer).
afterProcessFinish

Se produce después de finalizada la solicitud.

  • Número del proceso (Integer).
afterReleaseVersion

Se produce después de liberar una versión del proceso.

  • XML con la definición del proceso (String)
afterStateEntrySe produce después de la entrada a una neuva actividad.
  • Secuencia de la actividad (Integer).
afterStateLeaveSe produce después de salir de una actividad.
  • Secuencia de la actividad (Integer).
afterTaskComplete

Se produce después que el usuario completa una tarea, no obstante la información de la próxima tarea y usuarios destino ya han sido guardadas.

  • Usuario corriente (String)
  • Secuencia de la próxima actividad (Integer);
  • Lista de usuarios destino (List<String>).
afterTaskCreateSe produce después que el usuario recibe una tarea.
  • Matrícula del usuario (String).
afterTaskSave

Se produce después de guardar la información seleccionada por el usuario.

  • Usuario corriente (String)
  • Secuencia de la próxima actividad (Integer);
  • Lista de usuarios destino (List<String>).
beforeCancelProcess

Se produce después de cancelar la solicitud.

  • Usuario corriente (String)
  • Número del proceso (Integer).
beforeStateEntrySe produce después de entrar a una nueva actividad.
  • Secuencia de la actividad (Integer).
beforeStateLeaveSe produce antes de salir de una actividad.
  • Secuencia de la actividad (Integer).
beforeTaskComplete

Se produce antes que el usuario complete una tarea, no obstante la información de la próxima tarea y usuarios destino ya han sido guardadas.

  • Usuario corriente (String)
  • Secuencia de la próxima actividad (Integer);
  • Lista de usuarios destino (List<String>).
beforeTaskCreateSe produce antes que el usuario reciba una tarea.
  • Matrícula del usuario (String).
beforeTaskSave

Se produce antes de guardar la información seleccionada por el usuario.

  • Usuario corriente (String)
  • Secuencia de la próxima actividad (Integer);
  • Lista de usuarios destino (List<String>).
calculateAgreement

Se produce después de calcular el consenso (solamente para actividades conjuntas) y permite alterar los datos del consenso de una actividad.

Ejemplo:

function calculateAgreement(currentState, agreementData) {
	log.info("Consenso Actual: " + agreementData.get("currentPercentage"));
	log.info("Actividad Destino Actual: " +  agreementData.get("currentDestState"));
	log.info("Usuario Destino Actual: " + agreementData.get("currentDestUsers"));
	
	//Modifica el consenso
	agreementData.put("currentPercentage", 100);
	agreementData.put("currentDestState", 2);
	agreementData.put("currentDestUsers", "adm,prueba,super");
}
  • currentState (Integer): actividad que tendrá el consenso modificado;
  • agreementData (Map<String, Object>): mapa de datos con el porcentaje calculado, la actividad destino y los usuarios de destino. Para obtener los valores, utilice el método "get" y para atribuir un valor, utilice el método "put".
onNotify

Se produce después de ejecutar la solicitud y antes de enviar las notificaciones.

Para más detalles consulte el capítulo Personalización de correo electrónico.
setProcess

Se produce cuando se "establece" un proceso en la API.


Observación: La propiedad WKCompletTask no se debe utilizar en este evento, ya que mientras se ejecuta el producto aún no tiene la información respecto a si la actividad ha sido completada o no.

  • Número del proceso (Integer).
subProcessCreatedSe produce cuando se crea un subproceso.
  • Número del subproceso (Integer).
validateAvailableStates

Se produce después de realizada la lista de tareas disponibles para el usuario a partir de la tarea actual.

  • Secuencia de la actividad actual (Integer);
  • Lista de las secuencias de las actividades (List<Integer>).  
  • No es necesario crear todos los eventos del proceso - apenas aquellos en los cuales se esté interesado.
  • Todos los eventos se ejecutan de manera persistente.

Importante: No es posible capturar (hAPI.getCardValue) o agregar (hAPI.setCardValue) datos en el formulario en el inicio del proceso, solo es posible a partir de la segunda tarea.

Para esto se puede utilizar la siguiente lógica:

function beforeStateEntry(sequenceId) {
	if (sequenceId  != "NÚMERO_DE_LA_ACTIVIDADE_INICIAL") {
		var espacio = hAPI.getCardValue("espacio1");
	}
}

Personalización del Proceso

Con el uso de eventos, el Fluig permite que un proceso sea personalizado posibilitando ejecutar acciones definidas por el usuario, tales como:

  • Validar el acto de completar una actividad;
  • Tomar decisiones automáticamente;
  • Realizar integraciones con otros sistemas;
  • Iniciar nuevas solicitudes automáticamente.

Existen algunas propiedades que contienen informaciones referentes a la solicitud que se puede utilizar en la personalización del proceso, estas son:

ParâmetroDescrição
WKDefCódigo del proceso
WKVersDefVersión del proceso
WKNúmProcesNúmero de la solicitud de proceso
WKNumStateNúmero de la actividad
WKCompanyNúmero de la empresa
WKUserCódigo del usuario corriente
WKUserCommentComentario realizado por el usuario en la actividad o en la cancelación de la solicitud.
WKCompletTaskSi ha sido completada la tarea (true/false)
WKNextStateNúmero de la próxima actividad (destino)
WKCardIdCódigo del formulario del proceso
WKFormIdCódigo de la definición de formulario del proceso
WKIdentityCompanyIdentificador de la Empresa seleccionada para Experiencias de uso TOTVS.
WKMobileIdentifica si la acción ha sido realizada mediante un dispositivo mobile.
WKIsServiceIdentifica si la solicitud de cancelación ha sido realizada a través de un servicio. Esta variable sólo se podrá consultar en los eventos beforeCancelProcess y afterCancelProcess.


Además de estas propiedades ya alimentadas por el producto, es posible crear propiedades personalizadas que se pueden utilizar en los eventos. El producto ofrece la variableglobalVars, que consiste en un mapa de datos (Map<String, String>) y estará disponible en todos los eventos.

  Para agregar una propiedad y su valor, utilice el método globalVars.put("name", "value"), donde "name" es el nombre de la propiedad y "value"su valor. Ejemplo: globalVars.put("WDAprovador","adm");

 Para recuperar los valores de la variable globalVars, utilice el método globalVars.get("name"), donde "name" es el nombre de la propiedad a devolver el valor. Ejemplo: globalVars.get("WDAprovador");

    Para validar si el usuario está completando una actividad correctamente, se debe utilizar el eventobeforeTaskSave y responder algún mensaje en caso surjan errores. Por ejemplo, a continuación se indica un código de personalización de un proceso:

    function beforeTaskSave(colleagueId, nextSequenceId, userList) {
    	var activActual = getValue("WKNumState");
    	var process = parseInt(globalVars.get("process"));
    	
    	var resp1 = hAPI.getCardValue("resp1_H");
    	var eficacia1 = hAPI.getCardValue("eficaz1");  
    	var control1 = hAPI.getCardValue("controle1");
    	var eficaz = true;
    	var users = new java.util.ArrayList();
    	if (activActual == 7 && nextSequenceId == 12) {
    		if (resp1 != "" && eficacia1 != "1" && eficacia1 != "2") {
    			if (verificaUsuario(users, resp1)) {
    				users.add(resp1);
    			}
    		}
    		hAPI.setAutomaticDecision(8, users, "Decisión realizada automáticamente mediante el Fluig.");
    	
    	} else if (activActual == 9 && nextSequenceId == 13) {
    		if (resp1 != "" && eficacia1 == "2" && controle1 == ""){
    			eficaz = false;
    		}
    		if (eficaz) {
    			var codGrupo = buscaGrupo(process, "Calidade");
    			users.add("Pool:Group:" + codGrupo);
    			hAPI.setAutomaticDecision(6, users , "Decisión realizada automáticamente mediante el Fluig.");
    		}
    	}
    }

    Para que una decisión se realice automáticamente, se deben ejecutar los siguientes procedimientos:

    1. Agregar en Propiedades Avanzadas la propiedad AutomaticTasks con la lista de todas las actividades donde la decisión se puede delegar configurando la personalización. Ejemplo: AutomaticTasks=3,6,10.
    2. Implementar el evento beforeStateEntry y ejecutar el método "setAutomaticDecision" de la HAPI, informando como parámetros la próximidad actividad, el próximo usuario (o lista de usuarios) y una observación.


    function beforeStateEntry(sequenceId) {    
    	var userList = new java.util.ArrayList();
    	userList.add("adm");
    	hAPI.setAutomaticDecision(6, userList, "Decisión realizada automáticamente mediante el Fluig.");
    }

    Las actividades con decisión automática también se pueden crear a través del editor del proceso.

    Para iniciar una nueva solicitud de algún otro proceso al finalizar una solicitud, se pueden ejecutar los siguientes procedimientos:

    1. Registrar un servicio en el Fluig en que el URL sea WSDL del servicio ECMWorkflowEngineService.
    2. Implementar el evento afterProcessFinish utilizando el ejemplo a continuación. Siendo ‘process2’ el nuevo proceso a inicializar.

    Tratamiento de Excepciones

    Las excepciones a tratar en los siguientes eventos: beforeStateEntry, beforeTaskSave e beforeCancelProcess. El tratamiento de excepción en el evento beforeStateEntry, se puede utilizar en el inicio de las solicitudes, ya que este impide que se inicie la solicitud. El tratamiento de excepción en el evento beforeTaskSave sólo se puede utilizar una vez iniciada la solicitud.

    A continuación se presentan los modelos a utilizar en cada uno de los eventos:

    function beforeStateEntry(sequenceId) {
    	var activity = getValue("WKNumState");
    	if (activity == 0 || activity == 1) {
    		//Otra condición.
    		throw "TRATAMIENTO DE EXCEPCIÓN";
    	}
    }
    function beforeTaskSave(colleagueId, nextSequenceId, userList) {
    	var activity = getValue("WKNumState");
    	if (activity != 0 && activity != 1) {
    		//Otra condición
    		throw "TRATAMIENTO DE EXCEPCIÓN";
    	}
    }
    function beforeCancelProcess(colleagueId, processId) {
    	//Condición.
    	throw "TRATAMIENTO DE EXCEPCIÓN";
    }


    Es posible consultar el espacio observación de una solicitud de proceso verificando si ha sido completado o no. Para esto, es necesario validar la propiedadWKUserComment en el evento beforeTaskSave o en el evento beforeCancelProcess. Ejemplo:

    function beforeTaskSave(colleagueId, nextSequenceId, userList) {
    	if (getValue("WKUserComment") == null || getValue("WKUserComment") == "") {
    		throw "Se debe completar la observación";
    	}	
    }
    function beforeCancelProcess(colleagueId, processId) {
    	if (getValue("WKUserComment") == null || getValue("WKUserComment") == "") {
    		throw "Se debe completar la observación";
    	}	
    }

    Mecanismo de atribución

    Los mecanismo de atribución son instrumentos utilizados durante un proceso de workflow que permiten crear, según un criterio establecido por el mecanismo, una lista de posibles usuarios para una actividad. Se puede utilizar esta lista en dos momentos:

    1. En el inicio del proceso, donde el sistema verifica si el usuario corriente forma parte de esta lista, y por lo tanto, puede iniciarlo.
    2. En el momento de la derivación de una tarea, cuando se presenta esta lista al usuario corriente con opciones de derivación de la solicitud.

    En el primer caso, se genera la lista según al mecanismo de atribución existente en la primera actividad del proceso (que representa la actividad inicial). En las demás actividades se aporta el segundo procedimiento. Cuando no exista un mecanismo de atribución asociado a una actividad (sea inicial o no), todos los usuarios se considerarán válidos.


    El Fluig dispone de algunos mecanismos de atribuciones patrón, según se indica a continuación:

    Mecanismo de AtribuiçãoDescrição
    Para un Papel (Pool)Permite atribuir tareas a un papel y no a apenas a un usuario. De esta manera, cualquiera de los usuarios en este papel puede asumir las tareas para completarlas.
    Para un Grupo (Pool)Permite atribuir tareas a un grupo y no solamente a un usuario. Así, cualquiera de los usuarios de este grupo puede asumir las tareas para completarlas.
    Por AsociaciónPermite componer lógicas complejas de atribución asociando varios mecanismos.
    Por Espacio de Formulario

    Permite asignar tareas al usuario en un espacio del formulario del proceso.

    Por Ejecutor de Actividad.Permite seleccionar a los usuarios que ejecutaron una actividad anterior.
    Por grupoPermite apenas a los usuarios que formen parte de un determinado grupo.
    Por Grupos del Usuario.

    Permite filtrar apenas los usuarios que pertenezcan a uno de los grupos del usuario, o del usuario que inició el proceso (solicitante). También permite filtrar apenas los usuarios cuyo grupo de trabajo sea el mismo del usuario (corriente o solicitante).

    Por PapelPermite filtrar apenas los usuarios que tengan un determinado papel.
    Por UsuarioPermite atribuir tareas a un usuario específico.



    Cómo crear un Mecanismo de Atribución.

    La creación de un mecanismo de atribución se realiza mediante el Fluig Sutdio, siendo indispensable la existencia de un previo proyecto Fluig.

    Utilice el paso a paso para conocer el proceso de creación de un mecanismo de atribución de ejemplo:


      Para crear un nuevo mecanismo de atribución personalizado, haga clic con el botón derecho del mouse en el proyecto del Fluig, acceder a la opción New y luego la opción Other. En el asistente abierto, seleccionar la opción "Mecanismo personalizado Fluig" presente en la carpeta Fluir, y luego haga clic en el botón Next:



      El asistente Nuevo Mecanismo Fluis es abierto: Informar el Código y una descripción, y luego haga clic en el botón Finish.



      El archivo JavaScript del mecanismo de atribución se agrega al proyecto en la carpeta mechanisms y es abierto para la edición.

      El script de personalización de mecanismo de atribución recibe como parámetro el código del proceso y el usuario corriente. Este script debe responder una lista de usuarios que pueden asumir la tarea. A continuación indicamos ejemplos de implementación:

      function resolve(process, colleague) {
      	var userList = new java.util.ArrayList();
      	var groupId = colleague.getGroupId();
      	var c1 = DatasetFactory.createConstraint("cdArea", groupId, groupId, ConstraintType.MUST); 
      	var constraints = new Array(c1);
      	
      	var dataset = DatasetFactory.getDataset("dsResponsablesÁrea", null, constraints, null);
      	
      	for (var i = 0; i < dataset.rowsCount; i++) {
      		userList.add(dataset.getValue(i, "cdUsuarioResp"));
      	}
      	
      	return userList;
      }

      Se puede acceder a Datasets y Servicios registrados en el Fluig en la personalización del mecanismo de atribución.


      Finalmente, el mecanismo de atribución personalizado se debe exportar al servidor del Fluig y al realizar la exportación se debe informar obligatoriamente su código y nombre, y opcionalmente una descripción:



      Parámetros Workflow para Personalización de Formularios

      Para procesos que tengan una definición de formulario definida se notificarán algunos parámetros con información sobre el proceso a utilizar en los eventos de la definición de formulario, según se indica a continuación:

      ParâmetroDescrição
      WKDefCódigo del proceso
      WKVersDefVersión del proceso
      WKNúmProcesNúmero de la solicitud de proceso
      WKNumState

      Número de la actividad ejecutada

      WKCurrentState

      Número de la actividad actual

      WKCompanyNúmero da empresa
      WKUserCódigo del usuario corriente
      WKCompletTaskSi la tarea ha sido completada (true/false)
      WKNextStateNúmero de la próxima actividad (destino)
      WKCardIdCódigo del formulario del proceso
      WKFormIdCódigo de la definición de formulario del proceso
      WKIdentityCompanyIdentificador de la Empresa seleccionada para experiencias de uso TOTVS


      En los scripts de los eventos de la definición de formulario se puede recuperar la información con el comando getValue según se indica en el ejemplo a continuación:

      var vCodProcess = getValue("WKDef");


      Personalización de correo electrónico

      Es posible incluir personalizaciones de correo electrónico durante el curso de un workflow. Existen dos modalidades de personalización en esta categoría:

      • Envío y modificación de correo electrónico patrón a través del evento onNotify;
      • Envío de correo electrónico personalizado en cualquier evento del workflow.

      Envío de correo electrónico Patrón

      Para interferir en el envío de un correo electrónico patrón, se debe utilizar el evento onNotify, que se ejecuta en el mismo instante en que se envía cualquiera de los dos correo electrónicos de proceso. En este evento, se pueden realizar modificaciones, como por ejemplo agregar otros destinatarios al correo electrónico (además de aquellos que están participando del proceso), modificar los valores de los parámetros utilizados en el template de correo electrónico, etc.

      A continuación se indica un ejemplo de cómo implementar este evento:

      function onNotify(subject, receivers, template, params) {
      	if (template.match("TPLPROCESS_NEW_STATE_TO_MANAGER") != null) {
      		receivers.add("[email protected]");
      	}
      }

      Atención

      A partir de la versión 1.3.3 del Fluig, se recomienda realizar la validación del template utilizando template == "TPLPROCESS_NEW_STATE_TO_MANAGER" y no la función match(), para de esta manera evitar redundancias en la personalización, ya que el match() se puede volver true para más de un template en casos como TPLNEW_TASK e TPLNEW_TASK_POOL_GROUP.


      El evento onNotify se encuentra disponible en la lista de eventos del proceso. Por lo tanto, al seleccionar ese evento en la lista de eventos disponibles, la firma de la función anterior se completará automáticamente. Este evento ofrece los siguientes parámetros:


      Parámetro
      Descripción
      subjectEs el asunto del correo electrónico. La modificación de esta variable implicará que todos los usuarios reciban el correo electrónico con el nuevo asunto configurado, incluso aquellos que participan del proceso. Ejemplo de utilización: subject.add("ASUNTO");
      receiversLista de correo electrónicos destinatarios: También es posible agregar otros correo electrónicos de usuarios que no participan del proceso. Incluso, se pueden agregar correo electrónicos de usuarios que no estén registrados en el Fluig, en caso sea necesario notificar una persona que no tenga acceso al sistema.
      templatePermite validar qué tipo de correo electrónico se está enviando (por ejemplo, template de nueva tarea, notificación de gestor, etc). Basado en esta variable podemos distinguir qué correo electrónicos queremos personalizar. Se recomienda que siempre se verifique el código del template, para evitar que ocurran modificaciones en otros tipos de correo electrónicos, que no requieran personalización.
      paramsEs un mapa de datos que permite modificar/incluir parámetros para que se puedan presentar en el correo electrónico. El nombre de los parámetros informados en este mapa deben ser los mismos que se utilizan dentro del archivo de template.

      En este que ejemplo que se indicó anteriormente, es válido si el template es PLPROCESS_NEW_STATE_TO_MANAGER  (que corresponde a la Notificación del Gestor), en caso positivo, se agregará un nuevo correo electrónico en la lista de destinatarios. Es decir, además del gestor del proceso se notificará a otra persona, que recibirá una copia del correo electrónico que el gestor recibirá. Como se está validando el código del template, no impactará en los otros tipos de correo electrónico.

      Los templates se pueden encontrar en el directorio del volumen en: <VOLUME>\templates\tplmail. Si es necesario agregar algún parámetro en el correo electrónico patrón, los templates pueden editarse directamente del directorio.


      Envío de correo electrónico Personalizado

      Se deberá incluir, si es necesario, un nuevo tipo de correo electrónico, además de aquellos que se encuentran disponibles por el producto, el Fluig permite que el usuario registre templates de correo electrónicos personalizados, a través de la opción Templates de correo electrónicos localizada en la pestaña Generales del Panel de Control

      Para incluir un nuevo Template, se debe accionar la opción Agregar en el menú y completar los datos solicitados. En esta etapa también se debe realizar el upload del archivo de template.

      Para agregar parámetros dentro de un archivo de template (TXT ou HTML), se debe utilizar la siguiente señalización:

      ${NOMBRE_DEL_PARÁMETRO}


      En este caso, se utilizará el identificador "NOMBRE_DEL_PARÁMETRO" durante la personalización para atribuir un valor a este parámetro. Se pueden consultar los templates disponibles en el volumen de la empresa (<VOLUME>\templates\tplmail) para acceder a más ejemplos respecto a la utilización de parámetros.

       Después de registrar un nuevo template, es posible utiliarlo para enviar un correo electrónico a partir de cualquiera de los eventos del proceso (excepto en el onNotify – ver "Envío de correo electrónico Patrón")  Para realizar el envío de un correo electrónico, basado en un template personalizado, se debe utilizar el objeto notifier, llamando la función "notify", según el código indicado a continuación:

      try{
      	//Prepara mapa con parámetros del template 
      	var parámetros = new java.util.HashMap();
      	parámetros.put("NOMBRE_USUARIO", "JOAO");
      	parámetros.put("CÓDIGO_USUARIO", "01");
      	//Este parámetro es obligatorio y representa el asunto del correo electrónico
      	parámetros.put("subject", "ASUNTO");
      	//Prepara lista de destinatarios
      	var destinatarios = new java.util.ArrayList();
      	destinatarios.add("CÓDIGO-DESTINATARIO");
      	//Envía correo electrónico
      	notifier.notify("MATRÍCULA-REMITENTE", "CÓDIGO-TEMPLATE", parámetros, destinatarios, "text/html");
      } catch(e){
      	log.info(e);
      }

      Otra forma de ejecutar el método de envío de correo electrónico es informar el número de la ficha, según se indica a continuación:

      notifier.notify("MATRÍCULA-REMITENTE", NÚMERO DEL FORMULARIO, "CÓDIGO-TEMPLATE", parámetros, destinatarios, "text/html");

      Atención

       Es obligatorio que el valor informado sea un formulario. No se aceptarán otros tipos de documentos y resultará en un error en la ejecución del evento.


      Al ejecutar este método automáticamente los parámetros a continuación se agregarán a la lista de parámetros y podrán utilizarse en el template.

      Parámetro
      Descripción
      WDK_CardContentContenido HTML del formulario (simula la visualización)
      WDK_DocumentAuthorNombre del Autor
      WDK_DocumentCommentsComentario adicional
      WDK_DocumentDescriptionDescripción del formulario
      WDK_DocumentIconImageImagen del icono del formulario
      WDK_DocumentNumberNúmero del formulario
      WDK_DocumentUpdatedDateFecha de actualización del formulario
      WDK_DocumentVersionVersión de formulario
      WDK_DocumentViewLinkLink para acceder al formulario