ALTER TABLE FORMULAFISCAL ADD CDITEMMAPA VARCHAR2(20) NOT NULL
/

CREATE OR REPLACE PROCEDURE GERA_INFADIC_BENEFICIO( 
   P_NRSEQUMAPAPU IN MAPAAPURAC.NRSEQUMAPAPU%TYPE,
   P_CDIMPOSTO    IN MAPAAPURAC.CDIMPOSTO%TYPE,
   P_CDEMPRESA    IN MAPAAPURAC.CDEMPRESA%TYPE,
   P_CDINSCESTA   IN  MAPAAPURAC.CDINSCESTA%TYPE
)
AS
   V_NRSEQINFADIC    NUMBER;
   V_VRINFADICNF     NUMBER;
   V_VRINFADICTOT    NUMBER;
   V_CODINFADIC      VARCHAR2(10); 
   V_DSINFADIC       VARCHAR2(255);
   V_CDBENEC197      VARCHAR2(15);
   V_DSBENEFICIO     VARCHAR2(255);
   V_CDBENEE115      VARCHAR2(15);
   V_VRALIQUOTA      NUMBER;
   V_VRALIQRED       NUMBER;
   V_CDTIPOOPER      VARCHAR2(500);
   V_CDCHAVENOTA     VARCHAR2(15);
   V_NRSEQITMAPR     VARCHAR2(10);
   V_NRSEQDETITMAPA  VARCHAR2(20);
