Auditoria do benefício de alimentação em campo

Auditoria
R
Quarto
Benefícios
Um ano de recargas de alimentação cruzado com o diário de campo e o cadastro. Quanto foi pago fora da regra, onde e por quê.

Caso fictício. A Fiorena Redes Elétricas S.A., suas bases, pessoas e lançamentos não existem. Os dados foram gerados do zero por um script em R, com regras de benefício inventadas e defeitos de tamanho conhecido. O método é real.

Baixar o relatório (PDF) · Baixar os casos para revisar (CSV)

A pergunta

A controladoria da Fiorena viu o valor pago em alimentação por dia de equipe em campo subir de R$ 219 no primeiro semestre de 2025 para R$ 239 no segundo, 9,5% a mais, sem reajuste de valor e sem mudança no tipo de serviço. A pergunta era simples: quanto disso é gasto legítimo e quanto foi pago fora da regra?

Duas linhas mês a mês. O valor pago sobe de cerca de 205 reais em janeiro para perto de 250 reais em dezembro, com um salto em agosto. A linha sem o indevido sobe menos e fica abaixo da outra a partir de agosto.

Valor pago em alimentação por dia de equipe em campo, mês a mês, em 2025. A linha tracejada é o mesmo valor sem o que a auditoria classificou como indevido. A marca em agosto é a troca do sistema de recarga.

Duas linhas mês a mês. O valor pago sobe de cerca de 205 reais em janeiro para perto de 250 reais em dezembro, com um salto em agosto. A linha sem o indevido sobe menos e fica abaixo da outra a partir de agosto.

Valor pago em alimentação por dia de equipe em campo, mês a mês, em 2025. A linha tracejada é o mesmo valor sem o que a auditoria classificou como indevido. A marca em agosto é a troca do sistema de recarga.

A queda de julho tem causa nos dados: julho e janeiro são os meses com mais gente de férias (em julho, 81 eletricistas por dia útil, contra 37 na mediana do ano), e cada equipe saiu a campo com 3,5 pessoas, contra 3,8 na mediana. O valor por pessoa em campo não caiu: ficou entre R$ 58 e R$ 60 de janeiro a julho.

Cada eletricista recebe no cartão de alimentação uma recarga por dia em campo. A recarga é lançada pela base, aprovada pelo supervisor e paga sem cruzamento automático com o diário de campo nem com o cadastro de férias e afastamentos. Ninguém tinha olhado os 12 meses de lançamentos juntos.

A auditoria respondeu três perguntas, nessa ordem:

  1. Quanto foi pago fora de uma regra objetiva (duplicidade, acima do teto, pessoa que não estava trabalhando)?
  2. Quanto foi pago sem lastro: sem registro de equipe em campo naquele dia, ou com justificativa que não explica nada?
  3. Onde isso se concentra, e por quê?

A regra e os dados

A regra do benefício:

  • Almoço de R$ 52 por dia em campo.
  • Jantar de R$ 44, só quando o diário de campo registra pernoite da equipe.
  • Extra de até R$ 24, só com uma das justificativas da lista: “deslocamento acima de 300 km” ou “jornada estendida em mais de 2 horas”.
  • Teto de R$ 120 por pessoa por dia, somando tudo, e no máximo uma recarga de cada tipo por dia.
  • Só para quem está ativo, fora de férias e afastamentos, e numa equipe que esteve em campo naquele dia.

Foram auditadas 155.909 recargas de 2025, no total de R$ 7,63 milhões, pagas a 649 pessoas de 8 bases, cruzadas com 33.254 registros de equipe em campo no diário, com o cadastro e com as férias e afastamentos do RH.

Método

