Power Platform

Aprovação em várias etapas com Power Apps e Power Automate

Luiz Antonio Sgargeta
- Sócio fundador e CEO da Trinapse, IA aplicada, Microsoft 365 e Power Platform
· 17 min de leitura
Aprovação por alçada que sobrevive à auditoria

Em resumo

  • A aprovação por alçada se monta com três listas no SharePoint (pedidos, alçadas e histórico), um formulário no Power Apps que grava o pedido e chama o fluxo, e um fluxo do Power Automate que percorre as alçadas com uma aprovação por etapa.
  • A ação padrão Iniciar e aguardar uma aprovação, dentro de um laço, dispensa recurso em preview e permite gravar cada resposta no histórico no momento em que ela chega.
  • O histórico vai para uma lista porque a tela de aprovações mostra a cada pessoa só ela mesma e quem enviou o pedido, nunca a cadeia inteira.
  • Uma execução de fluxo dura no máximo 30 dias e a aprovação pendente nesse ponto é cancelada, então alçadas com prazo maior pedem o desenho em dois fluxos.
  • Quando as regras de alçada somam centenas de combinações, ou o pedido volta para a etapa anterior com frequência, Dataverse e app baseado em modelo sustentam melhor.

Como montar uma aprovação em várias etapas com Power Apps e Power Automate?

Grave o pedido numa lista do SharePoint a partir de um formulário do Power Apps e deixe um fluxo do Power Automate ler a lista de alçadas e abrir, para cada alçada que o valor exige, uma aprovação com a ação Iniciar e aguardar uma aprovação, gravando cada resposta numa lista de histórico. Você precisa de um ambiente com Dataverse, permissão para criar listas e fluxos, e o desenho serve quando as regras cabem numa tabela de poucas linhas e o pedido sobe sempre na mesma ordem.

O caso deste tutorial é composto: a aprovação de despesas administrativas de uma cooperativa de crédito, como a manutenção do prédio da agência, o material de uma assembleia ou a renovação de uma licença de software. Hoje isso costuma rodar em planilha e e-mail, e o problema aparece quando a auditoria interna pergunta quem aprovou o quê e em que dia, porque a resposta está espalhada em caixas de entrada. Quanto maior o valor, mais gente precisa aprovar, e em ordem: o coordenador primeiro, depois o gerente administrativo, depois o diretor financeiro. A ideia de registrar o nome de cada aprovador, a resposta, a data do pedido e a data da resposta vem do artigo de Matthew Devaney sobre aprovação sequencial, que grava esse histórico numa lista do SharePoint; aqui o resultado é construído de outro jeito, com uma aprovação por etapa.

O limite que decide o desenho está na página de limites e configuração do Power Automate, que fixa a duração máxima de uma execução em 30 dias. O relógio corre sobre a execução inteira, não sobre cada etapa, e por isso uma cadeia de quatro aprovadores com sete dias de espera cada já ocupa 28 dos 30 dias. A seção sobre o limite mostra o que acontece quando ele estoura e como desenhar com dois fluxos.

Pré-requisitos

  • Licença: SharePoint e Aprovações são conectores padrão, cobertos pelas licenças do Microsoft 365 que a cooperativa já tem para fluxos e apps que usam só esses conectores, conforme os tipos de licença do Power Automate. Se o app ou o fluxo passar a usar conector premium, a conta muda, então confirme isso antes de acrescentar qualquer integração.
  • Ambiente: com Dataverse, porque o conector de Aprovações guarda as solicitações lá, como descreve a página Introdução às aprovações.
  • Papéis: Criador do Ambiente (Environment Maker), descrito em funções de segurança predefinidas, para criar app e fluxo; e Proprietário do site no SharePoint, para criar as listas e quebrar a herança de permissões do histórico.
  • Conta de execução: uma conta de serviço para ser dona das conexões do fluxo. Se a conexão for de uma pessoa e ela sair da cooperativa, o fluxo para de gravar.

Passo a passo