BEGIN

   /******** DELETA OS REGISTROS NA TABELA, DEVIDO A REAPURAÇÃO DE MAPA ********/
   DELETE FROM INFADICMAPA
    WHERE NRSEQUMAPAPU = P_NRSEQUMAPAPU
      AND IDORIGEMINF  = 'B';

   /******** BUSCA O MAIOR SEQUENCIAL DE INFORMAÇÕES ADICIONAIS UTILIZADO NO MAPA ********/
   BEGIN
      SELECT MAX(NRSEQINFADIC)
        INTO V_NRSEQINFADIC
        FROM INFADICMAPA
       WHERE NRSEQUMAPAPU = P_NRSEQUMAPAPU;
   EXCEPTION
      WHEN NO_DATA_FOUND THEN
         V_NRSEQINFADIC := 0;
   END;

   V_CODINFADIC := NULL;
   /******** BUSCA AS NOTAS FISCAIS PRESENTES NO MAPA QUE TENHAM O CÓDIGO DE BENEFÍCIO FISCAL PREENCHIDO ********/
   FOR C_NF IN (SELECT IT.CDFILIAL, IT.NRLANCTONF, SUM(IT.VRCONTITIMP) AS VRCONTABIL,
                       IT.VRALIQITEM, IT.CDBENEFFISCAL, TB.IDBENEFICIO, TB.DSBENEFICIO
                  FROM TPBENEFICIOFISC TB, ITEMPROIMPOS IT, IMPOSTO IM, NOTAFISCAL NF,
                       (SELECT DISTINCT I.CDFILIAL, I.NRLANCTONF
                          FROM IMPOSTONF I
                         WHERE I.NRSEQUMAPAPU = P_NRSEQUMAPAPU) IP
                 WHERE IP.CDFILIAL      = NF.CDFILIAL
                   AND IP.NRLANCTONF    = NF.NRLANCTONF
                   AND NF.CDFILIAL      = IT.CDFILIAL
                   AND NF.NRLANCTONF    = IT.NRLANCTONF
                   AND IT.CDIMPOSTO     = IM.CDIMPOSTO
                   AND IM.CDIMPOSTONFE  = P_CDIMPOSTO
                   AND NF.IDENTRSAIDOP  = 'S'
                   AND IT.CDBENEFFISCAL = TB.CDBENEFICIO
                   AND NF.CDEMPRESA     = TB.CDEMPRESA
                   AND NF.CDINSCESTA    = TB.CDINSCESTA
                   AND TB.IDBENEFICIO   = 'IOP'
                   AND IT.VRALIQITEM    > 0
                 GROUP BY IT.CDFILIAL, IT.NRLANCTONF, IT.VRALIQITEM, IT.CDBENEFFISCAL, TB.IDBENEFICIO, TB.DSBENEFICIO
                 ORDER BY TB.IDBENEFICIO, IT.CDBENEFFISCAL) LOOP

       IF V_CODINFADIC IS NULL THEN
          V_CODINFADIC := C_NF.CDBENEFFISCAL;
          V_DSINFADIC  := C_NF.DSBENEFICIO;
       END IF;

       /***** CALCULA O VAOR DO BENEFÍCIO, QUANDO O MESMO FOR ISENÇÃO DE OPERAÇÕES COM ÓRGÃO PÚBLICO *****/
       IF C_NF.IDBENEFICIO = 'IOP' THEN
          V_VRINFADICNF := ROUND((C_NF.VRCONTABIL * 100 / (100 - C_NF.VRALIQITEM)) - C_NF.VRCONTABIL,2);
       END IF;

       /***** QUANDO TROCAR O CÓDIGO DO BENEFÍCIO, INSERE OS DADOS NA TABELA REFERENTE A TOTALIZAÇÃO DO BENEFÍCIO ANTERIOR *****/
       IF (V_CODINFADIC <> C_NF.CDBENEFFISCAL) THEN
          IF V_VRINFADICTOT > 0 THEN
             V_NRSEQINFADIC := NVL(V_NRSEQINFADIC,0) + 1;
             INSERT INTO INFADICMAPA
                (NRSEQUMAPAPU, NRSEQINFADIC, IDORIGEMINF, CDINFADICMAPA, DSINFADICMAPA, VRINFADICMAPA)
             VALUES
                (P_NRSEQUMAPAPU, LPAD(V_NRSEQINFADIC,5,'0'), 'B', V_CODINFADIC, V_DSINFADIC, V_VRINFADICTOT);
             V_VRINFADICTOT := NVL(V_VRINFADICNF,0);
             V_CODINFADIC   := NULL;
             V_DSINFADIC    := NULL;
          END IF;
       ELSE
          V_VRINFADICTOT := NVL(V_VRINFADICTOT,0) + V_VRINFADICNF;
       END IF;
   END LOOP;

   /***** AO TERMINAR O LOOP, INSERE O VALOR TOTAL DO ÚLTIMO BENEFÍCIO *****/
   IF V_VRINFADICTOT > 0 THEN
      V_NRSEQINFADIC := NVL(V_NRSEQINFADIC,0) + 1;
      INSERT INTO INFADICMAPA
         (NRSEQUMAPAPU, NRSEQINFADIC, IDORIGEMINF, CDINFADICMAPA, DSINFADICMAPA, VRINFADICMAPA)
      VALUES
         (P_NRSEQUMAPAPU, LPAD(V_NRSEQINFADIC,5,'0'), 'B', V_CODINFADIC, V_DSINFADIC, V_VRINFADICTOT);
   END IF;

   /******** Deleta da ITMAPARECUP as NF´s que vieram da IMPOSTONF que possuem valores informativos,
             gerados de forma automática pela rotina ********/
   DELETE ITMAPARECUP
    WHERE NRSEQUMAPAPU     = P_NRSEQUMAPAPU
      AND IDTIPOITMAPR     = 'VI'
      AND IDAJUSTEAPURAUTO = 'S';

   /******** Busca o último sequencial na ITMAPARECUP ********/
   V_NRSEQITMAPR := 0;
   BEGIN
      SELECT MAX(NRSEQITMAPR) AS NRSEQITMAPR
        INTO V_NRSEQITMAPR
        FROM ITMAPARECUP
       WHERE NRSEQUMAPAPU = P_NRSEQUMAPAPU
         AND IDTIPOITMAPR = 'VI';
   EXCEPTION
      WHEN NO_DATA_FOUND THEN
         V_NRSEQITMAPR := 0;
   END;

   /*VERIFICA SE EXISTE O CADASTRO PARA GERAÇÃO DO BENEFÍCIO DE ISENÇÃO*/
   BEGIN
      SELECT MAX(CDAJUSTENF) AS CDBENEC197, MAX(DSBENEFICIO) AS DSBENEFICIO,
             MAX(CDBENEFICIO) AS CDBENEE115, MAX(VRALIQUOTA) AS VRALIQUOTA,
             MAX(CDTPOPBENEFICIO) AS CDTIPOOPER
        INTO V_CDBENEC197, V_DSBENEFICIO, V_CDBENEE115, V_VRALIQUOTA, V_CDTIPOOPER
        FROM TPBENEFICIOFISC
       WHERE CDEMPRESA   = P_CDEMPRESA
         AND CDINSCESTA  = P_CDINSCESTA
         AND IDBENEFICIO = 'ISE';
   EXCEPTION
      WHEN NO_DATA_FOUND THEN
         V_CDBENEC197  := NULL;
         V_DSBENEFICIO := NULL;
         V_CDBENEE115  := NULL;
         V_VRALIQUOTA  := 0;
         V_CDTIPOOPER  := NULL;
   END;


   IF (V_CDBENEC197 IS NOT NULL) THEN
      V_CDCHAVENOTA  := '';
      V_VRINFADICTOT := 0;
      FOR C_NF IN (SELECT IT.CDFILIAL, IT.NRLANCTONF, IT.NRSEQITPROD,
                          SUM(IT.VRCONTITIMP) AS VRCONTABIL, IT.CDIMPOSTO,
                          IT.NRITPROIMPOS
                     FROM ITEMPROIMPOS IT, IMPOSTO IM,
                          (SELECT DISTINCT I.CDFILIAL, I.NRLANCTONF
                             FROM IMPOSTONF I, NOTAFISCAL N
                            WHERE I.NRSEQUMAPAPU = P_NRSEQUMAPAPU
                              AND I.CDFISCALNF   = '2'
                              AND I.CDFILIAL     = N.CDFILIAL
                              AND I.NRLANCTONF   = N.NRLANCTONF
                              AND ((INSTR(V_CDTIPOOPER, '_' ||N.IDENTRSAIDOP||N.CDTIPOOPER||'_' ) > 0) OR (V_CDTIPOOPER IS NULL))) IP
                    WHERE IT.CDFILIAL     = IP.CDFILIAL
                      AND IT.NRLANCTONF   = IP.NRLANCTONF
                      AND IT.CDIMPOSTO    = IM.CDIMPOSTO
                      AND IM.CDIMPOSTONFE = P_CDIMPOSTO
                      AND IT.CDFISCALIT   = '2'
                      AND IT.NRITPROIMPOS = '1'
                    GROUP BY IT.CDFILIAL, IT.NRLANCTONF, IT.NRSEQITPROD,
                          IT.CDIMPOSTO, IT.NRITPROIMPOS
                    ORDER BY IT.CDFILIAL, IT.NRLANCTONF, IT.NRSEQITPROD) LOOP

          /*CALCULA O VALOR DO ICMS DESONERADO*/
          V_VRINFADICNF := ROUND(C_NF.VRCONTABIL * V_VRALIQUOTA/100,2);
          V_VRINFADICTOT := NVL(V_VRINFADICTOT,0) + V_VRINFADICNF;

          /*QUANDO FOR UMA NOVA NOTA, INSERE OS DADOS DO AJUSTE DA NOTA*/
          IF NVL(V_CDCHAVENOTA,' ') <> C_NF.CDFILIAL||C_NF.NRLANCTONF THEN
             /*INSERE O REGISTRO DE AJUSTE PARA GERAR O C197/D197*/
             V_NRSEQITMAPR := NVL(V_NRSEQITMAPR,0) + 1;
             INSERT INTO ITMAPARECUP
                (NRSEQUMAPAPU, IDTIPOITMAPR, NRSEQITMAPR, DSITEMMAPR, VRITEMMAPR, CDITEMOCOR, DSITEMOCOR,
                 DSFLEGALOCOR, NRLANCTONF, CDFILIAL, CDAJUSTEITMAPA, CDAJUSTEITSEF, CDITPROCEDENCIA,
                 IDCREDPRESUMIDO, IDDIFALMANUAL, IDCARGATRIBUTARIA, IDCOMPOEC197, CDCFOPPADRAO,
                 VROUTROSITMAPR, IDAJUSTEAPURAUTO)
             VALUES
                (P_NRSEQUMAPAPU, 'VI', LPAD(V_NRSEQITMAPR,10,'0'), V_CDBENEE115, 0, '', '',
                 '', C_NF.NRLANCTONF, C_NF.CDFILIAL, V_CDBENEC197, '', '',
                 'N', 'N', 'N', 'I', '',
                 V_VRINFADICNF, 'S');
             V_CDCHAVENOTA := C_NF.CDFILIAL||C_NF.NRLANCTONF;
          /*QUANDO FOR A MESMA NOTA, ATUALIZA OS VALORES DO AJUSTE*/
          ELSE
             UPDATE ITMAPARECUP
                SET VROUTROSITMAPR = NVL(VROUTROSITMAPR,0) + NVL(V_VRINFADICNF,0)
              WHERE NRSEQUMAPAPU = P_NRSEQUMAPAPU
                AND IDTIPOITMAPR = 'VI'
                AND NRSEQITMAPR  = LPAD(V_NRSEQITMAPR,10,'0');
          END IF;

          /*INSERE OS AJUSTES POR ITENS*/
          NOVO_CODIGO('DETITMAPARECUP',V_NRSEQDETITMAPA);
          INSERT INTO DETITMAPARECUP
             (NRSEQDETITMAPA, NRSEQUMAPAPU, IDTIPOITMAPR, NRSEQITMAPR,
              CDFILIAL, NRLANCTONF, NRSEQITPROD, CDIMPOSTO, NRITPROIMPOS,
              VROUTROSIMPIT, VROUTALIQ, VROUTBASE)
          VALUES
             (TO_NUMBER(V_NRSEQDETITMAPA), P_NRSEQUMAPAPU, 'VI', LPAD(V_NRSEQITMAPR,10,'0'),
              C_NF.CDFILIAL, C_NF.NRLANCTONF, C_NF.NRSEQITPROD, C_NF.CDIMPOSTO, C_NF.NRITPROIMPOS,
              V_VRINFADICNF, V_VRALIQUOTA, C_NF.VRCONTABIL);
      END LOOP;
      IF V_VRINFADICTOT > 0 THEN
         /*INSERE O REGISTRO DE DADOS ADICIONAIS*/
         V_NRSEQINFADIC := NVL(V_NRSEQINFADIC,0) + 1;
         INSERT INTO INFADICMAPA
            (NRSEQUMAPAPU, NRSEQINFADIC, IDORIGEMINF, CDINFADICMAPA, DSINFADICMAPA, VRINFADICMAPA)
         VALUES
            (P_NRSEQUMAPAPU, LPAD(V_NRSEQINFADIC,5,'0'), 'B', V_CDBENEE115, V_DSBENEFICIO, V_VRINFADICTOT);
      END IF;
   END IF;

   /*VERIFICA SE EXISTE O CADASTRO PARA GERAÇÃO DO BENEFÍCIO DE REDUÇÃO DA BASE DE CÁLCULO*/
   BEGIN
      SELECT MAX(CDAJUSTENF) AS CDBENEC197, MAX(DSBENEFICIO) AS DSBENEFICIO,
             MAX(CDBENEFICIO) AS CDBENEE115, MAX(CDTPOPBENEFICIO) AS CDTIPOOPER
        INTO V_CDBENEC197, V_DSBENEFICIO, V_CDBENEE115, V_CDTIPOOPER
        FROM TPBENEFICIOFISC
       WHERE CDEMPRESA   = P_CDEMPRESA
         AND CDINSCESTA  = P_CDINSCESTA
         AND IDBENEFICIO = 'RBC';
   EXCEPTION
      WHEN NO_DATA_FOUND THEN
         V_CDBENEC197  := NULL;
         V_DSBENEFICIO := NULL;
         V_CDBENEE115  := NULL;
         V_VRALIQUOTA  := 0;
         V_CDTIPOOPER  := NULL;
   END;

   IF (V_CDBENEC197 IS NOT NULL) THEN
      V_CDCHAVENOTA  := '';
      V_VRINFADICTOT := 0;
      FOR C_NF IN (SELECT IT.CDFILIAL, IT.NRLANCTONF, IT.NRSEQITPROD,
                          '' AS CDFILIALVENDA, '' AS CDCAIXA, '' AS NRSEQVENDA,
                          '' AS NRSEQUITVEND, 0 AS VRPEALPRODIT,
                          SUM(IT.VRCONTITIMP) AS VRCONTABIL, IT.CDIMPOSTO,
                          IT.NRITPROIMPOS, IP.IDSISTEMA
                     FROM ITEMPROIMPOS IT, IMPOSTO IM,
                          (SELECT DISTINCT I.CDFILIAL, I.NRLANCTONF, N.IDSISTEMA
                             FROM IMPOSTONF I, NOTAFISCAL N
                            WHERE I.NRSEQUMAPAPU = P_NRSEQUMAPAPU
                              AND I.IDIMPOSTONF  = '2'
                              AND I.CDFILIAL     = N.CDFILIAL
                              AND I.NRLANCTONF   = N.NRLANCTONF
                              AND N.IDSISTEMA    <> 'FIS'
                              AND ((INSTR(V_CDTIPOOPER, '_' ||N.IDENTRSAIDOP||N.CDTIPOOPER||'_' ) > 0) OR (V_CDTIPOOPER IS NULL))) IP
                    WHERE IT.CDFILIAL     = IP.CDFILIAL
                      AND IT.NRLANCTONF   = IP.NRLANCTONF
                      AND IT.CDIMPOSTO    = IM.CDIMPOSTO
                      AND IM.CDIMPOSTONFE = P_CDIMPOSTO
                      AND IT.NRITPROIMPOS = '2'
                    GROUP BY IT.CDFILIAL, IT.NRLANCTONF, IT.NRSEQITPROD,
                          IT.CDIMPOSTO, IT.NRITPROIMPOS, IP.IDSISTEMA
                    UNION ALL
                   SELECT IP.CDFILIALNOTA AS CDFILIAL, IP.NRLANCTONF, '' AS NRSEQITPROD,
                          IP.CDFILIALVENDA, IP.CDCAIXA, IP.NRSEQVENDA,
                          IT.NRSEQUITVEND, IT.VRPEALPRODIT,
                          SUM(IT.VRBCREDUZICMS) AS VRCONTABIL,
                          IT.CDIMPOSTO, '' AS NRITPROIMPOS, IP.IDSISTEMA
                     FROM ITVENDAIMPOS IT, IMPOSTO IM,
                          (SELECT DISTINCT R.CDFILIALNOTA, R.NRLANCTONF, R.CDFILIALVENDA, R.CDCAIXA, R.NRSEQVENDA, N.IDSISTEMA
                             FROM IMPOSTONF I, NOTAFISCAL N,  RELACNFCEAPROV R
                            WHERE I.NRSEQUMAPAPU = P_NRSEQUMAPAPU
                              AND I.IDIMPOSTONF  = '2'
                              AND I.CDFILIAL     = N.CDFILIAL
                              AND I.NRLANCTONF   = N.NRLANCTONF
                              AND N.IDSISTEMA    = 'FIS'
                              AND N.CDFILIAL     = R.CDFILIALNOTA
                              AND N.NRLANCTONF   = R.NRLANCTONF
                              AND ((INSTR(V_CDTIPOOPER, '_' ||N.IDENTRSAIDOP||N.CDTIPOOPER||'_' ) > 0) OR (V_CDTIPOOPER IS NULL))) IP
                    WHERE IT.CDFILIAL     = IP.CDFILIALVENDA
                      AND IT.CDCAIXA      = IP.CDCAIXA
                      AND IT.NRSEQVENDA   = IP.NRSEQVENDA
                      AND IT.CDIMPOSTO    = IM.CDIMPOSTO
                      AND IM.CDIMPOSTONFE = P_CDIMPOSTO
                      AND IM.IDTPIMPOSFIS = 'T'
                      AND IT.VRPRBCREDUICMS > 0
                    GROUP BY IP.CDFILIALNOTA, IP.NRLANCTONF, IP.CDFILIALVENDA, IP.CDCAIXA,
                          IP.NRSEQVENDA, IT.NRSEQUITVEND, IT.VRPEALPRODIT, IT.CDIMPOSTO, IP.IDSISTEMA
                    ORDER BY 1, 2) LOOP

                    IF C_NF.IDSISTEMA = 'FIS' THEN
                       V_VRALIQUOTA := C_NF.VRPEALPRODIT;
                    ELSE
                       BEGIN
                          SELECT I.VRALIQITEM
                            INTO V_VRALIQUOTA
                            FROM ITEMPROIMPOS I
                           WHERE I.CDFILIAL    = C_NF.CDFILIAL
                             AND I.NRLANCTONF  = C_NF.NRLANCTONF
                             AND I.NRSEQITPROD = C_NF.NRSEQITPROD
                             AND I.CDIMPOSTO   = C_NF.CDIMPOSTO
                             AND I.CDFISCALIT  = '1';
                       EXCEPTION
                          WHEN NO_DATA_FOUND THEN
                             V_VRALIQUOTA := 0;
                       END;
                    END IF;

          /*CALCULA O VALOR DO ICMS DESONERADO*/
          V_VRINFADICNF  := ROUND(C_NF.VRCONTABIL * V_VRALIQUOTA/100,2);
          V_VRINFADICTOT := NVL(V_VRINFADICTOT,0) + V_VRINFADICNF;

          /*QUANDO FOR UMA NOVA NOTA, INSERE OS DADOS DO AJUSTE DA NOTA*/
          IF NVL(V_CDCHAVENOTA,' ') <> C_NF.CDFILIAL||C_NF.NRLANCTONF THEN
             /*INSERE O REGISTRO DE AJUSTE PARA GERAR O C197/D197*/
             V_NRSEQITMAPR := NVL(V_NRSEQITMAPR,0) + 1;
             INSERT INTO ITMAPARECUP
                (NRSEQUMAPAPU, IDTIPOITMAPR, NRSEQITMAPR, DSITEMMAPR, VRITEMMAPR, CDITEMOCOR, DSITEMOCOR,
                 DSFLEGALOCOR, NRLANCTONF, CDFILIAL, CDAJUSTEITMAPA, CDAJUSTEITSEF, CDITPROCEDENCIA,
                 IDCREDPRESUMIDO, IDDIFALMANUAL, IDCARGATRIBUTARIA, IDCOMPOEC197, CDCFOPPADRAO,
                 VROUTROSITMAPR, IDAJUSTEAPURAUTO)
             VALUES
                (P_NRSEQUMAPAPU, 'VI', LPAD(V_NRSEQITMAPR,10,'0'), V_CDBENEE115, 0, '', '',
                 '', C_NF.NRLANCTONF, C_NF.CDFILIAL, V_CDBENEC197, '', '',
                 'N', 'N', 'N', 'I', '',
                 V_VRINFADICNF, 'S');
             V_CDCHAVENOTA := C_NF.CDFILIAL||C_NF.NRLANCTONF;
          /*QUANDO FOR A MESMA NOTA, ATUALIZA OS VALORES DO AJUSTE*/
          ELSE
             UPDATE ITMAPARECUP
                SET VROUTROSITMAPR = NVL(VROUTROSITMAPR,0) + NVL(V_VRINFADICNF,0)
              WHERE NRSEQUMAPAPU = P_NRSEQUMAPAPU
                AND IDTIPOITMAPR = 'VI'
                AND NRSEQITMAPR  = LPAD(V_NRSEQITMAPR,10,'0');
          END IF;

          /*INSERE OS AJUSTES POR ITENS*/
          NOVO_CODIGO('DETITMAPARECUP',V_NRSEQDETITMAPA);
          INSERT INTO DETITMAPARECUP
             (NRSEQDETITMAPA, NRSEQUMAPAPU, IDTIPOITMAPR, NRSEQITMAPR,
              CDFILIAL, NRLANCTONF, NRSEQITPROD, CDIMPOSTO, NRITPROIMPOS,
              VROUTROSIMPIT, VROUTALIQ, VROUTBASE, CDFILIALVND, CDCAIXA,
              NRSEQVENDA, NRSEQUITVEND)
          VALUES
             (TO_NUMBER(V_NRSEQDETITMAPA), P_NRSEQUMAPAPU, 'VI', LPAD(V_NRSEQITMAPR,10,'0'),
              C_NF.CDFILIAL, C_NF.NRLANCTONF, C_NF.NRSEQITPROD, C_NF.CDIMPOSTO, C_NF.NRITPROIMPOS,
              V_VRINFADICNF, V_VRALIQUOTA, C_NF.VRCONTABIL, C_NF.CDFILIALVENDA, C_NF.CDCAIXA,
              C_NF.NRSEQVENDA, C_NF.NRSEQUITVEND);
      END LOOP;
      IF V_VRINFADICTOT > 0 THEN
         /*INSERE O REGISTRO DE DADOS ADICIONAIS*/
         V_NRSEQINFADIC := NVL(V_NRSEQINFADIC,0) + 1;
         INSERT INTO INFADICMAPA
            (NRSEQUMAPAPU, NRSEQINFADIC, IDORIGEMINF, CDINFADICMAPA, DSINFADICMAPA, VRINFADICMAPA)
         VALUES
            (P_NRSEQUMAPAPU, LPAD(V_NRSEQINFADIC,5,'0'), 'B', V_CDBENEE115, V_DSBENEFICIO, V_VRINFADICTOT);
      END IF;
   END IF;

   /*VERIFICA SE EXISTE O CADASTRO PARA GERAÇÃO DO BENEFÍCIO DE REDUÇÃO DA ALÍQUOTA*/
   BEGIN
      SELECT MAX(CDAJUSTENF) AS CDBENEC197, MAX(DSBENEFICIO) AS DSBENEFICIO,
             MAX(CDBENEFICIO) AS CDBENEE115, MAX(VRALIQUOTA) AS VRALIQUOTA,
             MAX(VRALIQRED) AS VRALIQRED, MAX(CDTPOPBENEFICIO) AS CDTIPOOPER
        INTO V_CDBENEC197, V_DSBENEFICIO, V_CDBENEE115, V_VRALIQUOTA, V_VRALIQRED, V_CDTIPOOPER
        FROM TPBENEFICIOFISC
       WHERE CDEMPRESA   = P_CDEMPRESA
         AND CDINSCESTA  = P_CDINSCESTA
         AND IDBENEFICIO = 'RAL';
   EXCEPTION
      WHEN NO_DATA_FOUND THEN
         V_CDBENEC197  := NULL;
         V_DSBENEFICIO := NULL;
         V_CDBENEE115  := NULL;
         V_VRALIQUOTA  := 0;
         V_VRALIQRED   := 0;
         V_CDTIPOOPER  := NULL;
   END;

   IF (V_CDBENEC197 IS NOT NULL) THEN
      V_CDCHAVENOTA  := '';
      V_VRINFADICTOT := 0;
      FOR C_NF IN (SELECT IT.CDFILIAL, IT.NRLANCTONF, IT.NRSEQITPROD,
                          SUM(IT.VRBASECALCIT) AS VRBASECALC, IT.CDIMPOSTO,
                          IT.NRITPROIMPOS
                     FROM ITEMPROIMPOS IT, IMPOSTO IM,
                          (SELECT DISTINCT I.CDFILIAL, I.NRLANCTONF
                             FROM IMPOSTONF I, NOTAFISCAL N
                            WHERE I.NRSEQUMAPAPU = P_NRSEQUMAPAPU
                              AND I.CDFISCALNF   = '1'
                              AND I.VRALIQNF     = V_VRALIQRED
                              AND I.CDFILIAL     = N.CDFILIAL
                              AND I.NRLANCTONF   = N.NRLANCTONF
                              AND ((INSTR(V_CDTIPOOPER, '_' ||N.IDENTRSAIDOP||N.CDTIPOOPER||'_' ) > 0) OR (V_CDTIPOOPER IS NULL))) IP
                    WHERE IT.CDFILIAL     = IP.CDFILIAL
                      AND IT.NRLANCTONF   = IP.NRLANCTONF
                      AND IT.CDIMPOSTO    = IM.CDIMPOSTO
                      AND IM.CDIMPOSTONFE = P_CDIMPOSTO
                      AND IT.CDFISCALIT   = '1'
                      AND IT.VRALIQITEM   = V_VRALIQRED
                      AND IT.NRITPROIMPOS = '1'
                    GROUP BY IT.CDFILIAL, IT.NRLANCTONF, IT.NRSEQITPROD,
                          IT.CDIMPOSTO, IT.NRITPROIMPOS
                    ORDER BY IT.CDFILIAL, IT.NRLANCTONF, IT.NRSEQITPROD) LOOP

          /*CALCULA O VALOR DO ICMS DESONERADO*/
          V_VRINFADICNF  := ROUND(C_NF.VRBASECALC * (V_VRALIQUOTA-V_VRALIQRED)/100,2);
          V_VRINFADICTOT := NVL(V_VRINFADICTOT,0) + V_VRINFADICNF;

          /*QUANDO FOR UMA NOVA NOTA, INSERE OS DADOS DO AJUSTE DA NOTA*/
          IF NVL(V_CDCHAVENOTA,' ') <> C_NF.CDFILIAL||C_NF.NRLANCTONF THEN
             /*INSERE O REGISTRO DE AJUSTE PARA GERAR O C197/D197*/
             V_NRSEQITMAPR := NVL(V_NRSEQITMAPR,0) + 1;
             INSERT INTO ITMAPARECUP
                (NRSEQUMAPAPU, IDTIPOITMAPR, NRSEQITMAPR, DSITEMMAPR, VRITEMMAPR, CDITEMOCOR, DSITEMOCOR,
                 DSFLEGALOCOR, NRLANCTONF, CDFILIAL, CDAJUSTEITMAPA, CDAJUSTEITSEF, CDITPROCEDENCIA,
                 IDCREDPRESUMIDO, IDDIFALMANUAL, IDCARGATRIBUTARIA, IDCOMPOEC197, CDCFOPPADRAO,
                 VROUTROSITMAPR, IDAJUSTEAPURAUTO)
             VALUES
                (P_NRSEQUMAPAPU, 'VI', LPAD(V_NRSEQITMAPR,10,'0'), V_CDBENEE115, 0, '', '',
                 '', C_NF.NRLANCTONF, C_NF.CDFILIAL, V_CDBENEC197, '', '',
                 'N', 'N', 'N', 'I', '',
                 V_VRINFADICNF, 'S');
             V_CDCHAVENOTA := C_NF.CDFILIAL||C_NF.NRLANCTONF;
          /*QUANDO FOR A MESMA NOTA, ATUALIZA OS VALORES DO AJUSTE*/
          ELSE
             UPDATE ITMAPARECUP
                SET VROUTROSITMAPR = NVL(VROUTROSITMAPR,0) + NVL(V_VRINFADICNF,0)
              WHERE NRSEQUMAPAPU = P_NRSEQUMAPAPU
                AND IDTIPOITMAPR = 'VI'
                AND NRSEQITMAPR  = LPAD(V_NRSEQITMAPR,10,'0');
          END IF;

          /*INSERE OS AJUSTES POR ITENS*/
          NOVO_CODIGO('DETITMAPARECUP',V_NRSEQDETITMAPA);
          INSERT INTO DETITMAPARECUP
             (NRSEQDETITMAPA, NRSEQUMAPAPU, IDTIPOITMAPR, NRSEQITMAPR,
              CDFILIAL, NRLANCTONF, NRSEQITPROD, CDIMPOSTO, NRITPROIMPOS,
              VROUTROSIMPIT, VROUTALIQ, VROUTBASE)
          VALUES
             (TO_NUMBER(V_NRSEQDETITMAPA), P_NRSEQUMAPAPU, 'VI', LPAD(V_NRSEQITMAPR,10,'0'),
              C_NF.CDFILIAL, C_NF.NRLANCTONF, C_NF.NRSEQITPROD, C_NF.CDIMPOSTO, C_NF.NRITPROIMPOS,
              V_VRINFADICNF, (V_VRALIQUOTA-V_VRALIQRED), C_NF.VRBASECALC);
      END LOOP;
      IF V_VRINFADICTOT > 0 THEN
         /*INSERE O REGISTRO DE DADOS ADICIONAIS*/
         V_NRSEQINFADIC := NVL(V_NRSEQINFADIC,0) + 1;
         INSERT INTO INFADICMAPA
            (NRSEQUMAPAPU, NRSEQINFADIC, IDORIGEMINF, CDINFADICMAPA, DSINFADICMAPA, VRINFADICMAPA)
         VALUES
            (P_NRSEQUMAPAPU, LPAD(V_NRSEQINFADIC,5,'0'), 'B', V_CDBENEE115, V_DSBENEFICIO, V_VRINFADICTOT);
      END IF;
   END IF;

   /*VERIFICA SE EXISTE O CADASTRO PARA GERAÇÃO DO BENEFÍCIO DE NÃO INCIDÊNCIA*/
   BEGIN
      SELECT MAX(CDAJUSTENF) AS CDBENEC197, MAX(DSBENEFICIO) AS DSBENEFICIO,
             MAX(CDBENEFICIO) AS CDBENEE115, MAX(VRALIQUOTA) AS VRALIQUOTA,
             MAX(CDTPOPBENEFICIO) AS CDTIPOOPER
        INTO V_CDBENEC197, V_DSBENEFICIO, V_CDBENEE115, V_VRALIQUOTA, V_CDTIPOOPER
        FROM TPBENEFICIOFISC
       WHERE CDEMPRESA   = P_CDEMPRESA
         AND CDINSCESTA  = P_CDINSCESTA
         AND IDBENEFICIO = 'NIN';
   EXCEPTION
      WHEN NO_DATA_FOUND THEN
         V_CDBENEC197  := NULL;
         V_DSBENEFICIO := NULL;
         V_CDBENEE115  := NULL;
         V_VRALIQUOTA  := 0;
         V_CDTIPOOPER  := NULL;
   END;

   IF (V_CDBENEC197 IS NOT NULL) THEN
      V_CDCHAVENOTA  := '';
      V_VRINFADICTOT := 0;
      FOR C_NF IN (SELECT IT.CDFILIAL, IT.NRLANCTONF, IT.NRSEQITPROD,
                          SUM(IT.VRCONTITIMP) AS VRCONTABIL, IT.CDIMPOSTO,
                          IT.NRITPROIMPOS
                     FROM ITEMPROIMPOS IT, IMPOSTO IM,
                          (SELECT DISTINCT I.CDFILIAL, I.NRLANCTONF
                             FROM IMPOSTONF I, NOTAFISCAL N
                            WHERE I.NRSEQUMAPAPU = P_NRSEQUMAPAPU
                              AND I.CDFISCALNF   = '3'
                              AND I.CDFILIAL     = N.CDFILIAL
                              AND I.NRLANCTONF   = N.NRLANCTONF
                              AND ((INSTR(V_CDTIPOOPER, '_' ||N.IDENTRSAIDOP||N.CDTIPOOPER||'_' ) > 0) OR (V_CDTIPOOPER IS NULL))) IP
                    WHERE IT.CDFILIAL     = IP.CDFILIAL
                      AND IT.NRLANCTONF   = IP.NRLANCTONF
                      AND IT.CDIMPOSTO    = IM.CDIMPOSTO
                      AND IM.CDIMPOSTONFE = P_CDIMPOSTO
                      AND IT.CDFISCALIT   = '3'
                      AND IT.NRITPROIMPOS = '1'
                    GROUP BY IT.CDFILIAL, IT.NRLANCTONF, IT.NRSEQITPROD,
                          IT.CDIMPOSTO, IT.NRITPROIMPOS
                    ORDER BY IT.CDFILIAL, IT.NRLANCTONF, IT.NRSEQITPROD) LOOP

          /*CALCULA O VALOR DO ICMS DESONERADO*/
          V_VRINFADICNF  := ROUND(C_NF.VRCONTABIL * V_VRALIQUOTA/100,2);
          V_VRINFADICTOT := NVL(V_VRINFADICTOT,0) + V_VRINFADICNF;

          /*QUANDO FOR UMA NOVA NOTA, INSERE OS DADOS DO AJUSTE DA NOTA*/
          IF NVL(V_CDCHAVENOTA,' ') <> C_NF.CDFILIAL||C_NF.NRLANCTONF THEN
             /*INSERE O REGISTRO DE AJUSTE PARA GERAR O C197/D197*/
             V_NRSEQITMAPR := NVL(V_NRSEQITMAPR,0) + 1;
             INSERT INTO ITMAPARECUP
                (NRSEQUMAPAPU, IDTIPOITMAPR, NRSEQITMAPR, DSITEMMAPR, VRITEMMAPR, CDITEMOCOR, DSITEMOCOR,
                 DSFLEGALOCOR, NRLANCTONF, CDFILIAL, CDAJUSTEITMAPA, CDAJUSTEITSEF, CDITPROCEDENCIA,
                 IDCREDPRESUMIDO, IDDIFALMANUAL, IDCARGATRIBUTARIA, IDCOMPOEC197, CDCFOPPADRAO,
                 VROUTROSITMAPR, IDAJUSTEAPURAUTO)
             VALUES
                (P_NRSEQUMAPAPU, 'VI', LPAD(V_NRSEQITMAPR,10,'0'), V_CDBENEE115, 0, '', '',
                 '', C_NF.NRLANCTONF, C_NF.CDFILIAL, V_CDBENEC197, '', '',
                 'N', 'N', 'N', 'I', '',
                 V_VRINFADICNF, 'S');
             V_CDCHAVENOTA := C_NF.CDFILIAL||C_NF.NRLANCTONF;
          /*QUANDO FOR A MESMA NOTA, ATUALIZA OS VALORES DO AJUSTE*/
          ELSE
             UPDATE ITMAPARECUP
                SET VROUTROSITMAPR = NVL(VROUTROSITMAPR,0) + NVL(V_VRINFADICNF,0)
              WHERE NRSEQUMAPAPU = P_NRSEQUMAPAPU
                AND IDTIPOITMAPR = 'VI'
                AND NRSEQITMAPR  = LPAD(V_NRSEQITMAPR,10,'0');
          END IF;

          /*INSERE OS AJUSTES POR ITENS*/
          NOVO_CODIGO('DETITMAPARECUP',V_NRSEQDETITMAPA);
          INSERT INTO DETITMAPARECUP
             (NRSEQDETITMAPA, NRSEQUMAPAPU, IDTIPOITMAPR, NRSEQITMAPR,
              CDFILIAL, NRLANCTONF, NRSEQITPROD, CDIMPOSTO, NRITPROIMPOS,
              VROUTROSIMPIT, VROUTALIQ, VROUTBASE)
          VALUES
             (TO_NUMBER(V_NRSEQDETITMAPA), P_NRSEQUMAPAPU, 'VI', LPAD(V_NRSEQITMAPR,10,'0'),
              C_NF.CDFILIAL, C_NF.NRLANCTONF, C_NF.NRSEQITPROD, C_NF.CDIMPOSTO, C_NF.NRITPROIMPOS,
              V_VRINFADICNF, V_VRALIQUOTA, C_NF.VRCONTABIL);
      END LOOP;
      IF V_VRINFADICTOT > 0 THEN
         /*INSERE O REGISTRO DE DADOS ADICIONAIS*/
         V_NRSEQINFADIC := NVL(V_NRSEQINFADIC,0) + 1;
         INSERT INTO INFADICMAPA
            (NRSEQUMAPAPU, NRSEQINFADIC, IDORIGEMINF, CDINFADICMAPA, DSINFADICMAPA, VRINFADICMAPA)
         VALUES
            (P_NRSEQUMAPAPU, LPAD(V_NRSEQINFADIC,5,'0'), 'B', V_CDBENEE115, V_DSBENEFICIO, V_VRINFADICTOT);
      END IF;
   END IF;
