Pular para o conteúdo principal

Parâmetro de Bloqueio de Estoque Negativo

Tela de configuração: MFA001 - Parâmetros de Faturamento Localização: Parâmetros → Ambos → Opção 1 Tabela: PARMFATUR.ST_ESTOQUENEGATIVO Valor padrão: N (Não) — definido em UdmMFA001.pas:485

Este parâmetro bloqueia a operação quando o item ficaria com estoque negativo. Diferente de ST_ALERTAESTOQUENEGATIVO, que apenas avisa o usuário, o ST_ESTOQUENEGATIVO = 'S' impede a gravação do item (lança exceção JException).

Telas impactadas​

MóduloCódigoUso
Pedido de VendaMPD002Bloqueia inclusão de item via VERIFICA_ESTOQUENEGATIVOPEDIDO (UMPD002.pas:6664); força parâmetro S em RETORNA_QTDEESTOQUEGRADE (UdmMPD002.pas:1143); valida ao salvar (UdmMPD002.pas:4268, UdmMPD002.pas:5938, 5972); checa ITEMLOCAL.ST_ESTOQUE antes de validar (UMPD002.pas:2185)
Pedido Mobile/SimplificadoMPD020Lê parâmetro em iST_ESTOQUENEGATIVO (UdmMPD020.pas:366); força Parametros[8] := 'S' na grade (UdmMPD020.pas:657); distingue bloqueio vs alerta (UdmMPD020.pas:955)
OrçamentoMPD018Lê em iST_ESTOQUENEGATIVO (UdmMPD018.pas:309); valida saldo em máquinas quando 'S' (UMPD018.pas:1217)
Pedido de CompraMPD092Lê o parâmetro no SELECT da PARMFATUR
Pedido (Apoio)MPD005Propaga para verificação de estoque
NF Saída (Outra) / ConfirmaçãoMNF017Lê em iST_ESTOQUENEGATIVO (UMNF017.pas:198); força ParamGrade[8] := 'S' ao aplicar saldo na grade (UdmMNF017.pas:1225)
Nota Fiscal SaídaMNF002Carrega o campo no SELECT do PARMFATUR
NF Saída (Compra)MNF007Carrega o campo no SELECT do PARMFATUR
NF Entrada (Avulsa)MNF008Carrega o campo no SELECT do PARMFATUR
NF Devolução CompraMNF026Carrega o campo no SELECT do PARMFATUR
Ordem de ServiçoMOF001Lê em iST_ESTOQUENEGATIVO (UdmMOF001.pas:753); valida saldo de peças utilizadas quando 'S' (UdmMOF001.pas:3055)
Ordem de Serviço (Outra)MOF002Carrega o parâmetro do PARMFATUR
Contas a ReceberMCO006Apenas no SELECT do PARMFATUR (sem uso direto encontrado)
Consulta PedidosCPD009Inclui o campo no UPDATE/SELECT do PARMFATUR
Cadastro AuxiliarRCA006Inclui o campo no UPDATE/SELECT do PARMFATUR
jGradeProduto (shared)jGrade.pasRecebe Parametros[8] = 'S' (flag "Valida apenas itens da grade com saldo") repassada pelas telas de venda

Procedures impactadas​

ProcedureArquivoUso
VERIFICA_ESTOQUENEGATIVOPEDIDOScripts/VERIFICA_ESTOQUENEGATIVOPEDIDO.sqlLê ST_ESTOQUENEGATIVO (linha 18, 29–32). Quando 'S', retorna O_ST_ALERTABLOQUEIA = 'B' (bloqueio) em vez de 'A' (alerta). Entra no IF principal quando ST_ALERTAESTOQUENEGATIVO <> 'N' OU ST_ESTOQUENEGATIVO <> 'N' (linhas 44–45).
VERIFICA_ESTOQUENEGATIVONOTAScripts/VERIFICA_ESTOQUENEGATIVONOTA.sqlMesmo padrão: decide entre 'B' (bloqueia) e 'A' (alerta) conforme ST_ESTOQUENEGATIVO.
VERIFICA_ESTOQUENEGATIVOOSScripts/VERIFICA_ESTOQUENEGATIVOOS.sqlCarrega ST_ESTOQUENEGATIVO em I_BLOQUEIA (linhas 27–32) e usa para definir O_ST_ALERTABLOQUEIA.
RETORNA_QTDEESTOQUEGRADEScripts/RETORNA_QTDEESTOQUEGRADE.sqlLê ST_ESTOQUENEGATIVO em V_ST_ESTOQUENEGATIVO (linha 31). Quando ST_ALERTAESTOQUENEGATIVO = 'N' mas ST_ESTOQUENEGATIVO = 'S', ainda filtra somente grades com saldo (linhas 43–47).