O tipo de aprovação sequencial nativo da ação de aprovação é a primeira ideia de quem procura aprovação sequencial no Power Automate. O artigo de 2024 que serviu de base o tratava como preview, dependente de ambiente com recursos antecipados, e esse rótulo muda, então confira o estado atual na página de aprovações sequenciais do Learn antes de decidir. Este tutorial usa o laço por etapa por dois motivos: ele só depende da ação padrão, que está em disponibilidade geral, e grava o histórico a cada resposta, em vez de entregar tudo junto no fim da cadeia.

Os nomes de ação abaixo seguem o novo designer em português, com o nome em inglês entre parênteses na primeira aparição, e o rótulo pode variar um pouco entre versões, então confirme na sua tela antes de procurar a ação, porque um nome ligeiramente diferente costuma ser a mesma ação com outro rótulo.

Oito passos do fluxo: gatilho do Power Apps, leitura do pedido e das alçadas, laço com aprovação, histórico e status final

Os passos 5 a 7 rodam dentro do laço, uma vez por alçada; se a execução inteira passar de 30 dias, o passo 8 nunca roda e o pedido fica em aprovação.

Passo 1. Criar as três listas no SharePoint

Crie as listas num site da área administrativa, em Novo > Lista > Lista em branco. Três listas separadas mantêm cada coisa no seu lugar: a regra muda sem mexer nos pedidos, e o histórico recebe permissão própria. Crie as colunas com nome sem espaço e sem acento (renomeie depois, se quiser), porque o nome interno é fixado na criação e é ele que vai no filtro do fluxo.

Lista

Coluna (nome interno)

Tipo

Alçadas

Title (nome da alçada)

Texto de linha única

Alçadas

Etapa

Número

Alçadas

Aprovador

Pessoa

Alçadas

ValorAcimaDe

Moeda

Alçadas

Ativa

Sim/Não

Pedidos de Despesa

Title (descrição)

Texto de linha única

Pedidos de Despesa

Valor

Moeda

Pedidos de Despesa

CentroDeCusto

Escolha

Pedidos de Despesa

Justificativa

Várias linhas de texto

Pedidos de Despesa

Status

Escolha: Enviado, Em aprovação, Aprovado, Rejeitado

Histórico de Aprovações

PedidoId

Número

Histórico de Aprovações

Etapa

Número

Histórico de Aprovações

Aprovador, AprovadorEmail

Texto de linha única

Histórico de Aprovações

Resposta

Texto de linha única

Histórico de Aprovações

DataPedido, DataResposta

Data e hora

Histórico de Aprovações

Comentarios

Várias linhas de texto

Não crie coluna de solicitante editável no pedido: o fluxo lê o campo Criado por, que o usuário não consegue trocar, e isso evita que alguém abra pedido em nome de outro. No histórico, o aprovador entra como texto (nome e e-mail) e não como pessoa, para o registro continuar legível mesmo quando a conta for desativada depois.

Passo 2. Preencher a lista de alçadas

Cada linha da lista Alçadas é uma etapa, e a regra é "acima de": um pedido passa por todas as etapas ativas cujo ValorAcimaDe seja menor ou igual ao valor dele, na ordem da coluna Etapa. Com os valores de exemplo abaixo, que cada cooperativa troca pelos seus, uma despesa de R$ 3.000 passa só pelo coordenador, uma de R$ 30.000 passa por três pessoas, e a regra é lida por qualquer um sem abrir o fluxo.

Etapa

Alçada

ValorAcimaDe (exemplo)

1

Coordenação administrativa

R$ 0

2

Gerência administrativa

R$ 5.000

3

Diretoria financeira

R$ 25.000

4

Diretoria executiva

R$ 100.000

A coluna Ativa serve para desligar uma etapa, por exemplo na troca de um diretor, sem apagar a linha, e assim a regra antiga continua registrada na lista. Dê permissão de edição nessa lista só a quem a governança da cooperativa autoriza, porque mudar uma linha muda quem aprova a próxima despesa.

Passo 3. Criar o formulário no Power Apps