Cada recarga passa pelas mesmas verificações e termina numa de quatro conclusões. A auditoria separa o que é erro objetivo, que pode ser cobrado, do que só merece uma segunda olhada da base; ela não tira conclusão sobre a intenção de ninguém.

  1. Preparar. Usar o dia trabalhado, e não a data em que a recarga foi lançada, e ligar cada recarga ao cadastro, às ausências e à equipe da pessoa naquele dia.
  2. Conferir as regras objetivas. Duplicidade, pessoa fora do trabalho, jantar sem pernoite, extra sem justificativa e soma do dia acima do teto. No teto, só o excedente conta como indevido.
  3. Conferir o lastro. A equipe estava em campo naquele dia? A justificativa do extra é válida, vaga ou ausente? Um dicionário de termos aceita erros de digitação, para “deslocamneto acima de 300km” contar como válida.
  4. Comparar com o esperado. Para cada base e mês, o valor por dia em campo é comparado com o das outras bases no mesmo mês. Fica fora da faixa esperada o grupo que se afasta muito mais do que as bases costumam se afastar umas das outras (o critério de Tukey, no código).
  5. Pontuar o risco. Um ponto para cada sinal: regra violada, sem lastro de campo, justificativa vaga ou ausente, base e mês acima da faixa.
  6. Concluir. Cada recarga recebe uma das quatro conclusões abaixo.
Conclusão Quando O que fazer
Indevido Violou uma regra objetiva Estornar ou recuperar, conforme a política da empresa e com apoio do RH e do jurídico
Revisar Nenhuma regra violada, mas sem lastro de campo ou com dois sinais ou mais A base confirma ou corrige em até 15 dias
Atenção Um sinal só, sem regra violada Entra na amostra do próximo mês
Regular Nenhum sinal Nada a fazer

Indevido

Quando: Violou uma regra objetiva

O que fazer: Estornar ou recuperar, conforme a política da empresa e com apoio do RH e do jurídico

Revisar

Quando: Nenhuma regra violada, mas sem lastro de campo ou com dois sinais ou mais

O que fazer: A base confirma ou corrige em até 15 dias

Atenção

Quando: Um sinal só, sem regra violada

O que fazer: Entra na amostra do próximo mês

Regular

Quando: Nenhum sinal

O que fazer: Nada a fazer

Ver o código R da etapa 1: preparar
# O que vale é o dia de referência (o dia trabalhado), e não a data em que a
# recarga foi lançada. Cada recarga é ligada ao cadastro, às ausências e à
# equipe da pessoa naquele dia no diário de campo.
recargas <- read_csv("dados/recargas.csv.gz", show_col_types = FALSE, na = "",
                     col_types = cols(justificativa = "c"))
diario <- read_csv("dados/diario_campo.csv", show_col_types = FALSE)
cadastro <- read_csv("dados/cadastro.csv", show_col_types = FALSE, na = "")
ausencias <- read_csv("dados/ausencias.csv", show_col_types = FALSE)

base_auditoria <- recargas |>
  mutate(dia = dia_referencia) |>
  left_join(cadastro |> select(matricula, equipe, admissao, desligamento), "matricula") |>
  left_join(ausencias |> select(matricula, tipo_ausencia = tipo, inicio, fim),
            join_by(matricula, between(dia, inicio, fim))) |>
  left_join(diario |> transmute(equipe, dia = data, em_campo = TRUE, pernoite = pernoite == "sim"),
            c("equipe", "dia")) |>
  mutate(em_campo = coalesce(em_campo, FALSE))
Ver o código R da etapa 2: regras objetivas
# Regras objetivas: cada violação pode ser cobrada. No teto, só o excedente
# conta como indevido; ele é calculado depois de tirar o que já é indevido por
# outra regra, para não contar o mesmo real duas vezes.
normalizar <- function(x) {
  x <- tolower(iconv(coalesce(x, ""), to = "ASCII//TRANSLIT"))
  x <- gsub("([0-9])\\s*km", "\\1 km", x)
  x <- gsub("([0-9])\\s*h\\b", "\\1 horas", x)
  trimws(gsub("[^a-z0-9 ]", " ", gsub("\\s+", " ", x)))
}
# Dicionário com tolerância a erro de digitação: a justificativa vale se
# estiver a até 15% de distância (em letras) de uma das frases da regra.
classificar_justificativa <- function(x) {
  n <- normalizar(x)
  validas <- normalizar(JUSTIFICATIVAS_VALIDAS)
  dist <- adist(n, validas, partial = FALSE) / outer(nchar(n), nchar(validas), pmax)
  case_when(n == "" ~ "ausente",
            apply(dist, 1, min) <= 0.15 ~ "válida",
            TRUE ~ "vaga")
}

