Árvore de páginas

Versões comparadas

Chave

  • Esta linha foi adicionada.
  • Esta linha foi removida.
  • A formatação mudou.

Índice

Índice
outlinetrue
stylenone
exclude.*ndice
stylenone

 

Propriedades extensão

As propriedades de extensão contêm informações especiais que podem alterar o comportamento padrão do processo em algum ponto. Elas devem ser utilizadas principalmente durante a fase de desenvolvimento sob a plataforma ou conter "flags" especiais que alterem alguma lógica interna (apenas em casos especiais).

...

Para a utilização desta funcionalidade, basta utilizar o trecho loading.setMessage(String message) na implementação do evento, conforme exemplo no trecho de código abaixo:

Bloco de código
languagejavascript
themeEclipselanguagejavascript
firstline1
linenumberstrue
function validateForm(form){
	
	loading.setMessage("Validando campos de formulário");
	
	if(form.getValue('nome') == null || form.getValue('nome') == '') {
		throw "Campo nome não está preenchido";
	}

	loading.setMessage("");
}

...

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

Permite acessar o valor de um campo do formulário do processo, onde:

  • nomeCampo: nome do campo do formulário.
setCardValue("nomeCampo", "valor")

Permite definir o valor de um campo do formulário do processo, onde:

  • nomeCampo: nome do campo do formulário;
  • valor: valor a ser definido para o campo do formulário.
setAutomaticDecision(numAtiv, listaColab, "obs")

Permite definir o fluxo de saída de uma atividade de forma automática, onde:

  • numAtiv: número da atividade destino;
  • listaColab: lista (do tipo String) dos usuários que receberão a tarefa;
    • Deve ser passada a matricula dos usuários que receberão a tarefa.
    • Se a atividade destino for automática ou um evento intermediário que não possui usuário, deve ser informado "System:Auto" no lugar da matrícula.
  • obs: observação da tarefa;

    Bloco de código
    languagejs
    themeEclipselanguagejs
    function afterStateEntry(sequenceId){
    	if(sequenceId == 4){
    		var users = new java.util.ArrayList();
    		
    		//Caso a próxima atividade seja uma automática utilizar users.add("System:Auto");
    		users.add("adm"); 
    
    		hAPI.setAutomaticDecision(7, users, "Decisao tomada automaticamente pelo Fluig");
    		
    	}
    }
    Informações

    É necessário adicionar na Extensão do Processo a propriedade AutomaticTasks com a lista de todas as atividades que terão decisão delegada por desenvolvimento sob a plataforma. Exemplo: AutomaticTasks=4

    Nota

    A propriedade AutomaticTasks marca uma atividade comum como uma automática, isso significa que ela tem comportamentos semelhantes a uma atividade automática, incluindo que ela não gera notificações durante sua execução.

getActiveStates()Retorna uma lista das atividades ativas do processo.
getActualThread(numEmpresa, numProcesso, numAtiv)

Retorna a thread da atividade que está ativa, lembrando que em caso de atividades paralelas, retorna 0, 1, 2 e assim sucessivamente.

  • numEmpresa: número da empresa;
  • numProcesso: número da solicitação;
  • numAtiv: número da atividade.
Exemplo de uso para esta função:

 

Bloco de código
languagejavascript
themeEclipselanguagejavascript
firstline1
linenumberstrue
function afterTaskCreate(colleagueId) {

    var nrProxAtividade = getValue("WKNextState");
    if (nrProxAtividade == "5"){ //atividade entre paralelas
 
		var data = new Date();
		var numEmpresa = getValue("WKCompany");
	
		//seta o dia, mês (Janeiro é 0) e ano
		data.setDate(20);
		data.setMonth(10);
		data.setFullYear(2010);
	   
		// Recupera o numero da solicitação
		var numProcesso = getValue("WKNumProces");
	
		// Seta o prazo para as 14:00
		hAPI.setDueDate(numProcesso, hAPI.getActualThread(numEmpresa, numProcesso, nrProxAtividade), colleagueId, data, 50400);
	}
}
setDueDate(numProcesso, numThread, "userId", dataConclusao, tempoSeg)

Permite alterar o prazo de conclusão para uma determinada atividade do processo, onde:

  • numProcesso: número da solicitação;
  • numThread: número da thread (normalmente 0, quando não se utiliza atividades paralelas);
  • userId: o usuário responsável pela tarefa;
  • dataConclusao: a nova data de conclusão;
  • tempoSeg: tempo que representa a nova hora de conclusão, calculado em segundos após a meia-noite.

Informações

Recomendamos a utilização deste método no evento afterTaskCreate, pois será executado logo após a criação da tarefa. Exemplo:

Bloco de código
languagejavascript
themeEclipse
languagejavascript
firstline1
linenumberstrue
function afterTaskCreate(colleagueId) {
	var data = new Date();
	
	//seta o dia, mês (Janeiro é 0) e ano
	data.setDate(20);
	data.setMonth(10);
	data.setFullYear(2010);
	   
	// Recupera o numero da solicitação
	var processo = getValue("WKNumProces");
	
	// Seta o prazo para as 14:00
	hAPI.setDueDate(processo, 0, colleagueId, data, 50400);
}
transferTask(transferUsers, "obs", int numThread)

Transfere uma tarefa de um usuário para outro(s) usuário(s).

  • transferUsers: lista (do tipo String) de usuários;
  • obs: a observação;
  • numThread: sequência da thread, em caso de atividades paralelas.
transferTask(transferUsers, "obs")

Transfere uma tarefa de um usuário para outro(s) usuário(s). Este método não pode ser usado em processos com atividades paralelas:

  • transferUsers: lista (do tipo String) de usuários;
  • obs: a observação.
startProcess(processId, ativDest, listaColab, "obs", completarTarefa, valoresForm, modoGestor)

Inicia uma solicitação workflow, onde:

  • processId: código do processo;
  • ativDest: atividade de destino;
  • listaColab: lista (do tipo String) de usuários;
  • obs: texto da observação;
  • completarTarefa: indica se deve completar a tarefa (true) ou apenas salvar (false);
  • valoresForm: um Mapa com os valores do formulário do processo;
  • modoGestor: indica que o usuário iniciará a solicitação como gestor (true) ou que o usuário iniciará a solicitação apenas como solicitante (false).

Retorna um mapa com informações da solicitação criada. Entre elas, o iProcess que é o número da solicitação criada.

setColleagueReplacement(userId)

Seta um usuário substituto, onde:

  • userId: código do usuário substituto.
setTaskComments("userId", numProcesso,  numThread, "obs")

Define uma observação para uma determinada tarefa do processo, onde:

  • userId: usuário responsável pela tarefa;
  • numProcesso: número da solicitação de processo;
  • numThread: é o número da thread (normalmente 0, quando não se utiliza atividades paralelas);
  • obs: a observação.
Nota
titleAtenção

É recomendado utilizar em eventos do tipo 'after', pois o comentário será criado no histórico da solicitação, então é necessário que já exista uma movimentação do processo para atribuir este comentário.

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")

Retorna o valor da propriedade avançada de um processo.

  • propriedade: nome da propriedade avançada. 
calculateDeadLineHours(data, segundos, prazo, periodId)

Calcula um prazo a partir de uma data com base no expediente e feriados cadastrados no produto passando o prazo em horas:

  • data: data inicial (tipo Date);
  • segundos: quantidade de segundos após a meia noite;
  • prazo: prazo que será aplicado em horas (tipo int);
  • periodId: código de expediente.  

Retorno: Array de Objeto, onde a primeira posição do array é a data e a segunda a hora.

Exemplo:

Bloco de código
language
languagejavascript
themeEclipse
javascriptfirstline1
linenumberstrue
function afterTaskCreate(colleagueId) {
   	var data = new Date();

   	//Calcula o prazo
   	var obj = hAPI.calculateDeadLineHours(data, 50000, 2, "Default");
	var dt = obj[0];
	var segundos = obj[1];

   	//Recupera o numero da solicitação
   	var processo = getValue("WKNumProces");

   	//Altera o prazo do processo
	hAPI.setDueDate(processo,0,colleagueId, dt, segundos);
}
calculateDeadLineTime(data, segundos, prazo, periodId)

Calcula um prazo a partir de uma data com base no expediente e feriados cadastrados no produto passando o prazo em minutos:

  • data: data inicial (tipo Date);
  • segundos: quantidade de segundos após a meia noite;
  • prazo: prazo que será aplicado em minutos (tipo int);
  • periodId: código de expediente.

Retorno: Array de Objeto, onde a primeira posição do array é a data e a segunda a hora.

 Exemplo:

Bloco de código
languagejavascript
themeEclipse
languagejavascript
firstline1
linenumberstrue
function afterTaskCreate(colleagueId) {
	var data = new Date();
	//Calcula o prazo
	var obj = hAPI.calculateDeadLineTime(data, 50000, 120, "Default");
	var dt = obj[0];
	var segundos = obj[1];

	//Recupera o numero da solicitação
	var processo = getValue("WKNumProces");

	// Altera o prazo do processo
	hAPI.setDueDate(processo,0,colleagueId, dt, segundos);
}
getUserTaskLink(numAtiv)

Permite buscar o link para movimentação de uma determinada atividade, e utilizá-lo para enviar um e-mail com template personalizado, por exemplo.

  • numAtiv: número da atividade
Retorno: link para movimentação da solicitação.

 

Nota
titleAtenção

Este método não retorna link para atividades que ainda não foram criadas, ou seja, não pode ser utilizado em eventos como afterTaskComplete(colleagueId,nextSequenceId,userList) para obter o link da atividade com "nextSequenceId".

Exemplo:

Bloco de código
languagejavascript
themeEclipselanguagejavascript
firstline1
linenumberstrue
function afterTaskCreate(colleagueId) {
	var sequenceId = getValue("WKCurrentState");
	if (sequenceId == 2) {
		var destinatarios = new java.util.ArrayList();
		destinatarios.add(colleagueId);
 
		var parametros = new java.util.HashMap();
		parametros.put("WDK_CompanyId", getValue("WKCompany"));
		parametros.put("WDK_TaskLink", hAPI.getUserTaskLink(sequenceId));
 
		notifier.notify(getValue("WKUser"), "tplCustomizado", parametros, destinatarios, "text/html");	
	}
}
createAdHocTasks(workflowProcessInstanceId, sequenceId, assunto, detalhamento, listatvidadesAhoc)

Permite a criação de atividades adhoc dentro dos eventos do fluig

  • workflowProcessInstanceId: número da solicitação workflow no qual se deseja criar as tarefas;
  • sequenceId: código de sequencia da atividade de SubprocessoAdhoc;
  • Assunto: assunto da listagem das tarefas que será repassado ao formulário de atividade ad-hoc;
  • Detalhe: texto com o detalhamento das atividades em questão. Esse texto também será repassado para o formulário da atividade ad-hoc;
  • listaAtividadesAdhoc: é a lista de atividades contento o que, quando e quem executará as tarefas ad-hoc.

Nota
titleAtenção

Certifique-se que o sequenceId é a sequência da atividade ad-hoc. Normalmente esta atividade contém o símbolo do sub-processo comum acompanhado do identificador "~", conforme exemplo abaixo :

A sequência pode ser consultada a partir do plugin fluig Designer verificando o campo código ao visualizar as propriedades da atividade de subprocesso ad-hoc.

 

Exemplo:

Bloco de código
languagejavascript
themeEclipse
languagejavascript
firstline1
linenumberstrue
function afterStateEntry(sequenceId){
	//lista das tarefas
	var adHocTasks = new Array();
	// variavel com o código da solicitação do processo.
    var process = getValue("WKNumProces");
    
    //criando uma tarefa
    var task = { name:"nome da tarefas", responsible:"adm", dueDate:"10/10/2014"};
    //adicionando a tarefa criada para a lista de tarefas
    adHocTasks.push(task);
	
    
    // process    = numero da solicitacao 
    // sequenceId = codigo processstate da atividade que tem o processo ad-hoc
    // meeting    = nome do assunto em questao
    // detalhe    = detalhamento do assunto
    // adHocTasks   lista te tarefas
   
    hAPI.createAdHocTasks(process, sequenceId, "Assunto das tarefas", "Detalhamento do assunto ", adHocTasks);
	 
	
}
listAttachments()

Retorna a lista de anexos do processo.

Nota
titleAtenção

O formulário do processo não é retornado, apenas anexos do tipo GED e Workflow.

publishWorkflowAttachment(documento)

Permite publicar anexos workflow da solicitação no GED do fluig, onde:

  • documento: anexo workflow a ser publicado no GED.

Nota
titleAtenção

É obrigatório informar o id da pasta destino do documento através do método setParentDocumentId, conforme o exemplo abaixo.

 

Exemplo:

Bloco de código
language
languagejavascript
themeEclipse
javascriptfirstline1
linenumberstrue
function beforeStateEntry(sequenceId){
	if (sequenceId == 4) {
		var calendar = java.util.Calendar.getInstance().getTime();
		var docs = hAPI.listAttachments();
		for (var i = 0; i < docs.size(); i++) {
			var doc = docs.get(i);
			
			if (doc.getDocumentType() != "7") {
				continue;
			}
			
			doc.setParentDocumentId(27);
			doc.setVersionDescription("Processo: " + getValue("WKNumProces"));
			doc.setExpires(false);
			doc.setCreateDate(calendar);
			doc.setInheritSecurity(true);
			doc.setTopicId(1);
			doc.setUserNotify(false);
			doc.setValidationStartDate(calendar);
			doc.setVersionOption("0");
			doc.setUpdateIsoProperties(true);
			
			hAPI.publishWorkflowAttachment(doc);
		}
	}
}

attachDocument(documentId)

Âncora
attachDocumentDocs
attachDocumentDocs

Permite anexar documentos do GED a solicitação workflow, onde:

  • documentId: código do documento a ser anexado a solicitação.

Exemplo:

Bloco de código
languagejavascript
themeEclipselanguagejavascript
firstline1
linenumberstrue
function beforeStateEntry(sequenceId) {
	var docList = [44, 46, 135];
	
	if (sequenceId == 2) {
		for (var i = 0; i < docList.length; i++) {
			var docId = docList[i];
			hAPI.attachDocument(docId);
		};	
	}
}

getAvailableStatesDetail(companyId, userId, processId, processInstanceId, threadSequence)

Retorna detalhes das atividades disponíveis para seleção.