END;
/

CREATE OR REPLACE PROCEDURE CALC_ESTORNO_FAT(
   P_NRSEQUMAPAPU    IN MAPAAPURAC.NRSEQUMAPAPU%TYPE,
   P_CDEMPRESA       IN MAPAAPURAC.CDEMPRESA%TYPE,
   P_CDIMPOSTO       IN MAPAAPURAC.CDIMPOSTO%TYPE,
   P_INSCRICAO       IN MAPAAPURAC.CDINSCESTA%TYPE)
AS
   V_CDTPOPERESTAPUR   VARCHAR2(500);
   V_CDCFOPESTAPUR     VARCHAR2(500);
   V_VRALIQEFETIVA     FLOAT(126);
   V_VRALIQINTERNA     FLOAT(126);
   V_CDAJUSTESTAPUR    VARCHAR2(20);
   V_DSESTORNODEBAPU   VARCHAR2(250);
   V_VRESTORNO         NUMBER;
   V_VRTOTALSAIDA      NUMBER;
   V_VRNORMDEBI        NUMBER;
   V_VRPERREDBC        NUMBER;
   V_VRBCEFETIVA       NUMBER;
   V_NRSEQITMAPR       NUMBER;
BEGIN
   V_VRESTORNO := 0;

   /******** Busca a parametrização para a geração do estorno da inscrição estadual do mapa ********/
   BEGIN
      SELECT CDTPOPERESTAPUR, CDCFOPESTAPUR, VRALIQEFETIVA,
             VRALIQINTERNA, CDAJUSTESTAPUR, DSESTORNODEBAPU
        INTO V_CDTPOPERESTAPUR, V_CDCFOPESTAPUR, V_VRALIQEFETIVA,
             V_VRALIQINTERNA, V_CDAJUSTESTAPUR, V_DSESTORNODEBAPU
        FROM INSCRESTAD
       WHERE CDEMPRESA    = P_CDEMPRESA
         AND CDINSCESTA   = P_INSCRICAO;
   EXCEPTION
      WHEN NO_DATA_FOUND THEN
         V_CDTPOPERESTAPUR := NULL;
         V_CDCFOPESTAPUR   := NULL;
         V_VRALIQEFETIVA   := 0;
         V_VRALIQINTERNA   := 0;
         V_CDAJUSTESTAPUR  := NULL;
         V_DSESTORNODEBAPU := NULL;
   END;

   /******** Calcula o valor do Estorno que deve ser gerado na apuração ********/
   BEGIN
      SELECT NVL(SUM(ROUND(I.VRCONTABILNF,2)),0.0) AS VRTOTALSAIDA,
             NVL(SUM(ROUND(DECODE(I.CDFISCALNF,'1',I.VRIMPOSTONF,0),2)),0.0) AS VRNORMDEBI
        INTO V_VRTOTALSAIDA, V_VRNORMDEBI
        FROM IMPOSTONF I, NOTAFISCAL N, IMPOSTO IM
       WHERE I.NRSEQUMAPAPU  = P_NRSEQUMAPAPU
         AND I.CDFILIAL      = N.CDFILIAL
         AND I.NRLANCTONF    = N.NRLANCTONF
         AND I.IDIMPOSTONF   <> '3'
         AND N.IDENTRSAIDOP  = 'S'
         AND I.CDIMPOSTO     = IM.CDIMPOSTO
         AND IM.CDIMPOSTONFE = P_CDIMPOSTO
         AND ((INSTR(V_CDTPOPERESTAPUR, '_' ||N.IDENTRSAIDOP||N.CDTIPOOPER||'_' ) > 0) OR (V_CDTPOPERESTAPUR IS NULL))
         AND ((INSTR(V_CDCFOPESTAPUR, '_' ||I.CDFISCOPERNF||'_') > 0) OR (V_CDCFOPESTAPUR IS NULL));
   EXCEPTION
      WHEN NO_DATA_FOUND THEN
         V_VRTOTALSAIDA := 0;
         V_VRNORMDEBI   := 0;
   END;

   /*Calcula o Percentual de Redução da Base de Cálculo, para obter o imposto efetivo*/
   V_VRPERREDBC  := ROUND(100 - (V_VRALIQEFETIVA * 100 / V_VRALIQINTERNA),2);
   /*Calcula o valor da base de cálculo efetiva, após abater o percentual de redução do faturamento*/
   V_VRBCEFETIVA := V_VRTOTALSAIDA - ROUND(V_VRTOTALSAIDA * V_VRPERREDBC / 100,2);
   /*Calcula o valor do ICMS efetivamente devido*/
   V_VRESTORNO := ROUND(V_VRBCEFETIVA * V_VRALIQINTERNA / 100,2);
   /*O valor do estorno será a diferença entre o valor do débito nas notas fiscais e o débito apurado*/
   V_VRESTORNO  := ROUND(NVL(V_VRNORMDEBI,0) - NVL(V_VRESTORNO,0),2);

   /******** Deleta o item de estorno de débitos gerado pela rotina, evitando erro na reapuração de mapas ********/
   DELETE FROM ITMAPARECUP
    WHERE NRSEQUMAPAPU  = P_NRSEQUMAPAPU
      AND IDTIPOITMAPR  = 'ED'
      AND IDESTORNOAPUR = 'S';

   /******** Verifica se deve ser gerado o item de estorno de débito ********/
   IF V_VRESTORNO > 0 THEN
      /******** Busca o maior sequencial de Estorno de Débitos ********/
      BEGIN
         SELECT NVL(MAX(NRSEQITMAPR),0) AS NRSEQITMAPR
           INTO V_NRSEQITMAPR
           FROM ITMAPARECUP
          WHERE NRSEQUMAPAPU = P_NRSEQUMAPAPU
            AND IDTIPOITMAPR = 'ED';
      EXCEPTION
         WHEN NO_DATA_FOUND THEN
            V_NRSEQITMAPR := NULL;
      END;

      V_NRSEQITMAPR := NVL(V_NRSEQITMAPR,0)+1;

      /******** Insere o item de estorno de débito com o valor calculado ********/
      INSERT INTO ITMAPARECUP
         (NRSEQUMAPAPU, IDTIPOITMAPR, NRSEQITMAPR, DSITEMMAPR, VRITEMMAPR, CDITEMOCOR, DSITEMOCOR,
          DSFLEGALOCOR, NRLANCTONF, CDFILIAL, CDAJUSTEITMAPA, IDESTORNOAPUR)
      VALUES
         (P_NRSEQUMAPAPU, 'ED', LPAD(V_NRSEQITMAPR,10,'0'), V_DSESTORNODEBAPU, V_VRESTORNO, '', '',
          '', '', '', V_CDAJUSTESTAPUR, 'S');
   END IF;