# Cada texto diferente é classificado uma vez só.
textos <- unique(coalesce(base_auditoria$justificativa[base_auditoria$tipo == "Extra"], ""))
classes <- classificar_justificativa(textos)

auditada <- base_auditoria |>
  mutate(justificativa_classe = if_else(tipo == "Extra", classes[match(coalesce(justificativa, ""), textos)], NA)) |>
  arrange(matricula, dia, tipo, data_recarga, id) |>
  group_by(matricula, dia, tipo) |>
  mutate(duplicidade = row_number() > 1) |>
  ungroup() |>
  mutate(
    fora_do_trabalho = dia < admissao | (!is.na(desligamento) & dia > desligamento) | !is.na(tipo_ausencia),
    jantar_sem_pernoite = tipo == "Jantar" & !coalesce(pernoite, FALSE),
    extra_sem_justificativa = tipo == "Extra" & justificativa_classe == "ausente",
    motivo_regra = case_when(duplicidade ~ "Duplicidade",
                             fora_do_trabalho ~ "Pessoa fora do trabalho",
                             jantar_sem_pernoite ~ "Jantar sem pernoite",
                             extra_sem_justificativa ~ "Extra sem justificativa"),
    valor_indevido = if_else(is.na(motivo_regra), 0, valor)
  )

# Teto diário: soma do que não é indevido por outra regra; o excedente sai
# primeiro do extra, depois do jantar.
ordem_corte <- c("Extra" = 1, "Jantar" = 2, "Almoço" = 3)
auditada <- auditada |>
  mutate(restante = valor - valor_indevido, corte = ordem_corte[tipo]) |>
  group_by(matricula, dia) |>
  mutate(excedente_dia = pmax(sum(restante) - TETO, 0)) |>
  arrange(corte, .by_group = TRUE) |>
  mutate(antes = cumsum(restante) - restante,
         acima_do_teto = pmin(restante, pmax(excedente_dia - antes, 0))) |>
  ungroup() |>
  mutate(valor_indevido = valor_indevido + acima_do_teto,
         motivo_regra = if_else(is.na(motivo_regra) & acima_do_teto > 0, "Acima do teto", motivo_regra),
         regra = !is.na(motivo_regra)) |>
  select(-restante, -corte, -excedente_dia, -antes)
Ver o código R da etapa 3: lastro
# A equipe estava em campo naquele dia? A justificativa do extra é válida,
# vaga ou ausente?
auditada <- auditada |>
  mutate(sem_lastro = !em_campo,
         justificativa_fraca = tipo == "Extra" & justificativa_classe %in% c("vaga", "ausente"))
Ver o código R da etapa 4: faixa esperada
# Valor pago por dia de equipe em campo, por base e mês. Como o nível geral
# muda de um mês para outro (mais pernoites no segundo semestre), cada base é
# comparada com a mediana das bases no mesmo mês; a faixa esperada desse
# índice vem do critério de Tukey sobre todos os grupos com pelo menos 15 dias
# de equipe em campo. Como a auditoria procura pagamento a mais, só ficar
# acima da faixa conta como sinal de risco; abaixo dela, o grupo só é anotado.
dias_campo <- diario |>
  mutate(mes = format(data, "%Y-%m")) |>
  count(base, mes, name = "dias_equipe")
base_mes <- auditada |>
  mutate(mes = format(dia, "%Y-%m")) |>
  group_by(base, mes) |>
  summarise(valor = sum(valor), .groups = "drop") |>
  left_join(dias_campo, c("base", "mes")) |>
  mutate(valor_dia = valor / dias_equipe) |>
  group_by(mes) |>
  mutate(mediana_mes = median(valor_dia), indice = valor_dia / mediana_mes) |>
  ungroup()
