CREATE OR ALTER PROCEDURE SPU_ATUALIZA_SALDO_CAIXABANCO (
    CAIXABANCO_CODIGO INTEGER,
    DATA_BASE DATE)
AS
DECLARE VARIABLE DATA_DIF1            INTEGER;
DECLARE VARIABLE DATA_DIF2            INTEGER;
DECLARE VARIABLE VALIDAR_BANCO        INTEGER;
DECLARE VARIABLE VALOR_DEBITO         NUMERIC(15,2);
DECLARE VARIABLE VALOR_CREDITO        NUMERIC(15,2);
DECLARE VARIABLE VALOR_SALDO_BASE_OLD NUMERIC(15,2);
DECLARE VARIABLE VALOR_SALDO_BASE     NUMERIC(15,2);
DECLARE VARIABLE VALOR_TOTAL_DEBITO   NUMERIC(15,2);
DECLARE VARIABLE VALOR_TOTAL_CREDITO  NUMERIC(15,2);
BEGIN
   DATA_DIF2           = 0;
   VALOR_DEBITO        = 0;
   VALOR_CREDITO       = 0;
   VALOR_TOTAL_DEBITO  = 0;
   VALOR_TOTAL_CREDITO = 0;
   VALIDAR_BANCO       = COALESCE((SELECT FIRST 1 A.CODIGO FROM TBCAIXABANCO              A WHERE A.CODIGO = :CAIXABANCO_CODIGO),0);
   VALOR_SALDO_BASE    = COALESCE((SELECT FIRST 1 K.SALDO  FROM TBCAIXABANCO_SALDO_DIARIO K WHERE K.CODIGO = :CAIXABANCO_CODIGO AND K.DATA < :DATA_BASE ORDER BY K.DATA DESC),0);
   VALOR_SALDO_BASE_OLD= VALOR_SALDO_BASE;
   DATA_DIF1           = DATEDIFF(DAY FROM :DATA_BASE TO CURRENT_DATE);
   /*VALIDAR BANCO UTILIZADO NA PROCEDURE*/
   IF(:VALIDAR_BANCO > 0)THEN
   BEGIN
      /*VALIDAR A DATA BASE ENVIADA NA PROCEDURE*/
      IF(:DATA_DIF1 > 0)THEN
      BEGIN
         WHILE(:DATA_DIF2 < :DATA_DIF1) DO
         BEGIN
             /*PARA CADA DIA CONSULTAR O TOTAL DE DÉBITOS E CRÉDITOS DO CAIXA/BANCO*/
             FOR SELECT
               (SELECT SUM(B.VALOR_TOTAL) FROM TBCAIXABANCO_LANCAMENTO B WHERE B.CAIXABANCO_CODIGO = :CAIXABANCO_CODIGO
                 AND B.DATA_LANCAMENTO = DATEADD(:DATA_DIF2 DAY TO :DATA_BASE) AND B.NATUREZA = 'C') VALOR_CREDITO,
               (SELECT SUM(B.VALOR_TOTAL) FROM TBCAIXABANCO_LANCAMENTO B WHERE B.CAIXABANCO_CODIGO = :CAIXABANCO_CODIGO
                 AND B.DATA_LANCAMENTO = DATEADD(:DATA_DIF2 DAY TO :DATA_BASE) AND B.NATUREZA = 'D') VALOR_DEBITO
             FROM RDB$DATABASE
             INTO :VALOR_CREDITO, :VALOR_DEBITO DO
             BEGIN
                 :VALOR_TOTAL_DEBITO  = :VALOR_TOTAL_DEBITO  + COALESCE(:VALOR_DEBITO,0);
                 :VALOR_TOTAL_CREDITO = :VALOR_TOTAL_CREDITO + COALESCE(:VALOR_CREDITO,0);
                 /*SE NENHUM LANÇAMENTO FOR ENCONTRADO EXCLUIR O SALDO DIARIO*/
                 IF(:VALOR_CREDITO IS NULL AND :VALOR_DEBITO IS NULL)THEN
                 BEGIN
                    DELETE FROM TBCAIXABANCO_SALDO_DIARIO X WHERE X.CODIGO = :CAIXABANCO_CODIGO AND X.DATA = DATEADD(:DATA_DIF2 DAY TO :DATA_BASE);
                 END
                 /*SE LANÇAMENTOS FOREM ENCONTRADOS ATUALIZAR O SALDO DIARIO DO CAIXA/BANCO*/
                 IF(:VALOR_CREDITO IS NOT NULL OR :VALOR_DEBITO IS NOT NULL)THEN
                 BEGIN
                    --EXCEPTION "..." 'VALOR SALDO BASE R$'||:VALOR_SALDO_BASE;
                    :VALOR_SALDO_BASE = (:VALOR_SALDO_BASE + COALESCE(:VALOR_DEBITO,0)) - COALESCE(:VALOR_CREDITO,0);
                    UPDATE OR INSERT INTO TBCAIXABANCO_SALDO_DIARIO (CODIGO, DATA, SALDO)
                      VALUES (:CAIXABANCO_CODIGO, DATEADD(:DATA_DIF2 DAY TO :DATA_BASE),:VALOR_SALDO_BASE)
                      MATCHING(CODIGO, DATA);
                 END
             END
            :DATA_DIF2 = :DATA_DIF2+1;
         END
         /*SE O SALDO RESULTANTE FOR DIFERENTE DO SALDO DIARIO ANTERIOR ATUALIZAR O CAMPO SALDO DO CAIXA/BANCO*/
         IF(:VALOR_SALDO_BASE <> :VALOR_SALDO_BASE_OLD)THEN
         BEGIN
            --EXCEPTION "..." 'VALOR SALDO RESULTANTE R$'||:VALOR_SALDO_BASE;
            UPDATE TBCAIXABANCO Y SET Y.SALDO = :VALOR_SALDO_BASE WHERE Y.CODIGO = :CAIXABANCO_CODIGO;
         END
      END
      IF(:DATA_DIF1 = 0)THEN
      BEGIN
         EXCEPTION "..." 'DATA BASE DEVE SER MENOR DO QUE '||FORMATDATE(CURRENT_DATE)||'. OPERACAO CANCELADA.';
      END
   END
   IF(:VALIDAR_BANCO = 0)THEN
   BEGIN
     EXCEPTION "..." 'CAIXA/BANCO INVALIDO OU NAO ENCONTRADO. OPERACAO CANCELADA.';
   END
END;