Rotina: Estoque e Movimentação
Saldo de estoque por item/local, movimentações, inventário, transferência entre filiais e custo médio.
Módulos Delphi
| Arquivo | Papel |
|---|---|
source/CEQ001/UCEQ001.pas | Consulta de estoque, saldo, lotes, grades, série |
source/CEQ001/UdmCEQ001.pas | DataModule (31 KB) — queries principais |
source/MEQ001/UMEQ001.pas | Configuração de parâmetros de estoque |
source/MEQ001/UdmMEQ001.pas | DataModule de parâmetros |
source/JunsoftEstoque/UfrmPrincipal.pas | App standalone de movimentação |
Tabelas do Banco de Dados
ESTOQUE — Saldo Consolidado
DDL: docs/schema/tables/ESTOQUE.sql
Chave primária: (CD_EMPRESA, CD_ITEM, CD_TIPOLOCAL, CD_LOCAL)
Esta é a tabela de saldo consolidado. O histórico detalhado está em MOVESTOQUE.
| Campo | Tipo | Descrição |
|---|---|---|
| CD_ITEM | INTEGER | Produto (FK → ITEM) |
| CD_TIPOLOCAL | INTEGER | Tipo de local (FK → TIPOLOCAL) |
| CD_LOCAL | INTEGER | Local físico (FK → LOCALESTOQUE) |
| QT_ESTOQUE | NUMERIC(15,5) | Saldo atual (5 casas decimais para granel/peso) |
| VL_ESTOQUE | NUMERIC(15,2) | Valor total em estoque |
| VL_PRECOMEDIO | NUMERIC(15,4) | Preço médio ponderado |
| VL_CUSTO | NUMERIC(15,4) | Custo unitário atual |
| VL_ULTIMOCUSTO | NUMERIC(15,4) | Último custo de entrada |
| QT_ALTERNATIVA | NUMERIC(15,3) | Quantidade em unidade alternativa |
| DT_MOVIMENTO | DATE | Data do último movimento |
| DT_REGISTRO | TIMESTAMP | Data de criação do registro |
MOVESTOQUE — Movimentação Detalhada (Trilha de Auditoria)
DDL: docs/schema/tables/MOVESTOQUE.sql
Chave primária: (NR_LANCAMENTO, CD_EMPRESA)
| Campo | Tipo | Descrição |
|---|---|---|
| NR_LANCAMENTO | INTEGER | Sequencial do movimento (PK) |
| CD_ITEM | INTEGER | Produto |
| CD_TIPOLOCAL, CD_LOCAL | INTEGER | Local de estoque |
| CD_OPERACAO | INTEGER | Tipo de operação (FK → OPERACAO) |
| CD_HISTORICO | INTEGER | Centro de custo / conta analítica |
| TP_DOCUMENTO | VARCHAR(2) | 'NF'=Nota Fiscal, 'OP'=Ordem Produção, 'OS'=OS, 'RQ'=Requisição, 'TR'=Transferência |
| NR_DOCUMENTO | INTEGER | Número do documento de origem |
| NR_LANCTONOTA | INTEGER | Lançamento da NF relacionada |
| CD_SERIE | VARCHAR(4) | Série da NF |
| TP_NOTA | CHAR(1) | Tipo da NF (E/S/D) |
| DT_LANCAMENTO | DATE | Data do movimento |
| QT_ESTOQUE | NUMERIC(15,5) | Quantidade movimentada (+entrada / -saída) |
| VL_ESTOQUE | NUMERIC(15,2) | Valor movimentado |
| VL_CUSTO | NUMERIC(15,4) | Custo unitário no momento |
| PS_ESTOQUE | NUMERIC(15,5) | Saldo antes do movimento (para rastreio) |
| ST_CANCELAMENTO | CHAR(1) | 'N'=Normal, 'C'=Cancelado |
| ST_BLOQUEADO | CHAR(1) | 'S'/'N' |
| NR_PLACA | VARCHAR(7) | Placa do veículo (para controle de frotas) |
| NR_LOTE | INTEGER | Lote do produto |
| NR_ORDEMPRODUCAO | INTEGER | Ordem de produção relacionada |
| CD_EMPRORIGEM | INTEGER | Empresa de origem (transferências) |
| CD_USUARIO | VARCHAR(5) | Usuário que registrou |
| DS_OBSERVACAO | VARCHAR(240) | Observações |
LOCALESTOQUE — Locais Físicos
DDL: docs/schema/tables/LOCALESTOQUE.sql
Chave primária: (CD_LOCAL, CD_TIPOLOCAL)
| Campo | Tipo | Descrição |
|---|---|---|
| DS_LOCAL | VARCHAR(60) | Descrição do local |
| TP_LOCAL | CHAR(1) | 'E'=Estoque, 'C'=Consignação, 'T'=Trânsito |
| ST_INVENTARIO | CHAR(1) | 'S' = participa do inventário |
| CD_PESSOA | INTEGER | Pessoa associada (para consignação) |
INVENTARIO — Contagem Física
DDL: docs/schema/tables/INVENTARIO.sql
Chave primária: (CD_EMPRESA, DT_INVENTARIO, CD_ITEM)
| Campo | Tipo | Descrição |
|---|---|---|
| DT_INVENTARIO | DATE | Data da contagem |
| QT_TOTAL | NUMERIC(15,5) | Quantidade física contada |
| VL_CUSTO | NUMERIC(15,4) | Custo unitário na data |
| VL_TOTAL | NUMERIC(15,2) | Valor total contado |
| TP_INVENTARIO | CHAR(1) | 'E'=Estoque próprio, 'C'=Consignação |
| PC_ICMS | NUMERIC(5,2) | ICMS do produto para valoração fiscal |
| PC_IPI | NUMERIC(5,2) | IPI para valoração |
ROMANEIO — Expedição
DDL: docs/schema/tables/ROMANEIO.sql
Chave primária: (CD_EMPRESA, NR_ROMANEIO)
| Campo | Tipo | Descrição |
|---|---|---|
| CD_PESSOA | INTEGER | Cliente ou transportador |
| DT_ROMANEIO | DATE | Data de expedição |
| ST_ROMANEIO | CHAR(1) | 'V'=Venda, 'D'=Devolução |
| VL_PRODUTOS | NUMERIC(15,2) | Valor dos produtos expedidos |
| VL_SERVICOS | NUMERIC(15,2) | Valor de serviços |
| CD_MUNICIPIO | INTEGER | Município de destino |
| DT_EXECUCAO | DATE | Data de execução |
| DT_PREVISTA | DATE | Data prevista de entrega |
ROMANEIOITEM: itens expedidos — (CD_EMPRESA, NR_ROMANEIO, NR_SEQUENCIAL)
Parâmetros (PARMESTOQUE)
DDL: docs/schema/tables/PARMESTOQUE.sql — um registro por empresa.
| Parâmetro | Tipo | Efeito quando ativo |
|---|---|---|
ST_CUSTONEGATIVO | S/N | 'S' = permite saldo negativo; 'N' = bloqueia ou alerta |
TP_VALIDACAOESTNEG | — | 'A'=Aborta a operação, 'B'=Bloqueia com mensagem |
ST_COMPROMETIDO | S/N | 'S' = controla estoque comprometido (separação por pedido) |
ST_COMPROMETIDOCOMPRA | S/N | 'S' = compromete estoque em pedidos de compra |
TP_CUSTOESTOQUE | — | 'M'=Preço médio, 'F'=FIFO, 'L'=Último custo |
ST_TRANSFEMPRESAS | S/N | 'S' = permite transferência entre filiais |
ST_PRODUCAO | S/N | 'S' = habilita módulo de produção |
ST_PRODUCAOLOTE | S/N | 'S' = controla lotes na produção |
ST_AJUSTACUSTONEGATIVO | S/N | 'S' = ajusta custo automaticamente quando negativo |
Operações padrão configuradas em PARMESTOQUE:
| Campo | Operação |
|---|---|
CD_OPERPRODSAI | Saída por produção |
CD_OPERPRODENT | Entrada por produção |
CD_OPERREQUISICAO | Requisição (saída) |
CD_OPERRECEBTO | Recebimento (entrada) |
CD_TRANSFENT | Transferência — entrada |
CD_TRANSFSAI | Transferência — saída |
CD_OPERACERTOENT | Acerto de inventário — entrada |
CD_OPERACERTOSAI | Acerto de inventário — saída |
Eventos que Geram Movimentação de Estoque
| Evento | TP_DOCUMENTO | Sentido | Acionador |
|---|---|---|---|
| NF de saída (venda) | 'NF' | Saída (−) | GERA_NOTAPEDIDO + CANCELA_NOTAFISCAL |
| NF de entrada (compra) | 'NF' | Entrada (+) | Recebimento de NF + conferência |
| Devolução de venda | 'NF' | Entrada (+) | NF de devolução (TP_NOTA='D') |
| Devolução de compra | 'NF' | Saída (−) | NF de devolução a fornecedor |
| Requisição (OS/Produção) | 'RQ' | Saída (−) | ORDEMSERVITEM + RequisicaoOficinaController |
| Devolução de requisição | 'RQ' | Entrada (+) | Cancelamento de requisição |
| Transferência entre locais | 'TR' | Saída + Entrada | MEQ / jLocalEstoque |
| Ajuste de inventário | 'IV' | +/− | Acerto pós-contagem |
| Produção (entrada) | 'OP' | Entrada (+) | Ordem de Produção |
| Produção (consumo) | 'OP' | Saída (−) | Consumo de matéria-prima |
Cálculo de Custo Médio
Quando PARMESTOQUE.TP_CUSTOESTOQUE = 'M':
Nova entrada: QT_NOVA a VL_CUSTO_NOVO
Novo preço médio =
(ESTOQUE.QT_ESTOQUE × ESTOQUE.VL_PRECOMEDIO + QT_NOVA × VL_CUSTO_NOVO)
/ (ESTOQUE.QT_ESTOQUE + QT_NOVA)
Update ESTOQUE:
QT_ESTOQUE += QT_NOVA
VL_ESTOQUE += QT_NOVA × VL_CUSTO_NOVO
VL_PRECOMEDIO := novo preço médio
VL_ULTIMOCUSTO := VL_CUSTO_NOVO
Custo negativo: se QT_ESTOQUE < 0 e ST_AJUSTACUSTONEGATIVO = 'S', o sistema ajusta o preço médio na próxima entrada.
Fluxo de Inventário
┌────────────────────────────────────────────────────────┐
│ 1. ABERTURA DO INVENTÁRIO │
│ DT_INVENTARIO := data de referência │
│ Bloquear movimentações dos itens (ST_BLOQUEADO='S') │
└───────────────────────────┬────────────────────────────┘
│
▼
┌────────────────────────────────────────────────────────┐
│ 2. CONTAGEM FÍSICA │
│ Usuário/Coletor escaneia ou digita cada item │
│ INSERT INVENTARIO { DT, CD_ITEM, QT_TOTAL, VL_CUSTO } │
│ Locais participantes: LOCALESTOQUE.ST_INVENTARIO='S' │
└───────────────────────────┬────────────────────────────┘
│
▼
┌────────────────────────────────────────────────────────┐
│ 3. APURAÇÃO DE DIFERENÇAS │
│ ESTOQUE.QT_ESTOQUE vs INVENTARIO.QT_TOTAL │
│ Diferença = QT_TOTAL − QT_ESTOQUE │
│ Relatório: itens com diferença + valor de ajuste │
└───────────────────────────┬────────────────────────────┘
│
▼
┌────────────────────────────────────────────────────────┐
│ 4. ACERTO AUTOMÁTICO/MANUAL │
│ Se diferença > 0 (entrada): │
│ INSERT MOVESTOQUE (CD_OPERACAO = CD_OPERACERTOENT) │
│ Se diferença < 0 (saída): │
│ INSERT MOVESTOQUE (CD_OPERACAO = CD_OPERACERTOSAI) │
│ UPDATE ESTOQUE.QT_ESTOQUE e VL_PRECOMEDIO │
└───────────────────────────┬────────────────────────────┘
│
▼
┌────────────────────────────────────────────────────────┐
│ 5. ENCERRAMENTO │
│ Desbloquear movimentações (ST_BLOQUEADO='N') │
│ DT_MOVIMENTO := DT_INVENTARIO │
└────────────────────────────────────────────────────────┘
Transferência Entre Filiais
Habilitado por: PARMESTOQUE.ST_TRANSFEMPRESAS = 'S'
Empresa A (origem)
→ INSERT MOVESTOQUE (CD_OPERACAO=CD_TRANSFSAI, CD_EMPRORIGEM=A)
→ ESTOQUE.QT_ESTOQUE -= QT
Empresa B (destino)
→ INSERT MOVESTOQUE (CD_OPERACAO=CD_TRANSFENT, CD_EMPRORIGEM=A)
→ ESTOQUE.QT_ESTOQUE += QT
→ VL_PRECOMEDIO recalculado
Queries de Referência
-- Saldo atual por produto e local
SELECT E.CD_ITEM, I.DS_ITEM,
L.DS_LOCAL, E.QT_ESTOQUE, E.VL_PRECOMEDIO
FROM ESTOQUE E
INNER JOIN ITEM I ON I.CD_ITEM = E.CD_ITEM
INNER JOIN LOCALESTOQUE L ON L.CD_LOCAL = E.CD_LOCAL
WHERE E.CD_EMPRESA = :empresa
AND E.QT_ESTOQUE > 0
-- Histórico de movimentações de um produto
SELECT M.DT_LANCAMENTO, O.DS_OPERACAO,
M.QT_ESTOQUE, M.VL_CUSTO,
M.PS_ESTOQUE AS QT_ANTES,
M.PS_ESTOQUE + M.QT_ESTOQUE AS QT_DEPOIS,
M.TP_DOCUMENTO, M.NR_DOCUMENTO
FROM MOVESTOQUE M
INNER JOIN OPERACAO O ON O.CD_OPERACAO = M.CD_OPERACAO
WHERE M.CD_EMPRESA = :empresa
AND M.CD_ITEM = :item
AND M.ST_CANCELAMENTO = 'N'
ORDER BY M.DT_LANCAMENTO DESC, M.NR_LANCAMENTO DESC
Influências em Outros Módulos
→ Pedido de Venda
- Pedido aprovado compromete estoque (
ST_COMPROMETIDO='S') - NF de saída gera saída definitiva em MOVESTOQUE
→ Emissão NF-e
CANCELA_NOTAFISCALreverte MOVESTOQUE quando nota é cancelada
→ Recebimento de Mercadoria
- NF de entrada confirmada gera entrada em MOVESTOQUE e atualiza ESTOQUE
→ Ordem de Serviço
- Requisição de peças da OS gera saída em MOVESTOQUE
- Cancelamento de OS reverte a saída
→ Fiscal e SPED
- MOVESTOQUE alimenta registros de estoque do SPED (bloco H — inventário)