CREATE OR REPLACE PROCEDURE FCT_APURAR_FATURAMENTO (  
    P_NRORG IN NUMBER,
    P_NRSEQCONTRATO IN VARCHAR2,
    P_NRPARCNEGOCIO IN VARCHAR2,
    P_CDOPERINCLUSAO IN FCT_APURACAO.CDOPERINCLUSAO%TYPE,
    P_DATAINI IN DATE,
    P_DATAFIN IN DATE,
    P_NRFATURACONT IN VARCHAR2,
    P_NRGRUPOFATURA IN VARCHAR2,
    P_NRRATEIOITEMVENC IN VARCHAR2 DEFAULT NULL,
    P_RETORNO OUT VARCHAR2,
    P_RETORNOERRO OUT VARCHAR2,
    P_NRITFATURACONT IN VARCHAR2 DEFAULT NULL)
AS
   V_NRAPURACAO         VARCHAR2(20);
   V_VRVENCIMENTO       FLOAT;
   V_EMPRESA            VARCHAR2(02);
   V_GRFATUR            NUMBER;
   V_TPOPERFAT          VARCHAR2(02);
   V_TPSERIENF          VARCHAR2(05);
   V_PRODFAT            VARCHAR2(30);
   V_NMITEMCONTRATO     VARCHAR2(60);
   V_NMPRODFAT          VARCHAR2(50);
   V_NRLANCTONF         VARCHAR2(10);
   V_CDCLIENTE          VARCHAR2(21);
   V_PRXLANCESTQ        VARCHAR2(10);
   V_TPORCA             NUMBER;
   VD_SERIE             VARCHAR2(05);
   V_RETORN             VARCHAR2(05);
   V_TESTAPUR           VARCHAR2(30);
   V_TESTAPUR2          VARCHAR2(30);
   V_APURA              FLOAT;
   V_DTEMISS            DATE;
   V_TPEMISSNF          VARCHAR2(01);
   V_DIAEMISSNF         VARCHAR2(02);
   V_DADOADIC           VARCHAR2(03);
   V_VENCIMENTO         DATE;
   V_DTINIREFFAT        DATE;
   V_DTFINREFFAT        DATE;
   V_NFCRIADA           VARCHAR2(3600);
   V_MEDPREVISTA        INTEGER;
   V_QTPRODNOTA         INTEGER;
   V_TESTAITEM          INTEGER;
   V_NRSEQIRPROD        VARCHAR2(4);
   V_FILIAL             VARCHAR2(4);
   V_VRCONTITEM         FLOAT;
   V_VRBRUTITEM         FLOAT;
   V_VRPERCRATEIO       FLOAT;
   V_VRRATEIO           FLOAT;
   V_COUNTRATEIO        INTEGER;
   V_VRNOTAFISC         FLOAT;
   V_VRFALTAFATURAR     FLOAT;
   V_IDSITUACAO         CHAR(1);
   V_DSSERVORCANF       VARCHAR2(4000);
   V_PARCELAS           VARCHAR2(30);
   V_NRLANCTONF_EXISTE  NOTAFISCAL.NRLANCTONF%TYPE;
   V_IDFATCONTJUNT      FCT_RELACAGRUPAMENTOCONT.IDFATCONTJUNT%TYPE;
   V_NRAPURACAOFATURA   FCT_RELACAPURACAOFATURA.NRAPURACAOFATURA%TYPE;
   V_APURACAOCONLUIDA   VARCHAR2(1);
   V_CDINSCESTA         VARCHAR2(16);
   V_CDINSCMUNI         VARCHAR2(16);
   V_EXISTE_SERIE       NUMBER;
   V_DSSERVORCABOL      VARCHAR2(4000);
   V_MEDVARIAVEIS       VARCHAR2(4000);
   V_IDGERARATEIO       VARCHAR2(1);
   V_VRVENCIMENTORATEIO FLOAT(126);
   V_DSTIPOAPURACAO     VARCHAR2(5);
   V_NRCONTRATOS        VARCHAR2(4000);

