FJFrigo · Relatórios › Conferências › 371 (antes 31A)

Alertas de Anomalias Financeiras

Seis detectores de situações do financeiro que merecem conferência (duplicidade, baixa a maior, troca de banco antes do pagamento, lançamento fora do horário, conciliação atrasada e baixa em período fechado). Só lê. Dois códigos, uma tela.

Tabelas: financeiro_baixas, financeiro_emissao, emitente_log, udf_logEndpoint: POST /lancamento/anomalias-financeirasPrograma antigo: nenhum (desenho novo)

Teste

Caso sugerido para QA: o que fazer, o que esperar e como conferir no banco.

Bloqueia

Recusa com a mensagem exata (HTTP 400, mostrada na tela).

Atenção

Limitação, pendência ou ponto em que o código e a ajuda não coincidem.

A

O que a tela é e faz

Identidade 31A = 371

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.

B

Filtros e opções

Padrões e limites
Campo da telaDefaultLimites / validaçãoEfeito
Período de / atéhoje − 30 dias até hojeObrigató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 filiaismarcadaDesmarcada = 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 marcadosFront: "Escolha ao menos um tipo de alerta." (texto só do front). Na API, lista vazia ou nula = todosSó roda o detector marcado.
Duplicado: janela de dias50 a 60Distância máxima entre as duas baixas do par. 0 = mesmo dia.
Troca bancária: dias antes do pagamento70 a 90Quantos dias antes da baixa uma troca de banco/PIX ainda conta.
Sem conciliação há mais de (dias)100 a 365Idade mínima do lançamento não conciliado.
Expediente das / às06:00 / 20:00Hora inicial tem de ser antes da final; hora inválida recusaFora desta faixa = fora do horário.
Fim de semana conta como fora do horáriomarcada—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).

C

De onde vem cada alerta

SQL e regras de negócio

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).

TipoGravidadeRecorte de períodoTabelas / colunas principais
PAGAMENTO_DUPLICADOALTAb1.data_baixa no períodofinanceiro_baixas ×2, financeiro_emissao ×2, emitente, filial, moeda
BAIXA_ACIMA_TITULOP = ALTA, R = MEDIAtí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_ALTERADOSALTAdata_baixa no período; troca de ini − diasBanco até o fim do períodoemitente_log (historico em BLOB windows-1252), financeiro_emissao_dados_pagto, usuario
FORA_DO_HORARIObaixa = MEDIA; título manual = BAIXAdata_inclusao no período, e data_baixa/data_emissao até 60 dias antes e depois do períodofinanceiro_baixas (idcoletivo, idusuario_incluiu), financeiro_emissao (idfaturamento, idusuario_incluiu)
CONCILIACAO_ATRASADAALTA se o mais antigo passa de 60 dias; senão MEDIAdata_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_FECHADOALTAdata_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 baixafinanceiro_baixas, udf_log (data, udf, idfilial, idusuario)

1. Pagamento duplicado

2. Baixa acima do título

3. Dados bancários alterados antes do pagamento

4. Fora do horário

5. Conciliação atrasada

6. Baixa lançada com o período fechado

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).

D

Permissões, travas e mensagens

Sem regra nomeada

Não há regra nomeada: o serviço não chama RegraAcessoService. O que existe:

Bloqueia

Informe a data inicial.

QuandoData inicial vazia (idem "final").

Bloqueia

Data inicial inválida: x

QuandoData fora do formato ISO (aaaa-mm-dd).

Bloqueia

A data final não pode ser anterior à inicial.

QuandoPeríodo invertido.

Bloqueia

O período pode ter no máximo 366 dias.

QuandoFim mais de 366 dias depois do início.

Bloqueia

A janela de dias do pagamento duplicado tem de ficar entre 0 e 60.

QuandoJanela fora de 0..60.

Bloqueia

Os dias antes do pagamento tem de ficar entre 0 e 90.

QuandoDias do banco fora de 0..90.

Bloqueia

Os dias para a conciliação tem de ficar entre 0 e 365.

QuandoDias de conciliação fora de 0..365.

Bloqueia

A hora inicial do expediente tem de ser antes da final.

QuandohoraInicio >= horaFim.

Bloqueia

Hora inválida: x

QuandoHora fora do formato HH:mm.

E

Configuração e dependências

Constantes e dados de origem

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:

F

Casos de teste sugeridos

QA
Teste

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.

Teste

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).

Teste

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

Teste

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

Teste

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

Teste

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").

Teste

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

Teste

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

Teste

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

Teste

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

Teste

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.

Teste

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).

G

Limitações, pendências e pontos de atenção

Achados da leitura do código
Atenção

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.

Atenção

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.

Atençã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).

Atenção

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).

Atenção

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).

Atenção

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.