Parâmetros:

  • companyId: código da empresa;
  • userId: id do usuário;
  • processId: código do processo;
  • processInstanceId: número da solicitação;
  • threadSequence: indica se existe atividade paralela no processo. Se não existir o valor é 0 (zero), caso exista, este valor pode ser de 1 a infinito, dependendo da quantidade de atividade paralelas existentes no processo.

Retorno: ProcessStateDto[].

getChildrenInstances(processInstanceId)

Retorna uma lista com os números das solicitações filhas, onde:

  • processInstanceId: número da solicitação pai.

Exemplo:

Bloco de código
languagejs
themeEclipse
languagejs
firstline1
function afterStateEntry(sequenceId){
if (sequenceId == 5) {
    var numProcess = getValue("WKNumProces");

    // Busca a Lista com o número da solicitação dos filhos
    var childrenProcess = hAPI.getChildrenInstances(numProcess);

    for (var i = 0; i < childrenProcess.size(); i++) {
    	// Busca os dados do formulário da solicitação filha
    	var childCardData = hAPI.getCardData(childrenProcess.get(i));

    	// Replica um dado do formulário da solicitação filha para o formulário da solicitação pai
    	var obs = childCardData.get("obs");
    	hAPI.setCardValue("obs", obs );
    	}
	}
}


getParentInstance(processInstanceId)

Retorna o número da solicitação pai, onde:

  • processInstanceId: número da solicitação filha.

Exemplo:

Bloco de código
languagejavascript
themeEclipse
languagejavascript
firstline1
linenumberstrue
function beforeStateEntry(sequenceId) {
    if (sequenceId == 2) {
        var numProcess = getValue("WKNumProces");
    
        // Busca o número da solicitação pai
        var parentProcess = hAPI.getParentInstance(numProcess);
 
        // Busca os dados do formulário da solicitação pai
        var parentCardData = hAPI.getCardData(parentProcess);
 
        // Replica um dado do formulário da solicitação pai para o formulário da solicitação filha
        var cnpj = parentCardData.get("cnpj");
        hAPI.setCardValue("cnpj", cnpj);
    } 
}
addCardChild(tableName, cardData)

Adiciona um filho no formulário pai e filho do processo, onde:

  • tableName: nome da tabela filha onde será criado o filho;
  • cardData: mapa com os campos do filho e seus valores.

Exemplo:

Bloco de código
languagejavascript
themeEclipselanguagejavascript
firstline1
linenumberstrue
function beforeStateEntry(sequenceId) {
	if (sequenceId == 4) {
		var childData = new java.util.HashMap();
		childData.put("matricula", "0041");
		childData.put("nome", "João Silva");
		childData.put("cpf", "44455889987");
		hAPI.addCardChild("funcionarios", childData);
	}
}

...

Abaixo um exemplo de como executar o WebService de Colleague para criar um usuário no fluig após executar uma tarefa:

Bloco de código
languagejavascript
themeEclipse
languagejavascript
firstline1
linenumberstrue
function afterTaskComplete(colleagueId, nextSequenceId, userList) {
	
	if (nextSequenceId == 2) {
		//Busca o webservices de Colaborador
		var colleagueServiceProvider = ServiceManager.getServiceInstance("Colleague");
		var colleagueServiceLocator = colleagueServiceProvider.instantiate("com.totvs.technology.ecm.foundation.ws.ECMColleagueServiceService");
		var colleagueService = colleagueServiceLocator.getColleagueServicePort();
	
		//Cria o ColleagueDto – Verificar a lista de métodos na visualização do serviço
		var colleagueDto = colleagueServiceProvider.instantiate("com.totvs.technology.ecm.foundation.ws.ColleagueDto");
		colleagueDto.setCompanyId(1);
		colleagueDto.setColleagueId("teste");
		colleagueDto.setColleagueName("Usuario Teste");
		colleagueDto.setActive(true);
		colleagueDto.setVolumeId("Default");
		colleagueDto.setLogin("teste");
		colleagueDto.setMail("[email protected]");
		colleagueDto.setPasswd("teste");
		colleagueDto.setAdminUser(false);
		colleagueDto.setEmailHtml(true);
		colleagueDto.setDialectId("pt_BR");
		
		//Cria o colleagueDtoArray e adiciona
		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);
	}
}

...

Abaixo um outro exemplo utilizando o WebService ECMCardService para alterar o valor do campo de um registro de formulário após a entrada em uma nova atividade:

Bloco de código
languagejs
themeEclipse
languagejs
firstline1
linenumberstrue
function afterStateEntry(sequenceId){
	if (sequenceId == 2) {
		//Servico "<url_fluig>/webdesk/ECMCardService?wsdl"cadastrado com o código "CardService"
		var cardServiceProvider = ServiceManager.getServiceInstance("CardService");
 		var cardServiceLocator = cardServiceProvider.instantiate("com.totvs.technology.ecm.dm.ws.ECMCardServiceServiceLocator");
 		var cardService = cardServiceLocator.getCardServicePort();
 		var cardFieldDtoArray = cardServiceProvider.instantiate("com.totvs.technology.ecm.dm.ws.CardFieldDtoArray");
 		var cardField = cardServiceProvider.instantiate("com.totvs.technology.ecm.dm.ws.CardFieldDto");
 	
		//Seta valor no campo com name = 'nome'
 		cardField.setField("nome");
 		cardField.setValue("Valor alterado via WS dentro de um evento workflow");
 
		var vetCardFields = new Array();
		vetCardFields.push(cardField);
 		cardFieldDtoArray.setItem(vetCardFields);
 	
		//Altera o(s) campo(s) do registro de formulário.
		//updateCardData(tenantId, login, senha, codRegistroForm, cardFieldDtoArray);
 		cardService.updateCardData(1, "adm", "adm", 8, cardFieldDtoArray);
	}
}

...

EventoDescriçãoParâmetros
afterCancelProcess

Ocorre após o cancelamento da solicitação. É recomendado não disparar exceções neste método, pois o cancelamento já foi realizado.

  • Usuário corrente (String);
  • Número do processo (Integer).
afterProcessCreate

Ocorre logo após a criação de um novo processo.

 

  • Número do novo processo (Integer).
afterProcessFinish

Ocorre após finalizada a solicitação.

  • Número do processo (Integer).
afterReleaseVersion

Ocorre após a liberação de uma versão do processo.

  • XML com a definição do processo (String).
afterStateEntryOcorre após a entrada em uma nova atividade.
  • Sequência da atividade (Integer).
afterStateLeaveOcorre após a saída de uma atividade.
  • Sequência da atividade (Integer).
afterTaskComplete

Ocorre após o usuário completar uma tarefa, porém as informações de próxima tarefa e usuários destino já foram salvas.

  • Usuário corrente (String);
  • Sequência da próxima atividade (Integer);
  • Lista de usuários destino (List<String>).
afterTaskCreateOcorre após o usuário receber uma tarefa.
  • Matrícula do usuário (String).
afterTaskSave

Ocorre após salvar as informações selecionadas pelo usuário.

  • Usuário corrente (String);
  • Sequência da próxima atividade (Integer);
  • Lista de usuários destino (List<String>).
beforeCancelProcess

Ocorre antes do cancelamento da solicitação.

  • Usuário corrente (String);
  • Número do processo (Integer).
beforeStateEntryOcorre antes da entrada em uma nova atividade.
  • Sequência da atividade (Integer).
beforeStateLeaveOcorre antes da saída de uma atividade.
  • Sequência da atividade (Integer).
beforeTaskComplete

Ocorre antes que o usuário complete uma tarefa, porém as informações de próxima tarefa e usuários destino já foram salvas.

Nota
titleObservação

Diferente dos demais eventos do tipo before, este evento não dispara suas validações ao servidor, fazendo com que o sistema não pare a movimentação da atividade quando o mesmo lança uma exceção.

  • Usuário corrente (String);
  • Seqüência da próxima atividade (Integer);
  • Lista de usuários destino (List<String>).
beforeTaskCreateOcorre antes que o usuário receba uma tarefa.
  • Matrícula do usuário (String).
beforeTaskSave

Ocorre antes de salvar as informações selecionadas pelo usuário.

  • Usuário corrente (String);
  • Sequência da próxima atividade (Integer);
  • Lista de usuários destino (List<String>).
calculateAgreement

Ocorre após o cálculo do consenso (somente para atividades conjuntas) e permite alterar os dados do consenso de uma atividade.

Exemplo:

Bloco de código
languagejavascript
themeEclipselanguagejavascript
firstline1
linenumberstrue
function calculateAgreement(currentState, agreementData) {
	log.info("Consenso Atual: " + agreementData.get("currentPercentage"));
	log.info("Atividade Destino Atual: " +  agreementData.get("currentDestState"));
	log.info("Usuario Destino Atual: " + agreementData.get("currentDestUsers"));
	
	//Altera o consenso
	agreementData.put("currentPercentage", 100);
	agreementData.put("currentDestState", 2);
	agreementData.put("currentDestUsers", "adm,teste,super");
}
  • currentState (Integer): atividade que terá o consenso alterado;
  • agreementData (Map<String, Object>): mapa de dados com o percentual calculado, a atividade destino e os usuários de destino. Para obter os valores, utilize o método "get" e para atribuir um valor, utilize o método "put".
onNotify

Se refere a um evento global que ocorre após a movimentação da solicitação e antes de enviar as notificações.

Para mais detalhes consulte a página Desenvolvimento de eventos - On Notify.
setProcess

Ocorre quando um processo é "setado" na API.

Nota
titleObservação

A propriedade WKCompletTask não deve ser utilizada neste evento, pois quando ele é executado o produto ainda não tem a informação se atividade foi ou não completada.

  • Número do processo (Integer).
subProcessCreatedOcorre quando um sub-processo é criado.
  • Número do sub-processo (Integer).
validateAvailableStates