Em Power Apps > Novo app > Aplicativo de tela em branco, conecte a fonte de dados Pedidos de Despesa, insira o controle Formulário de edição (Edit form), nomeie-o frmPedido e marque os campos Title, Valor, CentroDeCusto e Justificativa. Deixe a propriedade Item vazia para o formulário abrir em modo novo, e ponha um botão "Enviar para aprovação" com a fórmula abaixo. A fórmula que chama o fluxo entra no passo 8, porque o fluxo ainda não existe.

// OnSelect do botão "Enviar para aprovação"
SubmitForm(frmPedido)

Defina o campo Status do pedido como "Enviado" no valor padrão do formulário ou deixe o fluxo fazer isso, como no passo 4, e escolha um dos dois caminhos para que o status não tenha duas origens. O formulário só grava o pedido, e a regra de quem aprova fica fora do app, onde a TI consegue mudá-la sem republicar a tela.

Passo 4. Criar o fluxo: gatilho e preparação

Em Power Automate > Meus fluxos > Novo fluxo > Fluxo de nuvem instantâneo, escolha o gatilho do Power Apps (V2), chamado nos conectores de Quando o Power Apps chama um fluxo (V2) (When Power Apps calls a flow (V2)), e dê ao fluxo um nome como "Aprovação por alçada de despesas". Adicione a entrada IdPedido do tipo Número. Passar só o identificador, e não os campos do pedido, faz o fluxo ler os valores direto da lista, que é a fonte de verdade, e não o que o app achava que tinha gravado.

Depois do gatilho, adicione estas ações, renomeando cada uma como indicado, porque o nome vira parte das expressões e um nome diferente do indicado faz a expressão apontar para uma ação que não existe:

  1. Obter item (Get item) do SharePoint, renomeada para Obter_pedido, com o site, a lista Pedidos de Despesa e o Id vindo do gatilho.
  2. Atualizar item (Update item), com o Status "Em aprovação". A partir daqui qualquer pessoa que abra o pedido sabe que ele está andando.
  3. Obter itens (Get items), renomeada para Obter_alcadas, na lista Alçadas, com os campos avançados preenchidos como abaixo.
  4. Inicializar variável (Initialize variable), com o nome ResultadoFinal, tipo Cadeia, valor Aprovado.
Consulta de filtro:  Ativa eq 1 and ValorAcimaDe le @{outputs('Obter_pedido')?['body/Valor']}
Classificar por:     Etapa asc

O filtro devolve só as alçadas que o valor exige, e a classificação garante a ordem, que de outro modo ficaria a critério de como o SharePoint devolve a lista. Se o nome interno da coluna não bater com o que você escreveu, a ação falha na primeira execução, e o erro está descrito na seção de erros comuns.

Passo 5. O laço: uma aprovação por alçada

Adicione Aplicar a cada (Apply to each), renomeado para Aplicar_a_cada, e na entrada use a saída da consulta de alçadas. Dentro dele, a primeira ação é uma Condição que compara variables('ResultadoFinal') com Aprovado, e todo o resto vai no ramo Sim. Essa guarda faz as etapas seguintes serem puladas depois de uma rejeição, e dispensa um Encerrar dentro do laço, que impediria o fluxo de atualizar o pedido no fim.

Entrada do Aplicar a cada:
outputs('Obter_alcadas')?['body/value']

No ramo Sim, adicione Iniciar e aguardar uma aprovação (Start and wait for an approval), renomeada para Aguardar_aprovacao, com o tipo Aprovar/Rejeitar: primeiro a responder (Approve/Reject - First to respond), que com um único aprovador atribuído é o que se quer, então preencha os campos assim:

  • Título: texto fixo mais o identificador do pedido, como "Despesa nº 123: etapa 2".
  • Atribuído a: items('Aplicar_a_cada')?['Aprovador/Email'].
  • Detalhes: a descrição, o centro de custo, a justificativa e o valor, que se formata com a expressão abaixo.
  • Link do item: o endereço do pedido na lista, para o aprovador abrir o contexto completo.
  • Solicitante: o e-mail de outputs('Obter_pedido')?['body/Author/Email'].
formatNumber(outputs('Obter_pedido')?['body/Valor'], 'C2', 'pt-BR')

