Hola, pues bien .. la idea es esta:
- tb_articulo ( id INT PK)
- tb_almacen (id INT PK)
- tb_stock (id INT PK, idarticulo INT FK, idalmacen INT FK, cantidad INT)
Y este es el Trigger:
CREATE OR REPLACE FUNCTION tr_stock_articulo_almacen()
RETURNS TRIGGER AS
$BODY$
DECLARE i_existe INTEGER;
i_tipo INTEGER;
BEGIN
-- Calcula valores
i_tipo := (CASE WHEN TG_TABLE_NAME = 'tb_venta_detalle' THEN -1 ELSE 1 END);
i_existe := (SELECT COUNT(id) FROM tb_stock WHERE idalmacen = NEW.idalmacen AND idarticulo = NEW.idarticulo);
-- Inserta almacen y producto en tabla stock
IF i_existe = 0 THEN
INSERT INTO tb_stock (idalmacen, idarticulo, cantidad) VALUES (NEW.idalmacen, NEW.idarticulo, 0);
END IF;
-- Opera trigger
IF TG_OP = 'INSERT' THEN
UPDATE tb_stock SET cantidad = cantidad + (NEW.cantidad * i_tipo) WHERE idalmacen = NEW.idalmacen AND idarticulo = NEW.idarticulo;
ELSEIF TG_OP = 'UPDATE' THEN
UPDATE tb_stock SET cantidad = cantidad - (OLD.cantidad * i_tipo) WHERE idalmacen = OLD.idalmacen AND idarticulo = OLD.idarticulo;
UPDATE tb_stock SET cantidad = cantidad + (NEW.cantidad * i_tipo) WHERE idalmacen = NEW.idalmacen AND idarticulo = NEW.idarticulo;
ELSEIF TG_OP = 'DELETE' THEN
UPDATE tb_stock SET cantidad = cantidad - (OLD.cantidad * OLD.tipo) WHERE idalmacen = OLD.idalmacen AND idarticulo = OLD.idarticulo;
END IF;
RETURN NULL;
END;
$BODY$
LANGUAGE plpgsql VOLATILE;
Asi asignas el trigger a la tabla:
-- Para la tabla de detalle de compra
CREATE TRIGGER tb_compra_detalle_trigger
AFTER INSERT OR UPDATE OR DELETE
ON tb_compra_detalle
FOR EACH ROW
EXECUTE PROCEDURE tr_stock_articulo_almacen();
-- Para la tabla de detalle de venta
CREATE TRIGGER tb_venta_detalle_trigger
AFTER INSERT OR UPDATE OR DELETE
ON tb_venta_detalle
FOR EACH ROW
EXECUTE PROCEDURE tr_stock_articulo_almacen();
Saludos.