Ocorre após montada a lista de tarefas disponíveis para o usuário a partir da tarefa atual.

  • Sequência da atividade atual (Integer);
  • Lista das sequências das atividades (List<Integer>).  

...

Nota
titleImportante!

Não é possível capturar (hAPI.getCardValue) ou adicionar (hAPI.setCardValue) dados no formulário na inicialização do processo, sendo possível somente a partir da segunda tarefa.

Para isso pode ser utilizada a seguinte lógica:

Bloco de código
language
languagejavascript
themeEclipse
javascriptfirstline1
linenumberstrue
function beforeStateEntry(sequenceId) {
	if (sequenceId  != "NUMERO_DA_ATIVIDADE_INICIAL") {
		var campo = hAPI.getCardValue("campo1");
	}
}

...

MétodoEspecificação
copyDocumentToUploadArea(documentId, version)

Copia os arquivos físicos de um documento existente para a área de upload do usuário logado, onde:

  • documentId: id do documento a ser copiado;
  • version: versão do documento a ser copiado;

Retorno: Array de Strings contendo os nomes dos arquivos que foram disponibilizados na área de upload.

createDocument(document, attachments, securityConfig, approvers, relatedDocs)

Cria um novo documento no GED de acordo com os parâmetros informados, onde:

  • document: documento a ser criado;
  • attachments: lista de anexos do documento;
  • securityConfig: lista de configurações de segurança do documento;
  • approvers: lista de aprovadores do documento;
  • relatedDocs: lista de documentos relacionados ao documento;

Retorno: DocumentDto do documento criado.

Exemplo de utilização desta função em conjunto com a função copyDocumentToUploadArea:

Bloco de código
language
languagejavascript
themeEclipse
javascriptfirstline1
linenumberstrue
function beforeStateEntry(sequenceId) {

	if (sequenceId == 5) {
		var attachments = hAPI.listAttachments();
		for ( var i = 0; i < attachments.size(); i++) {
			var docDto = attachments.get(i);

			if (docDto.getDocumentType() == "7") {
				
				docAPI.copyDocumentToUploadArea(docDto.getDocumentId(), docDto.getVersion());
		
				docDto.setDocumentId(0);
				docDto.setParentDocumentId(20);
		
				var attachArray = new java.util.ArrayList();
				var mainAttach = docAPI.newAttachment();
				mainAttach.setFileName(docDto.getPhisicalFile());
				mainAttach.setPrincipal(true);
				mainAttach.setAttach(false);
				attachArray.add(mainAttach);
		
				try {
					var doc = docAPI.createDocument(docDto, attachArray, null, null,null);
					log.info("DOCUMENTO CRIADO COM O ID: " + doc.getDocumentId());
				} catch (e) {
					log.error("Problemas na criação do documento:\n" + e);
				}
			}
		}
	}
}
createFolder(document, securityConfig, approvers)

Cria uma nova pasta no GED de acordo com os parâmetros informados, onde:

  • document: pasta a ser criada;
  • securityConfig: lista de configurações de segurança da pasta;
  • approvers: lista de aprovadores da pasta;

Retorno: DocumentDto da pasta criada.

Exemplo de utilização desta função:

Bloco de código
languagejavascript
themeEclipselanguagejavascript
firstline1
linenumberstrue
function afterProcessFinish(processId) {
	try {
		var dto = docAPI.newDocumentDto();
		dto.setDocumentDescription("Planilhas");
		dto.setDocumentType("1");
		dto.setParentDocumentId(20);
		dto.setDocumentTypeId("");
		
		var folder = docAPI.createFolder(dto, null, null);
		log.info("PASTA CRIADA COM O ID :" + folder.getDocumentId());
	} catch (e) {
		log.error("Problemas na criação da pasta:\n" + e);
	}
}
getDocumentVersion(documentId, version)

Retorna o DocumentDto de um documento com base no seu id e sua versão, onde:

  • documentId: id do documento a ser retornado;
  • version: versão do documento a ser retornado;

 

getUserPermissions(documentId, version)

Retorna o nível de permissão do usuário logado no documento informado, onde:

  • documentId: id do documento;
  • version: versão do documento;

isUserInGroup(group)

Retorna se o usuário logado faz parte do grupo informado, onde:

  • group: código do grupo a ser verificado;
newAttachment()

Retorna uma nova instância de Attachment.

newRelatedDocumentDto()

Retorna uma nova instância de RelatedDocumentDto.

newDocumentSecurityConfigDto()

Retorna uma nova instancia de DocumentSecurityConfigDto.

newApproverDto()

Retorna uma nova instância de ApproverDto.

newDocumentDto()

Retorna uma nova instância de DocumentDto, com o tipo 2 (Documento) como padrão.

...

Deck of Cards
effectDuration0.5
historyfalse
idsamples
historyfalse
effectTypefade
Card
defaulttrue
id1
labelExemplo 1

