Trigger para Controle de Estoque - Calcular Saldo Anterior

09/04/2018

8

Olá galera, tudo bem? Bom, sou novato aqui no fórum. Bom, o meu problema está sendo no seguinte. Eu tenho uma aplicação web de um controle de estoque, nada muito complicado. Mas estou com duas dúvidas:
1. Qual a melhor estratégia de se trabalhar com estoque no banco de dados? O ideal é fazer a baixa no ato do cadastro dos itens do pedido ou só após o fechamento completo do pedido?

2. Minha estrutura do cadastro de estoque está assim:

CREATE TABLE `F001_ESTOQUE` (
  `ID` INTEGER(10) UNSIGNED NOT NULL AUTO_INCREMENT,
  `IDCOLIGADA` INTEGER(10) UNSIGNED NOT NULL,
  `IDPRODUTO` INTEGER(10) UNSIGNED NOT NULL COMMENT ''''ID DO PRODUTO'''',
  `IDTIPODOCUMENTO` INTEGER(10) UNSIGNED DEFAULT NULL,
  `IDPEDIDO` INTEGER(10) UNSIGNED DEFAULT NULL COMMENT ''''ID DO PEDIDO'''',
  `IDDETALHEPEDIDO` INTEGER(10) UNSIGNED DEFAULT NULL COMMENT ''''ID DO DETALHE DO PEDIDO'''',
  `IDUSUARIOCRIA` INTEGER(10) UNSIGNED NOT NULL,
  `IDUSUARIOALTERA` INTEGER(10) UNSIGNED DEFAULT NULL,
  `DATACADASTRO` DATE NOT NULL,
  `SALDOANTERIOR` DECIMAL(15,4) DEFAULT NULL,
  `VALORANTERIOR` DECIMAL(15,4) DEFAULT NULL,
  `ENTRADA` DECIMAL(15,4) DEFAULT NULL,
  `DATAENTRADA` DATE DEFAULT NULL,
  `VALORENTRADA` DECIMAL(15,4) DEFAULT NULL,
  `DOCUMENTO` VARCHAR(50) COLLATE utf8_general_ci DEFAULT NULL,
  `DATADOCUMENTO` DATE DEFAULT NULL,
  `SAIDA` DECIMAL(15,4) DEFAULT NULL,
  `DATASAIDA` DATE DEFAULT NULL,
  `VALORSAIDA` DECIMAL(15,4) DEFAULT NULL,
  `SALDOATUAL` DECIMAL(15,4) DEFAULT NULL,
  `VALORSALDOATUAL` DECIMAL(15,4) DEFAULT NULL,
  `OBSERVACAO` LONGTEXT COLLATE utf8_general_ci,
  PRIMARY KEY USING BTREE (`ID`),
  KEY `F001_ESTOQUE_FKIndex1` USING BTREE (`IDPRODUTO`),
  KEY `IDCOLIGADA` USING BTREE (`IDCOLIGADA`),
  CONSTRAINT `F001_ESTOQUE_fk1` FOREIGN KEY (`IDCOLIGADA`) REFERENCES `A006_COLIGADA` (`ID`),
  CONSTRAINT `F001_ESTOQUE_ibfk_1` FOREIGN KEY (`IDPRODUTO`) REFERENCES `E005_PRODUTOS` (`ID`) ON DELETE NO ACTION ON UPDATE NO ACTION
) ENGINE=InnoDB


E nela fiz a seguinte trigger:
CREATE DEFINER = ''''mdierpco_ilano''''@''''172.16.0.210'''' TRIGGER `F001_ESTOQUE_INCLUIR` BEFORE INSERT ON `F001_ESTOQUE`
  FOR EACH ROW
BEGIN
	SET NEW.SALDOATUAL =
    ((CASE WHEN NEW.SALDOANTERIOR IS NULL THEN 0 ELSE NEW.SALDOANTERIOR END) +
    (CASE WHEN NEW.ENTRADA IS NULL THEN 0 ELSE NEW.ENTRADA END)) -
    (CASE WHEN NEW.SAIDA IS NULL THEN 0 ELSE NEW.SAIDA END);
    
    SET NEW.VALORSALDOATUAL =
    ((CASE WHEN NEW.VALORANTERIOR IS NULL THEN 0 ELSE NEW.VALORANTERIOR END) +
    (CASE WHEN NEW.VALORENTRADA IS NULL THEN 0 ELSE NEW.VALORENTRADA END)) -
    (CASE WHEN NEW.VALORSAIDA IS NULL THEN 0 ELSE NEW.VALORSAIDA END);
    
    IF(NEW.IDPRODUTO = 0) THEN SET NEW.IDPRODUTO = NULL; END IF;
    IF(NEW.IDDETALHEPEDIDO = 0) THEN SET NEW.IDDETALHEPEDIDO = NULL; END IF;
    IF(NEW.IDUSUARIOALTERA = 0) THEN SET NEW.IDUSUARIOALTERA = NULL; END IF;
    
    UPDATE E005_PRODUTOS SET E005_PRODUTOS.QUANTESTOQUE = NEW.SALDOATUAL
    WHERE E005_PRODUTOS.ID = NEW.ID;
    
END;


Como faço para implementar nesta trigger o cálculo o saldo anterior para que o saldo atual bata corretamente? Antes de SET NEW.SALDOATUAL tentei fazer algo do tipo, mas não deu certo:

SET NEW.SALDOANTERIOR = (CASE WHEN NEW.ID = (SELECT MIN(X.ID) FROM F001_ESTOQUE X WHERE X.IDPRODUTO = NEW.IDPRODUTO LIMIT 1) THEN
IFNULL(NEW.SALDOANTERIOR, 0) ELSE
IFNULL((((SELECT IFNULL(X.SALDOANTERIOR, 0)
FROM F001_ESTOQUE X
WHERE X.IDPRODUTO = NEW.IDPRODUTO AND X.ID < NEW.ID
) + IFNULL(NEW.ENTRADA, 0)) - IFNULL(NEW.SAIDA, 0)), 0));


3. Como ocorre em casos de desistência do pedido? O cliente fez o pedido mas agora ele não quer mais? Isso tem como implementar em uma procedure?

Grato pela atenção de todos,

Ilano.
Ilano Frota

Ilano Frota

Responder

Posts

12/04/2018

Emerson Nascimento

se eu entendi o procedimento, você não precisa (e nem deve) tentar calcular o saldo anterior.
seu trigger deveria ter somente a instrução abaixo:

UPDATE E005_PRODUTOS SET
    E005_PRODUTOS.QUANTESTOQUE = E005_PRODUTOS.QUANTESTOQUE + (IFNULL(NEW.ENTRADA, 0) - IFNULL(NEW.SAIDA, 0))
WHERE E005_PRODUTOS.ID = NEW.ID;


Responder

Utilizamos cookies para fornecer uma melhor experiência para nossos usuários,
consulte nossa política de privacidade.

Aceitar