END;
/

CREATE OR REPLACE PROCEDURE APURA_IMPOSTOS_GERAIS( 
   P_CDIMPOSTO    IN  MAPAAPURAC.CDIMPOSTO%TYPE,
   P_CDEMPRESA    IN  MAPAAPURAC.CDEMPRESA%TYPE,
   P_CDINSCRICAO  IN  MAPAAPURAC.CDINSCESTA%TYPE,
   P_NRSEQUMAPAPU IN  MAPAAPURAC.NRSEQUMAPAPU%TYPE,
   P_DTINICIAL    IN  MAPAAPURAC.DTINIPERIODO%TYPE,
   P_DTFINAL      IN  MAPAAPURAC.DTFIMPERIODO%TYPE,
   P_BOBLOQ       IN  MAPAAPURAC.IDBLOQMAPAPU%TYPE,
   P_RETORNO      OUT VARCHAR2)
AS
   V_VERIFFORMULA    VARCHAR2(15);
   V_NFFORAPERIODO   VARCHAR2(50);
   V_VRIMPOSAID      NUMBER;
   V_VROUTRDEBI      NUMBER;
   V_VRESTOCRED      NUMBER;
   V_VRTOTADEBI      NUMBER;
   V_VRIMPOENTR      NUMBER;
   V_VROUTRCRED      NUMBER;
   V_VRESTODEBI      NUMBER;
   V_VRTOTACRED      NUMBER;
   V_VRSALDOCREDANT  NUMBER;
   V_VRDEDUCAO       NUMBER;
   V_VRSALDOCRED     NUMBER;
   V_VRSALDODEBI     NUMBER;
   V_VRDIFALIQU      NUMBER;
   V_BOBLOQ          BOOLEAN;
   V_NOTASMAPA       NUMBER;
   V_CDAJUSTEITMAPA  VARCHAR2(10);
   V_CDITPROCEDENCIA VARCHAR2(10);
   V_CDAJUSTEITSEF   VARCHAR2(03);
   V_VRALIQIMPOSREC  NUMBER;
   V_IDAPURCREDPRES  VARCHAR2(01);
   V_SGESTADO        VARCHAR2(02);
   V_IDREALIESTAPUR  VARCHAR2(01);