Para validar se o usuário está completando uma atividade corretamente, basta utilizar o evento beforeTaskSave e retornar alguma mensagem caso queira disparar um erro. Por exemplo, segue parte de um código de desenvolvimento de um processo sob a plataforma:

Bloco de código
languagejavascript
themeEclipselanguagejavascript
firstline1
linenumberstrue
function beforeTaskSave(colleagueId, nextSequenceId, userList) {
	var ativAtual = getValue("WKNumState");
	var process = parseInt(globalVars.get("process"));
	
	var resp1 = hAPI.getCardValue("resp1_H");
	var eficacia1 = hAPI.getCardValue("eficaz1");  
	var controle1 = hAPI.getCardValue("controle1");
	var eficaz = true;

	var users = new java.util.ArrayList();

	if (ativAtual == 7 && nextSequenceId == 12) {
		if (resp1 != "" && eficacia1 != "1" && eficacia1 != "2") {
			if (verificaUsuario(users, resp1)) {
				users.add(resp1);
			}
		}

		hAPI.setAutomaticDecision(8, users, "Decisao tomada automaticamente pelo Fluig.");
	
	} else if (ativAtual == 9 && nextSequenceId == 13) {
		if (resp1 != "" && eficacia1 == "2" && controle1 == ""){
			eficaz = false;
		}

		if (eficaz) {
			var codGrupo = buscaGrupo(process, "Qualidade");
			users.add("Pool:Group:" + codGrupo);
			hAPI.setAutomaticDecision(6, users , "Decisao tomada automaticamente pelo Fluig.");
		}
	}
}
Card
id2
labelExemplo 2

Para fazer com que uma decisão seja tomada automaticamente, os seguintes procedimentos devem ser executados:

  1. Adicionar na Extensão do Processo a propriedade AutomaticTasks com a lista de todas as atividades que terão decisão delegada via desenvolvimento sob a plataforma. Exemplo: AutomaticTasks=3,6,10.
  2. Implementar o evento beforeStateEntry e executar o método "setAutomaticDecision" da hAPI, passando como parâmetros a próxima atividade, o próximo usuário (ou lista de usuários) e uma observação.

 

Bloco de código
languagejavascript
themeEclipse
languagejavascript
firstline1
linenumberstrue
function beforeStateEntry(sequenceId) {    
	var userList = new java.util.ArrayList();
	userList.add("adm");
	hAPI.setAutomaticDecision(6, userList, "Decisao tomada automaticamente pelo Fluig.");
}
Informações

As atividades com decisão automática também podem ser criadas via editor de processo.

Card
id3
labelExemplo 3

Para iniciar uma nova solicitação de um outro processo ao finalizar uma solicitação podem ser executados os seguintes procedimentos:

  1. Cadastrar um serviço no fluig em que a URL seja o WSDL do serviço ECMWorkflowEngineService.
  2. Implementar o evento afterProcessFinish utilizando o exemplo abaixo, sendo ‘process2’ o novo processo a ser inicializado.

Bloco de código
languagejs
themeEclipse
languagejs
firstline1
linenumberstrue
function afterProcessFinish(processId) {
	
	// Servico <url_fluig>/webdesk/ECMWorkflowEngineService?wsdl
	// Busca o webservice cadastrado com o código "WorkflowEngineService"
	var workflowEngineServiceProvider = ServiceManager.getServiceInstance("WorkflowEngineService");
	var workflowEngineServiceLocator = workflowEngineServiceProvider.instantiate("com.totvs.technology.ecm.workflow.ws.ECMWorkflowEngineServiceService");
	var workflowEngineService = workflowEngineServiceLocator.getWorkflowEngineServicePort();
 
	// Cria o ProcessAttachmentDtoArray
	var processAttachmentDtoArray = workflowEngineServiceProvider.instantiate("com.totvs.technology.ecm.workflow.ws.ProcessAttachmentDtoArray");

	// Cria o ObjectFactory
	var objectFactory = workflowEngineServiceProvider.instantiate("net.java.dev.jaxb.array.ObjectFactory");
	
	// Cria um String[][]
	var cardData = objectFactory.createStringArrayArray();
	
	// Cria uma solicitação
	workflowEngineService.simpleStartProcess("adm", "adm", 1, "process2", "Comment", processAttachmentDtoArray, cardData);	
}
Informações

Existem outros métodos parar iniciar uma solicitação, consulte-os aqui.

Lembre-se de consultar a classe ObjectFactory do serviço, essa classe possui diversos métodos para criar instância de objetos necessários para utilização do serviço.

...

Abaixo é apresentado os modelos para utilização em cada um dos eventos:

Bloco de código
language
languagejavascript
themeEclipse
javascriptfirstline1
linenumberstrue
function beforeStateEntry(sequenceId) {
	var activity = getValue("WKNumState");
	if (activity == 0 || activity == 1) {
		//Outra condição.
		throw "TRATAMENTO DE EXCEÇÃO";
	}
}