Confira em Configurações do Aplicar a cada que o Controle de simultaneidade (Concurrency control) está desligado, que é o padrão, porque ligado o laço dispararia as aprovações em paralelo e a alçada deixaria de ser uma ordem.

Passo 6. Gravar o histórico e decidir o resultado

Ainda no ramo Sim, depois da aprovação, adicione Criar item (Create item) na lista Histórico de Aprovações, um por etapa respondida. O fluxo grava cada resposta assim que ela chega, e o item fica lá mesmo se uma etapa posterior ficar parada, o que o tipo sequencial nativo não permite ao entregar o resumo só no fim da cadeia. As expressões abaixo leem a primeira (e única) resposta da etapa.

PedidoId        outputs('Obter_pedido')?['body/ID']
Etapa           items('Aplicar_a_cada')?['Etapa']
Aprovador       first(body('Aguardar_aprovacao')?['responses'])?['responder']?['displayName']
AprovadorEmail  first(body('Aguardar_aprovacao')?['responses'])?['responder']?['email']
Resposta        first(body('Aguardar_aprovacao')?['responses'])?['approverResponse']
DataPedido      first(body('Aguardar_aprovacao')?['responses'])?['requestDate']
DataResposta    first(body('Aguardar_aprovacao')?['responses'])?['responseDate']
Comentarios     first(body('Aguardar_aprovacao')?['responses'])?['comments']

Os nomes dos campos dentro de responses são os que aparecem na saída da ação numa execução de teste, e é lá que você os confirma antes de depender deles. Em seguida, adicione uma Condição que verifica se body('Aguardar_aprovacao')?['outcome'] é igual a Approve. O valor é literal em inglês, mesmo com o ambiente em português, e se você escrever "Aprovar" a comparação sempre falha. No ramo Não, use Definir variável (Set variable) e ponha Rejeitado em ResultadoFinal.

Passo 7. Fechar o pedido e proteger o histórico

Fora do laço, depois dele, adicione um último Atualizar item no pedido, com o Status igual a variables('ResultadoFinal'), e, se quiser, uma mensagem ao solicitante com o resultado. Antes do laço, vale uma condição que verifica se length(outputs('Obter_alcadas')?['body/value']) é zero e, nesse caso, marca o pedido para tratamento manual, porque sem nenhuma alçada o laço não roda e o pedido sairia como Aprovado sem que ninguém tenha aprovado.

No site, em Configurações da lista > Permissões para esta lista do histórico, interrompa a herança e dê edição só à conta de serviço do fluxo e à TI, deixando leitura para auditoria e gestores, e depois ligue o controle de versão da lista, porque se alguém com permissão alterar uma linha, a versão anterior fica registrada.

Passo 8. Ligar o formulário ao fluxo

Volte ao Power Apps, abra o painel Power Automate à esquerda, escolha Adicionar fluxo e selecione o fluxo criado, conforme a documentação de execução de fluxos a partir de aplicativos de tela, e depois, no OnSuccess do formulário, chame o fluxo com o identificador que o formulário acabou de gravar.

// OnSuccess do frmPedido
AprovacaoPorAlcadaDeDespesas.Run(frmPedido.LastSubmit.ID);
Notify("Pedido enviado para aprovação", NotificationType.Success);
ResetForm(frmPedido)

O nome antes de .Run é o do fluxo sem espaços nem acentos, como o Power Apps o mostra no painel. Em ambientes configurados em português do Brasil, o Power Apps usa ;; como separador de comandos e vírgula decimal, e a fórmula acima, escrita com ;, é convertida na própria tela, então só confira se aparece sublinhado de erro.

O limite de 30 dias e o desenho em dois fluxos

Uma execução de fluxo dura no máximo 30 dias, e a aprovação pendente nesse ponto é cancelada, como detalha a página de limites do Power Automate. No desenho acima, o laço inteiro é uma execução só, então o prazo conta da abertura do pedido até a resposta do último aprovador, somando as férias do gerente e a semana de fechamento do trimestre. Quando o relógio chega ao fim, o histórico de execuções mostra o status Timed out, o passo 7 nunca roda e o pedido fica para sempre em "Em aprovação", com as linhas do histórico das etapas anteriores, mas sem uma resposta final.

