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)

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;
BEGIN

 /*
    ERROS
    -20001 - Empresa para faturamento nao encontrada
    -20002 - Grupo para faturamento nao encontrado
    -20003 - Cliente para faturamento nao encontrado
    */

   V_NFCRIADA := NULL;
   /* Realiza a busca dos dados do Faturamento */
   FOR C_APUR IN (SELECT FCT_FATURACONT.NRFATURACONT, FCT_FATURACONT.NRSEQCONTRATO, FCT_CONTRATO.NRCONTRATOFCT, FCT_CONTRATO.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.VRVENCIMENTO,
                         FCT_FATURACONT.VRFATURADO, FCT_FATURACONT.VRFALTAFATURAR, FCT_FATURACONT.IDFORMAFATURA, FCT_FATURACONT.DSJUSTIFICATIVA,
                         FCT_FATURACONT.NRAPURACAO, FCT_FATURACONT.NRMEDICAOFATURA, FCT_FATURACONT.IDATIVO, FCT_FATURACONT.NRORG
                    FROM FCT_FATURACONT
                    JOIN FCT_CONTRATO
                      ON FCT_CONTRATO.NRSEQCONTRATO = FCT_FATURACONT.NRSEQCONTRATO
                     AND FCT_CONTRATO.NRORG = FCT_FATURACONT.NRORG
                   WHERE (FCT_FATURACONT.NRORG = P_NRORG)
                     AND ((INSTR(P_NRSEQCONTRATO, '_' || TO_CHAR(FCT_FATURACONT.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 ((INSTR(P_NRGRUPOFATURA, '_' || TO_CHAR(FCT_FATURACONT.NRGRUPOFATURA) || '_') > 0) OR (P_NRGRUPOFATURA 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')) LOOP

      /*Preenche Filial*/
      V_FILIAL := C_APUR.CDFILIALFATURA;

      /* Recebe empresa para faturamento */
       BEGIN
          SELECT CDEMPRESA
            INTO V_EMPRESA
            FROM FILIAL
           WHERE CDFILIAL = V_FILIAL
             AND NRORG = P_NRORG;
       EXCEPTION
          WHEN NO_DATA_FOUND THEN
            RAISE_APPLICATION_ERROR('-20001', 'SEM_EMPRESA');
       END;

       /* Recebe dados do grupo de faturamento */
       BEGIN
          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;
       EXCEPTION
          WHEN NO_DATA_FOUND THEN BEGIN
             RAISE_APPLICATION_ERROR('-20002', 'SEM_GRUPO_FATURAMENTO');
          END;
       END;

       /* 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;
       EXCEPTION
          WHEN NO_DATA_FOUND THEN
             RAISE_APPLICATION_ERROR('-20003', 'SEM_CLIENTE');
       END;

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


       /* ----- Recebe a data de saída da NF ----- */

       V_DTEMISS := TRUNC(SYSDATE);

       /* 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,'FAS', 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
                        JOIN PRODUTO
                          ON PRODUTO.CDPRODUTO = FCT_ITFATURACONT.CDPRODFATURA
                         AND PRODUTO.NRORG = FCT_ITFATURACONT.NRORG
                       WHERE FCT_ITFATURACONT.NRFATURACONT = C_APUR.NRFATURACONT
                         AND FCT_ITFATURACONT.NRSEQCONTRATO = C_APUR.NRSEQCONTRATO
                         AND FCT_ITFATURACONT.NRORG = P_NRORG
      ) LOOP



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

          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, C_ITENS.VRVENCIMENTO);

          ELSE
             UPDATE ITEMPRODUTO
                SET VRUNITITEM = VRUNITITEM + C_ITENS.VRVENCIMENTO,
                    VRTOTAITEM = VRTOTAITEM + C_ITENS.VRVENCIMENTO
              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 */

          /* -- Rateio será realizado posteriormente --

          IF ((C_APUR.IDTPFATURA <> 'P') AND (C_ITENS.IDRATEADO = 'S')) THEN

             FOR C_RATEIO IN (
                 SELECT NRRATEIOITEMVENC, NRITVENCPREVCONT, NRVENCPREVCONT, NRSEQCONTRATO, NRITEMOCONTRATO,
                        NRESTRUTURAM, CDCENTCUST, VRRATEADO
                   FROM FCT_RATEIOITVENCIMENTO RAT
                  WHERE RAT.NRVENCPREVCONT   = C_APUR.NRVENCPREVCONT
                    AND RAT.NRSEQCONTRATO    = C_APUR.NRSEQCONTRATO
                    AND RAT.NRITVENCPREVCONT = C_ITENS.NRITVENCPREVCONT
                    AND RAT.IDSITUVENCRATEIO <> 'F'
                    AND ((INSTR(P_NRRATEIOITEMVENC, '_' || TO_CHAR(RAT.NRRATEIOITEMVENC) || '_') > 0) OR P_NRRATEIOITEMVENC IS NULL)
             ) LOOP
                   -- Busca o nímero 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.PROD;

                    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,
                                          C_RATEIO.VRRATEADO, P_NRORG, SYSDATE, 'S');
                   ELSE

                       UPDATE RATEIONF
                          SET VRRATENF = VRRATENF + C_RATEIO.VRRATEADO
                        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;

                   END IF;

             END LOOP; -- C_RATEIO
          END IF;  -- IDRATEADO = S
          -- Rateio será realizado posteriormente -- */
       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;

         /* Gera apuracao do contrato */
          IF (V_NRAPURACAO IS NULL) THEN

              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)
              VALUES
                    (V_NRAPURACAO, C_APUR.NRSEQCONTRATO, V_TPORCA,
                     C_APUR.NRPARCFATURA, NULL, C_APUR.NRGRUPOFATURA,
                     V_EMPRESA, C_APUR.CDFILIALFATURA, V_NRLANCTONF,
                     'FATURADA', C_APUR.VRVENCIMENTO, C_APUR.VRVENCIMENTO,
                     NULL, NULL, P_NRORG,
                     SYSDATE, P_NRORG, P_CDOPERINCLUSAO);
          END IF;

          /* Atualiza a tabela de rateios */

          /* -- Rateio será realizado posteriormente --
          IF (P_NRRATEIOITEMVENC IS NOT NULL) THEN

              UPDATE FCT_RATEIOITVENCIMENTO
                 SET NRAPURACAO       = V_NRAPURACAO,
                     IDSITUVENCRATEIO = 'F'
               WHERE NRORG          = P_NRORG
                 AND NRVENCPREVCONT = C_APUR.NRVENCPREVCONT
                 AND NRSEQCONTRATO  = C_APUR.NRSEQCONTRATO
                 AND NRAPURACAO     IS NULL
                 AND (INSTR(P_NRRATEIOITEMVENC, '_' || TO_CHAR(NRRATEIOITEMVENC) || '_') > 0);

          ELSE */

            /* Atualiza tabela de Previsao de Vencimento */

            UPDATE FCT_FATURACONT
              SET NRAPURACAO     = V_NRAPURACAO
            WHERE NRORG          = P_NRORG
              AND NRSEQCONTRATO  = C_APUR.NRSEQCONTRATO
              AND NRFATURACONT = C_APUR.NRFATURACONT;

/* -- Rateio será realizado posteriormente --
            UPDATE FCT_RATEIOITVENCIMENTO
               SET NRAPURACAO       = V_NRAPURACAO,
                   IDSITUVENCRATEIO = 'F'
             WHERE NRORG            = P_NRORG
               AND NRSEQCONTRATO    = C_APUR.NRSEQCONTRATO
               AND NRVENCPREVCONT   = C_APUR.NRFATURACONT
               AND NRAPURACAO       IS NULL
               AND IDSITUVENCRATEIO <> 'F';


         -- END IF;    Rateio será realizado posteriormente

             /*Contrato*/
             IF C_APUR.NRCONTRATOFCT 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'), 'Contrato: '||C_APUR.NRCONTRATOFCT);
             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'), 'Vencimento: '||TO_CHAR(V_VENCIMENTO,'DD/MM/YYYY'));
              END IF;

              /*Período*/
              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'), 'Período: '||TO_CHAR(C_APUR.DTINICOMPET,'DD/MM/YYYY')||' - '||TO_CHAR(C_APUR.DTFINCOMPET,'DD/MM/YYYY'));
              END IF;

              /*Observações*/
              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'), C_APUR.DSOBSERVACAOCONT);
              END IF;
       END IF;
    END LOOP;

    FOR C_NFFECHAMENTO IN (SELECT DISTINCT NRSEQCONTRATO, NRLANCTONF, CDFILIAL, NRFATURACONT, DSREFERENCIANOTA
                            FROM FCT_DADOSNF
                           WHERE (INSTR('_'||P_NRSEQCONTRATO||'_', '_'||TO_CHAR(NRSEQCONTRATO)||'_')>0)
                             AND (INSTR('_'||V_NFCRIADA||'_', '_'||NRLANCTONF||'_')>0)
                             AND NRORG = P_NRORG) 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) THEN
        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     = V_VRNOTAFISC,
                   VRFALTAFATURAR = 0,
                   IDFORMAFATURA  = 'A'
             WHERE NRFATURACONT = C_NFFECHAMENTO.NRFATURACONT
               AND NRORG          = P_NRORG;
        ELSE
            IF (V_VRNOTAFISC = V_VRFALTAFATURAR) THEN
                V_IDSITUACAO := '2';
            ELSE
                V_IDSITUACAO := 'I';
            END IF;

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

        /* -- Rateio será realizado posteriormente --

        IF (V_IDSITUACAO = 'F') THEN
            UPDATE FCT_RATEIOITVENCIMENTO
               SET IDSITUVENCRATEIO = 'F'
             WHERE NRVENCPREVCONT = C_NFFECHAMENTO.NRVENCPREVCONT
               AND NRORG          = P_NRORG;
        END IF;

        */
      END IF;

      UPDATE FCT_APURACAO
         SET VRAPURACAO         = V_VRNOTAFISC,
             VRAPURACAOORIGINAL = V_VRNOTAFISC
       WHERE NRAPURACAO = V_NRAPURACAO
         AND NRORG      = P_NRORG;

       /* -- Rateio será realizado posteriormente --

       -- UPDATA VALORES DO RATEIO PARA CONSIDER O VALOR CONTÃÂBIL 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;

           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;

       */

       /* atualiza a descrição 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 descrição do item da NF de acordo com a parametrização do serviço, SIM, ELA SUBSTITUI A DO FCT_DADOSNF*/
      FOR C_ITENSVENC IN (SELECT NRITFATURACONT, NRITEMOCONTRATO
                            FROM FCT_ITFATURACONT
                            WHERE NRFATURACONT = C_NFFECHAMENTO.NRFATURACONT
                              AND NRORG          = P_NRORG) LOOP

           V_DSSERVORCANF := NULL;

          FOR C_SERVICOS IN (SELECT ORC.NRORCAMENTO,
                                    CONT.NRCONTRATOFCT,
                                    PARC.NMPRINCIPALPARC,
                                    PARCELATOT.QTPARCELASTOT,
                                    NVL(PARCELA.QTPARCELAS, 0) AS QTPARCELAS,
                                    SERVORCA.CDPRODFATSERV,
                                    SERVORCA.DSSERVORCANF
                              FROM FCT_CONTRATO CONT
                              INNER JOIN PARCNEGOCIO PARC
                                ON PARC.NRPARCNEGOCIO = CONT.NRPARCNEGOCIO
                                AND PARC.NRORG = CONT.NRORG
                                LEFT JOIN (SELECT FCT_FATURACONT.NRSEQCONTRATO,
                                                  FCT_FATURACONT.NRORG,
                                                  COUNT(FCT_FATURACONT.NRFATURACONT) AS QTPARCELASTOT
                                            FROM FCT_FATURACONT
                                            JOIN FCT_ITFATURACONT
                                              ON FCT_ITFATURACONT.NRFATURACONT = FCT_FATURACONT.NRFATURACONT
                                            AND FCT_ITFATURACONT.NRORG = FCT_FATURACONT.NRORG
                                            AND FCT_ITFATURACONT.NRITEMOCONTRATO = C_ITENSVENC.NRITEMOCONTRATO
                                            WHERE FCT_FATURACONT.NRSEQCONTRATO = C_NFFECHAMENTO.NRSEQCONTRATO
                                              AND FCT_FATURACONT.NRORG = P_NRORG
                                            GROUP BY FCT_FATURACONT.NRSEQCONTRATO,
                                                    FCT_FATURACONT.NRORG) PARCELATOT
                                ON PARCELATOT.NRSEQCONTRATO = CONT.NRSEQCONTRATO
                                AND PARCELATOT.NRORG = CONT.NRORG
                                LEFT JOIN (SELECT FCT_FATURACONT.NRSEQCONTRATO,
                                                  FCT_FATURACONT.NRORG,
                                                  COUNT(FCT_FATURACONT.NRFATURACONT) AS QTPARCELAS
                                            FROM FCT_FATURACONT
                                            JOIN FCT_ITFATURACONT
                                              ON FCT_ITFATURACONT.NRFATURACONT = FCT_FATURACONT.NRFATURACONT
                                            AND FCT_ITFATURACONT.NRORG = FCT_FATURACONT.NRORG
                                            AND FCT_ITFATURACONT.NRITEMOCONTRATO = C_ITENSVENC.NRITEMOCONTRATO
                                            WHERE FCT_FATURACONT.NRSEQCONTRATO = C_NFFECHAMENTO.NRSEQCONTRATO
                                              AND FCT_FATURACONT.NRORG = P_NRORG
                                              AND FCT_FATURACONT.IDSITUACAO IN ('2','3')
                                            GROUP BY FCT_FATURACONT.NRSEQCONTRATO,
                                                    FCT_FATURACONT.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 ITEMCONT.NRITEMOCONTRATO = C_ITENSVENC.NRITEMOCONTRATO
                                AND ITEMCONT.NRORG = CONT.NRORG
                                INNER JOIN FCT_SERVICOORCA SERVORCA
                                ON SERVORCA.CDSERVORCA = ITEMCONT.CDSERVORCA
                                AND SERVORCA.NRORG = ITEMCONT.NRORG
                              WHERE CONT.NRSEQCONTRATO = C_NFFECHAMENTO.NRSEQCONTRATO
                                AND CONT.NRORG = P_NRORG
                                AND SERVORCA.DSSERVORCANF IS NOT NULL) LOOP

              V_DSSERVORCANF := C_SERVICOS.DSSERVORCANF;
              V_PARCELAS := C_SERVICOS.QTPARCELAS||'/'||C_SERVICOS.QTPARCELASTOT;
              /*Mnemônicos: [CODPROP] - Código Proposta | [CODCONT] - Código Contrato | [PARCEIRO] - Parceiro de Negócio | [PARCELA] - Parcelas*/

              V_DSSERVORCANF := REPLACE(V_DSSERVORCANF,'[CODPROP]', NVL(C_SERVICOS.NRORCAMENTO, ''));
              V_DSSERVORCANF := REPLACE(V_DSSERVORCANF,'[CODCONT]', NVL(C_SERVICOS.NRCONTRATOFCT, ''));
              V_DSSERVORCANF := REPLACE(V_DSSERVORCANF,'[PARCEIRO]', NVL(C_SERVICOS.NMPRINCIPALPARC, ''));
              V_DSSERVORCANF := REPLACE(V_DSSERVORCANF,'[PARCELA]', NVL(V_PARCELAS, ''));

              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;
      END LOOP;


   END LOOP;
   P_RETORNO := 'SUCESS';
   P_RETORNOERRO := 'Processo realizado com sucesso.';

 EXCEPTION
   -- Caso dÃª algum erro no faturamento, serÃ£o deletadas as notas fiscais para nÃ£o ficar lixo na base de dados. --
   WHEN OTHERS THEN BEGIN
      IF V_NFCRIADA IS NOT NULL THEN -- Verifica se tem NF criada --
         IF  V_NRAPURACAO IS NULL THEN -- Verifica se a NF criada jÃ¡ foi vinculadaÃÂ  apuraÃ§Ã£o. 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;

           END LOOP;

         ELSE

            FCT_CANC_APURCAO_FATURAMENTO (P_NRORG, P_NRSEQCONTRATO, P_CDOPERINCLUSAO, P_DATAINI, P_DATAFIN, P_NRFATURACONT);

         END IF;
      END IF;

      P_RETORNO := 'ERROR';
      P_RETORNOERRO := 'Operação bloqueada. Ocorreram erros na realização do processo.';
   END;
END;