O usuário não tem filial liberada.
Recusa e não gera. HTTP 200 com statuscode 400 e a frase indicada.
Comportamento que surpreende sem ser erro — origem da maioria dos chamados de "o número não bate". Parte sai como painel de avisos na tela.
O funil segue a SO pelos itens da CAN, do orçamento, da SC e da compra — as mesmas ligações do 24E.
O comprador está vazio em todo o central; a tabela por usuário usa idusuario_incluiu do orçamento.
A unidade é a solicitação de orçamento (24A) do período (pela almoxarifado_solicitacao_orcamento.data), seguida até hoje, mesmo depois do período. Desenho novo, sem legado. Etapas: SO → Autorizada → CAN (24D) → Orçamento (246) → Orçamento autorizado → SC (241) → Compra (242). Cada etapa vale pela primeira data em que a SO chega nela (compra parcial já conta).
| Etapa | Como a SO chega lá |
|---|---|
| Autorizada | autorizado = 1 ou idusuario_autorizou preenchido. Não há data da autorização (data_gerente/data_administrador vazios em 1.958 de 1.958): conta, mas não tem tempo. |
| CAN | almoxarifado_can_solicitacoes → almoxarifado_can com status <> 'CANCELADO'. Data = data_reuniao. A CAN é opcional: filial.controla_can_almox não diz quem usa (em central, abr–jun/2026, 1.835 de 1.979 SOs de filiais "sem CAN" passaram por CAN). |
| Orçamento | Pelo item da CAN (almoxarifado_orcamento_can_itens) ou pelo item da SO (almoxarifado_orcamento_solicitacao_orcamento_itens, produto ou serviço); orçamento vivo (excluido = 'F'). Data = almoxarifado_orcamento.data; autorização = data_hora_autorizou. |
| SC | Pelos itens (almoxarifado_solicitacao_compra_orcamento_itens, produto e serviço) e pelo cabeçalho almoxarifado_solicitacao_compra_orcamento (só 8 de 1.625 orçamentos no trimestre — sozinho, o funil caía a zero na SC). |
| Compra | almoxarifado_compra_solicitacao_compra e o idalmoxarifado_solicitacao_compra do item da compra (produto e serviço). Data = almoxarifado_compra.data_entrada. |
Reprovada na CAN: CAN com itens e todos decisao_compra = 'REPROVADO', sem orçamento — sai como "reprovada", não como parada.
Aberta = autorizada, não reprovada e sem compra. Parada na etapa = a última etapa alcançada; "desde" = a data mais recente já alcançada (há CAN com data_reuniao antes da própria SO). "Paradas há mais de 30 dias" conta as abertas com mais de 30 dias desde essa data.
Tempos em dias de calendário, não horas: SO e SC gravam só a data (meia-noite) e a autorização do orçamento grava hora — por hora, a SC do mesmo dia parecia anterior e o trecho Autorizado → SC media 760 de 1.592. Trecho com a ordem trocada fica fora da estatística. Mediana e p90 pelo método do "mais próximo" (sem interpolar: é sempre um tempo que aconteceu).
Trechos: SO → CAN, → Orçamento (da CAN, ou da SO quando não houve CAN), Orçamento → autorizado, Autorizado → SC (do orçamento, se não há data de autorização), SC → compra e Total (SO → compra).
Pessoa = quem lançou o orçamento (almoxarifado_orcamento.idusuario_incluiu → usuario.login): o idcomprador está vazio em todo orçamento e SC de central e em 1.342 de 1.958 SOs. Só entram na tabela por usuário as SOs que têm orçamento.
Fora: o aviso de recebimento (24F): 17 registros, o último de 06/2025, e só liga à compra por documento + fornecedor.
| Saída | Conteúdo |
|---|---|
| Indicadores | Solicitações; não autorizadas; reprovadas na CAN; viraram compra; autorizadas; Da solicitação à compra (mediana, p90, média); trecho mais lento; abertas e paradas há mais de 30 dias. |
| Gráficos | Funil (clique numa etapa abre as abertas paradas nela); tempo de cada trecho (mediana e p90); mês a mês (mediana de cada trecho pelo mês da solicitação; destaque quando a mediana passa do dobro da geral no trecho); por filial; por usuário. |
| Lista | As abertas, mais antigas primeiro: solicitação, data, setor, parada em, desde, dias, orçamento, quem lançou o orçamento. 500 linhas na tela (o endpoint de cliques traz até 2.000); o XLS traz todas. |
| XLS | Uma linha por SO (situação, etapa atual, dias na etapa, datas e números de CAN/orçamento/SC/compra, quem lançou, dias de cada trecho). Não há PDF. |
| Campo | Padrão | Efeito |
|---|---|---|
| Período de / até | 90 dias atrás até hoje | Pela data da solicitação. Faixa meio-aberta (aso.data >= de e < até + 1 dia). |
| Filial (multi) | Todas do usuário | aso.idfilial (a filial da solicitação). |
| Setor (multi) | Todos | almoxarifado_setor da solicitação. |
Três perguntas sobre as compras de fornecedor do almoxarifado: o preço subiu ou caiu, quem fornece (e se há fornecedor único), e o que a cotação (orçamento) economizou. Desenho novo, sem legado.
tipo_faturamento.tipo_operacao em PAINEL_ALMOX_OPERACOES_COMPRA (padrão 101,131: compra de insumos — inclusive importação e NF de produtor — e de serviços; mesma codificação em central e fjfrigo_concepcion). Fora: 171 transferência, 311 retorno, 551 ajuste/outras entradas, 501 cancelamento, 111 manutenção de imobilizado, 121 compra de imobilizado (Paraguai). Produto imobilizado fora. Valor = almoxarifado_compra_produto.valor_total_ml, só linhas com quantidade e valor > 0; com moeda escolhida, valor_total_ml ÷ cotação do dia da entrada (sem cotação, valor zero e aviso). Pela data_entrada.
| Número | Regra |
|---|---|
| Gasto com fornecedores | Soma do período (atual), todos os fornecedores (almoxarifado_compra.idemitente). |
| Variação de preço | Preço médio (valor ÷ quantidade) do item no período contra o do período anterior de mesmo tamanho, só itens comprados nos dois. Índice ponderado pela quantidade atual: Σ q·p_atual ÷ Σ q·p_anterior − 1. Impacto = q_atual · (p_atual − p_anterior). |
| Provável erro de unidade | Variação acima de 5× ou abaixo de 1/5 (óleo protetivo 1010289: R$ 652 → R$ 34 no 3º tri/2026): fora do índice, do impacto e das listas de altas/quedas; aparece numa lista à parte. |
| Fornecedores | Fatia de cada um no gasto; os 5 e os 10 maiores; os 20 maiores na tela (o clique abre os itens comprados dele, com o preço anterior de todos os fornecedores). |
| Fornecedor único | Item com duas compras (notas) ou mais no período, todas do mesmo fornecedor. Sem esse piso, 1.544 de 1.815 itens saíam "únicos" só por terem sido comprados uma vez. |
| Cotação | almoxarifado_orcamento_produtos de orçamento vivo, pela almoxarifado_orcamento.data. Por item de orçamento: vencedor = vencedor = 1, senão a menor oferta (regra do 24E). Economia sobre a média e sobre a maior só com 2+ ofertas; pago acima da menor = (vencedor − menor) × quantidade. Orçamento em outra moeda: moeda local pela cotação do dia dele, e dali à moeda escolhida. |
| Cotação com uma oferta só | % dos itens de orçamento com uma única oferta (ofertas < 2). |
Pessoa da cotação = quem lançou o orçamento (o comprador é vazio, ver 386). Quadros por mês e por pessoa na cotação.
Telas e arquivo: indicadores (gasto, variação de preço e impacto, fornecedores e os 10 maiores, fornecedor único, cotação com uma oferta só, economia, vencedor que não era o mais barato), variação por grupo, os 15 maiores impactos (altas e quedas), provável erro de unidade, os 20 maiores fornecedores, itens de fornecedor único. Listas com 300 linhas; o XLS traz tudo (preços item a item com "provável erro de unidade", seção fornecedores, seção cotação por pessoa). Sem PDF.
| Campo | Padrão | Efeito |
|---|---|---|
| Período de / até | 90 dias atrás até hoje | Entrada da compra e data do orçamento (cotação). O período anterior tem o mesmo número de dias, logo antes. |
| Filial (multi) | Todas do usuário | almoxarifado_compra_produto.idfilial e almoxarifado_orcamento.idfilial. |
| Grupo / Excluir grupo | Todos / nenhum | almoxarifado_grupo do produto. |
| Moeda conversão | Moeda local | Pela cotação do dia da entrada (e do orçamento). |
Os dois só leem. Sem regra de acesso nomeada; o alcance é o das filiais do usuário.
O usuário não tem filial liberada.
A filial N não está entre as filiais do usuário.
Não foram encontrados dados nessas condições.
386Nenhuma solicitação de orçamento no período e filtros.
389Nenhuma compra de fornecedor e nenhum item de orçamento no período e filtros (tela e XLS).
Nenhuma operação de compra em PAINEL_ALMOX_OPERACOES_COMPRA (Config. Globais).
QuandoA chave foi esvaziada sem valor.
N item(ns) de compra sem cotação de <moeda> no dia: ficam com valor zero.
TambémN item(ns) de orçamento em moeda estrangeira sem cotação no dia: entram sem valor na economia.
No 386 "não autorizadas" não tem tempo.
MotivoA autorização da solicitação não grava data: só entra na contagem; o trecho SO → CAN já parte da SO.
Pouca cotação real.
Motivofjfrigo_concepcion: 99,9% dos itens cotados têm uma oferta só — lá o orçamento quase não é usado para cotar com mais de um fornecedor. Em central: 67,5%.
Item comprado numa unidade diferente entre os períodos.
EfeitoBombona × litro, caixa × unidade dão variações enormes; só a faixa 5× / 1/5 é separada. Variações menores por troca de unidade entram no índice.
Mediana 0 dia em vários trechos é normal.
EfeitoSO → CAN e Autorizado → SC têm mediana 0 d porque a conta é por dia de calendário e muitas datas coincidem no mesmo dia.
| Chave | Padrão | Quem usa | Efeito |
|---|---|---|---|
PAINEL_ALMOX_OPERACOES_COMPRA | 101,131 | 389 (também o 38E) | tipo_operacao da compra de fornecedor. Vazia usa o padrão; os ids são tipos de operação (texto, ex. 101), não ids de tipo de faturamento. |
O 386 não tem chaves próprias: lê as tabelas do 24A, 24D, 246, 241 e 242 como estão. Item de menu sem idOpcao: qualquer usuário logado abre; o alcance é o das filiais do usuário. Barra de filtros salvos por usuário (códigos 386 e 389).
Banco: central (BMG). Referências de 03–04/10/2026.
| # | Opção | Passo | Esperado | Como conferir |
|---|---|---|---|---|
| 1 | 386 | 01/04/2026 a 30/06/2026, todas as filiais. | 2.013 SOs → 1.958 autorizadas → 1.835 CAN → 1.625 orçamento → 1.609 orçamento autorizado → 1.592 SC → 1.383 compra; 16 reprovadas na CAN, 55 não autorizadas, 559 abertas. ~1,5 s. | -- solicitações de orçamento (24A) do período e quantas estão autorizadas SELECT COUNT(*) AS sos, SUM(aso.autorizado = 1 OR aso.idusuario_autorizou IS NOT NULL) AS autorizadas FROM almoxarifado_solicitacao_orcamento aso WHERE aso.excluido = 'F' AND aso.data >= '2026-04-01' AND aso.data < '2026-07-01' -- central, abr–jun/2026: 2.013 e 1.958 -- SOs do período que passaram por CAN (24D) não cancelada
SELECT COUNT(DISTINCT cs.idalmoxarifado_solicitacao_orcamento) AS sos_com_can
FROM almoxarifado_can_solicitacoes cs
JOIN almoxarifado_can ac ON ac.id = cs.idalmoxarifado_can AND COALESCE(ac.status,'') <> 'CANCELADO'
JOIN almoxarifado_solicitacao_orcamento aso ON aso.id = cs.idalmoxarifado_solicitacao_orcamento AND aso.excluido = 'F'
AND aso.data >= '2026-04-01' AND aso.data < '2026-07-01'
WHERE COALESCE(cs.excluido,0) = 0
-- central, abr–jun/2026: 1.835 |
| 2 | 386 | Mesmo caso, trechos. | Medianas: SO→CAN 0 d; →orçamento 8 d (p90 30); orçamento→autorizado 1 d; autorizado→SC 0 d; SC→compra 2 d (p90 22); total 18 d (p90 47, média 23,7). O gargalo é a cotação (CAN → orçamento). | Para uma SO específica, compare as datas do XLS (linha da SO) com almoxarifado_orcamento.data, almoxarifado_solicitacao_compra.data, almoxarifado_compra.data_entrada. |
| 3 | 386 | Clicar na etapa "Orçamento" do funil. | Lista as abertas paradas nessa etapa (mais antigas primeiro) com dias desde a última etapa. | desde = a data mais recente entre SO, CAN, orçamento, autorização e SC. |
| 4 | 386 | Uma SO com compra no mesmo dia da SC. | O trecho SC → compra dá 0 (dia de calendário), não negativo; trecho com ordem trocada fica em branco. | — |
| 5 | 386 | Tabela por usuário. | Quem lançou o orçamento (login); "(sem usuário)" quando vazio; só SOs com orçamento. | SELECT u.login, COUNT(*) FROM almoxarifado_orcamento ao LEFT JOIN usuario u ON u.id = ao.idusuario_incluiu WHERE ao.excluido = 'F' GROUP BY 1 |
| 6 | 386 | Filtro de setor + filial; depois XLS. | As mesmas SOs na tela e no XLS (uma linha por SO). | — |
| 7 | 389 | 01/07/2026 a 30/09/2026, todas as filiais, moeda local. | Gasto R$ 26.324.908,86; 320 fornecedores; 1.815 itens; variação de preço ≈ −1,80% (impacto ≈ −R$ 346,8 mil sobre R$ 18,9 mi comparáveis, 614 itens); os 10 maiores = 46,9% do gasto; 258 itens de fornecedor único (R$ 3,58 mi). ~6 s. | SELECT ROUND(SUM(cp.valor_total_ml), 2) AS gasto, COUNT(DISTINCT ac.idemitente) AS fornecedores, COUNT(DISTINCT cp.idalmoxarifado_produto) AS itens
FROM almoxarifado_compra_produto cp
JOIN almoxarifado_compra ac ON ac.id = cp.idalmoxarifado_compra
JOIN tipo_faturamento tf ON tf.id = ac.idtipo_faturamento AND tf.tipo_operacao IN ('101','131') -- PAINEL_ALMOX_OPERACOES_COMPRA
JOIN almoxarifado_produto ap ON ap.id = cp.idalmoxarifado_produto AND COALESCE(ap.imobilizado,'F') <> 'T'
WHERE cp.excluido <> 'T' AND COALESCE(ac.excluido,'F') <> 'T' AND cp.quantidade > 0 AND cp.valor_total_ml > 0
AND ac.data_entrada >= '2026-07-01' AND ac.data_entrada < '2026-10-01'
-- central, 3º tri/2026 (04/10/2026): R$ 26.324.908,86 · 320 fornecedores · 1.815 itens |
| 8 | 389 | Abrir o item óleo protetivo 1010289. | Aparece em Provável erro de unidade (R$ 652 → R$ 34), fora do índice e do impacto. | -- preço médio do item no período atual e no anterior (mesmo tamanho), todos os fornecedores
SELECT (ac.data_entrada >= '2026-07-01') AS atual, SUM(cp.quantidade) AS q, SUM(cp.valor_total_ml) AS v,
SUM(cp.valor_total_ml) / SUM(cp.quantidade) AS preco
FROM almoxarifado_compra_produto cp
JOIN almoxarifado_compra ac ON ac.id = cp.idalmoxarifado_compra
JOIN tipo_faturamento tf ON tf.id = ac.idtipo_faturamento AND tf.tipo_operacao IN ('101','131')
WHERE cp.excluido <> 'T' AND COALESCE(ac.excluido,'F') <> 'T' AND cp.quantidade > 0 AND cp.valor_total_ml > 0
AND cp.idalmoxarifado_produto = <produto>
AND ac.data_entrada >= '2026-04-01' AND ac.data_entrada < '2026-10-01'
GROUP BY atual
-- variação = preço atual ÷ preço anterior − 1; acima de 5x ou abaixo de 1/5 = "provável erro de unidade" |
| 9 | 389 | Bloco de cotação, 3º tri. | ≈ 2.801 itens cotados; 67,5% com uma oferta só; economia ≈ R$ 401 mil sobre a média (11,5%); 151 itens em que o vencedor não era o mais barato (≈ R$ 74,8 mil acima). | -- ofertas de um item de orçamento (24A/246): o vencedor tem vencedor = 1; sem vencedor vale a menor oferta
SELECT ao.id AS orcamento, aop.idalmoxarifado_produto AS produto, COUNT(*) AS ofertas,
MAX(IF(aop.vencedor = 1, aop.valor_unitario, NULL)) AS preco_vencedor,
MIN(aop.valor_unitario) AS menor, AVG(aop.valor_unitario) AS media, MAX(aop.valor_unitario) AS maior
FROM almoxarifado_orcamento_produtos aop
JOIN almoxarifado_orcamento ao ON ao.id = aop.idalmoxarifado_orcamento AND ao.excluido = 'F'
WHERE COALESCE(aop.excluido,'F') <> 'T' AND aop.valor_unitario > 0
AND ao.data >= '2026-07-01' AND ao.data < '2026-10-01'
GROUP BY ao.id, aop.idalmoxarifado_produto
-- economia sobre a média = (média − vencedor) × quantidade, só com 2+ ofertas |
| 10 | 389 | Clicar num fornecedor. | Lista os itens comprados dele com preço atual e o anterior de todos os fornecedores. | Itens de almoxarifado_compra_produto com ac.idemitente = <fornecedor>. |
| 11 | 389 | fjfrigo_concepcion, jun–ago/2025, moeda U$. | Gasto ≈ U$ 6,75 mi; 99,9% dos itens cotados com uma oferta só. | — |
| 12 | 389 | Moeda de conversão sem cotação nos dias. | Aviso N item(ns) de compra sem cotação de <moeda> no dia: ficam com valor zero. | SELECT data FROM moeda_valores WHERE idmoeda = <moeda> AND data = '<dia>' |
| 13 | 386·389 | Usuário com uma filial; filial de fora via API. | Só as dele; A filial N não está entre as filiais do usuário. | — |
Pendências: teste de tela dos dois (o backend precisa reiniciar). O 389 nasceu como 387 e foi renumerado (outras sessões tomaram o 387 e o 388 no mesmo dia).
Decisão de desenho: o funil não usa o aviso de recebimento (24F) nem o comprador (vazio em todo o central).
1. 386 — SO não autorizada com CAN/compra. Uma SO sem autorização que mesmo assim chegou a orçamento/compra entra no funil (cada etapa vale pela data) e também em "não autorizadas" (que conta !autorizada); as contagens de etapas e de "não autorizadas" se sobrepõem.
2. 386 — aso.excluido = 'F' estrito. O filtro da SO e do orçamento é igualdade com 'F' (não IFNULL): linha com excluido nulo sai do funil. Nas tabelas do legado a coluna é NOT NULL, mas vale conferir em tenant novo.
3. 389 — a economia da cotação usa só valor_unitario × quantidade. Qualquer outro componente da oferta (frete, prazo) não entra na comparação.
4. 389 — MAX(quantidade) na cotação. Quando o item tem ofertas com quantidades diferentes e nenhum vencedor, a quantidade usada na economia é a maior oferta, não a pedida.
5. 389 — fornecedor 0. Compra sem emitente (idemitente nulo) agrupa como fornecedor 0 e entra no ranking com o id como nome.
Toda resposta sai com HTTP 200; quem diz o que aconteceu é o statuscode no corpo — 400 para as recusas deste documento.
O arquivo é pedido como download, mas a recusa chega como mensagem: a tela mostra a frase no lugar do arquivo. Enquanto gera, o botão mostra o contador Gerando… (Ns).
Avisos (cotação faltando, foto sem produção, estorno sem nota...) não interrompem: vêm no cabeçalho X-Aviso-Sistema e a tela mostra o painel de avisos. Teste sempre olhando o painel, não só o arquivo.
Ao abrir chamado, copie o código de ocorrência de 8 caracteres dos erros inesperados. Erro de tela vai para o log em POST /cadastro/erros-front.
Nenhuma regra bate com essa busca. Tente um trecho menor da mensagem, ou limpe os filtros.