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_VRDEBESP        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);
   V_VRESTODEBICP    NUMBER;
   V_VRINFORMATIVO   NUMBER;
BEGIN
   IF P_BOBLOQ = 'S' THEN
      V_BOBLOQ := TRUE;
   ELSE
      V_BOBLOQ := FALSE;
   END IF;

   /******** Verifica se o imposto utiliza formula de apuracao e se a parametrizacao esta 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 ja havia sido apurado anteriormente (Se o mesmo ja 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 necessarios para uma reapuracao do Mapa ********/
      DELETA_MAPA(P_NRSEQUMAPAPU, P_BOBLOQ);

      /*Verifica se a inscricao apura credito presumido pelo valor total do imposto a recolher e qual o estado da inscricao,
        para saber se precisa gerar rotina especifica 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 e necessario apagar o item de outros creditos que pode ter sido gerado pela rotina de credito presumido*/
      IF V_VRALIQIMPOSREC > 0 THEN
         /******** Salva os codigos de ajuste do item gerado pela rotina de credito presumido, no caso de reapuracao 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 os itens de outros creditos e estorno de debito gerados pela rotina de credito presumido, evitando erro na reapuracao de mapas ********/
         DELETE FROM ITMAPARECUP
          WHERE NRSEQUMAPAPU    = P_NRSEQUMAPAPU
            AND IDTIPOITMAPR    IN ('OC','ED')
            AND IDCREDPRESUMIDO = 'S';
      END IF;

      /******** Grava as informacoes referentes as 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);

      /******** Credito de Antecipacao do ICMS do Arroz ********/
      ANTECIPACAO_ICMS_ARROZ(P_NRSEQUMAPAPU);

      /******** Estorno de Credito ICMS Diferido ********/
      CALCULA_ESTORNO_CREDITO(P_CDEMPRESA,P_CDINSCRICAO,P_DTINICIAL,P_DTFINAL,P_NRSEQUMAPAPU);

      /******** Calcula o Diferencial de Aliquota ********/
      CALC_DIFE_ALIQ(P_NRSEQUMAPAPU, P_CDEMPRESA, P_CDIMPOSTO, P_CDINSCRICAO, P_DTINICIAL, P_DTFINAL);

      /******** Busca os valores de FECP ********/
      GERA_AJUSTE_FECP(P_NRSEQUMAPAPU, P_CDEMPRESA, P_CDINSCRICAO, P_CDIMPOSTO);

      /******** Busca os valores de CIAP ********/
      INSERE_AJUSTE_CIAP(P_CDEMPRESA,P_CDINSCRICAO,P_DTINICIAL,P_DTFINAL,P_NRSEQUMAPAPU,P_CDIMPOSTO);

      /******** Calcula o Diferencial de Aliquota e o Fundo de Combate a Pobreza nas operacoes para Nao Contribuinte*/
      IF P_CDIMPOSTO = '00' THEN
         CALC_DIFAL_FCP_NC(P_NRSEQUMAPAPU, P_CDEMPRESA, P_CDINSCRICAO);

         /*Estorno na Apuracao*/
         IF V_IDREALIESTAPUR = 'S' THEN
            CALC_ESTORNO_FAT(P_NRSEQUMAPAPU, P_CDEMPRESA, P_CDIMPOSTO, P_CDINSCRICAO);
         END IF;
      END IF;

      /******** Atualiza os Valores da Apuracao ********/
      /******** 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,
                NVL(SUM(DECODE(IDTIPOITMAPR,'DE',VRITEMMAPR,0)),0) AS VRDEBESP
           INTO V_VROUTRDEBI, V_VRESTOCRED, V_VROUTRCRED,
                V_VRESTODEBI, V_VRDEDUCAO,  V_VRDIFALIQU, V_VRDEBESP
           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;
             V_VRDEBESP   := 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 Debitos, Total Creditos, 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,
             VRDEBESPECIAL = V_VRDEBESP
       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;

      /******** Credito 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 Apuracao apos o calculo do credito presumido********/
         /******** Busca os valores da ITMAPARECUP para atualizar a tabela MAPARECUP ********/
         BEGIN
            SELECT NVL(SUM(DECODE(IDTIPOITMAPR,'OC',VRITEMMAPR,0)),0) AS VROUTRCRED,
                   NVL(SUM(DECODE(IDTIPOITMAPR,'ED',DECODE(IDESTSUBAPUR,'N',VRITEMMAPR,0),0)),0) AS VRESTDEB,
                   NVL(SUM(DECODE(IDTIPOITMAPR,'ED',DECODE(IDESTSUBAPUR,'S',VRITEMMAPR,0),0)),0) AS VRESTDEBCP
              INTO V_VROUTRCRED, V_VRESTODEBI, V_VRESTODEBICP
              FROM ITMAPARECUP
             WHERE NRSEQUMAPAPU = P_NRSEQUMAPAPU;
         EXCEPTION
            WHEN NO_DATA_FOUND THEN
               V_VROUTRCRED   := 0;
               V_VRESTODEBI   := 0;
               V_VRESTODEBICP := 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 Debitos, Total Creditos, 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,
                VRESTODEBI   = NVL(V_VRESTODEBI,0) + NVL(V_VRESTODEBICP,0),
                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 necessarios no SPED para o Estado de SP, de acordo com a Portaria CAT n66*/
      IF (V_SGESTADO = 'SP') AND (P_CDIMPOSTO = '00') THEN
         GERA_AJUSTE_DOC_SP(P_NRSEQUMAPAPU,P_CDEMPRESA,P_CDINSCRICAO);
      END IF;

      /*Gera as informacoes adicionais referente aos beneficios fiscais*/
      IF (V_SGESTADO <> 'SP') AND (P_CDIMPOSTO = '00') THEN
         GERA_INFADIC_BENEFICIO(P_NRSEQUMAPAPU,P_CDIMPOSTO,P_CDEMPRESA,P_CDINSCRICAO);
      END IF;

      /*Gera as informacoes adicionais referente ao credito de ressarcimento de ICMS ST no estado do Rio Grande do Sul*/
      IF (P_CDIMPOSTO = '00') THEN
         GERA_CREDITO_RESSARC_ST(P_NRSEQUMAPAPU,P_CDEMPRESA,P_CDINSCRICAO);
      END IF;

      /******** Busca os valores da ITMAPARECUP para atualizar a tabela MAPARECUP ********/
      BEGIN
         SELECT NVL(SUM(DECODE(IDTIPOITMAPR,'VI',VRITEMMAPR,0)),0) AS VRINFORMATIVO
           INTO V_VRINFORMATIVO
           FROM ITMAPARECUP
          WHERE NRSEQUMAPAPU = P_NRSEQUMAPAPU;
      EXCEPTION
         WHEN NO_DATA_FOUND THEN
             V_VRINFORMATIVO := 0;
      END;

      /***** Atualiza a tabela MAPARECUP *****/
      UPDATE MAPARECUP
         SET VRINFORMATIVO = NVL(V_VRINFORMATIVO,0)
       WHERE NRSEQUMAPAPU  = P_NRSEQUMAPAPU;

      P_RETORNO := 'OK'||V_NFFORAPERIODO;

      /******** Aplica a Formula de Apuracao, 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;
/