BEGIN
   IF P_BOBLOQ = 'S' THEN
      V_BOBLOQ := TRUE;
   ELSE
      V_BOBLOQ := FALSE;
   END IF;
   /******** Verifica se o imposto utiliza fórmula de apuração e se a parametrização está correta ********/
   V_VERIFFORMULA := VERIFICA_FORMULA(P_CDIMPOSTO, P_CDEMPRESA, P_CDINSCRICAO, P_NRSEQUMAPAPU);
   IF (V_VERIFFORMULA = 'N_FORMULA') OR (V_VERIFFORMULA = 'DIVIDE_ZERO') OR (V_VERIFFORMULA = 'VER_FORMULA') THEN
      P_RETORNO := V_VERIFFORMULA;
   ELSE
      /******** Atualiza o status do Mapa ********/
      UPDATE MAPAAPURAC
         SET IDBLOQMAPAPU = 'A'
       WHERE NRSEQUMAPAPU = P_NRSEQUMAPAPU;
      /******** Verifica se o mapa já havia sido apurado anteriormente (Se o mesmo já possuia notas) ********/
      BEGIN
         SELECT COUNT(*)
           INTO V_NOTASMAPA
           FROM IMPOSTONF
          WHERE (NRSEQUMAPAPU = P_NRSEQUMAPAPU OR
                 NRSEQMAPOIMP = P_NRSEQUMAPAPU);
      EXCEPTION
         WHEN NO_DATA_FOUND THEN
            V_NOTASMAPA := 0;
      END;
      V_NOTASMAPA := NVL(V_NOTASMAPA,0);
      /******** Deleta os itens necessários para uma reapuração do Mapa ********/
      DELETA_MAPA(P_NRSEQUMAPAPU, P_BOBLOQ);
      /*Verifica se a inscrição apura crédito presumido pelo valor total do imposto a recolher e qual o estado da inscrição,
        para saber se precisa gerar rotina específica do estado*/
      BEGIN
         SELECT VRALIQIMPOSREC, IDAPURLUCPRE, SGESTADO, IDREALIESTAPUR
           INTO V_VRALIQIMPOSREC, V_IDAPURCREDPRES, V_SGESTADO, V_IDREALIESTAPUR
           FROM INSCRESTAD
          WHERE CDEMPRESA    = P_CDEMPRESA
            AND CDINSCESTA   = P_CDINSCRICAO;
      EXCEPTION
         WHEN NO_DATA_FOUND THEN
            V_VRALIQIMPOSREC := 0;
            V_IDAPURCREDPRES := 'N';
            V_SGESTADO       := '';
            V_IDREALIESTAPUR := 'N';
      END;
      /*Nesse caso é necessário apagar o item de outros créditos que pode ter sido gerado pela rotina de crédito presumido*/
      IF V_VRALIQIMPOSREC > 0 THEN
         /******** Salva os códigos de ajuste do item gerado pela rotina de crédito presumido, no caso de reapuração de mapas ********/
         BEGIN
            SELECT MAX(CDAJUSTEITMAPA)  AS CDAJUSTEITMAPA,
                   MAX(CDITPROCEDENCIA) AS CDITPROCEDENCIA,
                   MAX(CDAJUSTEITSEF)   AS CDAJUSTEITSEF
              INTO V_CDAJUSTEITMAPA, V_CDITPROCEDENCIA, V_CDAJUSTEITSEF
              FROM ITMAPARECUP
             WHERE IDCREDPRESUMIDO = 'S'
               AND NRSEQUMAPAPU    = P_NRSEQUMAPAPU
               AND IDTIPOITMAPR    = 'OC';
         EXCEPTION
            WHEN NO_DATA_FOUND THEN
               V_CDAJUSTEITMAPA  := NULL;
               V_CDITPROCEDENCIA := NULL;
               V_CDAJUSTEITSEF   := NULL;
         END;
         /******** Deleta o item de outros créditos gerado pela rotina de crédito presumido, evitando erro na reapuração de mapas ********/
         DELETE FROM ITMAPARECUP
          WHERE NRSEQUMAPAPU    = P_NRSEQUMAPAPU
            AND IDTIPOITMAPR    = 'OC'
            AND IDCREDPRESUMIDO = 'S';
      END IF;
      /******** Grava as informações referentes às parcelas no ativo permanente ********/
      GRAVA_PARCELA(P_CDEMPRESA, P_CDINSCRICAO, P_DTINICIAL, P_DTFINAL, P_NRSEQUMAPAPU, P_CDIMPOSTO);
      /******** Atualiza os valores do mapa e as notas pertencentes ao mesmo ********/
      V_NFFORAPERIODO := SOMA_IMPOSTO(P_CDEMPRESA, P_CDIMPOSTO, P_NRSEQUMAPAPU, P_CDINSCRICAO, P_DTFINAL, P_DTINICIAL, V_NOTASMAPA);
      /******** Crédito de Antecipação do ICMS do Arroz ********/
      ANTECIPACAO_ICMS_ARROZ(P_NRSEQUMAPAPU);
      /******** Estorno de Crédito ICMS Diferido ********/
      CALCULA_ESTORNO_CREDITO(P_CDEMPRESA,P_CDINSCRICAO,P_DTINICIAL,P_DTFINAL,P_NRSEQUMAPAPU);
      /******** Calcula o Diferencial de Alíquota ********/
      CALC_DIFE_ALIQ(P_NRSEQUMAPAPU, P_CDEMPRESA, P_CDIMPOSTO, P_CDINSCRICAO, P_DTINICIAL, P_DTFINAL);
      /******** Calcula o Diferencial de Alíquota e o Fundo de Combate a Pobreza nas operações para Não Contribuinte*/
      IF P_CDIMPOSTO = '00' THEN
         CALC_DIFAL_FCP_NC(P_NRSEQUMAPAPU, P_CDEMPRESA, P_CDINSCRICAO);
         /*Estorno na Apuração*/
         IF V_IDREALIESTAPUR = 'S' THEN
            CALC_ESTORNO_FAT(P_NRSEQUMAPAPU, P_CDEMPRESA, P_CDIMPOSTO, P_CDINSCRICAO);
         END IF;
      END IF;
      /******** Atualiza os Valores da Apuração ********/
      /******** Busca os valores da ITMAPARECUP para atualizar a tabela MAPARECUP ********/
      BEGIN
         SELECT NVL(SUM(DECODE(IDTIPOITMAPR,'OD',VRITEMMAPR,0)),0) AS VROUTRDEBI,
                NVL(SUM(DECODE(IDTIPOITMAPR,'EC',VRITEMMAPR,0)),0) AS VRESTOCRED,
                NVL(SUM(DECODE(IDTIPOITMAPR,'OC',VRITEMMAPR,0)),0) AS VROUTRCRED,
                NVL(SUM(DECODE(IDTIPOITMAPR,'ED',VRITEMMAPR,0)),0) AS VRESTODEBI,
                NVL(SUM(DECODE(IDTIPOITMAPR,'DD',VRITEMMAPR,0)),0) AS VRDEDUCAO,
                NVL(SUM(DECODE(IDTIPOITMAPR,'DA',VRITEMMAPR,0)),0) AS VRDIFALIQU
           INTO V_VROUTRDEBI, V_VRESTOCRED, V_VROUTRCRED,
                V_VRESTODEBI, V_VRDEDUCAO,  V_VRDIFALIQU
           FROM ITMAPARECUP
          WHERE NRSEQUMAPAPU = P_NRSEQUMAPAPU;
      EXCEPTION
         WHEN NO_DATA_FOUND THEN
             V_VROUTRDEBI := 0;
             V_VRESTOCRED := 0;
             V_VROUTRCRED := 0;
             V_VRESTODEBI := 0;
             V_VRDEDUCAO  := 0;
             V_VRDIFALIQU := 0;
      END;
      /******** Busca os valores da MAPAAPURAC para atualizar os totalizadores ********/
      BEGIN
         SELECT NVL(VRNORMDEBI,0), NVL(VRNORMCRED,0), NVL(MR.VRSLDCRANTE, 0)
           INTO V_VRIMPOSAID, V_VRIMPOENTR, V_VRSALDOCREDANT
           FROM MAPARECUP MR
          WHERE MR.NRSEQUMAPAPU = P_NRSEQUMAPAPU;
      EXCEPTION
         WHEN NO_DATA_FOUND THEN
            V_VRIMPOSAID     := 0;
            V_VRIMPOENTR     := 0;
            V_VRSALDOCREDANT := 0;
      END;
      /******** Calcula os valores: Total Débitos, Total Créditos, Saldo Credor e Saldo Devedor  ********/
      V_VRTOTADEBI  := NVL(V_VRIMPOSAID,0) +  NVL(V_VROUTRDEBI,0) + NVL(V_VRESTOCRED,0);
      V_VRTOTACRED  := NVL(V_VRIMPOENTR,0) +  NVL(V_VROUTRCRED,0) + NVL(V_VRESTODEBI,0);
      V_VRSALDODEBI := NVL(V_VRTOTADEBI,0) - (NVL(V_VRTOTACRED,0) + NVL(V_VRSALDOCREDANT,0) + NVL(V_VRDEDUCAO,0));
      IF V_VRSALDODEBI < 0 THEN
         V_VRSALDOCRED := ABS(V_VRSALDODEBI);
         V_VRSALDODEBI := 0;
      ELSE
         V_VRSALDOCRED := 0;
      END IF;
      /***** Atualiza a tabela MAPARECUP *****/
      UPDATE MAPARECUP
         SET VROUTRDEBI   = V_VROUTRDEBI,
             VRESTOCRED   = V_VRESTOCRED,
             VRTOTADEBI   = V_VRTOTADEBI,
             VROUTRCRED   = V_VROUTRCRED,
             VRESTODEBI   = V_VRESTODEBI,
             VRTOTACRED   = V_VRTOTACRED,
             VRDEDUCAO    = V_VRDEDUCAO,
             VRDIFALIQU   = V_VRDIFALIQU,
             VRSALDOCRED  = V_VRSALDOCRED,
             VRSALDODEBI  = V_VRSALDODEBI
       WHERE NRSEQUMAPAPU = P_NRSEQUMAPAPU;
      /***** Atualiza a tabela MAPAAPURAC *****/
      UPDATE MAPAAPURAC
         SET VRTOTAIMPOS  = V_VRSALDODEBI,
             VRRECEGUIA   = DECODE(IDVRRECEGUIAMANUAL,'N',V_VRSALDODEBI,VRRECEGUIA),
             VRMULTAGUIA  = NVL(VRMULTAGUIA,0),
             VRJUROGUIA   = NVL(VRJUROGUIA,0),
             VRTOTAGUIA   = NVL(VRRECEGUIA,0) + NVL(VRMULTAGUIA,0) + NVL(VRJUROGUIA,0)
       WHERE NRSEQUMAPAPU = P_NRSEQUMAPAPU;
      /******** Crédito Presumido ********/
      IF V_IDAPURCREDPRES = 'S' AND P_CDIMPOSTO = '00' THEN
         CALC_CRED_PRESUMIDO(P_NRSEQUMAPAPU, P_CDEMPRESA, P_CDIMPOSTO, P_CDINSCRICAO, V_CDAJUSTEITMAPA, V_CDITPROCEDENCIA, V_CDAJUSTEITSEF);
         /******** Atualiza os Valores da Apuração após o cálculo do crédito presumido********/
         /******** Busca os valores da ITMAPARECUP para atualizar a tabela MAPARECUP ********/
         BEGIN
            SELECT NVL(SUM(DECODE(IDTIPOITMAPR,'OC',VRITEMMAPR,0)),0) AS VROUTRCRED
              INTO V_VROUTRCRED
              FROM ITMAPARECUP
             WHERE NRSEQUMAPAPU = P_NRSEQUMAPAPU;
         EXCEPTION
            WHEN NO_DATA_FOUND THEN
                V_VROUTRCRED := 0;
         END;
         /******** Busca os valores da MAPAAPURAC para atualizar os totalizadores ********/
         BEGIN
            SELECT NVL(VRNORMDEBI,0)
              INTO V_VRIMPOSAID
              FROM MAPARECUP MR
             WHERE MR.NRSEQUMAPAPU = P_NRSEQUMAPAPU;
         EXCEPTION
            WHEN NO_DATA_FOUND THEN
               V_VRIMPOSAID := 0;
         END;
         /******** Calcula os valores: Total Débitos, Total Créditos, Saldo Credor e Saldo Devedor  ********/
         V_VRTOTADEBI  := NVL(V_VRIMPOSAID,0) +  NVL(V_VROUTRDEBI,0) + NVL(V_VRESTOCRED,0);
         V_VRTOTACRED  := NVL(V_VRIMPOENTR,0) +  NVL(V_VROUTRCRED,0) + NVL(V_VRESTODEBI,0);
         V_VRSALDODEBI := NVL(V_VRTOTADEBI,0) - (NVL(V_VRTOTACRED,0) + NVL(V_VRSALDOCREDANT,0) + NVL(V_VRDEDUCAO,0));
         IF V_VRSALDODEBI < 0 THEN
            V_VRSALDOCRED := ABS(V_VRSALDODEBI);
            V_VRSALDODEBI := 0;
         ELSE
            V_VRSALDOCRED := 0;
         END IF;
         /***** Atualiza a tabela MAPARECUP *****/
         UPDATE MAPARECUP
            SET VROUTRCRED   = V_VROUTRCRED,
                VRTOTACRED   = V_VRTOTACRED,
                VRSALDOCRED  = V_VRSALDOCRED,
                VRSALDODEBI  = V_VRSALDODEBI
          WHERE NRSEQUMAPAPU = P_NRSEQUMAPAPU;
         /***** Atualiza a tabela MAPAAPURAC *****/
         UPDATE MAPAAPURAC
            SET VRTOTAIMPOS  = V_VRSALDODEBI,
                VRRECEGUIA   = DECODE(IDVRRECEGUIAMANUAL,'N',V_VRSALDODEBI,VRRECEGUIA),
                VRMULTAGUIA  = NVL(VRMULTAGUIA,0),
                VRJUROGUIA   = NVL(VRJUROGUIA,0),
                VRTOTAGUIA   = NVL(VRRECEGUIA,0) + NVL(VRMULTAGUIA,0) + NVL(VRJUROGUIA,0)
          WHERE NRSEQUMAPAPU = P_NRSEQUMAPAPU;
      END IF;
      /*Gera os ajustes de valor informativo necessários no SPED para o Estado de SP, de acordo com a Portaria CAT nº66*/
      IF (V_SGESTADO = 'SP') AND (P_CDIMPOSTO = '00') THEN
         GERA_AJUSTE_DOC_SP(P_NRSEQUMAPAPU,P_CDEMPRESA,P_CDINSCRICAO);
      END IF;
      /*Gera as informações adicionais referente aos benefícios fiscais*/
      IF (V_SGESTADO <> 'SP') AND (P_CDIMPOSTO = '00') THEN
         GERA_INFADIC_BENEFICIO(P_NRSEQUMAPAPU,P_CDIMPOSTO,P_CDEMPRESA,P_CDINSCRICAO);
      END IF;
      P_RETORNO := 'OK'||V_NFFORAPERIODO;
      /******** Aplica a Fórmula de Apuração, no caso de a mesma estar corretamente parametrizada ********/
      IF V_VERIFFORMULA = 'USA_FORMULA' THEN
         V_VERIFFORMULA := UTILIZA_FORMULA(P_CDIMPOSTO, P_CDEMPRESA, P_CDINSCRICAO, P_NRSEQUMAPAPU);
         IF (V_VERIFFORMULA = 'N_FORMULA') OR (V_VERIFFORMULA = 'DIVIDE_ZERO') OR (V_VERIFFORMULA = 'VER_FORMULA') THEN
            P_RETORNO := V_VERIFFORMULA;
         END IF;
      END IF;
   END IF;
   COMMIT;
EXCEPTION
   WHEN OTHERS THEN
      ROLLBACK;
      RAISE;
END;