BEGIN
    /*
    ERROS
    -20001 - SEM_CLIENTE = Cliente para faturamento nao encontrado
    -20002 - FK_SERIENF = Serie de NF nao esta relacionada com a inscricao estadual e municipal da filial informada
    */
   V_NFCRIADA         := NULL;
   V_IDFATCONTJUNT    := NULL;
   V_APURACAOCONLUIDA := NULL;

   /* Realiza a busca dos dados do Faturamento */
   FOR C_APUR IN (SELECT DISTINCT FCT_FATURACONT.NRFATURACONT, IDFATCONTJUNT, DECODE(IDPARCAGRUP, 'N', FCT_CONTRATO.NRCONTRATOFCT, 'AGRUPAMENTO DE CONTRATOS') AS NRCONTRATOFCT, TO_CHAR(FCT_CONTRATO.DSOBSERVACAOCONT) AS DSOBSERVACAOCONT,
                         FCT_FATURACONT.NRGRUPOFATURA, FCT_FATURACONT.CDFILIALFATURA, FCT_FATURACONT.NRPARCFATURA, FCT_FATURACONT.IDTPFATURA,
                         FCT_FATURACONT.IDSITUACAO, FCT_FATURACONT.DTINICOMPET, FCT_FATURACONT.DTFINCOMPET, FCT_FATURACONT.DTLIMITEAPU,
                         FCT_FATURACONT.DTVENCIMENTO, FCT_FATURACONT.NRDIASVENCIMENTO, FCT_FATURACONT.QTDIASFATUVENC,
                         FCT_FATURACONT.CDTIPOOPERFATURA, FCT_FATURACONT.CDSERIENF,
                         NVL((SELECT SUM(VRVENCIMENTO) FROM FCT_ITFATURACONT WHERE NRSEQCONTRATO IN(SELECT NRSEQCONTRATO
                              FROM FCT_RELACAGRUPAMENTOCONT WHERE NRAGRUPAMENTO = AGRUPCONT.NRAGRUPAMENTO
                                AND IDFATCONTJUNT = AGRUPCONT.IDFATCONTJUNT)), FCT_FATURACONT.VRVENCIMENTO) AS VRVENCIMENTO, FCT_FATURACONT.VRFATURADO, FCT_FATURACONT.VRFALTAFATURAR, FCT_FATURACONT.IDFORMAFATURA, TO_CHAR(FCT_FATURACONT.DSJUSTIFICATIVA) AS DSJUSTIFICATIVA,
                         FCT_FATURACONT.NRAPURACAO, FCT_FATURACONT.NRMEDICAOFATURA, FCT_FATURACONT.IDATIVO, FCT_FATURACONT.NRORG
                    FROM FCT_FATURACONT
                    INNER JOIN FCT_RELACAGRUPCONTFAT AGRUPFAT
                      ON AGRUPFAT.NRFATURACONT = FCT_FATURACONT.NRFATURACONT
                      AND AGRUPFAT.NRORG       = FCT_FATURACONT.NRORG
                    LEFT JOIN FCT_RELACAGRUPAMENTOCONT AGRUPCONT
                      ON AGRUPFAT.NRSEQCONTRATO = AGRUPCONT.NRSEQCONTRATO
                      AND AGRUPFAT.NRORG       = AGRUPCONT.NRORG
                    JOIN FCT_CONTRATO
                      ON FCT_CONTRATO.NRSEQCONTRATO = AGRUPFAT.NRSEQCONTRATO
                     AND FCT_CONTRATO.NRORG         = AGRUPFAT.NRORG
                   WHERE (FCT_FATURACONT.NRORG = P_NRORG)
                     AND ((INSTR(P_NRSEQCONTRATO, '_' || TO_CHAR(AGRUPFAT.NRSEQCONTRATO) || '_') > 0) OR (P_NRSEQCONTRATO IS NULL))
                     AND ((INSTR(P_NRPARCNEGOCIO, '_' || TO_CHAR(FCT_FATURACONT.NRPARCFATURA) || '_') > 0) OR (P_NRPARCNEGOCIO IS NULL))
                     AND ((INSTR(P_NRFATURACONT, '_' || TO_CHAR(FCT_FATURACONT.NRFATURACONT) || '_') > 0) OR (P_NRFATURACONT IS NULL))
                     AND ((TRUNC(TO_DATE(FCT_FATURACONT.DTINICOMPET)) >= TRUNC(TO_DATE(P_DATAINI))) OR (P_DATAINI IS NULL))
                     AND ((TRUNC(TO_DATE(FCT_FATURACONT.DTFINCOMPET)) <= TRUNC(TO_DATE(P_DATAFIN))) OR (P_DATAFIN IS NULL))
                     AND (FCT_FATURACONT.IDSITUACAO = '1' OR FCT_FATURACONT.IDSITUACAO = '6')
    ) LOOP

        /*Preenche Filial*/
        V_FILIAL    := C_APUR.CDFILIALFATURA;
        V_TPOPERFAT := C_APUR.CDTIPOOPERFATURA;
        V_TPSERIENF := C_APUR.CDSERIENF;

        /* Recebe empresa para faturamento */
        SELECT CDEMPRESA
          INTO V_EMPRESA
          FROM FILIAL
         WHERE CDFILIAL = V_FILIAL
           AND NRORG = P_NRORG;

        /*Recebe dados do grupo de faturamento
        SELECT CDTIPOOPERFATURA, CDSERIENF, CDPRODUTOVENDA, NMPRODUTO
         INTO V_TPOPERFAT, V_TPSERIENF, V_PRODFAT, V_NMPRODFAT
         FROM FCT_GRUPOFATURA GRP, PRODUTO PRO
        WHERE GRP.NRGRUPOFATURA = C_APUR.NRGRUPOFATURA
          AND GRP.NRORG = P_NRORG
          AND PRO.CDPRODUTO(+) = GRP.CDPRODUTOVENDA;*/

        /* Recebe codigo do cliente */
        BEGIN
            SELECT CL.CDCLIENTE
              INTO V_CDCLIENTE
              FROM PARCNEGOCIO PN, CLIENTE CL
             WHERE PN.NRPARCNEGOCIO = C_APUR.NRPARCFATURA
               AND PN.NRORG = P_NRORG
               AND CL.NRPARCNEGOCIO = PN.NRPARCNEGOCIO
               AND CL.NRORG = PN.NRORG
               AND CL.IDCLIEATIV = 'S';
        EXCEPTION WHEN NO_DATA_FOUND THEN
            RAISE_APPLICATION_ERROR('-20001', 'SEM_CLIENTE');
        END;

        /* Recebe Tipo do OrAamento
        BEGIN
          SELECT RF.NRTIPOORCAMENTO
            INTO V_TPORCA
            FROM FCT_ORCAMENTO OC, FCT_REFEORCACONT RF
           WHERE RF.NRORG = P_NRORG
             AND OC.NRORG = RF.NRORG
             AND OC.NRSEQORCAMENTO = RF.NRSEQORCAMENTO;
        EXCEPTION
         WHEN NO_DATA_FOUND THEN
            V_TPORCA := NULL;
        END;*/

        /* ----- Recebe a data de saAda da NF ----- */
        V_DTEMISS := TRUNC(SYSDATE);

        /* INICIO: verificacao da serie da nota de acordo com a empresa e filial */
        SELECT MAX(F.CDINSCESTA), MAX(F.CDINSCMUNI)
          INTO V_CDINSCESTA, V_CDINSCMUNI
          FROM FILIAL F, INSCRESTAD I
         WHERE (F.CDFILIAL   = C_APUR.CDFILIALFATURA)
           AND (F.CDEMPRESA  = V_EMPRESA)
           AND (I.CDINSCESTA = F.CDINSCESTA)
           AND (I.CDEMPRESA  = F.CDEMPRESA)
           AND (NVL(V_DTEMISS, TRUNC(SYSDATE)) >= NVL(NVL(I.DTINIVIGIEST, V_DTEMISS), TRUNC(SYSDATE)))
           AND (NVL(V_DTEMISS, TRUNC(SYSDATE)) <= NVL(NVL(I.DTFIMVIGIEST, V_DTEMISS), TRUNC(SYSDATE)));

        IF (V_CDINSCESTA IS NULL) OR (V_CDINSCMUNI IS NULL) THEN
           SELECT MAX(E.CDINSCESTA), MAX(E.CDINSCMUNI)
             INTO V_CDINSCESTA, V_CDINSCMUNI
             FROM EMPRCNTRFIL E, INSCRESTAD I
            WHERE (E.CDFILIAL  = C_APUR.CDFILIALFATURA)
              AND (E.CDEMPRESA = V_EMPRESA)
              AND (E.CDINSCESTA = I.CDINSCESTA)
              AND (E.CDEMPRESA  = I.CDEMPRESA)
              AND (NVL(V_DTEMISS, TRUNC(SYSDATE)) >= NVL(NVL(I.DTINIVIGIEST, V_DTEMISS), TRUNC(SYSDATE)))
              AND (NVL(V_DTEMISS, TRUNC(SYSDATE)) <= NVL(NVL(I.DTFIMVIGIEST, V_DTEMISS), TRUNC(SYSDATE)));
        END IF;

        IF (V_CDINSCESTA IS NULL) OR (V_CDINSCMUNI IS NULL) THEN
           SELECT MAX(CDINSCESTA), MAX(CDINSCMUNI)
             INTO V_CDINSCESTA, V_CDINSCMUNI
             FROM FILIAL
            WHERE (CDFILIAL  = C_APUR.CDFILIALFATURA)
              AND (CDEMPRESA = V_EMPRESA);
        END IF;

        IF (V_CDINSCESTA IS NULL) OR (V_CDINSCMUNI IS NULL) THEN
            RAISE_APPLICATION_ERROR('-20002', 'FK_SERIENF');
        ELSE
            SELECT COUNT(*)
              INTO V_EXISTE_SERIE
              FROM SERIENF
             WHERE CDEMPRESA  = V_EMPRESA
               AND CDINSCESTA = V_CDINSCESTA
               AND CDINSCMUNI = V_CDINSCMUNI
               AND CDSERIE    = V_TPSERIENF;
            IF (V_EXISTE_SERIE = 0) THEN
                RAISE_APPLICATION_ERROR('-20002', 'FK_SERIENF');
            END IF;
        END IF;
        /* FIM: verificacao da serie da nota de acordo com a empresa e filial */

        /* Geracao do CORPO da nota fiscal da apuracao*/
        GERA_NOTAFISCAL_CORPO(C_APUR.CDFILIALFATURA, C_APUR.CDFILIALFATURA, V_EMPRESA, V_TPOPERFAT, V_TPSERIENF, V_CDCLIENTE, V_DTEMISS,'DFS', V_NRLANCTONF, V_PRXLANCESTQ);
        IF (V_NRLANCTONF IS NOT NULL) THEN
            --ALTERAR
            FCT_PREENCHE_DADOS_NOTAFISC(P_NRORG, C_APUR.CDFILIALFATURA, V_NRLANCTONF, C_APUR.NRFATURACONT, P_CDOPERINCLUSAO);
            V_NFCRIADA := V_NFCRIADA||'_'||V_NRLANCTONF||'_';
        END IF;

        /* Insercao dos itens na nota fical */
        FOR C_ITENS IN (SELECT FCT_ITFATURACONT.NRITFATURACONT, FCT_ITFATURACONT.NRFATURACONT, FCT_ITFATURACONT.NRSEQCONTRATO,
                         FCT_ITFATURACONT.NRITEMOCONTRATO, FCT_ITFATURACONT.CDPRODFATURA, PRODUTO.NMPRODUTO,
                         FCT_ITFATURACONT.IDSITUACAO, 1 AS QUANTIDADE, FCT_ITFATURACONT.VRVENCIMENTO, FCT_ITFATURACONT.VRFATURADO,
                         FCT_ITFATURACONT.VRFALTAFATURAR, FCT_ITFATURACONT.IDFORMAFATURA, FCT_ITFATURACONT.DSJUSTIFICATIVA,
                         FCT_ITFATURACONT.NRAPURACAO, FCT_ITFATURACONT.IDATIVO, FCT_ITFATURACONT.NRORG
                    FROM FCT_ITFATURACONT
                    LEFT JOIN FCT_RELACAGRUPAMENTOCONT AGRUP
                      ON FCT_ITFATURACONT.NRSEQCONTRATO = AGRUP.NRSEQCONTRATO
                      AND FCT_ITFATURACONT.NRORG        = AGRUP.NRORG
                    JOIN PRODUTO
                      ON FCT_ITFATURACONT.CDPRODFATURA = PRODUTO.CDPRODUTO
                     AND FCT_ITFATURACONT.NRORG        = PRODUTO.NRORG
                   WHERE (AGRUP.IDFATCONTJUNT          = C_APUR.IDFATCONTJUNT
                          OR C_APUR.IDFATCONTJUNT      IS NULL)
                     AND FCT_ITFATURACONT.NRFATURACONT = C_APUR.NRFATURACONT
                     AND FCT_ITFATURACONT.NRORG        = P_NRORG
                     AND ((P_NRITFATURACONT IS NULL AND P_NRRATEIOITEMVENC IS NULL)
                          OR (P_NRRATEIOITEMVENC IS NULL AND (INSTR(P_NRITFATURACONT, '_' || TO_CHAR(NRITFATURACONT) || '_') > 0))
                          OR (P_NRITFATURACONT IS NULL AND FCT_ITFATURACONT.NRITFATURACONT IN (SELECT NRITFATURACONT
                                                                                               FROM FCT_RATEIOITFATURACONT
                                                                                               WHERE ((INSTR(P_NRRATEIOITEMVENC, '_' || TO_CHAR(NRRATEIOITEMFAT) || '_') > 0)))))
        ) LOOP

            SELECT COUNT(*)
              INTO V_QTPRODNOTA
              FROM ITEMPRODUTO
             WHERE NRLANCTONF = V_NRLANCTONF
               AND CDFILIAL   = C_APUR.CDFILIALFATURA
               AND CDPRODUTO  = C_ITENS.CDPRODFATURA;

            V_VRVENCIMENTORATEIO := ROUND(C_ITENS.VRVENCIMENTO, 2);
            IF(P_NRRATEIOITEMVENC IS NOT NULL) THEN
                BEGIN
                    SELECT ROUND(SUM(VRRATEADO), 2)
                    INTO V_VRVENCIMENTORATEIO
                    FROM FCT_RATEIOITFATURACONT
                    WHERE NRITFATURACONT = C_ITENS.NRITFATURACONT
                      AND (INSTR(P_NRRATEIOITEMVENC, '_' || TO_CHAR(NRRATEIOITEMFAT) || '_') > 0);
                EXCEPTION WHEN NO_DATA_FOUND THEN
                    V_VRVENCIMENTORATEIO := ROUND(C_ITENS.VRVENCIMENTO, 2);
                END;
            END IF;

            IF (V_QTPRODNOTA = 0) THEN
              GERA_NOTAFISCAL_PRODUTO(C_APUR.CDFILIALFATURA, V_NRLANCTONF, C_ITENS.CDPRODFATURA, C_ITENS.CDPRODFATURA, C_ITENS.NMPRODUTO, C_ITENS.QUANTIDADE, V_VRVENCIMENTORATEIO);
            ELSE
               UPDATE ITEMPRODUTO
                  SET VRUNITITEM = ROUND(VRUNITITEM + V_VRVENCIMENTORATEIO, 2),
                      VRTOTAITEM = ROUND(VRTOTAITEM + V_VRVENCIMENTORATEIO, 2)
                WHERE NRLANCTONF = V_NRLANCTONF
                  AND CDFILIAL   = C_APUR.CDFILIALFATURA
                  AND CDPRODUTO  = C_ITENS.CDPRODFATURA;
            END IF;

            /* Caso o item tenha rateio, serao criados os rateios na Nota Fiscal */
            IF (C_APUR.IDTPFATURA <> 'P') THEN
                FOR C_RATEIO IN (
                    SELECT NRITFATURACONT, NRFATURACONT, NRSEQCONTRATO,
                        NRESTRUTURAM, CDCENTCUST, VRRATEADO
                    FROM FCT_RATEIOITFATURACONT RAT
                    WHERE RAT.NRFATURACONT       = C_APUR.NRFATURACONT
                        AND RAT.NRSEQCONTRATO    = C_ITENS.NRSEQCONTRATO
                        AND RAT.NRITFATURACONT   = C_ITENS.NRITFATURACONT
                        AND RAT.IDSITUVENCRATEIO IN('1', '6')
                        AND (P_NRRATEIOITEMVENC IS NULL OR INSTR(P_NRRATEIOITEMVENC, '_' || TO_CHAR(NRRATEIOITEMFAT) || '_') > 0)
                ) LOOP
                    -- Busca o nAmero do item na Nota Fiscal
                    SELECT NRSEQITPROD
                      INTO V_NRSEQIRPROD
                      FROM ITEMPRODUTO
                     WHERE NRLANCTONF = V_NRLANCTONF
                       AND CDFILIAL   = C_APUR.CDFILIALFATURA
                       AND CDPRODUTO  = C_ITENS.CDPRODFATURA;

                    SELECT COUNT(*)
                      INTO V_COUNTRATEIO
                      FROM RATEIONF
                     WHERE NRLANCTONF  = V_NRLANCTONF
                       AND CDFILIAL    = C_APUR.CDFILIALFATURA
                       AND NRSEQITPROD = V_NRSEQIRPROD
                       AND CDFILICCUST = C_APUR.CDFILIALFATURA
                       AND CDCENTCUSNF = C_RATEIO.CDCENTCUST
                       AND NRORG       = P_NRORG;

                    IF V_COUNTRATEIO = 0 THEN
                        INSERT INTO RATEIONF(
                          CDFILIAL, NRLANCTONF, NRSEQITPROD, CDFILICCUST, CDCENTCUSNF,
                          VRRATENF, NRORG,      DTINCLUSAO,  IDATIVO
                        ) VALUES(
                          C_APUR.CDFILIALFATURA,        V_NRLANCTONF, V_NRSEQIRPROD, C_APUR.CDFILIALFATURA, C_RATEIO.CDCENTCUST,
                          ROUND(C_RATEIO.VRRATEADO, 2), P_NRORG,      SYSDATE,       'S'
                        );
                    ELSE
                       UPDATE RATEIONF
                          SET VRRATENF = ROUND(VRRATENF + C_RATEIO.VRRATEADO, 2)
                        WHERE NRLANCTONF  = V_NRLANCTONF
                          AND NRSEQITPROD = V_NRSEQIRPROD
                          AND CDFILIAL    = C_APUR.CDFILIALFATURA
                          AND CDFILICCUST = C_APUR.CDFILIALFATURA
                          AND CDCENTCUSNF = C_RATEIO.CDCENTCUST
                          AND NRORG       = P_NRORG;
                    END IF;

                    IF C_ITENS.VRFATURADO + C_RATEIO.VRRATEADO = C_ITENS.VRVENCIMENTO THEN
                        V_IDSITUACAO := '2';
                    ELSE
                        V_IDSITUACAO := '6';
                    END IF;

                    UPDATE FCT_ITFATURACONT
                       SET IDSITUACAO     = V_IDSITUACAO,
                           VRFATURADO     = ROUND(VRFATURADO     + C_RATEIO.VRRATEADO, 2),
                           VRFALTAFATURAR = ROUND(VRFALTAFATURAR - C_RATEIO.VRRATEADO, 2)
                    WHERE NRORG          = P_NRORG
                      AND NRFATURACONT   = C_APUR.NRFATURACONT
                      AND NRITFATURACONT = C_RATEIO.NRITFATURACONT
                      AND (IDSITUACAO = '1' OR IDSITUACAO = '6');

                    FOR C_RATITENS IN (
                        SELECT NRESTRUTURAM,
                          SUM(VRRATEADO) AS VRRATEADO
                         FROM FCT_RATEIOITFATURACONT
                         WHERE NRFATURACONT = C_APUR.NRFATURACONT
                          AND NRSEQCONTRATO = C_ITENS.NRSEQCONTRATO
                          AND NRESTRUTURAM  = C_RATEIO.NRESTRUTURAM
                         GROUP BY NRESTRUTURAM
                    ) LOOP

                        IF ROUND(C_RATITENS.VRRATEADO, 2) = ROUND(C_RATEIO.VRRATEADO, 2) THEN
                            V_IDSITUACAO := '2';
                        ELSE
                            V_IDSITUACAO := '6';
                        END IF;

                        UPDATE FCT_RATEIOITFATURACONT
                           SET IDSITUVENCRATEIO = V_IDSITUACAO
                         WHERE NRORG        = P_NRORG
                           AND NRFATURACONT = C_APUR.NRFATURACONT
                           AND NRESTRUTURAM = C_RATITENS.NRESTRUTURAM;

                    END LOOP; -- C_RATITENS

                END LOOP; --C_RATEIO
          END IF;  -- C_APUR.IDTPFATURA <> 'P'
        END LOOP;  -- C_ITENS
        /* ====== Abaixo ele testa se a nota fiscal possui algum item, se ela nao possuir ele deleta a nota fiscal e ignora o resto da rotina.
                 Se ela possuir, ele continua a rotina normalmente. */
        SELECT COUNT(*)
          INTO V_TESTAITEM
          FROM ITEMPRODUTO
         WHERE NRLANCTONF = V_NRLANCTONF
           AND CDFILIAL   = C_APUR.CDFILIALFATURA
           AND NRORG      = P_NRORG;

        IF V_TESTAITEM = 0 THEN
            DELETE FROM NOTAFISCAL
             WHERE NRLANCTONF = V_NRLANCTONF
               AND CDFILIAL = C_APUR.CDFILIALFATURA
               AND NRORG    = P_NRORG;
        ELSE

          /* UPDATA DATAS DE COMPETENCIA DE FATURAMENTO NA NF */
          UPDATE NOTAFISCAL
             SET DTINIREFEFAT = C_APUR.DTINICOMPET,
                 DTFINREFEFAT = C_APUR.DTFINCOMPET
           WHERE NRLANCTONF   = V_NRLANCTONF
             AND CDFILIAL     = C_APUR.CDFILIALFATURA;

          IF(V_IDFATCONTJUNT IS NULL OR V_IDFATCONTJUNT <> C_APUR.IDFATCONTJUNT) THEN
            V_NRAPURACAO    := NULL;
            V_IDFATCONTJUNT := C_APUR.IDFATCONTJUNT;
          END IF;

         /* Gera apuracao do contrato */
         IF (V_NRAPURACAO IS NULL) THEN
            IF(P_NRRATEIOITEMVENC IS NOT NULL) THEN
                V_DSTIPOAPURACAO := 'RAT';
            ELSIF (P_NRITFATURACONT IS NOT NULL) THEN
                V_DSTIPOAPURACAO := 'ITEM';
            ELSE
                V_DSTIPOAPURACAO := 'APU';
            END IF;

            NOVO_CODIGO('FCT_APURACAO', V_NRAPURACAO, 1, P_NRORG);
            V_NRAPURACAO := SUBSTR(V_NRAPURACAO, 11, 10);
            INSERT INTO FCT_APURACAO
                    (NRAPURACAO, NRSEQCONTRATO, NRTIPOORCAMENTO,
                     NRPARCNEGOCIO, CDMODPGTO, NRGRUPOFATURA,
                     CDEMPRESA, CDFILIAL, NRLANCTONF,
                     IDSITUACAOAPURACAO, VRAPURACAO, VRAPURACAOORIGINAL,
                     DSALTERACAO, CDAGRUPANF, NRORG,
                     DTINCLUSAO, NRORGINCLUSAO, CDOPERINCLUSAO, DSTIPOAPURACAO)
            VALUES
                    (V_NRAPURACAO, NULL, V_TPORCA,
                     C_APUR.NRPARCFATURA, NULL, NULL,
                     V_EMPRESA, C_APUR.CDFILIALFATURA, V_NRLANCTONF,
                     'FATURADA', ROUND(C_APUR.VRVENCIMENTO, 2), ROUND(C_APUR.VRVENCIMENTO, 2),
                     NULL, NULL, P_NRORG,
                     SYSDATE, P_NRORG, P_CDOPERINCLUSAO, V_DSTIPOAPURACAO);

            /* cria uma ligaAAo entre as apuraAAos e a parcela */
            NOVO_CODIGO('FCT_RELACAPURACAOFATURA', V_NRAPURACAOFATURA, 1, P_NRORG);
            INSERT INTO FCT_RELACAPURACAOFATURA (
                NRAPURACAOFATURA, NRAPURACAO,    NRFATURACONT,
                NRORG,            IDATIVO,       DTINCLUSAO,
                DTULTATU,         NRORGINCLUSAO, CDOPERINCLUSAO,
                NRORGULTATU,      CDOPERULTATU
            ) VALUES (
                V_NRAPURACAOFATURA, V_NRAPURACAO,    C_APUR.NRFATURACONT,
                P_NRORG,            'S',       SYSDATE,
                NULL,               P_NRORG, P_CDOPERINCLUSAO,
                NULL,               NULL
            );
            V_APURACAOCONLUIDA := 'S';
        END IF;

        /** Atualiza a tabela de itens **/
        IF (P_NRITFATURACONT IS NOT NULL) THEN

            UPDATE FCT_ITFATURACONT
               SET IDSITUACAO     = '2',
                   VRFATURADO     = ROUND(VRVENCIMENTO, 2),
                   NRAPURACAO     = V_NRAPURACAO,
                   VRFALTAFATURAR = 0
             WHERE NRORG         = P_NRORG
               AND NRFATURACONT  = C_APUR.NRFATURACONT
               AND ((INSTR(P_NRSEQCONTRATO, '_' || TO_CHAR(NRSEQCONTRATO) || '_') > 0) OR (P_NRSEQCONTRATO IS NULL))
               AND ((INSTR(P_NRITFATURACONT, '_' || TO_CHAR(NRITFATURACONT) || '_') > 0) OR P_NRITFATURACONT IS NULL);

        ELSIF (P_NRRATEIOITEMVENC IS NULL) THEN

            UPDATE FCT_ITFATURACONT
               SET IDSITUACAO     = '2',
                   VRFATURADO     = ROUND(VRVENCIMENTO, 2),
                   NRAPURACAO     = V_NRAPURACAO,
                   VRFALTAFATURAR = 0
             WHERE NRORG         = P_NRORG
               AND NRFATURACONT  = C_APUR.NRFATURACONT
               AND (IDSITUACAO = '1' OR IDSITUACAO = '6')
               AND ((INSTR(P_NRSEQCONTRATO, '_' || TO_CHAR(NRSEQCONTRATO) || '_') > 0) OR (P_NRSEQCONTRATO IS NULL));

        END IF;

        /* Atualiza a tabela de rateios */
        IF (P_NRRATEIOITEMVENC IS NOT NULL) THEN

            UPDATE FCT_RATEIOITFATURACONT
               SET NRAPURACAO       = V_NRAPURACAO,
                   IDSITUVENCRATEIO = '2'
             WHERE NRORG         = P_NRORG
               AND NRFATURACONT  = C_APUR.NRFATURACONT
               AND NRAPURACAO    IS NULL
               AND ((INSTR(P_NRSEQCONTRATO, '_' || TO_CHAR(NRSEQCONTRATO) || '_') > 0) OR (P_NRSEQCONTRATO IS NULL))
               AND (INSTR(P_NRRATEIOITEMVENC, '_' || TO_CHAR(NRRATEIOITEMFAT) || '_') > 0);

        ELSIF (P_NRITFATURACONT IS NOT NULL) THEN

            UPDATE FCT_RATEIOITFATURACONT
               SET NRAPURACAO       = V_NRAPURACAO
             WHERE NRORG            = P_NRORG
               AND NRFATURACONT     = C_APUR.NRFATURACONT
               AND NRAPURACAO       IS NULL
               AND ((INSTR(P_NRSEQCONTRATO, '_' || TO_CHAR(NRSEQCONTRATO) || '_') > 0) OR (P_NRSEQCONTRATO IS NULL))
               AND ((INSTR(P_NRITFATURACONT, '_' || TO_CHAR(NRITFATURACONT) || '_') > 0));

        ELSE

            UPDATE FCT_RATEIOITFATURACONT
               SET NRAPURACAO       = V_NRAPURACAO,
                   IDSITUVENCRATEIO = '2'
             WHERE NRORG            = P_NRORG
               AND NRFATURACONT     = C_APUR.NRFATURACONT
               AND NRAPURACAO       IS NULL
               AND (IDSITUVENCRATEIO = '1' OR IDSITUVENCRATEIO = '6')
               AND ((INSTR(P_NRSEQCONTRATO, '_' || TO_CHAR(NRSEQCONTRATO) || '_') > 0) OR (P_NRSEQCONTRATO IS NULL));

        END IF;

        /*Contrato*/
        IF C_APUR.NRCONTRATOFCT IS NOT NULL THEN

            SELECT LISTAGG(CONT.NRCONTRATOFCT, ', ') WITHIN GROUP (ORDER BY NRCONTRATOFCT)
            INTO V_NRCONTRATOS
            FROM FCT_RELACAGRUPCONTFAT RELACFAT
            INNER JOIN FCT_CONTRATO CONT
                ON RELACFAT.NRSEQCONTRATO = CONT.NRSEQCONTRATO
                AND RELACFAT.NRORG        = CONT.NRORG
            WHERE RELACFAT.NRFATURACONT   = C_APUR.NRFATURACONT
              AND RELACFAT.NRORG          = C_APUR.NRORG;

            SELECT MAX(NRDADOADIC)
              INTO V_DADOADIC
              FROM DADOSADIC
             WHERE CDFILIAL   = C_APUR.CDFILIALFATURA
               AND NRLANCTONF = V_NRLANCTONF;

            IF V_DADOADIC IS NULL THEN
                V_DADOADIC := '001';
            ELSE
                V_DADOADIC := V_DADOADIC+1;
            END IF;

            INSERT INTO DADOSADIC(
                CDFILIAL,   NRLANCTONF,
                NRDADOADIC, DSDADOADIC
            ) VALUES (
                C_APUR.CDFILIALFATURA,  V_NRLANCTONF,
                LPAD(V_DADOADIC,3,'0'), SUBSTR('Contrato (s): '|| V_NRCONTRATOS, 1, 255)
            );
        END IF;

        /*Vencimento*/
        IF C_APUR.DTVENCIMENTO IS NOT NULL THEN
            SELECT MAX(NRDADOADIC)
            INTO V_DADOADIC
            FROM DADOSADIC
            WHERE CDFILIAL     = C_APUR.CDFILIALFATURA
                AND NRLANCTONF = V_NRLANCTONF;

            IF V_DADOADIC IS NULL THEN
                V_DADOADIC := '001';
            ELSE
                V_DADOADIC := V_DADOADIC + 1;
            END IF;

            BEGIN
                SELECT DTATUAVENREC
                INTO V_VENCIMENTO
                FROM CONTARECEBER
                WHERE NRLANCTONF = V_NRLANCTONF
                    AND CDFILIAL = C_APUR.CDFILIALFATURA;
            EXCEPTION WHEN NO_DATA_FOUND THEN
                    V_VENCIMENTO := C_APUR.DTVENCIMENTO;
            END;

            INSERT INTO DADOSADIC(CDFILIAL, NRLANCTONF, NRDADOADIC, DSDADOADIC)
            VALUES(C_APUR.CDFILIALFATURA, V_NRLANCTONF, LPAD(V_DADOADIC,3,'0'), SUBSTR('Vencimento: '||TO_CHAR(V_VENCIMENTO,'DD/MM/YYYY'), 1, 255));
        END IF;

        /*PerAodo*/
        IF C_APUR.DTINICOMPET IS NOT NULL THEN
            SELECT MAX(NRDADOADIC)
                INTO V_DADOADIC
                FROM DADOSADIC
            WHERE CDFILIAL     = C_APUR.CDFILIALFATURA
                AND NRLANCTONF = V_NRLANCTONF;

            IF V_DADOADIC IS NULL THEN
                V_DADOADIC := '001';
            ELSE
                V_DADOADIC := V_DADOADIC+1;
            END IF;

            INSERT INTO DADOSADIC(CDFILIAL, NRLANCTONF, NRDADOADIC, DSDADOADIC)
                VALUES(C_APUR.CDFILIALFATURA, V_NRLANCTONF, LPAD(V_DADOADIC,3,'0'), SUBSTR('Periodo: '||TO_CHAR(C_APUR.DTINICOMPET,'DD/MM/YYYY')||' - '||TO_CHAR(C_APUR.DTFINCOMPET,'DD/MM/YYYY'), 1, 255));
            END IF;

            /*ObservaAAues*/
            IF C_APUR.DSOBSERVACAOCONT IS NOT NULL THEN
                SELECT MAX(NRDADOADIC)
                    INTO V_DADOADIC
                    FROM DADOSADIC
                    WHERE CDFILIAL   = C_APUR.CDFILIALFATURA
                      AND NRLANCTONF = V_NRLANCTONF;

                IF V_DADOADIC IS NULL THEN
                    V_DADOADIC := '001';
                ELSE
                    V_DADOADIC := V_DADOADIC+1;
                END IF;

                INSERT INTO DADOSADIC(CDFILIAL, NRLANCTONF, NRDADOADIC, DSDADOADIC)
                    VALUES(C_APUR.CDFILIALFATURA, V_NRLANCTONF, LPAD(V_DADOADIC,3,'0'), SUBSTR(C_APUR.DSOBSERVACAOCONT, 1, 255));
            END IF; --C_APUR.DSOBSERVACAOCONT  IS NOT NULL
        END IF; --C_APUR.DTINICOMPET IS NOT NULL
    END LOOP; -- C_APUR

    FOR C_NFFECHAMENTO IN (
        SELECT LISTAGG(RELAC.NRSEQCONTRATO, ',') WITHIN GROUP (ORDER BY RELAC.NRSEQCONTRATO) AS DSNRSEQCONTRATO,
               LISTAGG(RELAC.NRSEQCONTRATO, '_') WITHIN GROUP (ORDER BY RELAC.NRSEQCONTRATO) AS NRSEQCONTRATO,
               DADOS.NRLANCTONF, DADOS.CDFILIAL, DADOS.NRFATURACONT, DADOS.DSREFERENCIANOTA
        FROM FCT_DADOSNF DADOS
        INNER JOIN FCT_RELACAGRUPCONTFAT RELAC
            ON DADOS.NRFATURACONT = RELAC.NRFATURACONT
            AND DADOS.NRORG       = RELAC.NRORG
        WHERE (INSTR('_'||P_NRFATURACONT||'_', '_'||TO_CHAR(DADOS.NRFATURACONT)||'_')>0)
            AND (INSTR('_'||V_NRLANCTONF||'_', '_'||DADOS.NRLANCTONF||'_') > 0)
            AND DADOS.NRORG = P_NRORG
        GROUP BY DADOS.NRLANCTONF, DADOS.CDFILIAL, DADOS.NRFATURACONT, DADOS.DSREFERENCIANOTA
    ) LOOP

        GERA_NOTAFISCAL_FECHAMENTO(C_NFFECHAMENTO.CDFILIAL, C_NFFECHAMENTO.NRLANCTONF);

        SELECT VRNOTAFISC
          INTO V_VRNOTAFISC
          FROM NOTAFISCAL
         WHERE NRLANCTONF = C_NFFECHAMENTO.NRLANCTONF
           AND CDFILIAL   = C_NFFECHAMENTO.CDFILIAL
           AND NRORG      = P_NRORG;

        BEGIN
            SELECT VRVENCIMENTO, VRFALTAFATURAR
              INTO V_VRVENCIMENTO, V_VRFALTAFATURAR
              FROM FCT_FATURACONT
             WHERE NRFATURACONT = C_NFFECHAMENTO.NRFATURACONT
               AND NRORG        = P_NRORG;
        EXCEPTION WHEN NO_DATA_FOUND THEN
            V_VRVENCIMENTO := NULL;
            V_VRFALTAFATURAR := NULL;
        END;

        IF(V_VRFALTAFATURAR IS NOT NULL AND V_VRFALTAFATURAR <> 0) THEN
            V_VRNOTAFISC     := ROUND(V_VRNOTAFISC, 2);
            V_VRVENCIMENTO   := ROUND(V_VRVENCIMENTO, 2);
            V_VRFALTAFATURAR := ROUND(V_VRFALTAFATURAR, 2);

            IF (V_VRNOTAFISC = V_VRVENCIMENTO) THEN
                V_IDSITUACAO := '2';
                UPDATE FCT_FATURACONT
                   SET IDSITUACAO     = V_IDSITUACAO,
                       VRFATURADO     = ROUND(V_VRNOTAFISC, 2),
                       VRFALTAFATURAR = 0,
                       IDFORMAFATURA  = 'A'
                 WHERE NRFATURACONT = C_NFFECHAMENTO.NRFATURACONT
                   AND NRORG          = P_NRORG;
            ELSE
                IF (V_VRFALTAFATURAR - V_VRNOTAFISC) = 0 THEN
                    V_IDSITUACAO := '2';
                ELSE
                    V_IDSITUACAO := '6';
                END IF;

                UPDATE FCT_FATURACONT
                   SET IDSITUACAO     = V_IDSITUACAO,
                       VRFATURADO     = ROUND(VRFATURADO + V_VRNOTAFISC, 2),
                       VRFALTAFATURAR = ROUND(VRFALTAFATURAR - V_VRNOTAFISC, 2),
                       IDFORMAFATURA  = 'A'
                 WHERE NRFATURACONT   = C_NFFECHAMENTO.NRFATURACONT
                   AND NRORG          = P_NRORG;
            END IF;

            IF (V_IDSITUACAO = '2') THEN
                UPDATE FCT_RATEIOITFATURACONT
                   SET IDSITUVENCRATEIO = '2'
                 WHERE NRFATURACONT = C_NFFECHAMENTO.NRFATURACONT
                   AND NRORG        = P_NRORG;

                UPDATE FCT_ITFATURACONT
                   SET IDSITUACAO     = '2',
                       VRFALTAFATURAR = 0,
                       VRFATURADO     = ROUND(VRVENCIMENTO, 2)
                 WHERE NRFATURACONT = C_NFFECHAMENTO.NRFATURACONT
                   AND NRORG        = P_NRORG;
            END IF; --V_IDSITUACAO = '2'

        END IF; --V_VRFALTAFATURAR IS NOT NULL AND V_VRFALTAFATURAR <> 0

        UPDATE FCT_APURACAO
           SET VRAPURACAO         = ROUND(V_VRNOTAFISC, 2),
               VRAPURACAOORIGINAL = ROUND(V_VRNOTAFISC, 2)
         WHERE NRAPURACAO = V_NRAPURACAO
           AND NRORG      = P_NRORG;

        -- UPDATA VALORES DO RATEIO PARA CONSIDER O VALOR CONTAAAoAAparam1BIL DO ITEM DA NF (ITEMPRODUTO.VRCONTITEM)
        FOR C_UPDRATEIO IN (
            SELECT NRSEQITPROD, VRRATENF, CDFILICCUST, CDCENTCUSNF
            FROM RATEIONF RAT
            WHERE RAT.NRLANCTONF =  C_NFFECHAMENTO.NRLANCTONF
                AND RAT.CDFILIAL = C_NFFECHAMENTO.CDFILIAL
                AND NRORG        = P_NRORG
        ) LOOP

            -- Busca valores do item
            SELECT VRCONTITEM, VRBRUTITEM
              INTO V_VRCONTITEM, V_VRBRUTITEM
              FROM ITEMPRODUTO
             WHERE NRLANCTONF  = C_NFFECHAMENTO.NRLANCTONF
               AND CDFILIAL    = C_NFFECHAMENTO.CDFILIAL
               AND NRSEQITPROD = C_UPDRATEIO.NRSEQITPROD
               AND NRORG       = P_NRORG;

            /*SELECT (C_UPDRATEIO.VRRATENF*100)/ V_VRBRUTITEM
              INTO V_VRPERCRATEIO
              FROM DUAL;*/
            V_VRPERCRATEIO := (C_UPDRATEIO.VRRATENF * 100) / V_VRBRUTITEM;

            IF V_VRPERCRATEIO = 100 THEN
                V_VRRATEIO := V_VRCONTITEM;
            ELSE
                V_VRRATEIO := (V_VRCONTITEM * V_VRPERCRATEIO)/100;
            END IF;

            UPDATE RATEIONF
               SET VRRATENF = V_VRRATEIO
             WHERE CDFILIAL    = C_NFFECHAMENTO.CDFILIAL
               AND NRLANCTONF  = C_NFFECHAMENTO.NRLANCTONF
               AND CDFILICCUST = C_UPDRATEIO.CDFILICCUST
               AND CDCENTCUSNF = C_UPDRATEIO.CDCENTCUSNF
               AND NRSEQITPROD = C_UPDRATEIO.NRSEQITPROD
               AND NRORG       = P_NRORG;
        END LOOP; --C_UPDRATEIO

        /* atualiza a descriAAo do item da NF de acordo com a referencia da FCT_DADOSNF*/
        IF C_NFFECHAMENTO.DSREFERENCIANOTA IS NOT NULL THEN
            UPDATE ITEMPRODUTO
               SET DSPRODEMIS = C_NFFECHAMENTO.DSREFERENCIANOTA
             WHERE NRLANCTONF = C_NFFECHAMENTO.NRLANCTONF
               AND CDFILIAL   = C_NFFECHAMENTO.CDFILIAL
               AND NRORG      = P_NRORG;
        END IF;

        /* atualiza a descriAAo do item da NF de acordo com a parametrizaAAo do serviAo, SIM, ELA SUBSTITUI A DO FCT_DADOSNF*/
        FOR C_ITENSVENC IN (
            SELECT ITCONT.CDSERVORCA,
              LISTAGG(ITFAT.NRITFATURACONT, '_') WITHIN GROUP (ORDER BY ITFAT.NRITFATURACONT) AS NRITFATURACONT,
              LISTAGG(ITFAT.NRITEMOCONTRATO, '_') WITHIN GROUP (ORDER BY ITFAT.NRITEMOCONTRATO) AS NRITEMOCONTRATO
            FROM FCT_ITFATURACONT ITFAT
            INNER JOIN FCT_ITEMCONTRATO ITCONT
              ON ITFAT.NRITEMOCONTRATO = ITCONT.NRITEMOCONTRATO
              AND ITFAT.NRORG          = ITCONT.NRORG
            WHERE ITFAT.NRFATURACONT = C_NFFECHAMENTO.NRFATURACONT
                AND ITFAT.NRORG      = P_NRORG
                AND (INSTR('_'|| C_NFFECHAMENTO.NRSEQCONTRATO ||'_', '_'|| ITFAT.NRSEQCONTRATO ||'_') > 0)
            GROUP BY ITCONT.CDSERVORCA
        ) LOOP

            V_DSSERVORCANF  := NULL;
            V_DSSERVORCABOL := NULL;
            FOR C_SERVICOS IN (
                SELECT LISTAGG(PARCELA.NRORCAMENTO, ', ') WITHIN GROUP (ORDER BY PARCELA.NRORCAMENTO) AS NRORCAMENTO,
                       LISTAGG(PARCELA.NRCONTRATOFCT, ', ') WITHIN GROUP (ORDER BY PARCELA.NRCONTRATOFCT) AS NRCONTRATOFCT,
                       PARCELA.DTINICONT,
                       PARCELA.DTFINCONT,
                       PARCELA.NMPRINCIPALPARC,
                       MAX(PARCELA.QTPARCELASTOT) AS QTPARCELASTOT,
                       MAX(PARCELA.QTPARCELAS) AS QTPARCELAS,
                       PARCELA.DTINICOMPET,
                       PARCELA.DTFINCOMPET,
                       PARCELA.NMITEMCONTRATO,
                       SUM(PARCELA.VRTOTITEMCONT) AS VRTOTITEMCONT,
                       PARCELA.CDPRODFATSERV,
                       PARCELA.CDSERVORCA,
                       LISTAGG(PARCELA.NRMEDICAOFATURA, '_') WITHIN GROUP (ORDER BY PARCELA.NRMEDICAOFATURA) AS NRMEDICAOFATURA,
                       PARCELA.DSSERVORCANF,
                       PARCELA.DSSERVORCABOL,
                       PARCELA.MESCOMPET
                FROM (
                      SELECT ORC.NRORCAMENTO,
                         CONT.NRCONTRATOFCT,
                         NVL (TO_CHAR(CONT.DTINIVIGENCONT, 'DD/MM/YYYY'), TO_CHAR(CONT.DTINICIOCONTRATO, 'DD/MM/YYYY')) AS DTINICONT,
                         NVL (TO_CHAR(CONT.DTFINVIGENCONT, 'DD/MM/YYYY'), TO_CHAR(CONT.DTFIMCONTRATO, 'DD/MM/YYYY')) AS DTFINCONT,
                         PARC.NMPRINCIPALPARC,
                         PARCELATOT.QTPARCELASTOT,
                         NVL(PARCELA.QTPARCELAS, 0) AS QTPARCELAS,
                         TO_CHAR(FAT.DTINICOMPET, 'MM/YYYY') AS MESCOMPET,
                         TO_CHAR(FAT.DTINICOMPET, 'DD/MM/YYYY') AS DTINICOMPET,
                         TO_CHAR(FAT.DTFINCOMPET, 'DD/MM/YYYY') AS DTFINCOMPET,
                         ITEMCONT.NMITEMCONTRATO,
                         NVL(ITEMCONT.VRTOTITEMCONT,0) AS VRTOTITEMCONT,
                         SERVORCA.CDPRODFATSERV,
                         SERVORCA.CDSERVORCA,
                         AGCONTFAT.NRMEDICAOFATURA,
                         SERVORCA.DSSERVORCANF,
                         SERVORCA.DSSERVORCABOL
                    FROM FCT_CONTRATO CONT
                    INNER JOIN FCT_RELACAGRUPCONTFAT AGCONTFAT
                          ON AGCONTFAT.NRSEQCONTRATO = CONT.NRSEQCONTRATO
                         AND AGCONTFAT.NRORG         = CONT.NRORG
                    INNER JOIN FCT_FATURACONT FAT
                         ON FAT.NRFATURACONT = AGCONTFAT.NRFATURACONT
                        AND FAT.NRORG        = AGCONTFAT.NRORG
                    INNER JOIN PARCNEGOCIO PARC
                         ON PARC.NRPARCNEGOCIO = CONT.NRPARCNEGOCIO
                        AND PARC.NRORG         = CONT.NRORG
                    LEFT JOIN (
                        SELECT AGRUPCONT.NRSEQCONTRATO,
                             AGRUPCONT.NRORG,
                             COUNT(AGRUPCONT.NRFATURACONT) AS QTPARCELASTOT
                        FROM FCT_RELACAGRUPCONTFAT AGRUPCONT
                        JOIN FCT_ITFATURACONT
                          ON FCT_ITFATURACONT.NRFATURACONT    = AGRUPCONT.NRFATURACONT
                         AND FCT_ITFATURACONT.NRORG           = AGRUPCONT.NRORG
                         AND (INSTR('_'|| C_ITENSVENC.NRITEMOCONTRATO ||'_', '_'||FCT_ITFATURACONT.NRITEMOCONTRATO||'_') > 0)
                       WHERE (INSTR('_'|| C_NFFECHAMENTO.NRSEQCONTRATO ||'_', '_'||AGRUPCONT.NRSEQCONTRATO||'_') > 0)
                         AND AGRUPCONT.NRORG = P_NRORG
                      GROUP BY AGRUPCONT.NRSEQCONTRATO, AGRUPCONT.NRORG
                    ) PARCELATOT
                        ON PARCELATOT.NRSEQCONTRATO = CONT.NRSEQCONTRATO
                        AND PARCELATOT.NRORG = CONT.NRORG
                    LEFT JOIN (
                        SELECT AGRUPCONT.NRSEQCONTRATO,
                             AGRUPCONT.NRORG,
                             COUNT(AGRUPCONT.NRFATURACONT) AS QTPARCELAS
                        FROM FCT_RELACAGRUPCONTFAT AGRUPCONT
                        JOIN FCT_ITFATURACONT
                          ON FCT_ITFATURACONT.NRFATURACONT    = AGRUPCONT.NRFATURACONT
                         AND FCT_ITFATURACONT.NRORG           = AGRUPCONT.NRORG
                         AND (INSTR('_'|| C_ITENSVENC.NRITEMOCONTRATO ||'_', '_'||FCT_ITFATURACONT.NRITEMOCONTRATO||'_') > 0)
                       WHERE (INSTR('_'|| C_NFFECHAMENTO.NRSEQCONTRATO ||'_', '_'||AGRUPCONT.NRSEQCONTRATO||'_') > 0)
                         AND AGRUPCONT.NRORG = P_NRORG
                         AND FCT_ITFATURACONT.IDSITUACAO IN('2', '3')
                      GROUP BY AGRUPCONT.NRSEQCONTRATO, AGRUPCONT.NRORG
                    ) PARCELA
                         ON PARCELA.NRSEQCONTRATO = CONT.NRSEQCONTRATO
                        AND PARCELA.NRORG = CONT.NRORG
                    LEFT JOIN FCT_REFEORCACONT RELACCONTPROP
                         ON RELACCONTPROP.NRSEQCONTRATO = CONT.NRSEQCONTRATO
                         AND RELACCONTPROP.NRORG = CONT.NRORG
                    LEFT JOIN FCT_ORCAMENTO ORC
                         ON RELACCONTPROP.NRSEQORCAMENTO = ORC.NRSEQORCAMENTO
                        AND RELACCONTPROP.NRORG = ORC.NRORG
                    INNER JOIN FCT_ITEMCONTRATO ITEMCONT
                         ON ITEMCONT.NRSEQCONTRATO = CONT.NRSEQCONTRATO
                        AND (INSTR('_'|| C_ITENSVENC.NRITEMOCONTRATO ||'_', '_'||ITEMCONT.NRITEMOCONTRATO||'_') > 0)
                        AND ITEMCONT.NRORG = CONT.NRORG
                    INNER JOIN FCT_SERVICOORCA SERVORCA
                         ON SERVORCA.CDSERVORCA = ITEMCONT.CDSERVORCA
                        AND SERVORCA.NRORG = ITEMCONT.NRORG
                    WHERE (INSTR('_'|| C_NFFECHAMENTO.NRSEQCONTRATO ||'_', '_'||CONT.NRSEQCONTRATO||'_') > 0)
                        AND CONT.NRORG             = P_NRORG
                        AND AGCONTFAT.NRFATURACONT = C_NFFECHAMENTO.NRFATURACONT
                        AND SERVORCA.DSSERVORCANF IS NOT NULL
                ) PARCELA
                GROUP BY PARCELA.DTINICONT,
                       PARCELA.DTFINCONT,
                       PARCELA.NMPRINCIPALPARC,
                       PARCELA.DTINICOMPET,
                       PARCELA.DTFINCOMPET,
                       PARCELA.NMITEMCONTRATO,
                       PARCELA.CDPRODFATSERV,
                       PARCELA.CDSERVORCA,
                       PARCELA.DSSERVORCANF,
                       PARCELA.DSSERVORCABOL,
                       PARCELA.MESCOMPET
            ) LOOP

                V_DSSERVORCANF := C_SERVICOS.DSSERVORCANF;

                IF V_DSSERVORCABOL IS NULL THEN
                    V_DSSERVORCABOL := C_SERVICOS.DSSERVORCABOL;
                ELSE
                    V_DSSERVORCABOL := V_DSSERVORCABOL||CHR(10)||CHR(10)||C_SERVICOS.DSSERVORCABOL;
                END IF;

                V_MEDVARIAVEIS := NULL;

                IF (C_SERVICOS.NRMEDICAOFATURA IS NOT NULL) THEN
                    FOR MEDVAR IN (
                        SELECT SERV.NMSERVORCA,
                          TPMEDIDA.DSTPMEDIDASERV,
                          NVL(QTMEDIDAMEDICAO, QTMEDIDAVARIAVEL) AS QTMEDIDAVAR,
                          CONT.NRCONTRATOFCT
                        FROM FCT_MEDVARMEDICAOFATURA MEDVAR
                        JOIN FCT_TIPOMEDIDASERV TPMEDIDA
                           ON MEDVAR.CDTPMEDIDAVARIAVEL = TPMEDIDA.CDTPMEDIDASERV
                          AND MEDVAR.NRORG              = TPMEDIDA.NRORG
                        JOIN FCT_SERVICOORCA SERV
                           ON MEDVAR.IDELEMENTORAIZ = SERV.IDELEMENTO
                          AND MEDVAR.NRORG          = SERV.NRORG
                        INNER JOIN FCT_MEDICAOFATURA MEDICAO
                          ON MEDVAR.NRMEDICAOFATURA = MEDICAO.NRMEDICAOFATURA
                          AND MEDVAR.NRORG          = MEDICAO.NRORG
                        INNER JOIN FCT_CONTRATO CONT
                          ON MEDICAO.NRSEQCONTRATO = CONT.NRSEQCONTRATO
                          AND MEDICAO.NRORG        = CONT.NRORG
                        WHERE (INSTR('_'|| C_SERVICOS.NRMEDICAOFATURA ||'_', '_'|| MEDVAR.NRMEDICAOFATURA ||'_') > 0)
                          AND MEDVAR.CDSERVORCA = C_SERVICOS.CDSERVORCA
                          AND MEDVAR.NRORG      = P_NRORG
                        ORDER BY NRCONTRATOFCT
                    ) LOOP
                        IF(V_MEDVARIAVEIS IS NULL OR INSTR(V_MEDVARIAVEIS, MEDVAR.NRCONTRATOFCT) = 0) THEN
                            IF(V_MEDVARIAVEIS IS NULL) THEN
                                V_NRCONTRATOS := 'Contrato: ' || MEDVAR.NRCONTRATOFCT || ':' || CHR(13);
                            ELSE
                                V_NRCONTRATOS := CHR(13) || 'Contrato: ' || MEDVAR.NRCONTRATOFCT || ':' || CHR(13);
                            END IF;
                        ELSE
                            V_NRCONTRATOS := CHR(13);
                        END IF;

                        IF (V_MEDVARIAVEIS IS NULL) THEN
                            V_MEDVARIAVEIS := V_NRCONTRATOS || MEDVAR.NMSERVORCA ||' - Medida: '|| MEDVAR.DSTPMEDIDASERV||' - Qtde:'||MEDVAR.QTMEDIDAVAR;
                        ELSE
                            V_MEDVARIAVEIS := V_MEDVARIAVEIS || V_NRCONTRATOS || MEDVAR.NMSERVORCA||' - Medida: '||MEDVAR.DSTPMEDIDASERV||' - Qtde:'||MEDVAR.QTMEDIDAVAR;
                        END IF;

                    END LOOP; --MEDVAR
                END IF; --C_SERVICOS.NRMEDICAOFATURA IS NOT NULL

                V_PARCELAS := C_SERVICOS.QTPARCELAS ||'/'|| C_SERVICOS.QTPARCELASTOT;
                /*MnemAnicos: [CODPROP] - CAdigo Proposta | [CODCONT] - CAdigo Contrato [DTINICONT] - Data inicial do Contrato | [DTFINCONT] - Data final do contrato | [PARCEIRO] - Parceiro de NegAcio |
                            [PARCELA] - Parcelas | [MESCOMPET] - MAs de CompetAncia da Parcela | [DTINICOMPET] - Data de Inicio da CompetAncia | [DTFINCOMPET] - Data Final de CompetAncia |
                            [NMSERVICO] - Nome do ServiAo | [VRSERVICO] - Valor do ServiAo | [MEDVARIAVES] - Elementos e tipos Medidas variAveis e suas quantidades (Somente para serviAos que sejam de mediAAo) */

                V_DSSERVORCANF  := REPLACE(V_DSSERVORCANF,'[CODPROP]', NVL(C_SERVICOS.NRORCAMENTO, ''));
                V_DSSERVORCABOL := REPLACE(V_DSSERVORCABOL,'[CODPROP]', NVL(C_SERVICOS.NRORCAMENTO, ''));

                V_DSSERVORCANF  := REPLACE(V_DSSERVORCANF,'[CODCONT]', NVL(C_SERVICOS.NRCONTRATOFCT, ''));
                V_DSSERVORCABOL := REPLACE(V_DSSERVORCABOL,'[CODCONT]', NVL(C_SERVICOS.NRCONTRATOFCT, ''));

                V_DSSERVORCANF  := REPLACE(V_DSSERVORCANF,'[DTINICONT]', NVL(C_SERVICOS.DTINICONT, ''));
                V_DSSERVORCABOL := REPLACE(V_DSSERVORCABOL,'[DTINICONT]', NVL(C_SERVICOS.DTINICONT, ''));

                V_DSSERVORCANF  := REPLACE(V_DSSERVORCANF,'[DTFINCONT]', NVL(C_SERVICOS.DTFINCONT, ''));
                V_DSSERVORCABOL := REPLACE(V_DSSERVORCABOL,'[DTFINCONT]', NVL(C_SERVICOS.DTFINCONT, ''));

                V_DSSERVORCANF  := REPLACE(V_DSSERVORCANF,'[PARCEIRO]', NVL(C_SERVICOS.NMPRINCIPALPARC, ''));
                V_DSSERVORCABOL := REPLACE(V_DSSERVORCABOL,'[PARCEIRO]', NVL(C_SERVICOS.NMPRINCIPALPARC, ''));

                V_DSSERVORCANF  := REPLACE(V_DSSERVORCANF,'[PARCELA]', NVL(V_PARCELAS, ''));
                V_DSSERVORCABOL := REPLACE(V_DSSERVORCABOL,'[PARCELA]', NVL(V_PARCELAS, ''));

                V_DSSERVORCANF  := REPLACE(V_DSSERVORCANF,'[MESCOMPET]', NVL(C_SERVICOS.MESCOMPET, ''));
                V_DSSERVORCABOL := REPLACE(V_DSSERVORCABOL,'[MESCOMPET]', NVL(C_SERVICOS.MESCOMPET, ''));

                V_DSSERVORCANF  := REPLACE(V_DSSERVORCANF,'[DTINICOMPET]', NVL(C_SERVICOS.DTINICOMPET, ''));
                V_DSSERVORCABOL := REPLACE(V_DSSERVORCABOL,'[DTINICOMPET]', NVL(C_SERVICOS.DTINICOMPET, ''));

                V_DSSERVORCANF  := REPLACE(V_DSSERVORCANF,'[DTFINCOMPET]', NVL(C_SERVICOS.DTFINCOMPET, ''));
                V_DSSERVORCABOL := REPLACE(V_DSSERVORCABOL,'[DTFINCOMPET]', NVL(C_SERVICOS.DTFINCOMPET, ''));

                V_DSSERVORCANF  := REPLACE(V_DSSERVORCANF,'[NMSERVICO]', NVL(C_SERVICOS.NMITEMCONTRATO, ''));
                V_DSSERVORCABOL := REPLACE(V_DSSERVORCABOL,'[NMSERVICO]', NVL(C_SERVICOS.NMITEMCONTRATO, ''));

                V_DSSERVORCANF  := REPLACE(V_DSSERVORCANF,'[VRSERVICO]', NVL(C_SERVICOS.VRTOTITEMCONT, ''));
                V_DSSERVORCABOL := REPLACE(V_DSSERVORCABOL,'[VRSERVICO]', NVL(C_SERVICOS.VRTOTITEMCONT, ''));

                V_DSSERVORCANF  := REPLACE(V_DSSERVORCANF,'[MEDVARIAVEIS]', NVL(V_MEDVARIAVEIS, ''));
                V_DSSERVORCABOL := REPLACE(V_DSSERVORCABOL,'[MEDVARIAVEIS]', NVL(V_MEDVARIAVEIS, ''));

                /*Atualiza a descriAAo do produto da NF*/
                UPDATE ITEMPRODUTO
                   SET DSPRODEMIS = V_DSSERVORCANF
                 WHERE NRLANCTONF = C_NFFECHAMENTO.NRLANCTONF
                   AND CDFILIAL   = C_NFFECHAMENTO.CDFILIAL
                   AND CDPRODUTO  = C_SERVICOS.CDPRODFATSERV
                   AND NRORG      = P_NRORG;

            END LOOP; --C_SERVICOS

            /* Corta a descriAAo do boleto para caber em 400 charactAres */

            IF (LENGTH(V_DSSERVORCABOL) > 400) THEN
                V_DSSERVORCABOL := SUBSTR(V_DSSERVORCABOL, 0 ,400);
            END IF;

            IF (LENGTH(V_DSSERVORCANF) > 400) THEN
                V_DSSERVORCANF := SUBSTR(V_DSSERVORCANF, 0 ,400);
            END IF;

            /* Atualiza o Boleto da NF */
            UPDATE CONTARECEBER
               SET DSCONTAREC = V_DSSERVORCABOL
             WHERE NRLANCTONF = C_NFFECHAMENTO.NRLANCTONF
               AND CDFILIAL = C_NFFECHAMENTO.CDFILIAL
               AND NRORG = P_NRORG;

        END LOOP; --C_ITENSVENC
    END LOOP; --C_NFFECHAMENTO
    P_RETORNO := 'SUCESS';
    P_RETORNOERRO := 'Processo realizado com sucesso.';
 EXCEPTION
   -- Caso d~e algum erro no faturamento, serAo deletadas as notas fiscais para nAo ficar lixo na base de dados. --
    WHEN OTHERS THEN BEGIN
        IF V_NFCRIADA IS NOT NULL THEN -- Verifica se tem NF criada --
            IF V_APURACAOCONLUIDA IS NULL THEN -- Verifica se a NF criada nAo foi vinculada A  apuraAAo. No caso, se ja foi gravada a ITEMPRODUTO e a FCT_APURACAO --
                FOR C_EXCEPTION IN (SELECT DISTINCT NRLANCTONF, CDFILIAL
                                  FROM NOTAFISCAL
                                 WHERE (INSTR('_'||V_NFCRIADA||'_', '_'||NRLANCTONF||'_')>0)
                                   AND (CDFILIAL = V_FILIAL)
                                   AND NRORG = P_NRORG
                ) LOOP
                    --  Caso exista rateio para nota, deleta o rateio --
                    DELETE FROM RATEIONF
                          WHERE NRORG = P_NRORG
                            AND NRLANCTONF = C_EXCEPTION.NRLANCTONF
                            AND CDFILIAL = C_EXCEPTION.CDFILIAL;
                    -- Deleta a NF ---
                    DELETA_NF(C_EXCEPTION.CDFILIAL,C_EXCEPTION.NRLANCTONF);

                    --  ALTERA O STATUS DO VENCIMEMNTO PARA PENDENTE --
                    FOR C_UPDVENC IN (SELECT NRAPURACAO
                                   FROM FCT_APURACAO
                                  WHERE NRLANCTONF = C_EXCEPTION.NRLANCTONF
                                    AND CDFILIAL = C_EXCEPTION.CDFILIAL
                                    AND NRORG = P_NRORG
                    ) LOOP
                        UPDATE FCT_FATURACONT
                           SET IDSITUACAO = '1',
                               IDFORMAFATURA  = NULL
                         WHERE NRORG = P_NRORG
                           AND NRAPURACAO = C_UPDVENC.NRAPURACAO;
                    END LOOP; --C_UPDVENC
                END LOOP; --C_EXCEPTION
            ELSE
                FCT_CANC_APURCAO_FATURAMENTO (P_NRORG, P_NRSEQCONTRATO, P_CDOPERINCLUSAO, P_DATAINI, P_DATAFIN, P_NRFATURACONT, P_NRRATEIOITEMVENC, P_NRITFATURACONT);
            END IF; --V_APURACAOCONLUIDA IS NULL
        END IF; --V_NFCRIADA IS NOT NULL
        P_RETORNO := 'ERROR';
        P_RETORNOERRO := 'OperaAAo bloqueada. Ocorreram erros na realizaAAo do processo.';
   END;
END;
/