function beforeTaskSave(colleagueId, nextSequenceId, userList) {
	var activity = getValue("WKNumState");
	if (activity != 0 && activity != 1) {
		//Outra condição
		throw "TRATAMENTO DE EXCEÇÃO";
	}
}

function beforeCancelProcess(colleagueId, processId) {
	//Condição.
	throw "TRATAMENTO DE EXCEÇÃO";
}

...

É possível consultar o campo Observação de uma solicitação de processo, verificando se ele foi preenchido ou não. Para isto, é necessário validar a propriedade WKUserComment no evento beforeTaskSave ou no evento beforeCancelProcess. Exemplo:

Bloco de código
languagejavascript
themeEclipse
languagejavascript
firstline1
linenumberstrue
function beforeTaskSave(colleagueId, nextSequenceId, userList) {
	if (getValue("WKUserComment") == null || getValue("WKUserComment") == "") {
		throw "A observação deve ser preenchida";
	}	
}

function beforeCancelProcess(colleagueId, processId) {
	if (getValue("WKUserComment") == null || getValue("WKUserComment") == "") {
		throw "A observação deve ser preenchida";
	}	
}

...

Deck of Cards
startHiddenfalse
effectDuration0.5
historyfalse
idmecatrib
historyfalse
effectTypefade
Card
defaulttrue
id1
label1º Passo

 

Para criar um novo mecanismo de atribuição desenvolvido sob a plataforma, clicar com o botão direito do mouse no projeto do fluig, acessar a opção New e então a opção Other. No assistente aberto, selecionar a opção "Mecanismo customizado fluig" presente na pasta fluig e clicar no botão Next:

 

Card
id2
label2º Passo

 

O assistente Novo mecanismo fluig é aberto. Informar o código e uma descrição e clicar no botão Finish:

 

Card
id3
label3º Passo (Implementação)

 

O arquivo JavaScript do mecanismo de atribuição é adicionado ao projeto na pasta mechanisms e aberto para edição.

O script de mecanismo de atribuição desenvolvido sob a plataforma recebe como parâmetro o código do processo e o usuário corrente. Este script deve retornar uma lista dos usuários que podem assumir a tarefa. Abaixo, exemplo de implementação:

Bloco de código
languagejavascript
themeEclipselanguagejavascript
firstline1
linenumberstrue
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("dsResponsaveisArea", null, constraints, null);
	
	for (var i = 0; i < dataset.rowsCount; i++) {
		userList.add(dataset.getValue(i, "cdUsuarioResp"));
	}
	
	return userList;
}
Informações

É possível acessar Datasets e Serviços cadastrados no fluig no desenvolvimento do mecanismo de atribuição sob a plataforma.

Card
id4
labelÚltimo Passo (Exportação)


Por fim, o mecanismo de atribuição desenvolvido sob a plataforma deve ser exportado para o servidor do fluig e ao realizar a exportação deve ser informado obrigatoriamente seu código e nome, e opcionalmente uma descrição:

 

...

Nos scripts dos eventos da definição de formulário basta recuperar as informações com o comando getValue, conforme exemplo:

Bloco de código
languagejavascript
themeEclipselanguagejavascript
var vCodProcess = getValue("WKDef");

...

EventoDescrição
beforeMovementOptions

É executada quando o usuário pressiona o botão Movimentar antes de serem exibidas as opções de movimentação do processo.

Nota

Se o fluxo não necessitar da interação do usuário, este método não será executado!  

 

Parâmetros:

    • numState: número da atividade atual.

Opcionais:

    • return false: impedirá a execução do processo. Esta opção permite que sejam exibidos erros personalizados no formulário.
    • throw(“Erro”): impedirá a execução e exibirá uma tela de erro padrão do fluig com o texto informado.

Exemplo:

Bloco de código
language
languagejs
themeEclipse
jsfirstline1
linenumberstrue
var beforeMovementOptions = function(numState){
	console.log("-beforeMovementOptions-");
	console.log("numState: " + numState);	
	console.log("valor campo Email: " +document.formulario.email.value);
	if(document.cad01.nome.value === 'false'){
		return false;
	}
	if(document.cad01.nome.value !== ''){
		throw("Erro " + document.formulario.nome.value);
	}
}
beforeSendValidate

Ocorre antes da solicitação ser movimentada, após já ter sido selecionada a atividade destino, o usuário e demais informações necessárias à solicitação.

Parâmetros:

    • numState: número da atividade atual.
    • nextState: número da atividade destino.

Opcionais:

    • return false: impedirá a execução do processo. Esta opção permite que seja exibido um erro personalizado no formulário.
    • throw(“Erro”): impedirá a execução e exibirá uma tela de erro padrão do fluig com o texto informado.

Exemplo:

Bloco de código
languagejs
themeEclipselanguagejs
firstline1
linenumberstrue
var beforeSendValidate = function(numState,nextState){
	console.log("-beforeSendValidate-");
	console.log("numState: " + numState);
	console.log("nextState: " + nextState);	
	throw("Erro Xyz");
}

...