validos <- base_mes |> filter(dias_equipe >= 15)
q <- quantile(validos$indice, c(0.25, 0.75))
faixa <- c(q[[1]] - 1.5 * diff(q), q[[2]] + 1.5 * diff(q))
base_mes <- base_mes |>
  mutate(faixa_min = faixa[1] * mediana_mes, faixa_max = faixa[2] * mediana_mes,
         abaixo_da_faixa = dias_equipe >= 15 & indice < faixa[1],
         fora_da_faixa = dias_equipe >= 15 & indice > faixa[2])
auditada <- auditada |>
  mutate(mes = format(dia, "%Y-%m")) |>
  left_join(base_mes |> select(base, mes, fora_da_faixa), c("base", "mes")) |>
  mutate(fora_da_faixa = coalesce(fora_da_faixa, FALSE))
Ver o código R da etapa 5: score de risco
# Um ponto para cada sinal, de 0 a 4.
auditada <- auditada |>
  mutate(score = regra + sem_lastro + justificativa_fraca + fora_da_faixa,
         score_sem_regra = score - regra)
Ver o código R da etapa 6: conclusão
# Indevido: violou uma regra objetiva. Revisar: sem regra violada, mas sem
# lastro de campo ou com score de 2 ou mais. Atenção: score 1. Regular: 0.
# Numa recarga que passou do teto só em parte, o excedente é Indevido e o
# resto recebe a conclusão que teria sem essa regra.
concluir <- function(sem_lastro, score) {
  case_when(sem_lastro | score >= 2 ~ "Revisar", score == 1 ~ "Atenção", TRUE ~ "Regular")
}
auditada <- auditada |>
  mutate(conclusao = if_else(regra, "Indevido", concluir(sem_lastro, score)),
         conclusao_resto = concluir(sem_lastro, score_sem_regra),
         valor_resto = valor - valor_indevido)
NIVEIS <- c("Indevido", "Revisar", "Atenção", "Regular")

Resultado

Do valor pago no ano, R$ 305 mil (4,0%) foram indevidos, e outros R$ 235 mil (3,1%) precisam de confirmação da base.

Uma barra horizontal com o valor do ano. Indevido, Revisar e Atenção ocupam juntos pouco mais de um décimo da barra; o resto é Regular.

O valor pago em 2025, dividido nas quatro conclusões da auditoria.

Uma barra horizontal com o valor do ano. Indevido, Revisar e Atenção ocupam juntos pouco mais de um décimo da barra; o resto é Regular.

O valor pago em 2025, dividido nas quatro conclusões da auditoria.
  • Indevido é o que violou uma regra objetiva e pode ser cobrado.
  • Revisar é quase todo formado por recargas sem lastro de campo: R$ 234 mil em 4.500 recargas lançadas em dias em que a equipe não aparece no diário. Pode ser falha do diário, e não da recarga; por isso a base confirma antes de qualquer cobrança.
  • Atenção não é acusação. Das 8.686 recargas em Atenção, 7.925 estão lá só porque a base e o mês ficaram acima da faixa esperada; a recarga em si cumpre a regra. Entre elas estão 1.072 lançamentos que só pareciam erro (lançados um ou dois dias depois, pernoite registrado com atraso, justificativa com erro de digitação). As outras 872 têm justificativa vaga, como “ajuste” ou “conforme combinado”.

O indevido por tipo de defeito

Barras horizontais do maior para o menor. Duplicidade, em azul, é o maior defeito, seguido de jantar sem pernoite, pessoa fora do trabalho, acima do teto e extra sem justificativa.

Valor indevido em 2025 por tipo de defeito. No teto, só o excedente acima do limite diário.

Barras horizontais do maior para o menor. Duplicidade, em azul, é o maior defeito, seguido de jantar sem pernoite, pessoa fora do trabalho, acima do teto e extra sem justificativa.

Valor indevido em 2025 por tipo de defeito. No teto, só o excedente acima do limite diário.

O que explica o salto do segundo semestre

O valor por dia em campo subiu R$ 20,86. Desse aumento, R$ 10,21 (49%) vieram de pagamentos indevidos. Outros R$ 8,51 (41%) vieram de mais jantares legítimos, porque os pernoites passaram de 11,5% para 16,8% dos dias em campo. O resto, R$ 2,14, acompanha os pernoites, nos extras.

