Voltar para o blog
Desenvolvimento Fluig5 min de leitura

Eventos de processo no Fluig: ordem e quando usar

Lista dos eventos de processo do Fluig, a ordem em que disparam ao movimentar uma solicitação e qual usar para validar, integrar ou preencher dados.

Eventos de processo são scripts JavaScript que o Fluig executa em momentos definidos da vida de uma solicitação: ao criar, salvar, movimentar, finalizar ou cancelar. É neles que ficam as regras de negócio que o diagrama sozinho não resolve.

A maior parte dos problemas não vem do código do evento, mas de escolher o evento errado. Uma validação no lugar errado não bloqueia nada, e uma integração no lugar errado deixa a tela presa. Este guia reúne o que a documentação oficial define e como usar isso na prática.

Ordem dos eventos ao movimentar uma solicitação

Quando o usuário clica em Enviar em uma solicitação já iniciada, a ordem é esta:

  1. validateAvailableStates
  2. beforeTaskSave
  3. afterTaskSave
  4. beforeTaskComplete
  5. afterTaskComplete
  6. beforeStateLeave
  7. afterStateLeave
  8. beforeStateEntry
  9. beforeTaskCreate
  10. afterTaskCreate
  11. afterStateEntry
  12. beforeSendData
  13. onNotify

A leitura é simples: primeiro salva a tarefa atual, depois sai da atividade atual, em seguida entra na próxima e cria a nova tarefa.

Ordem em outras ações

Salvar sem enviar: validateAvailableStates, beforeTaskSave e afterTaskSave. Nenhuma atividade muda.

Criar nova solicitação e enviar: a sequência começa pela entrada na atividade inicial (beforeStateEntry, beforeTaskCreate, afterTaskCreate, afterStateEntry), passa pelo salvamento e pela conclusão da tarefa e termina com afterProcessCreate e onNotify.

Finalizar: a sequência de movimentação segue até a entrada na atividade final, com afterProcessFinish antes do beforeSendData.

Cancelar: beforeCancelProcess, afterCancelProcess, beforeSendData e onNotify.

Abrir uma solicitação na Central de Tarefas: validateAvailableStates e checkComplementsPermission.

Qual evento usar em cada situação

Para validar o que a pessoa preencheu. Use o validateForm, que é evento de formulário e vale inclusive na abertura. Concentrar a validação nele evita ter a mesma regra espalhada por vários scripts.

function validateForm(form) {
    // Em Salvar nao valida, para a pessoa poder guardar um rascunho
    if (getValue("WKCompletTask") != "true") {
        return;
    }

    var erros = [];

    if (form.getValue("centroCusto") == "") {
        erros.push("Informe o centro de custo.");
    }

    if (erros.length > 0) {
        throw "<ul><li>" + erros.join("</li><li>") + "</li></ul>";
    }
}

Note que os erros são acumulados e há um único throw. Assim a pessoa vê tudo o que falta de uma vez, em vez de corrigir um campo por tentativa.

Para bloquear por uma regra que o formulário não enxerga. Use beforeTaskSave ou beforeStateEntry. Um throw interrompe o envio e mostra a mensagem ao usuário. Um exemplo é exigir um anexo com hAPI.listAttachments().

Atenção à atividade inicial. A documentação da hAPI avisa que não é possível ler ou gravar o formulário com hAPI.getCardValue e hAPI.setCardValue na inicialização do processo. Em nossos testes, o beforeTaskSave da abertura conseguiu ler o card, mas não conte com o valor recém-digitado em hAPI.getCardValue nesse evento.

Para preencher dados na tarefa seguinte. Use beforeStateEntry e hAPI.setCardValue, a partir da segunda atividade. Para normalizar dados da abertura, use o afterProcessCreate.

Para definir o prazo de uma tarefa. O afterTaskCreate ocorre quando a pessoa já recebeu a tarefa. É o ponto usado no exemplo de hAPI.setDueDate na documentação da hAPI.

