DROP TABLE TMP_REGDADOSGIASP
/

CREATE GLOBAL TEMPORARY TABLE TMP_REGDADOSGIASP
(
   CDFILIAL        VARCHAR2(04)    NOT NULL,
   NRLANCTONF      VARCHAR2(10)    NOT NULL,
   CDFISCOPERNF    VARCHAR2(06)    NULL,
   VRCONTABILNF    FLOAT           NULL,
   VRBASECALCNF    FLOAT           NULL,
   VRIMPOSTONF     FLOAT           NULL,
   VRISENTO        FLOAT           NULL,
   VROUTROS        FLOAT           NULL,
   VRIMPRETST      FLOAT           NULL,
   VRSUBSTITUTO    FLOAT           NULL,
   VRSUBSTITUIDO   FLOAT           NULL,
   VROUTROSIMP     FLOAT           NULL,
   CONSTRAINT PK_TMP_REGDADOSGIASP PRIMARY KEY(CDFILIAL, NRLANCTONF, CDFISCOPERNF)) ON COMMIT PRESERVE ROWS
/

DROP TABLE TMP_REGDADOSGIASP_AUX
/

CREATE TABLE TMP_REGDADOSGIASP_AUX AS (SELECT * FROM TMP_REGDADOSGIASP)
/

CREATE OR REPLACE PROCEDURE GERA_DADOS_GIA_SP(
   P_NRSEQUMAPAPU   IN MAPAAPURAC.NRSEQUMAPAPU%TYPE)
AS
   V_VRCONTABILNF    IMPOSTONF.VRCONTABILNF%TYPE;
   V_VRBASECALCNF    IMPOSTONF.VRBASECALCNF%TYPE;
   V_VRIMPOSTONF     IMPOSTONF.VRIMPOSTONF%TYPE;
   V_VRISENTO        IMPOSTONF.VRCONTABILNF%TYPE;
   V_VROUTROS        IMPOSTONF.VRCONTABILNF%TYPE;
   V_VRIMPRETST      IMPOSTONF.VRIMPOSTONF%TYPE;
   V_VRSUBSTITUTO    IMPOSTONF.VRIMPOSTONF%TYPE;
   V_VRSUBSTITUIDO   IMPOSTONF.VRIMPOSTONF%TYPE;
   V_VROUTROSIMP     IMPOSTONF.VRIMPOSTONF%TYPE;
   V_MAXCDFISCOPER   IMPOSTONF.CDFISCOPERNF%TYPE;
