Informe a data inicial.
QuandoData inicial vazia (idem "final").
Caso sugerido para QA: o que fazer, o que esperar e como conferir no banco.
Recusa com a mensagem exata (HTTP 400, mostrada na tela).
Limitação, pendência ou ponto em que o código e a ajuda não coincidem.
31A e 371 são a mesma tela. 31A era o código provisório (desenho novo, 27/09/2026, sem linha em opcao_sistema, menu com idOpcao: null). Em 29/09/2026 o usuário cadastrou a opção e a tela passou a ser 371, no grupo novo 3-Relatórios › 7-Conferências › 1-Alertas de Anomalias (histórico 368). Confirmado no código: um único componente (AnomaliasFinanceiras.vue, rota anomaliasFinanceiras), um único endpoint (POST /lancamento/anomalias-financeiras) e uma única ajuda (371.md/.es.md; não existe 31A.md). Por isso este documento leva os dois códigos no nome: o botão "</>" resolve tanto 31A quanto 371.
A tela só lê. Procura, num período, seis tipos de situação do financeiro que merecem uma segunda olhada e lista um alerta por caso, com gravidade, filial, emitente, documento, valor, usuário e os ids dos títulos e das baixas envolvidos. Não existe no legado Harbour nem no ceif (desenho novo). Serviço: cadastro.anomalia.AnomaliaFinanceiraService.
| Campo da tela | Default | Limites / validação | Efeito |
|---|---|---|---|
| Período de / até | hoje − 30 dias até hoje | Obrigatório; fim ≥ início; no máximo 366 dias (início + 366 dias não pode ser antes do fim) | Recorte em faixa meio-aberta: col >= ini AND col < fim + 1 dia. Cada detector aplica o período a uma coluna diferente (ver C). |
| Todas as minhas filiais | marcada | Desmarcada = só a filial da sessão (user.idFilial()) | Marcada = FiliaisDoUsuario.permitidas: usuario_filial.idfilial_uso; sem linhas, usuario.idfilial; sem isso, a da sessão. |
| Tipos de alerta (6 caixas) | todos marcados | Front: "Escolha ao menos um tipo de alerta." (texto só do front). Na API, lista vazia ou nula = todos | Só roda o detector marcado. |
| Duplicado: janela de dias | 5 | 0 a 60 | Distância máxima entre as duas baixas do par. 0 = mesmo dia. |
| Troca bancária: dias antes do pagamento | 7 | 0 a 90 | Quantos dias antes da baixa uma troca de banco/PIX ainda conta. |
| Sem conciliação há mais de (dias) | 10 | 0 a 365 | Idade mínima do lançamento não conciliado. |
| Expediente das / às | 06:00 / 20:00 | Hora inicial tem de ser antes da final; hora inválida recusa | Fora desta faixa = fora do horário. |
| Fim de semana conta como fora do horário | marcada | — | Sábado e domingo (DAYOFWEEK IN (1,7)) entram. |
A resposta traz alertas (ordem: gravidade ALTA, MEDIA, BAIXA e, dentro dela, data decrescente) e porTipo (contagem de cada tipo, que alimenta os botões-resumo). Clicar num botão-resumo só filtra a lista já carregada, sem nova consulta. Imprimir tira PDF/planilha da grade (BotaoImprimirGrade).
Todos usam financeiro_baixas / financeiro_emissao vivos (excluido <> 'T') e limitam a filial pelo título (fe.idfilial IN (...)), exceto a conciliação (filial da conta bancária).
| Tipo | Gravidade | Recorte de período | Tabelas / colunas principais |
|---|---|---|---|
PAGAMENTO_DUPLICADO | ALTA | b1.data_baixa no período | financeiro_baixas ×2, financeiro_emissao ×2, emitente, filial, moeda |
BAIXA_ACIMA_TITULO | P = ALTA, R = MEDIA | título com ao menos uma baixa no período (data_baixa) | financeiro_baixas (todas as baixas vivas do título), financeiro_emissao.valor_parcela |
DADOS_BANCARIOS_ALTERADOS | ALTA | data_baixa no período; troca de ini − diasBanco até o fim do período | emitente_log (historico em BLOB windows-1252), financeiro_emissao_dados_pagto, usuario |
FORA_DO_HORARIO | baixa = MEDIA; título manual = BAIXA | data_inclusao no período, e data_baixa/data_emissao até 60 dias antes e depois do período | financeiro_baixas (idcoletivo, idusuario_incluiu), financeiro_emissao (idfaturamento, idusuario_incluiu) |
CONCILIACAO_ATRASADA | ALTA se o mais antigo passa de 60 dias; senão MEDIA | data_baixa/data de ini até o menor entre o fim do período e (hoje − dias + 1) | financeiro_baixas.data_conciliacao, financeiro_lancamento_banco.data_conciliacao, conta_bancaria |
BAIXA_EM_PERIODO_FECHADO | ALTA | data_baixa de 180 dias antes do início até o fim; data_inclusao dentro do período e pelo menos 1 dia depois da data da baixa | financeiro_baixas, udf_log (data, udf, idfilial, idusuario) |
tipo_emissao = 'P'), com o mesmo idemitente, documento, parcela e valor, cujas datas de baixa ficam a no máximo janela dias uma da outra (b2.data_baixa >= b1.data_baixa - janela DIA e < b1.data_baixa + (janela+1) DIA).REGEXP '[0-9].*[0-9].*[0-9]') e não pode ser só zeros/hífens/espaços (NOT REGEXP '^[-0 ]*$'). Em agosto/2026 no central, "TARIFA", "ADTO", "DIARIAS" e "RECIBO" davam 130 pares falsos.idfaturamento > 0 AND idfaturamento igual AND idtipo_faturamento igual (comparação null-safe).valor − valor_acrescimo − valor_juros + valor_desconto + valor_devolucao + valor_retencao) de todas as baixas vivas do título (mesma conta do 221), com nulos tratados como zero. Acusa quando amortizado > valor_parcela + 0,01.emitente_log (blob decodificado por TextoLegado.ler) cujo texto tem linha começando por Banco 1/2, Agência Banc, Conta Banc, Titular Banc, CNPJ/CPF 1, Tipo Conta, Tipo Pix ou Chave Pix. Cruza com baixas a pagar do período do mesmo emitente: a troca vale se estiver entre (dia da baixa − diasBanco, 00:00) e o fim do dia da baixa.financeiro_emissao_dados_pagto com data_alteracao > data_inclusao + 1 minuto e data_alteracao entre (data da baixa − diasBanco) e o fim do dia da baixa.emitente_log as trocas feitas pelo sistema web (EmitenteLogService.registrarDadosBancarios, 13 campos, só quando mudam, no formato do ceif COLUNA / VALOR NOVO / VALOR ANTIGO) e pelo ceif. Troca feita no sistema antigo não gera alerta da fonte A.idcoletivo: um alerta por pagamento coletivo, valor = soma, emitente "(vários)" quando há mais de um) ou título manual (IFNULL(idfaturamento,0) <= 0, ou seja, nascido no 221) incluído fora de [horaInicio, horaFim) ou, se marcado, em sábado/domingo. A hora é a de data_inclusao (hora local, sem fuso).idusuario_incluiu).data_baixa (ou data_emissao) entre 60 dias antes do início e 60 dias depois do fim: lançamento incluído no período com data mais distante que isso não é visto.data_conciliacao (baixa ou lançamento bancário) nos últimos 180 dias.data_conciliacao IS NULL no período, mais velhos que diasConciliacao (o fim efetivo é o menor entre o fim do período e hoje − dias + 1). Um alerta por conta, com quantidade, valor e o mais antigo. ALTA quando o mais antigo passa de 60 dias.conta_bancaria.idfilial. Campos de emitente/documento ficam vazios.data_inclusao >= data_baixa + 1 dia. O estado do fechamento "naquela hora" vem do udf_log: a última troca da U.D.F. financeira até a inclusão, da filial da baixa ou de todas (idfilial nulo). Acusa se a data da baixa é anterior ou igual à U.D.F. vigente.udf_log, então baixa lançada com o período reaberto não acusa. Sem log anterior à inclusão, não se sabe e não acusa. Alteração de baixa não conta (a data_alteracao muda em lote, p. ex. na conciliação: dava 8.916 alertas falsos em jul-set/2026).Baixa sem contabilização não é detector (tentado em 03/10/2026 e retirado): o 252 agrupa as baixas e exclui de propósito empréstimo, doação, devoluções, "mesmo RUC", conta com udf_contab; saber qual deveria ter asiento exige a simulação do 252 (decisão registrada em ConferenciaContabilService).
Não há regra nomeada: o serviço não chama RegraAcessoService. O que existe:
opcao_sistema; sem linha em grupo_permissao a tela some para quem não é ADM (conceder no 444). Isso só esconde o menu: o endpoint está sob /lancamento/* (JWT obrigatório) e responde a qualquer sessão válida.DynamicDataSourceManager.obterHomologacao(user.database()) (pool do tenant).Informe a data inicial.
QuandoData inicial vazia (idem "final").
Data inicial inválida: x
QuandoData fora do formato ISO (aaaa-mm-dd).
A data final não pode ser anterior à inicial.
QuandoPeríodo invertido.
O período pode ter no máximo 366 dias.
QuandoFim mais de 366 dias depois do início.
A janela de dias do pagamento duplicado tem de ficar entre 0 e 60.
QuandoJanela fora de 0..60.
Os dias antes do pagamento tem de ficar entre 0 e 90.
QuandoDias do banco fora de 0..90.
Os dias para a conciliação tem de ficar entre 0 e 365.
QuandoDias de conciliação fora de 0..365.
A hora inicial do expediente tem de ser antes da final.
QuandohoraInicio >= horaFim.
Hora inválida: x
QuandoHora fora do formato HH:mm.
A tela não tem configuração própria: nada em system_config, nada em application.yml, nenhuma rotina agendada e nenhum e-mail. O que influencia o resultado:
emitente_log (só web/ceif), udf_log (gravado ao trocar a U.D.F. no 421, tanto no legado, menu421.prg:369-371, quanto no porte, UdfRepository), data_conciliacao (conciliação 225).data_inclusao.ColunasDaTabela); em tenant sem financeiro_emissao_dados_pagto, udf_log ou emitente_log a consulta correspondente estoura (recusa com mensagem de erro inesperado, código de ocorrência).Abrir e verificar com os padrões
FazerAbrir a tela (371), deixar os padrões e clicar em Verificar.
EsperadoO botão mostra "Verificando… (Ns)"; a grade lista os alertas em ordem ALTA, MEDIA, BAIXA; "Todos (N)" é igual à soma dos seis botões-resumo. Sem alerta: "Nenhuma anomalia encontrada no período.". Antes de verificar: "Escolha o período e clique em Verificar.".
ConferirTempo de referência no central (histórico 294): um mês ~2,9 s (4 tipos); ago-set com os seis tipos ~11,4 s.
Validações de entrada
FazerInverter as datas; período de 400 dias; janela 61; diasBanco 91; diasConciliacao 400; expediente 20:00 às 06:00; desmarcar todos os tipos.
EsperadoMensagens da seção D, uma a uma (desmarcar todos os tipos: texto do front, sem chamada ao servidor).
Pagamento duplicado verdadeiro
FazerVerificar 01/08/2026 a 31/08/2026 no central, só o tipo "Pagamento duplicado", janela 5.
EsperadoReferência do histórico 294: VERO SA, documento 07/2026, R$ 1.314,71 em dois títulos, baixas em 11 e 13/08, gravidade ALTA, descrição "2 pagamentos do mesmo valor, documento e parcela em 2 títulos diferentes, entre 11/08/2026 e 13/08/2026.".
ConferirAproximação do detector (sem janela e sem a exclusão de mesmo faturamento; use para achar candidatos):SELECT fe.idemitente, fe.documento, fe.parcela, b.valor, COUNT(DISTINCT fe.id) titulos,
GROUP_CONCAT(fe.id) ids, MIN(b.data_baixa) d1, MAX(b.data_baixa) d2
FROM financeiro_baixas b
JOIN financeiro_emissao fe ON fe.id = b.idfinanceiro_emissao AND fe.tipo_emissao = 'P' AND fe.excluido <> 'T'
WHERE b.excluido <> 'T' AND b.valor > 0
AND b.data_baixa >= '2026-08-01' AND b.data_baixa < '2026-09-01'
AND fe.documento REGEXP '[0-9].*[0-9].*[0-9]' AND fe.documento NOT REGEXP '^[-0 ]*$'
GROUP BY fe.idemitente, fe.documento, fe.parcela, b.valor
HAVING COUNT(DISTINCT fe.id) > 1
Pagamento duplicado que NÃO deve aparecer
FazerProcurar (a) documento "TARIFA"/"ADTO"/"RECIBO" pago duas vezes ao mesmo emitente e valor; (b) rateio por centro de custo (dois títulos do mesmo idfaturamento + idtipo_faturamento com mesmo documento e parcela).
EsperadoNenhum alerta para (a) nem (b). Janela 0: só pares baixados no mesmo dia; janela 60 amplia, nunca reduz o número de grupos.
ConferirPara (b): SELECT idfaturamento, idtipo_faturamento, documento, parcela, COUNT(*) FROM financeiro_emissao WHERE excluido <> 'T' AND idfaturamento > 0 GROUP BY 1,2,3,4 HAVING COUNT(*) > 1 LIMIT 20
Baixa acima do título
FazerEscolher um título com baixas no período e comparar o amortizado com a parcela (em homologação, baixar a mais via 221 se for preciso criar o caso).
EsperadoAlerta só se amortizado > parcela + 0,01; "a pagar" ALTA, "a receber" MEDIA; o valor da coluna é o excesso; a coluna Baixas lista todas as baixas vivas do título.
ConferirSELECT fe.id, fe.valor_parcela,
SUM(b.valor - IFNULL(b.valor_acrescimo,0) - IFNULL(b.valor_juros,0) + IFNULL(b.valor_desconto,0)
+ IFNULL(b.valor_devolucao,0) + IFNULL(b.valor_retencao,0)) AS amortizado
FROM financeiro_emissao fe
JOIN financeiro_baixas b ON b.idfinanceiro_emissao = fe.id AND b.excluido <> 'T'
WHERE fe.id = :idtitulo AND fe.excluido <> 'T' GROUP BY fe.id
Dados bancários alterados (pela web)
FazerNo cadastro 15, trocar a chave PIX (ou conta) de um fornecedor com título a pagar; baixar o título no mesmo dia (221/222); verificar o período incluindo o dia, tipo "Dados bancários".
EsperadoAlerta ALTA na data da baixa: "Cadastro do fornecedor alterado em ... por USUARIO (Chave Pix, ...) antes do pagamento de ...". Com dias antes = 0 só vale troca do mesmo dia. Troca feita no sistema desktop não gera alerta.
ConferirSELECT l.id, l.data, l.idusuario, LEFT(CONVERT(l.historico USING latin1), 200) FROM emitente_log l WHERE l.idemitente = :id ORDER BY l.data DESC LIMIT 5 Histórico 294: no bimestre ago-set o tipo deu 506 alertas em todas as filiais ("vale olhar se é ruído").
Dados de pagamento do título alterados
FazerNo 221 (Dados Pagamento) alterar o banco/PIX de um título a pagar já incluído (depois de 1 minuto) e baixá-lo no mesmo dia.
EsperadoAlerta ALTA "Dados de pagamento do título alterados em ... por USUARIO antes do pagamento de ...".
ConferirSELECT idfinanceiro_emissao, data_inclusao, data_alteracao, idusuario_alterou FROM financeiro_emissao_dados_pagto WHERE idfinanceiro_emissao = :idtitulo
Fora do horário
FazerIncluir (em homologação) uma baixa às 22h ou num sábado; verificar o dia, tipo "Lançamento fora do horário", expediente 06:00-20:00 e depois com fim de semana desmarcado.
EsperadoBaixa = MEDIA; título manual = BAIXA. Pagamento coletivo = um alerta só ("N baixas (coletivo)"). Com "Fim de semana..." desmarcado o sábado às 10h deixa de aparecer.
ConferirSELECT b.id, b.data_baixa, b.data_inclusao, DAYNAME(b.data_inclusao)
FROM financeiro_baixas b
WHERE b.excluido <> 'T' AND b.data_inclusao >= '2026-09-01' AND b.data_inclusao < '2026-10-01'
AND (TIME(b.data_inclusao) < '06:00:00' OR TIME(b.data_inclusao) >= '20:00:00' OR DAYOFWEEK(b.data_inclusao) IN (1,7))
LIMIT 50
Conciliação atrasada
FazerVerificar jul-set/2026 no central, tipo "Conciliação atrasada", 10 dias.
EsperadoReferência de 03/10/2026 (histórico 294): 5 contas; a maior, STARS FOMENTO-NOVO, com 287 lançamentos desde 01/07 somando 10,58 mi. Conta que não concilia há mais de 180 dias não aparece. Gravidade ALTA quando o mais antigo passa de 60 dias (contado a partir do início do período escolhido, ver G).
ConferirSELECT b.idconta_bancaria, COUNT(*) n, SUM(b.valor) v, MIN(b.data_baixa) mais_antigo
FROM financeiro_baixas b
WHERE b.excluido <> 'T' AND b.data_conciliacao IS NULL
AND b.data_baixa >= '2026-07-01' AND b.data_baixa < DATE_SUB(CURDATE(), INTERVAL 9 DAY)
GROUP BY b.idconta_bancaria
Baixa lançada com o período fechado
FazerVerificar 01/08/2026 a 30/09/2026 no central, tipo "Baixa lançada com o período fechado".
EsperadoReferência (histórico 294): baixa 1001576815, data 28/08, incluída em 11/09 às 11:00 por Felipe Rodrigues Morais; a U.D.F. de todas as filiais estava em 31/08 desde 09/09 10:03. Não deve acusar: baixa incluída com o período reaberto por token; baixa só alterada depois do fechamento.
ConferirSELECT id, data_baixa, data_inclusao, idusuario_incluiu FROM financeiro_baixas WHERE id = 1001576815 e SELECT data, udf, idfilial, idusuario FROM udf_log ORDER BY data DESC LIMIT 10
Só a filial da sessão × todas
FazerRepetir a mesma verificação com "Todas as minhas filiais" marcada e desmarcada.
EsperadoDesmarcada: só alertas da filial ativa (conciliação: conta da filial). Marcada: todas as de usuario_filial. A contagem desmarcada é sempre ≤ a marcada.
Filtro por botão e impressão
FazerClicar em um botão-resumo; clicar em Imprimir.
EsperadoA grade mostra só o tipo clicado, sem nova consulta; botão com contagem 0 fica desabilitado; o PDF/planilha reflete a lista filtrada (colunas Gravidade, Alerta, Data, Filial, Emitente, Documento, Parc., Valor, Usuário, Descrição, Títulos, Baixas).
Corrigido em 04/10/2026: ajuda dizia "incluída ou alterada"
O código está certo (só data_inclusao; a alteração muda em lote e dava 8.916 falsos em central — histórico 294). A ajuda (371.md/.es.md) foi ajustada: só a inclusão conta.
Corrigido em 04/10/2026: alertas repetidos para a mesma baixa em "Dados bancários"
dadosBancarios junta tudo num alerta por baixa (umPorBaixa, chave = id da baixa): as descrições de cada troca do cadastro e de cada alteração dos dados do título vão juntas, em ordem. O total do tipo cai na mesma proporção.
Idade da conciliação medida dentro do período (texto ajustado em 04/10/2026)
O "mais antigo" é MIN(data) dentro de [início do período, fim efetivo) — coerente com os outros detectores, que são todos do período. O texto do alerta passou a dizer "sem conciliação no período; o mais antigo deles é de ..." e a ajuda avisa que o que ficou antes do início não entra. Medir a idade real da conta (sem o corte do início) mudaria a gravidade e a contagem: decisão em aberto. Até lá, escolher período longo (até 366 dias).
Fora do horário: janela de ±60 dias na data do lançamento
Lançamento incluído no período mas com data_baixa/data_emissao mais de 60 dias antes ou depois do período não é visto (escolha de índice, documentada no código).
Colunas do serviço sem proteção por tenant
Diferente de outros serviços, este não usa ColunasDaTabela: tenant sem emitente_log, udf_log ou financeiro_emissao_dados_pagto derruba o tipo correspondente (e a verificação inteira, já que roda tudo numa chamada).
Pendências registradas
Status REVISAR nas duas linhas do docs/status-porte.csv (31A de 27/09 e 371 de 03/10: a mesma tela duplicada na planilha). Não testada na tela; backend do IntelliJ precisa reiniciar. Falta decidir regra de acesso. O comentário no topo de AnomaliasFinanceiras.vue ainda diz "quatro regras" e o método poucos do serviço não é usado.
Nada bate com essa busca. Tente um trecho menor, ou limpe os filtros.