Onde e por quê

  • A troca de sistema em agosto criou duplicidades. Até julho, elas somam R$ 6 mil; de agosto a dezembro, R$ 112 mil. O sistema novo aceita duas recargas do mesmo tipo para a mesma pessoa no mesmo dia.
  • O cadastro chega atrasado. 100% das recargas pagas a quem estava de férias caíram nos cinco primeiros dias do período: a base só fica sabendo das férias depois que elas começaram.
  • Duas bases pagam jantar sem pernoite. A Base 3 e a Base 6 concentram 100% do jantar sem pernoite, e são as únicas com meses acima da faixa esperada: 3 meses na primeira e 3 na segunda.

Oito pequenos gráficos, um por base. Em seis bases a linha fica dentro da faixa cinza o ano todo. Nas bases 3 e 6, em azul, a linha passa acima da faixa em três meses cada.

Valor pago por dia de equipe em campo, por base e mês, contra a faixa esperada (área cinza). Os pontos azuis são os meses acima da faixa.

Oito pequenos gráficos, um por base. Em seis bases a linha fica dentro da faixa cinza o ano todo. Nas bases 3 e 6, em azul, a linha passa acima da faixa em três meses cada.

Valor pago por dia de equipe em campo, por base e mês, contra a faixa esperada (área cinza). Os pontos azuis são os meses acima da faixa.

Casos para revisar

A lista completa tem 12.033 recargas classificadas como Indevido ou Revisar, ordenadas por conclusão, risco e valor, e pode ser baixada no topo da página. Abaixo, primeiro as 5 pessoas com maior valor indevido (só a parte indevida de cada recarga) e depois as 5 com maior valor para revisar.

Conclusão Matrícula Base Período Recargas Valor Motivo
Indevido F6561 Base 3 06/01/2025 a 17/12/2025 40 R$ 1.692 Jantar sem pernoite
Indevido F5109 Base 3 24/02/2025 a 11/12/2025 40 R$ 1.684 Jantar sem pernoite
Indevido F5730 Base 6 27/03/2025 a 31/12/2025 37 R$ 1.616 Jantar sem pernoite
Indevido F4119 Base 6 22/04/2025 a 26/12/2025 37 R$ 1.580 Jantar sem pernoite
Indevido F5573 Base 3 23/01/2025 a 29/12/2025 37 R$ 1.568 Jantar sem pernoite
Revisar F3012 Base 2 13/01/2025 a 29/12/2025 18 R$ 936 Sem lastro de campo
Revisar F8211 Base 6 23/01/2025 a 31/12/2025 18 R$ 936 Sem lastro de campo
Revisar F1355 Base 6 08/01/2025 a 23/12/2025 18 R$ 872 Sem lastro de campo
Revisar F6862 Base 6 15/01/2025 a 16/12/2025 17 R$ 852 Sem lastro de campo
Revisar F1035 Base 2 27/01/2025 a 29/12/2025 16 R$ 832 Sem lastro de campo

Indevido

Matrícula: F6561

Base: Base 3

Período: 06/01/2025 a 17/12/2025

Recargas: 40

Valor: R$ 1.692

Motivo: Jantar sem pernoite

Indevido

Matrícula: F5109

Base: Base 3

Período: 24/02/2025 a 11/12/2025

Recargas: 40

Valor: R$ 1.684

Motivo: Jantar sem pernoite

Indevido

Matrícula: F5730

Base: Base 6

Período: 27/03/2025 a 31/12/2025

Recargas: 37

Valor: R$ 1.616

Motivo: Jantar sem pernoite

Indevido

Matrícula: F4119

Base: Base 6

Período: 22/04/2025 a 26/12/2025

Recargas: 37

Valor: R$ 1.580

Motivo: Jantar sem pernoite

Indevido

Matrícula: F5573

Base: Base 3

Período: 23/01/2025 a 29/12/2025

Recargas: 37

Valor: R$ 1.568

Motivo: Jantar sem pernoite

Revisar

Matrícula: F3012

Base: Base 2

Período: 13/01/2025 a 29/12/2025

Recargas: 18

Valor: R$ 936

