SET TERM ^ ; CREATE OR ALTER PROCEDURE SP_MOVIMENTA_ESTOQUE ( P_CODGRUPO VARCHAR(16), P_CODPRODUTO VARCHAR(30), P_QUANTIDADE FLOAT, P_TIPO CHAR(1), -- E=Entrada, S=Saída P_NUMEROVENDA INTEGER DEFAULT NULL, P_VALORUNITITEM FLOAT DEFAULT NULL, P_VALORTOTALITEM FLOAT DEFAULT NULL, P_OBSERVACAO VARCHAR(54) DEFAULT NULL ) RETURNS ( MSGRETORNO VARCHAR(255) ) AS DECLARE VARIABLE V_BAIXAR CHAR(1); DECLARE VARIABLE V_QTDEATUAL FLOAT; DECLARE VARIABLE V_PERMESTNEGATIVO CHAR(1); DECLARE VARIABLE V_CODMOVIMENTO INTEGER; DECLARE VARIABLE V_QTDEBAIXAR FLOAT; DECLARE VARIABLE V_CODGRUPOEXTRA VARCHAR(16); DECLARE VARIABLE V_CODPRODUTOEXTRA VARCHAR(30); BEGIN MSGRETORNO = NULL; -- Verifica se o produto baixa estoque SELECT BAIXAR FROM CADPRODUTOSCOMP WHERE CODGRUPO = :P_CODGRUPO AND CODPRODUTO = :P_CODPRODUTO INTO :V_BAIXAR; IF (V_BAIXAR IS NULL) THEN BEGIN MSGRETORNO = 'Produto não encontrado'; SUSPEND; EXIT; END IF (V_BAIXAR <> 'S') THEN BEGIN MSGRETORNO = 'Produto não controla estoque'; SUSPEND; EXIT; END -- Verifica permissão para estoque negativo SELECT FIRST 1 PERMESTNEGATIVO FROM CUSTOMIZACAO INTO :V_PERMESTNEGATIVO; -- Obtém o saldo atual SELECT QTDEATUAL FROM CADPRODUTOS WHERE CODGRUPO = :P_CODGRUPO AND CODPRODUTO = :P_CODPRODUTO INTO :V_QTDEATUAL; -- Validação de estoque insuficiente (somente na SAÍDA) IF ((:P_TIPO = 'S') AND (V_PERMESTNEGATIVO <> 'S') AND (V_QTDEATUAL < :P_QUANTIDADE)) THEN BEGIN MSGRETORNO = 'Estoque insuficiente. Qtde Atual: ' || CAST(V_QTDEATUAL AS VARCHAR(20)) || ' | Qtde Solicitada: ' || CAST(:P_QUANTIDADE AS VARCHAR(20)); SUSPEND; EXIT; END -- Atualização de estoque IF (:P_TIPO = 'E') THEN UPDATE CADPRODUTOS SET QTDEATUAL = COALESCE(QTDEATUAL,0) + :P_QUANTIDADE WHERE CODGRUPO = :P_CODGRUPO AND CODPRODUTO = :P_CODPRODUTO; ELSE IF (:P_TIPO = 'S') THEN UPDATE CADPRODUTOS SET QTDEATUAL = COALESCE(QTDEATUAL,0) - :P_QUANTIDADE WHERE CODGRUPO = :P_CODGRUPO AND CODPRODUTO = :P_CODPRODUTO; -- MOVESTOQUE (cabeçalho) SELECT FIRST 1 CODMOVIMENTO FROM MOVESTOQUE WHERE CODGRUPO = :P_CODGRUPO AND CODPRODUTO = :P_CODPRODUTO AND TIPO = :P_TIPO INTO :V_CODMOVIMENTO; IF (V_CODMOVIMENTO IS NULL) THEN BEGIN V_CODMOVIMENTO = GEN_ID(GEN_CODMOVESTOQUE,1); INSERT INTO MOVESTOQUE (CODMOVIMENTO, CODGRUPO, CODPRODUTO, DESCRICAO, TIPO, OBSERVACAO) VALUES (:V_CODMOVIMENTO, :P_CODGRUPO, :P_CODPRODUTO, '', :P_TIPO, :P_OBSERVACAO); END -- MOVESTOQUEITENS (principal) INSERT INTO MOVESTOQUEITENS (CODMOVIMENTO, NUMEROVENDA, DATAMOV, QTDEMOV, QTDEATUAL, VALORUNITITEM, VALORTOTALITEM, OBSERVACAO) VALUES (:V_CODMOVIMENTO, :P_NUMEROVENDA, CURRENT_DATE, :P_QUANTIDADE, (SELECT QTDEATUAL FROM CADPRODUTOS WHERE CODGRUPO = :P_CODGRUPO AND CODPRODUTO = :P_CODPRODUTO), :P_VALORUNITITEM, :P_VALORTOTALITEM, :P_OBSERVACAO); -- Controle de BAIXA EXTRA FOR SELECT CODGRUPOEXTRA, CODPRODUTOEXTRA, QTDEBAIXAR FROM CADPRODUTOSBAIXAEXTRA WHERE CODGRUPO = :P_CODGRUPO AND CODPRODUTO = :P_CODPRODUTO INTO :V_CODGRUPOEXTRA, :V_CODPRODUTOEXTRA, :V_QTDEBAIXAR DO BEGIN IF (:P_TIPO = 'E') THEN UPDATE CADPRODUTOS SET QTDEATUAL = COALESCE(QTDEATUAL,0) + (:P_QUANTIDADE * :V_QTDEBAIXAR) WHERE CODGRUPO = :V_CODGRUPOEXTRA AND CODPRODUTO = :V_CODPRODUTOEXTRA; ELSE IF (:P_TIPO = 'S') THEN UPDATE CADPRODUTOS SET QTDEATUAL = COALESCE(QTDEATUAL,0) - (:P_QUANTIDADE * :V_QTDEBAIXAR) WHERE CODGRUPO = :V_CODGRUPOEXTRA AND CODPRODUTO = :V_CODPRODUTOEXTRA; INSERT INTO MOVESTOQUEITENS (CODMOVIMENTO, NUMEROVENDA, DATAMOV, QTDEMOV, QTDEATUAL, VALORUNITITEM, VALORTOTALITEM, OBSERVACAO) VALUES (:V_CODMOVIMENTO, :P_NUMEROVENDA, CURRENT_DATE, CASE WHEN :P_TIPO = 'E' THEN (:P_QUANTIDADE * :V_QTDEBAIXAR) ELSE -(:P_QUANTIDADE * :V_QTDEBAIXAR) END, (SELECT QTDEATUAL FROM CADPRODUTOS WHERE CODGRUPO = :V_CODGRUPOEXTRA AND CODPRODUTO = :V_CODPRODUTOEXTRA), :P_VALORUNITITEM, :P_VALORTOTALITEM, 'BAIXA EXTRA - ' || COALESCE(:P_OBSERVACAO, '')); END MSGRETORNO = NULL; SUSPEND; END SET TERM ^ ;