CREATE OR REPLACE
PROCEDURE GERA_BAIXA(
   P_IDENTRSAID   IN NOTAFISCAL.IDENTRSAIDOP%TYPE,
   P_CDEMPRESA    IN NOTAFISCAL.CDEMPRESA%TYPE,
   P_CDFILIAL     IN NOTAFISCAL.CDFILIAL%TYPE,
   P_NRLANBOL     IN BOLETRECEBER.NRLANBOLREC%TYPE,
   P_FILIPROC     IN NOTAFISCAL.CDFILIAL%TYPE,
   P_DTBAIXA      IN BAIXARECEBIDA.DTBAIXAREC%TYPE,
   P_CDCONTCORR   IN BAIXARECEBIDA.CDREDUCONT%TYPE,
   P_CDTIPOBAIXA  IN BAIXARECEBIDA.CDTPBAIXAREC%TYPE,
   P_CDOPERADOR   IN BAIXARECEBIDA.CDOPERADOR%TYPE,
   P_IDBAIXACUPOM IN BAIXARECEBIDA.IDBAIXAAUTOCUPOM%TYPE)
AS
   V_NRMOVBANC    VARCHAR2(20);
   V_NRRECIBO     VARCHAR2(20);
   V_NRBAIXA      VARCHAR2(20);
   V_CDHISTPADR   LANCCONT.CDHISTPADR%TYPE;
   V_DSHISTPADR   HISTPADR.DSHISTPADR%TYPE;
   V_NRLANCTONF   NOTAFISCAL.NRLANCTONF%TYPE;
   V_NRSEQVENBOL CONTARECEBER.NRSEQVENREC%TYPE;
   V_VRORIGBOL    CONTARECEBER.VRORIGREC%TYPE;
   V_CDFILIBOL CONTARECEBER.CDFILIBOLREC%TYPE;
   V_CDCLASSFINA  CONTARECEBER.CDCLASSFINA%TYPE;
   V_CDEMPRESA    CONTARECEBER.CDEMPRESA%TYPE;
   V_CDFIMOVFL CONTARECEBER.CDFIMOVFLREC%TYPE;
   V_DTMOVFLUXO   CONTARECEBER.DTMOVFLUXO%TYPE;
   V_IDMOVFLUXO   CONTARECEBER.IDMOVFLUXO%TYPE;
   V_DTPROC       DATE;
   V_NRPARCELABOL CONTARECEBER.NRPARCELAREC%TYPE;
   V_VRFINALBOL   BOLETRECEBER.VRFINALBREC%TYPE;
   V_DTSALDO      DATE;
   V_VRATUAL      SDOCCORR.VRSDOCCORR%TYPE;
   V_DTFERIADO    DATE;
   V_DTBAIXA      DATE;
   V_IDCOFERIBANC PARAMGERAL.IDCOFERIBANC%TYPE;
   V_NRLANCCTB    LANCCONT.NRLANCCONT%TYPE;