Motivo: Sem lastro de campo

Revisar

Matrícula: F8211

Base: Base 6

Período: 23/01/2025 a 31/12/2025

Recargas: 18

Valor: R$ 936

Motivo: Sem lastro de campo

Revisar

Matrícula: F1355

Base: Base 6

Período: 08/01/2025 a 23/12/2025

Recargas: 18

Valor: R$ 872

Motivo: Sem lastro de campo

Revisar

Matrícula: F6862

Base: Base 6

Período: 15/01/2025 a 16/12/2025

Recargas: 17

Valor: R$ 852

Motivo: Sem lastro de campo

Revisar

Matrícula: F1035

Base: Base 2

Período: 27/01/2025 a 29/12/2025

Recargas: 16

Valor: R$ 832

Motivo: Sem lastro de campo

Como saber que a auditoria acertou

Como os dados deste caso foram gerados por script, foi possível conferir a auditoria contra o que o gerador plantou: ela encontrou os 12.905 defeitos plantados, sem exceção, e nenhum dos 19.885 lançamentos que só pareciam erro virou Indevido ou Revisar. A auditoria não lê o gabarito; um script separado compara os dois no fim. Com dados reais não existe gabarito, e essa conferência é feita com a base: uma amostra de casos de cada conclusão é revisada com quem conhece o processo antes de o relatório ser fechado.

Recomendações

Cada achado vira uma correção no processo, para o problema não voltar no ano seguinte.

Achado Correção recomendada Responsável
Duplicidade depois da troca de sistema Bloqueio no sistema de uma recarga por tipo, pessoa e dia TI e fornecedor do cartão
Cadastro atrasado Lista diária de férias, afastamentos e desligamentos enviada ao sistema de recarga RH
Jantar sem pernoite Jantar só liberado quando o diário registra pernoite Operação e supervisores das bases
Acima do teto Teto diário aplicado pelo próprio sistema TI
Justificativa vaga Justificativa escolhida numa lista fechada, não digitada Controladoria
Valores já pagos como indevido Estorno ou recuperação conforme a política da empresa RH, com apoio do jurídico

Duplicidade depois da troca de sistema

Correção recomendada: Bloqueio no sistema de uma recarga por tipo, pessoa e dia

Responsável: TI e fornecedor do cartão

Cadastro atrasado

Correção recomendada: Lista diária de férias, afastamentos e desligamentos enviada ao sistema de recarga

Responsável: RH

Jantar sem pernoite

Correção recomendada: Jantar só liberado quando o diário registra pernoite

Responsável: Operação e supervisores das bases

Acima do teto

Correção recomendada: Teto diário aplicado pelo próprio sistema

Responsável: TI

Justificativa vaga

Correção recomendada: Justificativa escolhida numa lista fechada, não digitada

Responsável: Controladoria

Valores já pagos como indevido

Correção recomendada: Estorno ou recuperação conforme a política da empresa

Responsável: RH, com apoio do jurídico

A auditoria também deixa três indicadores para acompanhar todo mês:

  • Taxa de recargas indevidas: valor indevido ÷ valor pago, com meta abaixo de 0,5%.
  • Cobertura de lastro: recargas com equipe registrada em campo ÷ total de recargas, com meta acima de 99%.
  • Valor por dia em campo: por base, contra a faixa esperada.

O que o caso demonstra

  • Cruzar bases que ninguém cruzava. O erro não estava em nenhuma base sozinha, e sim na falta de conferência entre o cartão, o diário de campo e o RH.
  • Separar erro objetivo de suspeita. Só o que viola uma regra vai para cobrança; o resto vai para a base confirmar, sem acusar ninguém.
  • Um número que explica o problema. O salto do segundo semestre foi dividido entre o que é indevido e o que é legítimo, em vez de virar uma ordem genérica de corte de gastos.
  • Um relatório que se repete. O código fica com a empresa, e o mesmo relatório roda no ano seguinte com os dados novos.

Sua empresa paga algum benefício, reembolso ou adicional sem cruzar com outra base?

Me conte como funciona hoje e eu digo o que dá para conferir.

Fale comigo