BEGIN
   FOR C_NOTAS IN (SELECT DISTINCT I.CDFILIAL, I.NRLANCTONF, I.CDFISCOPERNF
                     FROM IMPOSTONF I, IMPOSTO IM
                    WHERE I.NRSEQUMAPAPU  = P_NRSEQUMAPAPU
                      AND I.CDIMPOSTO     = IM.CDIMPOSTO
                      AND IM.CDIMPOSTONFE = '00') LOOP

      /*Inicializa as variaveis para cada NF */
      V_VRCONTABILNF  := 0;
      V_VRBASECALCNF  := 0;
      V_VRIMPOSTONF   := 0;
      V_VRISENTO      := 0;
      V_VROUTROS      := 0;
      V_VRIMPRETST    := 0;
      V_VRSUBSTITUTO  := 0;
      V_VRSUBSTITUIDO := 0;
      V_VROUTROSIMP   := 0;

      /*Busca o maior CFOP da nota para evitar que quando houver mais de um CFOP na mesma nota
        os valores de ST e IPI quando parametrizados como encargo venham duplicados,
        dando preferencia para os CFOP's com CST de substituicao tributaria*/
      BEGIN
         SELECT MAX(CDFISCOPERNF)
           INTO V_MAXCDFISCOPER
           FROM IMPOSTONF I
          WHERE I.CDFILIAL     = C_NOTAS.CDFILIAL
            AND I.NRLANCTONF   = C_NOTAS.NRLANCTONF
            AND I.NRSEQUMAPAPU = P_NRSEQUMAPAPU
            AND SUBSTR(I.CDSITUTRIBNF,2,2) IN ('10','30','60','70');
      EXCEPTION
         WHEN NO_DATA_FOUND THEN
            V_MAXCDFISCOPER := '';
      END;

      IF V_MAXCDFISCOPER IS NULL THEN
         BEGIN
            SELECT MAX(CDFISCOPERNF)
              INTO V_MAXCDFISCOPER
              FROM IMPOSTONF I
             WHERE I.CDFILIAL     = C_NOTAS.CDFILIAL
               AND I.NRLANCTONF   = C_NOTAS.NRLANCTONF
               AND I.NRSEQUMAPAPU = P_NRSEQUMAPAPU;
         EXCEPTION
            WHEN NO_DATA_FOUND THEN
               V_MAXCDFISCOPER := '';
         END;
      END IF;

      /*Busca o valor contabil da NF e o valor de isentos ou nao tributados*/
      BEGIN
         SELECT NVL(SUM(ROUND(IP.VRCONTABILNF,2)),0) AS VRCONTABILNF,
                NVL(SUM(ROUND(DECODE(IP.CDFISCALNF,'2',IP.VRCONTABILNF,0),2)),0) AS VRNAOTRIBUTADO
           INTO V_VRCONTABILNF, V_VRISENTO
           FROM IMPOSTONF IP, IMPOSTO IM
          WHERE IP.CDFILIAL     = C_NOTAS.CDFILIAL
            AND IP.NRLANCTONF   = C_NOTAS.NRLANCTONF
            AND IP.CDFISCOPERNF = C_NOTAS.CDFISCOPERNF
            AND IP.CDIMPOSTO    = IM.CDIMPOSTO
            AND IM.CDIMPOSTONFE IN ('00')
            AND NVL(IP.IDIMPOSTONF,'1') <> '3';
      EXCEPTION
         WHEN NO_DATA_FOUND THEN
            V_VRCONTABILNF := 0;
            V_VRISENTO     := 0;
      END;

      /*Busca os valores de Base de Calculo e Imposto, com ou sem Carga Tributaria*/
      BEGIN
         SELECT NVL(SUM(I.VRBASECALCNF),0) AS VRBASECALCNF,
                NVL(SUM(I.VRIMPOSTONF),0)  AS VRIMPOSTONF
           INTO V_VRBASECALCNF, V_VRIMPOSTONF
           FROM (SELECT NVL(SUM(VALOR_IMPOSTO_ITEM_NFE_CARGA(IT.CDFILIAL, IT.NRLANCTONF, IT.NRSEQITPROD, 'B', '', '1')),0) AS VRBASECALCNF,
                        NVL(SUM(NVL(VALOR_IMPOSTO_ITEM_NFE_CARGA(IT.CDFILIAL, IT.NRLANCTONF, IT.NRSEQITPROD, 'I', '', '1'),0)+
                                NVL(VALOR_FECP_ITEM_NFE(IT.CDFILIAL, IT.NRLANCTONF, IT.NRSEQITPROD, '00', 'I', '1', '1'),0)),0) AS VRIMPOSTONF
                   FROM NOTAFISCAL NF, ITEMPROIMPOS IT, IMPOSTO IM
                  WHERE NF.CDFILIAL     = C_NOTAS.CDFILIAL
                    AND NF.NRLANCTONF   = C_NOTAS.NRLANCTONF
                    AND NF.CDFILIAL     = IT.CDFILIAL
                    AND NF.NRLANCTONF   = IT.NRLANCTONF
                    AND IT.CDFISCOPERIT = C_NOTAS.CDFISCOPERNF
                    AND IT.CDIMPOSTO    = IM.CDIMPOSTO
                    AND IM.CDIMPOSTONFE = '00'
                    AND IT.NRITPROIMPOS = '1'
                    AND NF.IDSISTEMA   <> 'FIS'
                  UNION ALL
                 SELECT NVL(SUM(ROUND(IP.VRBASECALCNF,2)),0) AS VRBASECALCNF,
                        NVL(SUM(ROUND(IP.VRIMPOSTONF + NVL(IP.VRADICFECP,0),2)),0) AS VRIMPOSTONF
                   FROM NOTAFISCAL NF, IMPOSTONF IP, IMPOSTO IM
                  WHERE NF.CDFILIAL     = C_NOTAS.CDFILIAL
                    AND NF.NRLANCTONF   = C_NOTAS.NRLANCTONF
                    AND NF.CDFILIAL     = IP.CDFILIAL
                    AND NF.NRLANCTONF   = IP.NRLANCTONF
                    AND IP.CDFISCOPERNF = C_NOTAS.CDFISCOPERNF
                    AND IP.CDIMPOSTO    = IM.CDIMPOSTO
                    AND IM.CDIMPOSTONFE IN ('00','03')
                    AND IP.IDIMPOSTONF  = '1'
                    AND IP.CDFISCALNF   = '1'
                    AND NF.IDSISTEMA    = 'FIS') I;
      EXCEPTION
         WHEN NO_DATA_FOUND THEN
            V_VRBASECALCNF := 0;
            V_VRIMPOSTONF  := 0;
      END;

      /*Busca os valores de ICMS ST(Substituto e Substituido) e IPI*/
      BEGIN
         SELECT SUM(VRSTSUBSTITUTO) AS VRSTSUBSTITUTO, SUM(VRSTSUBSTITUIDO) AS VRSTSUBSTITUIDO, SUM(VROUTROSIMPO) AS VROUTROSIMPO
           INTO V_VRSUBSTITUTO, V_VRSUBSTITUIDO, V_VROUTROSIMP
           FROM (SELECT NVL(SUM(ROUND(DECODE(IM.CDIMPOSTONFE,'80',CASE WHEN SUBSTR(CDSITUTRIBNF,2,2) IN     ('10','70') THEN IP.VRIMPOSTONF + NVL(IP.VRADICFECP,0) ELSE 0 END,0),2)),0) AS VRSTSUBSTITUTO,
                        NVL(SUM(ROUND(DECODE(IM.CDIMPOSTONFE,'80',CASE WHEN SUBSTR(CDSITUTRIBNF,2,2) NOT IN ('10','70') THEN IP.VRIMPOSTONF + NVL(IP.VRADICFECP,0) ELSE 0 END,0),2)),0) AS VRSTSUBSTITUIDO,
                        NVL(SUM(ROUND(DECODE(IM.CDIMPOSTONFE,'10',IP.VRIMPOSTONF + NVL(IP.VRADICFECP,0),0),2)),0) AS VROUTROSIMPO
                   FROM IMPOSTONF IP, IMPOSTO IM
                  WHERE IP.CDFILIAL     = C_NOTAS.CDFILIAL
                    AND IP.NRLANCTONF   = C_NOTAS.NRLANCTONF
                    AND IP.CDFISCOPERNF = C_NOTAS.CDFISCOPERNF
                    AND IP.CDIMPOSTO    = IM.CDIMPOSTO
                    AND IM.CDIMPOSTONFE IN ('10','80')
                    AND IP.CDFISCALNF   = '1'
                    AND NVL(IP.IDIMPOSTONF,'1') <> '3'
                  UNION ALL
                 SELECT 0 AS VRSTSUBSTITUTO,
                        NVL(SUM(ROUND(DECODE(I.CDIMPOSTONFE,'80',VALOR_ENCARGO(C_NOTAS.CDFILIAL, C_NOTAS.NRLANCTONF, E.IDENCARGO, E.CDENCARGO),0),2)),0) AS VRSTSUBSTITUIDO,
                        NVL(SUM(ROUND(DECODE(I.CDIMPOSTONFE,'10',VALOR_ENCARGO(C_NOTAS.CDFILIAL, C_NOTAS.NRLANCTONF, E.IDENCARGO, E.CDENCARGO),0),2)),0) AS VROUTROSIMPO
                   FROM IMPOSTO I, ENCARGO E
                  WHERE I.CDIMPOSTONFE    IN ('10','80')
                    AND I.CDENCARGOIMPXML = E.CDENCARGO
                    AND NVL(V_MAXCDFISCOPER,' ') = NVL(C_NOTAS.CDFISCOPERNF,' '));
      EXCEPTION
         WHEN NO_DATA_FOUND THEN
            V_VRSUBSTITUTO  := 0;
            V_VRSUBSTITUIDO := 0;
            V_VROUTROSIMP   := 0;
      END;

      /****************************************************************************************
        Realiza as verificacoes para que a conta feita pela GIA SP feche corretamente:
        Vr. Contabil = Base de Calculo + Isentos ou Nao Tributados + Outros + IPI + ICMS ST
      ****************************************************************************************/

      /*Testa a BC do ICMS para os casos em que os outros impostos (IPI e ICMS ST) compoe a BC do ICMS, pois, sendo assim,
        esses impostos devem ser subtraidos do valor da base de calculo, ja que sao exibidos em campos separados*/
      IF V_VRBASECALCNF > 0 THEN
         /*Quando o IPI e o ICMS ST acrescer a BC do ICMS, assim o valor contabil e igual a base de calculo + isentos(quando houver)*/
         IF (V_VRCONTABILNF = V_VRBASECALCNF + V_VRISENTO) AND (V_VRBASECALCNF - V_VROUTROSIMP - V_VRSUBSTITUTO > 0) THEN
            V_VRBASECALCNF := V_VRBASECALCNF - V_VROUTROSIMP - V_VRSUBSTITUTO;
         /*Quando apenas o ICMS ST acrescer a BC do ICMS, assim o valor contabil sera a base de calculo + IPI + isentos(quando houver)*/
         ELSIF (V_VRCONTABILNF = V_VRBASECALCNF + V_VROUTROSIMP + V_VRISENTO) AND (V_VRBASECALCNF - V_VRSUBSTITUTO > 0) THEN
            V_VRBASECALCNF := V_VRBASECALCNF - V_VRSUBSTITUTO;
         /*Quando apenas o IPI acrescer a BC do ICMS, assim o valor contabil sera a base de calculo + ICMS ST + isentos(quando houver)*/
         ELSIF (V_VRCONTABILNF = V_VRBASECALCNF + V_VRSUBSTITUTO + V_VRISENTO) AND (V_VRBASECALCNF - V_VROUTROSIMP > 0) THEN
            V_VRBASECALCNF := V_VRBASECALCNF - V_VROUTROSIMP;
         END IF;
      END IF;

      /*Testa o valor de isentos para os casos em que os outros impostos (IPI e ICMS ST) acrescerem o valor da nota e o ICMS for isento,
        pois, sendo assim, esses impostos devem ser subtraidos do valor de isentos ou nao tributados, ja que sao exibidos em campos separados*/
      IF V_VRISENTO > 0 THEN
         /*Quando o IPI e o ICMS ST acrescem o Vr. da Nota e o ICMS e isento, assim o valor contabil sera igual ao valor de isentos*/
         IF (V_VRCONTABILNF = V_VRISENTO) AND (V_VRISENTO - V_VROUTROSIMP - V_VRSUBSTITUIDO > 0) THEN
            V_VRISENTO := V_VRISENTO - V_VROUTROSIMP - V_VRSUBSTITUIDO;
         /*Quando apenas o ICMS ST acresce o Vr. da Nota e o ICMS e isento, assim o valor contabil sera igual ao valor de isentos + IPI*/
         ELSIF (V_VRISENTO = V_VRISENTO + V_VROUTROSIMP) AND (V_VRISENTO - V_VRSUBSTITUIDO > 0) THEN
            V_VRISENTO := V_VRISENTO - V_VRSUBSTITUIDO;
         /*Quando apenas o IPI acresce o Vr. da Nota e o ICMS e isento, assim o valor contabil sera igual ao valor de isentos + ICMS ST*/
         ELSIF (V_VRISENTO = V_VRISENTO + V_VRSUBSTITUIDO) AND (V_VRISENTO - V_VROUTROSIMP > 0) THEN
            V_VRISENTO := V_VRISENTO - V_VROUTROSIMP;
         END IF;
      END IF;

      /*Realiza a conta Vr. Contabil - (BC do ICMS + Isentas + ICMS ST Substituto e Substituido + IPI )*/
      IF (V_VRCONTABILNF - V_VRBASECALCNF - V_VRISENTO - V_VRSUBSTITUTO - V_VRSUBSTITUIDO - V_VROUTROSIMP) > 0 THEN
         V_VROUTROS := V_VRCONTABILNF - V_VRBASECALCNF - V_VRISENTO - V_VRSUBSTITUTO - V_VRSUBSTITUIDO - V_VROUTROSIMP;
      END IF;

      INSERT INTO TMP_REGDADOSGIASP
         (CDFILIAL, NRLANCTONF, CDFISCOPERNF, VRCONTABILNF, VRBASECALCNF,  VRIMPOSTONF,
          VRISENTO, VROUTROS,   VRIMPRETST,   VRSUBSTITUTO, VRSUBSTITUIDO, VROUTROSIMP)
      VALUES
         (C_NOTAS.CDFILIAL, C_NOTAS.NRLANCTONF, NVL(C_NOTAS.CDFISCOPERNF,' '), V_VRCONTABILNF, V_VRBASECALCNF,  V_VRIMPOSTONF,
          V_VRISENTO,       V_VROUTROS,         V_VRIMPRETST,         V_VRSUBSTITUTO, V_VRSUBSTITUIDO, V_VROUTROSIMP);
   END LOOP;
END;
/