Campos envolvidos​

CampoDescrição
PARMFATUR.ST_ESTOQUENEGATIVOFlag (S/N) que bloqueia operações com estoque negativo
PARMFATUR.ST_ALERTAESTOQUENEGATIVOFlag complementar (F/S/N) que apenas alerta (ver doc)
ITEMPEDIDO.CD_OPERACAOOperação de movimentação do item. Parâmetro só age quando preenchido
ITEMLOCAL.ST_ESTOQUEEm MPD002, consulta se o item controla estoque no local antes de validar (UMPD002.pas:2188)
MOVIMENTACAO.ST_ESTOQUENEGATIVO, MOVIMENTACAO.TP_ESTOQUEDefinem se a operação efetivamente baixa estoque (flag flagEstoqueNegativo interna)
Retorno O_ST_ALERTABLOQUEIAB = Bloqueia / A = Alerta / N = OK — definido em VERIFICA_ESTOQUENEGATIVOPEDIDO.sql:173–179

Opções disponíveis​

ComboBox cmbST_ESTOQUENEGATIVO (UMFA001.dfm:3270–3296) com apenas duas opções: Items.Strings = ('Sim'#9'S', 'Não'#9'N')

S - Sim (Bloqueia)​

O que fazDetalhe
Permite salvar com estoque negativo?Não — lança JException.Create('W-0000', ...) e aborta a gravação
Onde bloqueia no DelphiMPD002 UMPD002.pas:6664–6698 executa VERIFICA_ESTOQUENEGATIVOPEDIDO; se retornar 'B' levanta exceção
Onde bloqueia no SQLVERIFICA_ESTOQUENEGATIVOPEDIDO.sql:173–175, VERIFICA_ESTOQUENEGATIVONOTA.sql, VERIFICA_ESTOQUENEGATIVOOS.sql definem O_ST_ALERTABLOQUEIA = 'B'
Grades de produtoEm RETORNA_QTDEESTOQUEGRADE, quando 'S', oculta grades sem saldo da pesquisa (linhas 45–47). Em MPD002/MPD020/MNF017, força Parametros[8] := 'S' para jGrade.pas (seleciona só grades com saldo)
Checagem de ITEMLOCAL.ST_ESTOQUEMPD002 UMPD002.pas:2185–2193 consulta ITEMLOCAL.ST_ESTOQUE antes — itens que não controlam estoque no local são ignorados
Base de cálculoDepende de ST_ALERTAESTOQUENEGATIVO: 'S' → saldo comprometido; 'F' → saldo físico; 'N' → usa saldo comprometido como padrão no SQL
Ordem de ServiçoMOF001 UdmMOF001.pas:3055 valida saldo de peças e serviços quando 'S'
OrçamentoMPD018 UMPD018.pas:1217–1220 percorre tabMAQUINA para validar quando 'S'
Mensagem"O Item XXX não possui saldo suficiente para operação! Quantidade necessária: ... Quantidade em Estoque: ..." (texto gerado pelas procedures VERIFICA_ESTOQUENEGATIVO*)

Simulação passo a passo​

  1. Acesse MFA001 → aba Ambos → subaba Opção 1
  2. Altere ST_ESTOQUENEGATIVO para "Sim" e salve (F6)
  3. Tenha um produto com saldo físico de 10 unidades (sem reservas)
  4. Abra um Pedido de Venda (MPD002)
  5. Adicione o produto com quantidade 15 → sistema dispara JException com a mensagem "O Item XXX não possui saldo suficiente..." e cancela a inclusão do item
  6. Adicione o produto com quantidade 8 → salvo normalmente
  7. Abra a pesquisa de grade de um produto com grades sem saldo → as grades zeradas não aparecem (foram filtradas por Parametros[8] = 'S')
  8. Tente incluir um item cuja operação (CD_OPERACAO) não baixa estoque → não bloqueia (regra depende de flagEstoqueNegativo)
  9. Em MOF001, crie uma OS e adicione uma peça em quantidade maior que o saldo → bloqueia a gravação

Resultado esperado: O sistema impede qualquer inclusão/gravação que deixe o estoque negativo. Também filtra grades sem saldo nas telas de pesquisa. A regra só age quando o item possui CD_OPERACAO preenchida e a operação baixa estoque.


N - Não (Permite)​

O que fazDetalhe
Permite salvar com estoque negativo?Sim
Onde age no DelphiOs blocos if parmfatur.values['ST_ESTOQUENEGATIVO'] = 'S' (p.ex. UMPD002.pas:6664) são pulados. O item é gravado livremente
Onde age no SQLVERIFICA_ESTOQUENEGATIVO* só entra no IF principal se ST_ESTOQUENEGATIVO <> 'N' OU ST_ALERTAESTOQUENEGATIVO <> 'N' (linhas 44–45 de VERIFICA_ESTOQUENEGATIVOPEDIDO.sql). Se ambos forem 'N', procedure não valida nada
GradeParâmetro [8] enviado a jGrade.RateioGrade fica vazio → grades sem saldo aparecem na pesquisa
Valor padrãoN — definido em UdmMFA001.pas:485 no AfterInsert da tabPARMFATUR

Simulação passo a passo​

  1. Acesse MFA001 → aba Ambos → Opção 1
  2. Altere ST_ESTOQUENEGATIVO para "Não" (valor padrão) e salve (F6)
  3. Tenha um produto com saldo físico de 10 unidades
  4. Abra um Pedido de Venda (MPD002)
  5. Adicione o produto com quantidade 50 → item é gravado normalmente, sem bloqueio
  6. Se ST_ALERTAESTOQUENEGATIVO estiver como 'S' ou 'F', o usuário recebe um aviso (I-0000) mas pode prosseguir
  7. Se ambos os parâmetros estiverem 'N', nenhum alerta/bloqueio acontece — operação é silenciosa

Resultado esperado: O usuário pode operar livremente com estoque insuficiente. O controle passa a ser apenas informativo (via ST_ALERTAESTOQUENEGATIVO) ou inexistente.


Interação com ST_ALERTAESTOQUENEGATIVO​

Os dois parâmetros são complementares e agem em níveis diferentes:

ST_ESTOQUENEGATIVOST_ALERTAESTOQUENEGATIVOComportamento
NNNenhuma validação. Sistema ignora estoque negativo completamente
NF ou SSó alerta. Usuário recebe aviso (I-0000) mas pode continuar. Base de cálculo: físico (F) ou comprometido (S)
SNBloqueia, sem alerta prévio. Ao salvar o item, VERIFICA_ESTOQUENEGATIVOPEDIDO retorna 'B' e o sistema lança W-0000. Em MPD002, o trecho de alerta em UMPD002.pas:6630–6631 é pulado (condição inclui ST_ESTOQUENEGATIVO = 'N')
SF ou SAlerta + bloqueio. Alerta dispara antes (grid/inclusão) e o bloqueio valida novamente ao gravar. O código evita duplicar alerta quando vai bloquear (ver UMPD002.pas:6631: alerta só se ST_ESTOQUENEGATIVO = 'N')

Pontos-chave do código​

MPD002 UMPD002.pas:6630–6632 — alerta só se não vai bloquear:

if ( ((parmfatur.values['ST_ALERTAESTOQUENEGATIVO'] = 'S') or (parmfatur.values['ST_ALERTAESTOQUENEGATIVO'] = 'F'))
and (parmfatur.values['ST_ESTOQUENEGATIVO'] = 'N') and (flagEstoqueNegativo)
and ( Trim(dmMPD002.tabITEMPEDIDOCD_OPERACAO.AsString)<> '') ) then

MPD002 UMPD002.pas:6664–6665 — bloqueio:

{ Bloqueio Estoque Negativo }
if ( (parmfatur.values['ST_ESTOQUENEGATIVO'] = 'S') and
(flagEstoqueNegativo) and ( Trim(dmMPD002.tabITEMPEDIDOCD_OPERACAO.AsString)<> '') ) then

VERIFICA_ESTOQUENEGATIVOPEDIDO.sql:171–180 — decide bloqueio vs alerta:

IF ( O_DS_MENSSAGEM IS NOT NULL ) THEN
BEGIN
IF (V_ST_ESTOQUENEGATIVO = 'S') THEN
BEGIN
O_ST_ALERTABLOQUEIA = 'B';
END ELSE
BEGIN
O_ST_ALERTABLOQUEIA = 'A';
END
END

Observação Importante: Dependência de CD_OPERACAO e flagEstoqueNegativo​

O bloqueio nunca dispara quando:

  1. tabITEMPEDIDOCD_OPERACAO está vazio (item sem operação de movimentação).
  2. flagEstoqueNegativo (flag interna) está desligada — indica que a operação não baixa estoque (MOVIMENTACAO.ST_ESTOQUENEGATIVO/TP_ESTOQUE).
  3. Em MPD002, TP_PEDIDO = 'O' (orçamento): o bloco de bloqueio ignora (UMPD002.pas:6668).

Itens que não controlam estoque (ITEM.ST_ESTOQUE <> 'S') ou que estão em local sem controle (ITEMLOCAL.ST_ESTOQUE) também são ignorados (verificado em UMPD002.pas:2185–2196).


Observação Importante: Filtro de Grades​

Em telas com grade (MPD002 UdmMPD002.pas:1143, MPD020 UdmMPD020.pas:657, MNF017 UdmMNF017.pas:1225), quando ST_ESTOQUENEGATIVO = 'S' o Parametros[8]/ParamGrade[8] passado a jGrade.pas é forçado para 'S' ("Valida apenas Itens da Grade com Saldo"). Isso esconde grades zeradas da tela de rateio, evitando que o usuário selecione uma combinação sem saldo.

A procedure RETORNA_QTDEESTOQUEGRADE.sql:43–47 reforça esse comportamento: quando ST_ALERTAESTOQUENEGATIVO = 'N' mas ST_ESTOQUENEGATIVO = 'S', o cursor dá SUSPEND somente para grades com saldo.


Tabela Comparativa Resumida​

OpçãoDescriçãoPermite salvar com estoque negativo?Filtra grades sem saldo?Procedure retornaValor padrão?
SSim (Bloqueia)Não (levanta JException)SimO_ST_ALERTABLOQUEIA = 'B'—
NNão (Permite)SimNãoO_ST_ALERTABLOQUEIA = 'A' (se alerta ativo) ou não validaSim

Referências no Código Fonte​

Tela MFA001 (onde o parâmetro é configurado)​

  • source/MFA001/UMFA001.dfm:3270–3296 — ComboBox cmbST_ESTOQUENEGATIVO (Items: Sim=S, Não=N)
  • source/MFA001/UMFA001.pas:245 — Declaração do componente
  • source/MFA001/UdmMFA001.pas:137 — Campo tabPARMFATURST_ESTOQUENEGATIVO: TStringField
  • source/MFA001/UdmMFA001.pas:485 — Valor padrão 'N' atribuído no AfterInsert
  • source/MFA001/UdmMFA001.dfm:142, 1142–1147, 2378, 2537, 2751, 3022 — SELECT/INSERT/UPDATE do PARMFATUR

Telas consumidoras (Delphi)​

  • source/MPD002/UMPD002.pas:2185, 6630–6631, 6664–6665
  • source/MPD002/UdmMPD002.pas:1143, 4268, 5745, 5938, 5972
  • source/MPD018/UdmMPD018.pas:246, 288, 309 e UMPD018.pas:1217
  • source/MPD020/UdmMPD020.pas:240, 324, 366, 657, 955
  • source/MNF017/UMNF017.pas:164, 198 e UdmMNF017.pas:285, 1225
  • source/MNF002/UdmMNF002.pas, source/MNF007/UdmMNF007.pas, source/MNF008/UdmMNF008.pas, source/MNF026/UdmMNF026.pas — SELECT do PARMFATUR
  • source/MOF001/UdmMOF001.pas:446, 727, 753, 3055
  • source/MOF002/UdmMOF002.pas — SELECT do PARMFATUR
  • source/MPD005/UMPD005.pas, source/MPD092/UdmMPD092.pas — SELECT do PARMFATUR
  • source/MCO006/UdmMCO006.pas — SELECT do PARMFATUR
  • source/CPD009/UdmCPD009.dfm, source/RCA006/UdmRCA006.dfm — UPDATE/SELECT do PARMFATUR
  • source/jGradeProduto/jGrade.pas — parâmetro [8] "Valida apenas grades com saldo"

Procedures SQL​

  • Scripts/VERIFICA_ESTOQUENEGATIVOPEDIDO.sql:18, 29, 32, 45, 58, 150, 173, 194, 302 — núcleo do bloqueio em pedidos
  • Scripts/VERIFICA_ESTOQUENEGATIVONOTA.sql — mesmo padrão em notas fiscais
  • Scripts/VERIFICA_ESTOQUENEGATIVOOS.sql:29, 32 — validação em OS
  • Scripts/RETORNA_QTDEESTOQUEGRADE.sql:25, 28, 31, 45 — filtro de grades sem saldo

Backend Java​

  • source/Server/JunsoftWebAPI/src/main/java/junsoft/erp/repository/JunsoftBuilder.java
  • source/Server/JunsoftWebAPI/src/main/java/junsoft/erp/repository/queries/ParmFaturSQL.java
  • source/Server/JunsoftWebAPI/src/main/java/junsoft/erp/service/PedidoService.java