Para quem precisa de prazo maior, ou só de margem, a saída é quebrar a cadeia em dois fluxos, de forma que cada etapa tenha o seu próprio relógio de 30 dias. O primeiro, "Abrir etapa", é o do passo 4: lê o pedido, consulta as alçadas, cria no histórico a linha da primeira etapa com Resposta igual a "Pendente" e termina. O segundo, "Responder etapa", dispara com o gatilho Quando um item é criado do SharePoint na lista de histórico: manda a aprovação para o aprovador da linha, espera, atualiza a própria linha com resposta, datas e comentários e, se aprovou, busca a próxima alçada pela coluna Etapa e cria uma nova linha, o que dispara uma nova execução do mesmo fluxo. Se não há próxima, grava "Aprovado" no pedido, e, se rejeitou, grava "Rejeitado" e não cria nada.

O gatilho é de criação, e por isso a atualização da linha não dispara o fluxo de novo. O custo é a depuração: a cadeia de um pedido passa a estar espalhada em várias execuções, e é o PedidoId em cada linha do histórico que permite reconstruir o caminho. Também sobra uma etapa que pode estourar sozinha, a do aprovador que não responde em 30 dias, e para isso crie um terceiro fluxo, recorrente e diário, que lista as linhas com Resposta igual a "Pendente" e criadas há mais de alguns dias, e lembra ou escala o aprovador antes do limite.

Como validar que deu certo

Abra o app com um usuário de teste e envie um pedido de R$ 30.000. O fluxo deve aparecer em Meus fluxos > Histórico de execuções como Em execução, e o pedido deve mudar para "Em aprovação". O coordenador recebe a primeira solicitação em Aprovações no Power Automate e no Teams, e só depois que ele responder o gerente recebe a segunda, e depois o diretor financeiro, sem que ninguém da etapa seguinte veja a solicitação antes.

Ao fim, o pedido deve estar em "Aprovado" e a lista de histórico deve ter três linhas, uma por etapa, cada uma com nome, resposta, data do pedido, data da resposta e comentários. Repita rejeitando na etapa 2: o pedido deve terminar em "Rejeitado", com duas linhas no histórico e nenhuma solicitação para o diretor. Por fim, abra a tela de aprovações com a conta de um aprovador de teste, e você verá que ela mostra só ele mesmo e quem enviou, nunca a cadeia inteira, e é por isso que o histórico auditável está na lista e não ali.

Erros comuns

"Column 'Valor Acima De' does not exist. It may have been deleted by another user." (ou mensagem equivalente na ação Obter itens): o filtro usa o nome de exibição, e não o interno. Abra a coluna em Configurações da lista e leia o nome na barra de endereço, no parâmetro Field=; ele é fixado na criação e não muda quando a coluna é renomeada.

"The template language function 'first' expects its parameter to be an array or a string. The provided value is of type 'Null'.": a expressão do histórico foi avaliada sem resposta, geralmente porque a ação de aprovação foi renomeada e a expressão ainda aponta para o nome antigo, ou porque a gravação está fora do ramo Sim, depois da aprovação. Corrija o nome entre aspas ou mova o Criar item.

O pedido sai "Aprovado" sem ninguém aprovar: a consulta de alçadas devolveu zero linhas, porque nenhuma está ativa para aquele valor, e o laço não rodou. A condição do passo 7 é a defesa, e a causa costuma ser uma lista de alçadas com a primeira etapa configurada acima de zero.

A comparação da resposta nunca dá verdadeiro: o valor da saída é Approve ou Reject, em inglês, qualquer que seja o idioma do ambiente, então a comparação escrita em português nunca encontra o texto que procura.

Todas as aprovações chegam de uma vez: o controle de simultaneidade do Aplicar a cada foi ligado, e o laço roda as iterações em paralelo, então desligue essa opção em Configurações da ação para que a ordem das alçadas volte a valer.

O fluxo para depois que alguém sai da cooperativa: a conexão estava no nome de uma pessoa, e quando a conta dela deixa de valer o fluxo perde o acesso. Recrie as conexões na conta de serviço e adicione a TI como coproprietária do fluxo.

