Automatizando o processo
Após o processo estar mapeado, inicie a sua automatização: construção do processo definido e chamada das integrações, condições, variáveis, entre outros. Após essa automatização o processo fica pronto para ser executado pelo Workflow.
Iniciar
- Defina como o processo será iniciado;
- Determine o tipo da tarefa a partir da guia Propriedades, no campo Tipo. Com esta definição, a tarefa recebe um ícone correspondente ao tipo. Acesse Atividades para visualizar todos os tipos disponíveis e obter mais informações sobre o funcionamento de cada um;
- Salve o projeto.
Com exceções dos tipos "Tarefa manual" e "Tarefa de script", ao selecionar um determinado tipo para a tarefa, um erro é gerado e exibido na visão Problemas. Isto ocorre porquê a configuração ainda não está completa, sendo necessário definir um executor na visão Propriedades, em Execução, e preencher os campos apresentados, conforme a escolha do executor.
Nota
Antes de definir um executor, recomenda-se avaliar as configurações de cada um:
Receber valores de entrada
Para o processo, a estrutura que armazena os valores é chamada de variável. Portanto, para armazenar esses valores é necessário definir a variável para cada parâmetro de entrada. Para isso, acesse a visão Propriedades, quando nenhum elemento do processo estiver selecionado, e clique em Variáveis. A tela Variáveis é responsável por armazenar todas as variáveis que estão disponíveis para serem utilizadas no processo. Nesta tela crie as variáveis.
Definindo tarefa Aprovar solicitação
Após a definição da tela inicial e das variáveis do processo vamos definir a automatização da próxima tarefa, a tarefa de Aprovar solicitação. Para automatizar a tela Aprovar solicitação realizaremos os seguintes passos:
- Definir o tipo de tarefa e executor;
- Definir parâmetros que o processo vai passar pra tela (usuário aprovador e medicamentos solicitados);
- Definir na tela quais são os parâmetros de entrada que ela espera;
- Definir na tela a ação de responder para o processo assim que a decisão do usuário for tomada;
- Processo receber e interpretar a resposta do executor.
Em sequência, começaremos pelo primeiro item.
a) Definir o tipo de tarefa e executor;
O tipo de executor deverá ser Tarefa de usuário – isso pois quem irá tratar a tarefa é o usuário aprovador da solicitação. Para conhecer os demais tipos de tarefa, consulte a documentação.
![]()
Na parte de “Execução” da tarefa, definiremos as seguintes propriedades:
- Executor com o valor Perspectiva Seniortools e;
- Produto com o valor Workflow Container.
b) Definir parâmetros que o processo vai passar pra tela (usuário aprovador e medicamentos solicitados);
Antes de criarmos a perspectiva, iremos definir os valores de entrada para a tela através do script. Clique no botão Scripts..., na tela que abrirá, poderemos definir um script para ser executado antes do executor da tarefa e um outro para ser executado após o executor da tarefa. Em linhas gerais, usamos o script de beforeExecute para definirmos os dados de entrada para o executor da tarefa e o afterExecute para obter os dados retornados pelo executor da tarefa.
A tela Aprovar solicitação precisa receber os valores gerados pela tela inicial e que foram armazenados no processo. Para fazermos isso, iremos definir um script que executa antes da criação da pendência. O nosso script de beforeExecute é responsável por encontrar o usuário responsável pela tarefa, definir esse usuário como responsável e definir como entrada para a tarefa os dados “seniortools_data” (com origem do contexto) e “aprovador” (com origem de uma chamada a função getTaskSystemResponsible).
var contextVars = context.getVars();
// identifica o aprovador da solicitação
var solicitante = contextVars.getLong("solicitante");
var aprovador = context.getSecurity().getTaskSystemResponsible(solicitante);
// define como responsável da tarefa o aprovador
context.getTask().setResponsible(aprovador);
// define as entradas para a perspectiva
var input = context.getTask().getInput();
input.setLong("aprovador", aprovador);
input.copy(contextVars, "seniortools_data");
Consulte a documentação para encontrar as funções disponibilizadas via script.
c) Definir na tela quais são os parâmetros de entrada;
Com a definição do beforeExecute, temos até o momento a configuração de que, ao executar a tarefa, será invocado uma perspectiva Seniortools, e essa perspectiva irá receber do processo dois parâmetros:
- seniortools_data: parâmetro que contém os dados dos cursores exportados, no nosso tutorial, os dados dos medicamentos solicitados (nome, valor e quantidade);
- aprovador: usuário responsável por aprovar a pendência.
Agora precisaremos fazer a perspectiva que cuidará da integração com o Workflow. Novamente, alguns artefatos são fornecidos, nos restando somente criar a perspectiva e programar a resposta do processo. Entre os artefatos fornecidos e diferentes do que já vimos, temos:
- custom.com.senior.medicamentos.workflow.ui.FrAprovarSolicitacao.java
Fragmento que exibirá a lista dos medicamentos solicitados e dois botões: Aprovar ou Rejeitar.- custom.com.senior.medicamentos.workflow.ui.FrAprovarSolicitacao.fragment
Fragmento que define a ordem dos botões.A perspectiva que iremos montar será similar à está abaixo e utilizará os dois fragmentos que foram citados acima, conforme pode ser visto pela imagem.
![]()
Na perspectiva o usuário responsável consegue ver a lista dos medicamentos solicitados e ele tem a opção de Aprovar ou Rejeitar a compra dos medicamentos. Primeiramente criaremos a perspectiva através do Wizard fornecido em: Arquivo > Novo > Outras... > Senior > Perspectiva.
Na parte Perspectiva informaremos o pacote, nome e título da perspectiva:
- Pacote: custom.com.senior.medicamentos.workflow.ui
- Nome: AprovarSolicitacao
- Título: Aprovação da Solicitação de Medicamentos
Na tela Visão Default definiremos o visual da perspectiva. Como só temos um fragmento, simplesmente informemos FrAprovarSolicitacao como sendo o fragmento central.
![]()
Após essa definição, avançar para a próxima tela.
Na tela Expressão de ligação não faremos nada. Isso pois nosso fragmento não usufrui desse recurso e por isso simplesmente iremos para a próxima tela.
A próxima tela possui a primeira parte da nossa integração do Workflow com o SeniorTools: Integrar cursores com o workflow. Essa é a tela responsável por configurar os cursores de entrada e saída do Workflow. Para o nosso tutorial, precisamos configurar para que a tela de aprovação seja capaz de receber os dados do cursor de medicamentos solicitados.
Adicionaremos um cursor com as seguintes configurações:
![]()
Detalhando cada informação:
- Cursor: crIMedicamentos
Este é o cursor que será importado do processo.- Exportação: CHANGES
Define que importaremos somente as mudanças que estiverem no cursor- Link: (vazio)
Por ser o cursor único, não possui link com nenhum outro cursor.- Dataset: dsIMedicamento
- Direção: INPUT
Define que o cursor será utilizado somente para a importação dos dados.
No momento da exportação, os dados dos cursores não irão para o processo.- Modo de Concorrência: NONE
Não utiliza controle de controle de concorrência por não haver acesso concorrente à base no nosso tutorial.- Campos: (nenhum)
Desabilitado devido ao modo de concorrência.A próxima tela é responsável por receber as variáveis definidas no beforeExecute: Integrar variáveis com o Workflow. Para o tutorial, precisamos armazenar na perspectiva a variável “aprovador”. Adicionaremos uma variável com os seguintes valores:
![]()
Detalhando cada informação:
- Variável: aprovador
Nome da variável conforme definido no script de beforeExecute.- Tipo: LONG
Tipo da variável conforme tipo do processo.- Direção: INPUT
Igualmente ao cursor, define que o valor da variável não será exportado novamente para ao processo ao responder um processo.- Tamanho: 19
Define o tamanho máximo em caracteres comportados pela variável, escolhemos 19 por suportar todos os valores válidos para um signed long.Após isso, podemos concluir a criação da perspectiva. Com a perspectiva criada, nos resta configurar o fragmento para responder o processo. Precisamos programar os botões Aprovar e Rejeitar.
d) Definir na tela a ação de responder para o processo;
Para o nosso tutorial, já temos a ação dos botões definidas no fragmento junto com a sua integração Java. Na parte abaixo, explicaremos o que ocorrerá ao clicar nos botões Aprovar ou Rejeitar.
Começaremos pelo botão Aprovar. Para isso, vamos voltar para o nosso processo para ver o que ocorre quando a solicitação é aprovada.
![]()
Quando o usuário aprovador responder informando a aprovação, temos que informar para o processo que a solicitação foi aprovada e temos também que informar a entrada para a próxima tarefa Encaminhar pedido ao fornecedor. Essa tarefa corresponde ao serviço da farmácia responsável por receber uma lista de medicamentos e informar se há ou não disponibilidade – e havendo efetuar o pedido.
Ao responder para o processo, a tela Aprovar solicitação deverá informar que houve sucesso da aprovação e informar um JSON que, no nosso caso, será a entrada para o serviço. O nosso código para aprovação na classe FrAprovarSolicitacao é o seguinte:
public void aprovarSolicitacao(MouseEvent<VButton> me) {
// cria a entrada para o serviço da próxima tela
String json = criaEntradaParaServico();
// responde para o processo a aprovação e entrada para o serviço
IServiceResult respostaProcesso = responderProcesso(true, json);
// trata a resposta do processo
tratarRespostaDoProcesso(respostaProcesso, "Compra de medicamentos aprovada.");
}
O método criaEntradaParaServico é o método responsável por transformar o cursor de medicamentos em uma entrada válida para o serviço da farmácia.
O método responderProcesso recebe como parametrização um boolean que indica se ocorreu com sucesso ou não a solicitação e a resposta que será retornada para o processo. A implementação do método é a seguinte:
private IServiceResult responderProcesso(boolean aprovacao, String resultadoAprovacao) {
String token;
// este contém todas as pendências que a perspectiva recebeu
ICursor<IPendency> cursor = getEntitySession().newCursor(IPendency.class);
cursor.open();
try {
cursor.first();
assert cursor.isAtRecord();
IPendency pendency = cursor.read();
token = pendency.getToken();
} finally {
cursor.close();
}
// cria um objeto para respostas para um token específico
WorkflowParams param = new WorkflowParams(token);
// define o resultado da aprovação, conforme opção do usuário
param.addParamField(new WorkflowParamField("aprovacao", aprovacao, WorkflowDataType.BOOLEAN));
// define o resultado que será repassado para o processo
param.addParamField(new WorkflowParamField("resultado_aprovacao", resultadoAprovacao, WorkflowDataType.STRING));
// responde para o processo
IResponseProcessParam responseProcess = new ResponseProcessParam(param);
WorkflowServiceProvider.getInstance().responseProcess(responseProcess);
return responseProcess;
}
O método tratarRespostaDoProcesso recebe como parametrização uma lista com a resposta do processo e uma mensagem que deve ser exibida como feedback para o caso de ocorrer erro ao responder o processo. A sua implementação é a seguinte:
private void tratarRespostaDoProcesso(IServiceResult respostaProcesso, String mensagemParaExibicao) {
// verifica se ocorreu erro durante a resposta.
// Se ocorreu erro, exibe uma mensagem de erro, senão a mensagem de sucesso (de acordo com a opção escolhida)
if (respostaProcesso.hasError()) {
DefaultDialog.showErrorSync(this, "Ocorreu um erro responder o processo. Erro: " + respostaProcesso.getMessage());
} else {
DefaultDialog.showInfoSync(this, mensagemParaExibicao);
}
// fecha a perspectiva
getPerspectiveAccessor().closePerspective();
}
Com esses trechos de código, já somos capazes de responder para o processo a aprovação da solicitação e tratar os casos de erro que podem ocorrer durante a comunicação com o servidor do Workflow. Nos resta a opção de Rejeição da solicitação. Voltando para o processo, temos o seguinte.
![]()
Em caso de rejeição, precisaremos notificar da falha. Nos preocuparemos em como realizar a Notificação da falha depois, para o momento é importante saber que temos que informar um motivo para a falha.
De forma parecida com aprovar, a rejeição deverá informar que houve a rejeição da aprovação e informar um motivo para notificar a falha. O trecho de código que faz isso é o seguinte:
public void rejeitarSolicitacao(MouseEvent<VButton> me) {
// responde para o processo a rejeição e informa o motivo do cancelamento
IServiceResult respostaProcesso = responderProcesso(false, "Cancelado por indisponibilidade de verba.");
// trata a resposta do processo
tratarRespostaDoProcesso(respostaProcesso, "Compra de medicamentos rejeitada.");
}
Com isso, a perspectiva está apta para aprovar ou rejeitar a solicitação.
Após a definição da perspectiva, precisamos definir no processo para que a tarefa Aprovar solicitação utilize tal perspectiva. Iremos preencher o campo perspectiva com o valor: “custom.com.senior.medicamentos.workflow.ui.AprovarSolicitacao”.
![]()
O nosso próximo passo é receber os dados enviados pela tela e salvar no nosso processo. Esta é a principal utilidade do script de afterExecute.
e) Processo receber e interpretar a resposta do executor
Queremos nesse caso, armazenar no processo o valor recebido por “aprovacao” e “resultado_aprovacao”. Então precisaremos de mais duas variáveis do processo novas para armazenar esses valores. Para adicionar as variáveis do processo, clicaremos no botão “Variáveis...” dentro da tela de edição de variáveis do processo.
![]()
Dentro da tela de variáveis, adicionaremos as seguintes variáveis:
- aprovacao_da_solicitacao / Boolean;
- resultado / String
![]()
Agora que temos as variáveis do processo, copie o seguinte script:
var vars = context.getVars();
var output = context.getTask().getOutput();
vars.copy(output, 'aprovacao_da_solicitacao:aprovacao', 'resultado:resultado_aprovacao');
![]()
Verificando aprovação da solicitação
Com a resposta da tarefa, o próximo passo é programar qual será o caminho que será tomado pelo nosso gateway exclusivo. A decisão do caminho é feita programando um script para cada caminho que pode ser tomado. Esse script é programado de forma a sempre retornar um valor boolean.
Para programar o script, selecione a sequência que será programada, conforme figura abaixo.
Clique no botão Expressão... da guia Propriedades.
Agora podemos programar cada script.
- Fluxo de sequência que trata o sucesso – o nomeado com “sim”
Retornaremos a variável do processo que salvamos da tarefa anterior.
return context.getVars().getBoolean('aprovacao_da_solicitacao');
- Fluxo de sequência que trata a rejeição da aprovação do pedido – o nomeado com “não”
Para rejeição, retornaremos a negação do valor contido na variável do processo.
return !context.getVars().getBoolean('aprovacao_da_solicitacao');
Com a definição do script, temos uma bifurcação na execução. Para este tutorial, primeiramente trataremos o “caminho feliz” onde o pedido é aprovado. Sendo assim, vamos a próxima tarefa que é onde efetivamente o pedido solicitado e já aprovado irá ser encaminhado ao fornecedor.
Encaminhando pedido ao fornecedor
O próximo passo do nosso processo será encaminhar o pedido para o nosso fornecedor. Nesse tutorial a comunicação com o nosso fornecedor se dá através de um Web service disponibilizado pelo fornecedor. Esse Web service é escrito no protocolo SOAP. Vamos então iniciar a configuração dessa tarefa definindo que ela será uma Tarefa de Serviço.
O serviço que queremos invocar é SeniorFarmacia. Um serviço que está pronto para publicado e utilizado pelo nosso tutorial. Este serviço é responsável por:
- Receber uma lista de medicamentos no formato JSON;
- Nesse JSON, cada item deve conter o id do medicamento, o nome do medicamento e a quantidade desejada;
- O nome do parâmetro é “jsonMedicamentos”;
- Exemplo de formato válido:
[
{"id":1,"nome":"Amoxicilina","quantidade":1},
{"id":2,"nome":"Cataflan","quantidade":2}
]
- • Retornar um Json indicando a aprovação do pedido junto de uma mensagem de sucesso;
- Os nós do JSON serão “sucesso” (boolean) e “detalhes” (string);
- O nome do retorno é “resultado”;
- Exemplo de retorno válido: {"sucesso":true,"detalhes":"Pedido aceito."}
- Retornar um Json indicando a falha no pedido junto com a causa do erro.
- Para esse tutorial, retornaremos falha sempre que for solicitado qualquer medicamento com mais de 30 unidades;
- Os nós serão o mesmo que o nó de sucesso;
- Exemplo de retorno válido:
{"sucesso":false,"detalhes":"Quantidade de itens no estoque insuficiente."}
O executor da tarefa será Web service Genérico, com os valores:
- • URL: http://teste08:9090/SeniorFarmacia/FarmaciaBean
Nota
A URL pode ser alterada, dependendo da máquina que está sendo utilizada para executar.
- • Operação: solicitarMedicamentos
- • Target namespace: http://services.senior.com.br
- • Modo de execução da tarefa: síncrono (valor padrão)
- • Timeout: 0 (valor padrão)
- • Permitir capturar o erro (erro de negócio): desmarcado (valor padrão)
O próximo passo, igual nas tarefas anterior, é definir o script de beforeExecute para entrada de valores do processo para o Web service. Este script irá pegar o JSON gerado pela tarefa anterior e definir como parâmetro para o Web service, o nome do parâmetro é “jsonMedicamentos” (conforme definido anteriormente).
O nosso script obtém o valor de uma variável do processo e copia o conteúdo dessa variável – com ajuda de uma função utilitária - para a entrada dos dados do executor. Para conhecer mais funções para manipulação de dados nos scripts, consulte a documentação.
var resultado_aprovacao = context.getVars().getString('resultado');
context.getTask().getInput().setString('jsonMedicamentos', resultado_aprovacao);
Esse script define que ao ser invocado o Web service, ele receberá o JSON gerado pela tela de aprovação da solicitação. Nosso próximo passo é obter o retorno do Web service, isso através do afterExecute.
O retorno do Web service também é um JSON – essa definição é do serviço que estamos utilizando. Novamente, precisamos rever o processo para decidir o que fazer com a resposta do serviço. Vejamos:
Primeiramente precisamos saber se houve sucesso ou não. Depois, precisaremos de alguma mensagem para notificar sucesso/falha. Como o nosso JSON de resposta tem ambas as informações, o que faremos será realizar o parse desse JSON e armazenar os valores em variáveis do processo. Não temos nenhum local para armazenar a variável de aprovação ou não do fornecedor, por isso criaremos uma variável de processo com o nome “aprovacao_do_fornecedor” (deve ter o tipo Boolean). Para armazenar os detalhes da mensagem, podemos reaproveitar a variável “resultado”.
Com a variável criada, agora iremos programar o script de afterExecute. Este script irá utilizar a função parseJson() para percorrer a estrutura de dados retorna pelo serviço e então extrairmos as informações necessárias ao nossos processo. Nesse caso, essas informações são o resultado da execução (sucesso ou falha) e os detalhes. Essas duas informações serão armazenadas em variáveis de processo para que possam ser utilizadas nas próximas tarefas e decisões.
var output = context.getTask().getOutput();
var vars = context.getVars();
var retorno_fornecedor = context.utils.parseJson( output.getString('resultado') );
vars.setBoolean('aprovacao_do_fornecedor', retorno_fornecedor.sucesso);
vars.setString('resultado', retorno_fornecedor.detalhes);
Após a definição desse script, temos a chamada a um serviço externo configurada. Apenas relembrando, nessa tarefa nós fizemos os seguintes passos:
- Definimos a passagem dos parâmetros de entrada para o serviço e;
- Obtivemos o retorno do serviço para armazenarmos em variáveis do processo.
Vamos agora para o próximo passo! Nesse caso é a tomada de decisão para identificarmos o retorno do fornecedor e programarmos o que será feito com o sucesso ou falha da compra.
Verificando a efetivação do pedido
De forma parecida com o que foi feito ao Verificar a aprovação da solicitação, iremos configurar os scripts de cada fluxo de sequência para verificar se houve sucesso ou falha na efetivação do pedido por parte do nosso fornecedor.
- Fluxo de sequência que trata o sucesso
Basta verificarmos a variável que foi armazenada anteriormente com este propósito:
var vars = context.getVars();
return vars.getBoolean('aprovacao_do_fornecedor');
- Fluxo de sequência que trata qualquer exceção ocorrida junto ao fornecedor
Para este caso, é a negação da variável anterior.
var vars = context.getVars();
return !vars.getBoolean('aprovacao_do_fornecedor');
Seguiremos agora para a definição da tarefa Notificar sucesso.
Notificar o sucesso do pedido
Agora que já foram definidas as condições para saber se houve sucesso ou falha na efetivação do pedido junto ao fornecedor, vamos começar a implementar a execução de cada um desses caminhos, começando pelo sucesso.
Para enviar o e-mail, utiliza-se o executor de tarefas chamado de Envio de e-mail. Este executor é o padrão para envio de e-mails, não recomenda-se mais a utilização do serviço do Middleware Senior para esse fim, pois, o novo executor é específico para isso. Ele possui novos recursos, mais facilitadores, configuração facilitada e sua execução é menos suscetível a falhas.
Então, para enviar o e-mail, primeiramente o tipo da tarefa será uma Tarefa de usuário, enquanto o executor da tarefa será Envio de e-mail.
Há duas maneiras de configurar o Envio de e-mail. Utilizaremos uma forma para notificar o sucesso do pedido e a outra para notificar a falha do pedido, através de variáveis ou de script.
Para configurar o Envio de e-mail usando variáveis, é necessário criar as seguintes variáveis de processo:
- para: string
- cc: string
- assunto: string.
Em seguida, definimos o valor paras os campos:
- Ignorar erros ocorridos durante o envio de e-mail (erro de negócio): desmarcado (valor padrão).
- Para: o e-mail do destinatário que será o nosso maior interessado - o usuário solicitante.
- CC: quem irá receber o e-mail com cópia - usuário aprovador.
- Assunto: o título do nosso e-mail, que será uma mensagem informando que o pedido foi aprovado.
- Campo de texto do e-mail: o corpo da nossa mensagem, que será o retorno do serviço que foi salvo anteriormente na variável "resultado".
Abaixo, uma imagem que ilustra as configurações já com os valores preenchidos:
Depois que as variáveis foram criadas e definidas nos campos do executor, deve-se definir também seus valores via script. Nesse primeiro momento, não vamos nos preocupar em buscar o e-mail do usuário e então, para facilitar a aferição de que o processo está funcionando, os e-mails utilizados para notificação deverão ser o seu próprio e-mail. Sendo assim, quando a notificação ocorrer, "você(VERIFICAR AQUI)" será notificado.
O script de beforeExecute, da tarefa Notificar sucesso, ficará assim:
context.getVars().setString("para", "<seu_email>@senior.com.br"); // email solicitante
context.getVars().setString("cc", "<seu_email>@senior.com.br"); // email aprovador
context.getVars().setString("assunto", "<seu_email>@senior.com.br"); // assunto
// necessário para indicar ao serviço qual usuário deve ser utilizado para autenticar
// para o tutorial, utilizaremos o usuário com o id 1
context.getTask().setResponsible(1);
Para essa tarefa, somente o script de beforeExecute é definido, pois não existe retorno do serviço.
Pronto! A primeira parte do nosso processo está completa. O nosso processo já é capaz de receber uma entrada de dados a partir de um usuário solicitante, enviar essa demanda para um usuário aprovador, encaminhar para um fornecedor e notificar o sucesso do pedido via e-mail. Na próxima parte trataremos das exceções.
Notificar a falha do pedido
Para terminarmos a primeira parte da automatização do tutorial, precisamos automatizar a tarefa Notificar falha. Esta parte trata da exceção da bifurcação dos caminhos, ou seja, o que acontece quando a solicitação junto ao fornecedor falhar (caminho destacado abaixo).
Para notificar uma falha, utilizaremos a segunda forma para configurar o recurso de envio de e-mail, que será via script. Portanto, o tipo da tarefa e executor serão as mesmas da tarefa Notificar sucesso. Já as propriedades não serão preenchidas, pois serão definidas via script.
Conforme a imagem abaixo, na guia Execução, apenas o campo executor deve ser informado:
Assim como na outra notificação, deve-se utilizar o seu endereço de e-mail para as notificações.
O nosso script de beforeExecute ficará assim:
// Obtém o executor da tarefa
var input = context.getTask().getPerformer();
input.addToAsMail("<seu_email>@senior.com.br"); // email solicitante
input.addCCAsMail("<seu_email>@senior.com.br"); // email aprovador
// assunto
input.setSubject("Pedido de solicitação de compras de medicamentos rejeitado!");
// mensagem
input.setMessage("Causa do cancelamento: " + vars.getString('resultado'));
// necessário para indicar para o serviço qual usuário deve ser utilizado para autenticar
// para o tutorial, utilizaremos o usuário com o id 1
context.getTask().setResponsible(1);
Para que o processo de envio de e-mail funcione, é necessário configurá-lo no Senior Config. Center, no caminho Sistemas > Performance Corporativa> Workflow > E-mail.
Assim, encerramos a última parte da automatização do tutorial. Não devemos ter nenhum erro na guia Problemas. Dê uma olhada no seu processo, devemos ter algo similar disso:
Agora, nosso processo também é capaz de lidar com os caminhos alternativos ao “caminho feliz” e notificar o usuário da falha da solicitação de medicamentos.

English
Español