Para agir ao fim do processo. Use afterProcessFinish, que recebe o número da solicitação.

Para reordenar ou esconder saídas de uma atividade. Use validateAvailableStates, que recebe a lista de atividades disponíveis.

As armadilhas mais comuns

beforeTaskComplete não bloqueia. Apesar do nome, a TOTVS avisa que uma exceção nele não para a movimentação. Quem coloca uma validação aqui descobre tarde demais que ela não impede nada.

Erro em afterStateEntry é ignorado. Ele não retorna erros para a tela naturalmente. Uma falha silenciosa aqui deixa o processo seguir como se tudo estivesse certo.

throw em afterCancelProcess não adianta. O cancelamento já foi feito. A própria documentação recomenda não disparar exceções nesse evento.

beforeSendData não é lugar de lógica. Ele serve para enviar dados ao Analytics, e o importador não interpreta if e else. Faça os cálculos antes, em eventos como beforeStateEntry.

Dados de pai e filho só existem depois de salvos. Para ler linhas de tabela pai e filho com hAPI.getChildrenIndexes, use eventos After.

WKCompletTask não serve em afterCancelProcess. O guia de referência alerta que, nesse ponto, o produto ainda não sabe se a atividade foi concluída.

Não coloque integração pesada em evento

Esse é o erro de maior impacto. Um evento roda enquanto o usuário espera. Se ele chama o ERP e o ERP demora, a tela trava e a transação pode expirar.

Para isso existe a Atividade de Serviço, que a própria TOTVS recomenda quando integrações externas causam lentidão na movimentação. No modo Automatizado, ela roda de forma assíncrona, com tentativas configuráveis e um fluxo de erro desenhado no processo:

function servicetask9(attempt, message) {
    log.info("Tentativa " + attempt + " na solicitação " + getValue("WKNumProces"));
    // Chamada ao serviço externo. Em caso de falha, lance a exceção:
    // o Fluig tenta de novo e, ao esgotar as tentativas, segue pelo fluxo de erro.
    return true;
}

Como a atividade pode ser reexecutada, a integração precisa estar preparada para receber a mesma operação duas vezes. Sem isso, você troca a tela lenta por pedidos duplicados no ERP.

Os detalhes estão no guia de atividade de serviço, e o código da integração em si, em como chamar a API REST do Protheus pelo Fluig.

Boas práticas

  • Implemente só o necessário. Não é preciso criar todos os eventos, apenas os que têm função.
  • Mantenha os eventos before rápidos. Eles estão entre os primeiros suspeitos em telas lentas.
  • Registre o contexto no log. Inclua o número da solicitação e a atividade, com getValue("WKNumProces") e getValue("WKNumState").
  • Confira a versão. Comportamentos variam entre versões da plataforma. Valide em homologação antes de publicar.

Perguntas frequentes

Como impedir que uma solicitação avance no Fluig?

Para campos do formulário, use throw no validateForm. Para regras que ele não enxerga, use throw "mensagem" em beforeTaskSave ou beforeStateEntry. Evite o beforeTaskComplete, que não para a movimentação.

Qual a diferença entre beforeTaskSave e beforeTaskComplete?

O beforeTaskSave ocorre antes de salvar o que o usuário selecionou e pode bloquear. O beforeTaskComplete ocorre depois que próxima tarefa e destinatários já foram gravados e não bloqueia a movimentação.

Onde crio um evento de processo?

No Fluig Studio, com o projeto aberto: New, Other, pasta fluig, opção "Script evento workflow". Depois escolha o evento e o processo. Quem usa Mac pode seguir o guia de Fluig Studio no Apple Silicon.

Processos que travam, integrações que falham em silêncio e regras espalhadas por vários eventos têm conserto. Se isso soa familiar, fale com a MyQube.

Sua operação ainda depende de planilhas e retrabalho?

Agende uma conversa gratuita e receba um diagnóstico inicial dos seus gargalos operacionais.

Falar com a MyQube

Ou conheça nosso serviço de Consultoria Fluig