Quando este desenho não serve

O desenho tem duas listas pequenas e um laço, e isso é uma vantagem enquanto a regra cabe numa tabela. Quando as regras de alçada têm centenas de combinações, por exemplo valor por centro de custo por tipo de despesa por agência, a tabela do SharePoint vira uma matriz que ninguém consegue manter e o filtro do fluxo fica lento de ler e de testar. O mesmo vale quando o pedido volta para a etapa anterior com frequência, porque o laço só avança, e simular o "devolver para ajuste" exige ramificações que viram o problema que o fluxo veio resolver. Nesses casos, Dataverse com um app baseado em modelo (model-driven app) sustenta melhor, porque a regra vive em tabelas relacionais, a etapa é um estado que se pode reabrir e a segurança é por linha.

O que levar para quem aprova

Depois de pronto, o gerente administrativo abre um formulário só, cada alçada é lida de uma lista que a TI controla e o histórico de cada pedido, com nome, resposta, data do pedido e data da resposta, fica numa lista com permissão restrita e controle de versão, e não em caixas de entrada. O custo de licença é nenhum extra enquanto o app e o fluxo ficarem nos conectores padrão do SharePoint e de Aprovações dentro do Microsoft 365, com um ambiente com Dataverse; o esforço é de um fluxo, um app e três listas para sustentar, e a manutenção recorrente é trocar linhas da lista de alçadas quando mudar quem aprova. O risco que precisa ser dito antes de prometer prazo é o limite de 30 dias por execução, que o desenho em dois fluxos resolve ao custo de uma depuração mais espalhada, e as conexões devem estar numa conta de serviço, com a TI como coproprietária, para o processo não depender de uma pessoa.

Se ajudar na conversa interna, a Trinapse monta com você o resumo de uma página com os limites e a lista de alçadas de exemplo da sua cooperativa, para levar ao gerente de TI antes de fechar o prazo com a área.

Luiz Antonio Sgargeta
Sócio fundador e CEO da Trinapse, IA aplicada, Microsoft 365 e Power Platform

Luiz Antonio Sgargeta é sócio fundador e CEO da Trinapse, consultoria brasileira de Microsoft 365 com quase duas décadas de operação, acumula mais de 20 anos em desenvolvimento de software e em ambientes corporativos de alta complexidade.

Ver maisVer menos

Trabalha com SharePoint desde o SharePoint Portal Server 2003 e com .NET desde a versão 1.0. Acompanhou a plataforma em todas as suas reinvenções, do portal de documentos on-premises ao SharePoint Online dentro do Microsoft 365, o que dá a ele uma leitura rara sobre o que muda de verdade e o que é apenas nome novo para o mesmo problema.

No início da carreira atuou em uma das maiores operações de e-commerce do país, em sistemas que não toleram degradação de performance nem indisponibilidade, essa origem definiu o critério que ele aplica até hoje: solução boa é a que sustenta volume real, integra com o legado que já existe e não quebra no pico.

Depois disso, passou por praticamente todo tipo de projeto corporativo, de portais e intranets de milhares de usuários a integrações críticas e automação de processos de ponta a ponta, sempre em grandes empresas e em desafios de alta exigência.

A marca do trabalho dele é a tradução entre tecnologia e negócio, levanta a necessidade real por trás do pedido do cliente, questiona o processo antes de automatizá-lo e desenha a solução pelo resultado esperado, não pela ferramenta disponível, é o que permite conversar com a diretoria sobre retorno e com o time técnico sobre arquitetura na mesma reunião.

Hoje lidera a frente comercial e estratégica da Trinapse e conduz a empresa no novo ciclo da inteligência artificial, com foco em agentes de IA e operação de processos assistida por IA para cooperativas de crédito, agronegócio e indústria. Escreve no blog da Trinapse desde 2019, com mais de 450 artigos sobre IA, SharePoint, Power Platform, Modern Workplace e transformação de processos, sempre a partir de projeto entregue e não de teoria.

LinkedIn
Compartilhar:

Precisa aplicar isso na sua empresa? Fale com nossos especialistas.

Falar com um especialista