BEGIN
   NOVO_CODIGO_NT('MOVBANCARIO' || P_CDCONTCORR, V_NRMOVBANC);
   V_NRMOVBANC := SUBSTR(V_NRMOVBANC, 11, 10);
   IF P_IDENTRSAID = 'S' THEN
      NOVO_CODIGO_NT('NRRECIBOREC', V_NRRECIBO);
      V_NRRECIBO := SUBSTR(V_NRRECIBO, 11, 10);

      NOVO_CODIGO_NT('BAIXARECEBIDA' || P_FILIPROC, V_NRBAIXA);
      V_NRBAIXA := SUBSTR(V_NRBAIXA, 11, 10);

      SELECT MAX(IDCOFERIBANC)
        INTO V_IDCOFERIBANC
        FROM PARAMGERAL;

      V_DTBAIXA := P_DTBAIXA;

      /*Considera feriado bancario para gerar a baixa*/
      IF (V_IDCOFERIBANC = 'S') THEN

        SELECT MAX(DTFERIBANC)
          INTO V_DTFERIADO
          FROM FERIBANC
         WHERE CDFILIAL   = P_FILIPROC
           AND DTFERIBANC = V_DTBAIXA;

        WHILE (V_DTFERIADO = V_DTBAIXA) LOOP
            V_DTBAIXA := V_DTBAIXA + 1;
            SELECT MAX(DTFERIBANC)
              INTO V_DTFERIADO
              FROM FERIBANC
             WHERE CDFILIAL   = P_FILIPROC
               AND DTFERIBANC = V_DTBAIXA;
        END LOOP;
      END IF;

      SELECT MAX(T.CDHISTPADR), MAX(H.DSHISTPADR)
        INTO V_CDHISTPADR, V_DSHISTPADR
        FROM TIPOBAIXAREC T, HISTPADR H
       WHERE T.CDTPBAIXAREC = P_CDTIPOBAIXA
         AND T.CDHISTPADR   = H.CDHISTPADR;

      SELECT MAX(VRFINALBREC)
        INTO V_VRFINALBOL
        FROM BOLETRECEBER
       WHERE CDFILIAL    = P_FILIPROC
         AND NRLANBOLREC = P_NRLANBOL;

      SELECT CR.NRLANCTONF, CR.NRSEQVENREC, CR.NRPARCELAREC,
             CR.VRORIGREC, CR.CDFILIBOLREC, CR.CDCLASSFINA,
             CR.CDEMPRESA, CR.CDFIMOVFLREC, CR.DTMOVFLUXO, CR.IDMOVFLUXO
        INTO V_NRLANCTONF, V_NRSEQVENBOL, V_NRPARCELABOL,
             V_VRORIGBOL, V_CDFILIBOL, V_CDCLASSFINA,
             V_CDEMPRESA, V_CDFIMOVFL, V_DTMOVFLUXO, V_IDMOVFLUXO
        FROM NOTAFISCAL NF, CONTARECEBER CR
       WHERE (CR.CDFILIAL    = P_FILIPROC)
         AND (CR.NRLANBOLREC = P_NRLANBOL)
         AND (NF.CDFILIAL    = CR.CDFILIAL)
         AND (NF.NRLANCTONF  = CR.NRLANCTONF)
         AND (NF.CDEMPRESA   = CR.CDEMPRESA)
         AND (NF.CDEMPRESA   = P_CDEMPRESA);

      ATUALIZA_FLUXO_DE_CAIXA(V_CDEMPRESA,
                              V_CDFIMOVFL,
                              V_DTMOVFLUXO,
                              V_IDMOVFLUXO,
                              V_CDCLASSFINA,
                              V_VRORIGBOL * -1,
                              0);

      ATUALIZA_FLUXO_DE_CAIXA(V_CDEMPRESA,
                              V_CDFIMOVFL,
                              V_DTBAIXA,
                              'R',
                              V_CDCLASSFINA,
                              V_VRORIGBOL,
                              0);

      /*Atualiza a conta com os dados do recebibento*/
      UPDATE CONTARECEBER
         SET IDMOVFLUXO = 'R',
             IDSTATREC  = 'B',
             DTMOVFLUXO = V_DTBAIXA
       WHERE CDFILIAL     = P_FILIPROC
         AND NRLANCTONF   = V_NRLANCTONF
         AND NRSEQVENREC  = V_NRSEQVENBOL
         AND NRPARCELAREC = V_NRPARCELABOL;

      INSERT INTO MOVBANCARIO
         (CDREDUCONT, NRMOVBANC, DTMOVBANC, IDMOVBANC,
          NRDOCMBANC, DSHISMBANC, VRMOVBANC, IDORIGMBANC)
      VALUES
         (P_CDCONTCORR, V_NRMOVBANC, V_DTBAIXA, 'C',
          '', 'bxRec', V_VRFINALBOL, 'R');

      INSERT INTO BAIXARECEBIDA
         (CDEMPRESA, NRMOVBANC, NRBAIXAREC, NRRECIBOREC,
          IDSTATUSBREC, CDFILIAL, DTBAIXAREC, VRBAIXAREC,
          CDREDUCONT, CDTPBAIXAREC, CDOPERADOR, DTLANCBAIXAR,
          DSBAIXAREC, IDBAIXAAUTOCUPOM)
      VALUES
         (V_CDEMPRESA, V_NRMOVBANC, V_NRBAIXA, V_NRRECIBO,
          'E',  P_FILIPROC, V_DTBAIXA, V_VRFINALBOL,
          P_CDCONTCORR, P_CDTIPOBAIXA, P_CDOPERADOR, SYSDATE,
          DECODE(NVL(P_IDBAIXACUPOM,'N'),'S','Baixa Realizada Automaticamente pelo Fechamento de Cupom',''), NVL(P_IDBAIXACUPOM,'N'));

      UPDATE BOLETRECEBER
         SET IDSTATBREC   = 'B',
             NRBAIXAREC   = V_NRBAIXA,
             CDTPBAIXAREC = P_CDTIPOBAIXA,
             CDFILIBAIREC = P_FILIPROC,
             DTLIQBOLREC  = V_DTBAIXA
       WHERE (CDFILIAL    = P_CDFILIAL)
         AND (NRLANBOLREC = P_NRLANBOL);

      /*Atualiza saldo da conta corrente*/
      SELECT MAX(DTSDOCCORR)
        INTO V_DTSALDO
        FROM SDOCCORR
       WHERE CDREDUCONT = P_CDCONTCORR
         AND DTSDOCCORR <= V_DTBAIXA;

      SELECT MAX(VRSDOCCORR)
        INTO V_VRATUAL
        FROM SDOCCORR
       WHERE CDREDUCONT = P_CDCONTCORR
         AND DTSDOCCORR = V_DTSALDO;

      V_VRATUAL := NVL(V_VRATUAL,0) + NVL(V_VRFINALBOL,0);

      IF V_DTBAIXA =  V_DTSALDO THEN
         UPDATE SDOCCORR
            SET VRSDOCCORR = V_VRATUAL,
                VRSDOIMPLA = NULL
          WHERE CDREDUCONT = P_CDCONTCORR
            AND DTSDOCCORR = V_DTSALDO;
      ELSE
         INSERT INTO SDOCCORR
            (CDREDUCONT, DTSDOCCORR, VRSDOCCORR, VRSDOIMPLA)
         VALUES
            (P_CDCONTCORR, V_DTBAIXA, V_VRATUAL, NULL);
      END IF;
   ELSE
      NOVO_CODIGO_NT('BAIXAPAGA' || P_FILIPROC, V_NRBAIXA);
      V_NRBAIXA := SUBSTR(V_NRBAIXA, 11, 10);

      SELECT MAX(IDCOFERIBANC)
        INTO V_IDCOFERIBANC
        FROM PARAMGERAL;

      V_DTBAIXA := P_DTBAIXA;

      /*Considera feriado bancario para gerar a baixa*/
      IF (V_IDCOFERIBANC = 'S') THEN

        SELECT MAX(DTFERIBANC)
          INTO V_DTFERIADO
          FROM FERIBANC
         WHERE CDFILIAL   = P_FILIPROC
           AND DTFERIBANC = V_DTBAIXA;

        WHILE (V_DTFERIADO = V_DTBAIXA) LOOP
            V_DTBAIXA := V_DTBAIXA + 1;
            SELECT MAX(DTFERIBANC)
              INTO V_DTFERIADO
              FROM FERIBANC
             WHERE CDFILIAL   = P_FILIPROC
               AND DTFERIBANC = V_DTBAIXA;
        END LOOP;
      END IF;

      SELECT MAX(T.CDHISTPADR), MAX(H.DSHISTPADR)
        INTO V_CDHISTPADR, V_DSHISTPADR
        FROM TIPOBAIXAPAG T, HISTPADR H
       WHERE T.CDTPBAIXAPAG = P_CDTIPOBAIXA
         AND T.CDHISTPADR   = H.CDHISTPADR;

      SELECT MAX(VRFINALBPAG)
        INTO V_VRFINALBOL
        FROM BOLETPAGAR
       WHERE CDFILIAL    = P_FILIPROC
         AND NRLANBOLPAG = P_NRLANBOL;

      SELECT CR.NRLANCTONF, CR.NRSEQVENPAG, CR.NRPARCELAPAG,
             CR.VRORIGPAG, CR.CDFILIBPAG, CR.CDCLASSFINA,
             CR.CDEMPRESA, CR.CDFIMOVFLPAG, CR.DTMOVFLUXO, CR.IDMOVFLUXO
        INTO V_NRLANCTONF, V_NRSEQVENBOL, V_NRPARCELABOL,
             V_VRORIGBOL, V_CDFILIBOL, V_CDCLASSFINA,
             V_CDEMPRESA, V_CDFIMOVFL, V_DTMOVFLUXO, V_IDMOVFLUXO
        FROM NOTAFISCAL NF, CONTAPAGAR CR
       WHERE (CR.CDFILIAL    = P_FILIPROC)
         AND (CR.NRLANBOLPAG = P_NRLANBOL)
         AND (NF.CDFILIAL    = CR.CDFILIAL)
         AND (NF.NRLANCTONF  = CR.NRLANCTONF)
         AND (NF.CDEMPRESA   = CR.CDEMPRESA)
         AND (NF.CDEMPRESA   = P_CDEMPRESA);

      ATUALIZA_FLUXO_DE_CAIXA(V_CDEMPRESA,
                              V_CDFIMOVFL,
                              V_DTMOVFLUXO,
                              V_IDMOVFLUXO,
                              V_CDCLASSFINA,
                              0,
                              V_VRORIGBOL * -1);

      ATUALIZA_FLUXO_DE_CAIXA(V_CDEMPRESA,
                              V_CDFIMOVFL,
                              V_DTBAIXA,
                              'R',
                              V_CDCLASSFINA,
                              0,
                              V_VRORIGBOL);

      /*Atualiza a conta com os dados do pagamento*/
      UPDATE CONTAPAGAR
         SET IDMOVFLUXO = 'R',
             IDSTATPAG  = 'B',
             DTMOVFLUXO = V_DTBAIXA
       WHERE CDFILIAL     = P_FILIPROC
         AND NRLANCTONF   = V_NRLANCTONF
         AND NRSEQVENPAG  = V_NRSEQVENBOL
         AND NRPARCELAPAG = V_NRPARCELABOL;

      INSERT INTO MOVBANCARIO
         (CDREDUCONT, NRMOVBANC, DTMOVBANC, IDMOVBANC,
          NRDOCMBANC, DSHISMBANC, VRMOVBANC, IDORIGMBANC)
      VALUES
         (P_CDCONTCORR, V_NRMOVBANC, V_DTBAIXA, 'D',
          '', 'Baixa Referente a Sangria de Despesa', V_VRFINALBOL, 'P');

      INSERT INTO BAIXAPAGA
         (CDEMPRESA, NRMOVBANC, NRBAIXAPAG,
          IDSTATUSBPAG, CDFILIAL, DTBAIXAPAG, VRBAIXAPAG,
          CDREDUCONT, CDTPBAIXAPAG, CDOPERADOR, DTLANCBAIXAP,
          DSBAIXAPAG)
      VALUES
         (V_CDEMPRESA, V_NRMOVBANC, V_NRBAIXA,
          'E',  P_FILIPROC, V_DTBAIXA, V_VRFINALBOL,
          P_CDCONTCORR, P_CDTIPOBAIXA, P_CDOPERADOR, SYSDATE,
          'Baixa Realizada Automaticamente Referente a Sangria de Despesa');

      UPDATE BOLETPAGAR
         SET IDSTATBPAG   = 'B',
             NRBAIXAPAG   = V_NRBAIXA,
             CDTPBAIXAPAG = P_CDTIPOBAIXA,
             CDFILIBAIPAG = P_FILIPROC,
             DTLIQBOLPAG  = V_DTBAIXA
       WHERE (CDFILIAL    = P_CDFILIAL)
         AND (NRLANBOLPAG = P_NRLANBOL);

      CTB_BAIXA_PAG(V_CDEMPRESA,P_FILIPROC, V_NRBAIXA, V_NRLANCCTB );
      /*Atualiza saldo da conta corrente*/
      SELECT MAX(DTSDOCCORR)
        INTO V_DTSALDO
        FROM SDOCCORR
       WHERE CDREDUCONT = P_CDCONTCORR
         AND DTSDOCCORR <= V_DTBAIXA;

      SELECT MAX(VRSDOCCORR)
        INTO V_VRATUAL
        FROM SDOCCORR
       WHERE CDREDUCONT = P_CDCONTCORR
         AND DTSDOCCORR = V_DTSALDO;

      V_VRATUAL := NVL(V_VRATUAL,0) + NVL(V_VRFINALBOL,0);

      IF V_DTBAIXA =  V_DTSALDO THEN
         UPDATE SDOCCORR
            SET VRSDOCCORR = V_VRATUAL,
                VRSDOIMPLA = NULL
          WHERE CDREDUCONT = P_CDCONTCORR
            AND DTSDOCCORR = V_DTSALDO;
      ELSE
         INSERT INTO SDOCCORR
            (CDREDUCONT, DTSDOCCORR, VRSDOCCORR, VRSDOIMPLA)
         VALUES
            (P_CDCONTCORR, V_DTBAIXA, V_VRATUAL, NULL);
      END IF;
   END IF;
END;

/