CREATE OR REPLACE PROCEDURE FCT_VENCPREV_CONT (
    P_NRORG IN NUMBER,
    P_NRSEQCONTRATO IN NUMBER,
    P_DTREFERENCIA IN DATE
)
AS
  V_IDSOMAITGRUPFAT VARCHAR2(1);
  V_IDSOMAFATUCONT VARCHAR2(1);
  V_NRVENCPREVCONT NUMBER;
  V_NRITVENCPREVCONT NUMBER;
  V_NRSEQOPERACAO NUMBER;
  V_VERIFICAMEDICAO NUMBER;
  V_IDFATURACONTR VARCHAR2(10);
  V_CDMODPGTO VARCHAR2(10);
  V_DTVENCANTE VARCHAR2(20);
  V_CDMODPAGMTO VARCHAR2(10);
  V_GRFATURAMEN VARCHAR2(10);
  V_TIPO VARCHAR2(10);
  V_DTINICOMPET DATE;
  V_DTFINCOMPET DATE;
  V_IDSITUVENCPREV VARCHAR2(1);
  V_IDSITUVENCPREVPAI VARCHAR2(1);
  V_EXISTE_IT_APURACAO NUMBER;
  V_NRPARCNEG VARCHAR2(10);
  V_VRRATEADO FLOAT;
  V_NRRATEIOITEMVENC NUMBER;
  V_GERARATEIO VARCHAR2(1);

BEGIN

   FOR C_VENCDEL IN (SELECT NRVENCPREVCONT
                       FROM FCT_VENCPREVCONT
                      WHERE NRSEQCONTRATO = P_NRSEQCONTRATO
                        AND NRAPURACAO IS NULL
                        AND NRORG = P_NRORG)LOOP

      SELECT COUNT(*) AS QTMEDIC
        INTO V_VERIFICAMEDICAO
        FROM FCT_MEDICAOAPU
       WHERE NRSEQCONTRATO = P_NRSEQCONTRATO
         AND NRVENCPREVCONT = C_VENCDEL.NRVENCPREVCONT
         AND NRORG = P_NRORG;

      IF(V_VERIFICAMEDICAO = 0) THEN
         SELECT COUNT(*) AS QTMEDIC
           INTO V_VERIFICAMEDICAO
           FROM FCT_MEDICAOAPU M, FCT_ITVENCPREVCONT IT
          WHERE M.NRSEQCONTRATO = P_NRSEQCONTRATO
            AND M.NRITVENCPREVCONT = IT.NRITVENCPREVCONT
            AND IT.NRVENCPREVCONT = C_VENCDEL.NRVENCPREVCONT
            AND M.NRORG = P_NRORG;
      END IF;

      IF(V_VERIFICAMEDICAO = 0) THEN
          DELETE FROM FCT_VENCPREVCONT
           WHERE NRSEQCONTRATO = P_NRSEQCONTRATO
             AND NRVENCPREVCONT = C_VENCDEL.NRVENCPREVCONT
             AND NRAPURACAO IS NULL
             AND NRORG = P_NRORG;
      END IF;
   END LOOP;

   NOVO_CODIGO_NT('NRSEQOPERATRAB', V_NRSEQOPERACAO, 1, P_NRORG);

   FOR C_CONTRATO IN (
      SELECT FPIF.NRSEQFATUITCONT
        FROM FCT_PARAMFATITCONT FPIF, FCT_ITEMCONTRATO IT
       WHERE FPIF.NRSEQCONTRATO   = P_NRSEQCONTRATO
         AND FPIF.NRITEMOCONTRATO = IT.NRITEMOCONTRATO
         AND FPIF.NRSEQCONTRATO = IT.NRSEQCONTRATO
         AND IT.NRORG = FPIF.NRORG
         AND FPIF.NRORG = P_NRORG
         AND IT.IDFATURAITEM = 'SIM'
   ) LOOP
      
      FCT_CALCITEM_VENCIMENTO(P_NRORG, V_NRSEQOPERACAO, C_CONTRATO.NRSEQFATUITCONT);

   END LOOP;

   SELECT IDFATURACONTR
     INTO V_IDFATURACONTR
     FROM FCT_CONTRATO
    WHERE NRSEQCONTRATO = P_NRSEQCONTRATO
      AND NRORG         = P_NRORG;

   IF (V_IDFATURACONTR = 'X') THEN
      V_IDSOMAFATUCONT := 'S';
      V_IDSOMAITGRUPFAT := 'S';
   ELSE
      BEGIN
          SELECT IDSOMAFATUCONT, IDSOMAITGRUPFAT, IDGERARATEIO
            INTO V_IDSOMAFATUCONT, V_IDSOMAITGRUPFAT, V_GERARATEIO
            FROM FCT_PARAMFATCONT
           WHERE NRSEQCONTRATO = P_NRSEQCONTRATO
             AND NRORG = P_NRORG;
      EXCEPTION WHEN NO_DATA_FOUND THEN
          RAISE_APPLICATION_ERROR('-20001', 'FALTA PARAMETRIZACAO DE CONTRATO');
      END;
   END IF;

   SELECT COUNT(*)
     INTO V_EXISTE_IT_APURACAO
     FROM FCT_ITEMCONTRATO
    WHERE NRSEQCONTRATO = P_NRSEQCONTRATO
      AND NRORG         = P_NRORG
      AND IDFATURACONTR = 'X';
    
    IF (V_EXISTE_IT_APURACAO > 0) THEN
       V_IDSOMAFATUCONT := 'S';
       V_IDSOMAITGRUPFAT := 'S';
    END IF;
   
   /*
    INCLUSÃO DOS VENCIMENTOS SE O PARAMETRO
      'Consolidar na Parcela de Vencimento itens com o mesmo Grupo de Faturamento'
    ESTIVER DESMARCADO

    -> Neste caso, deve ser gerado um vnecimento para cada item do contrato.

    -> Grupos de faturamento diferentes não devem ser mesclados.
   */
   
   IF(V_IDSOMAITGRUPFAT = 'N') THEN
      FOR C_ITENS IN (SELECT NRITEMOCONTRATO, IDFATURACONTR, CDMODPGTO, QTDIASVENCIMENTO, DTINICOMPET, DTFINCOMPET,
                             DTVENCIMENTO, DTEMISSAO, VRVENCIMENTO, QTITEMCONTRATO, CDTPMEDIDASERV,
                             QTMEDIDACONTR, VRUNITITEMCONT, VRTOTITEMCONT, NRGRUPOFATURA, NRPARCNEGOCIO
                        FROM TRAB_ITVENCPREV
                       WHERE NRSEQOPERATRAB = V_NRSEQOPERACAO
                         AND NRORG = P_NRORG
                       ORDER BY NRSEQTRABVENCPREV
      )LOOP

         NOVO_CODIGO_NT('FCT_VENCPREVCONT', V_NRVENCPREVCONT, 1, P_NRORG);
         INSERT INTO FCT_VENCPREVCONT (
                NRVENCPREVCONT, NRSEQCONTRATO, NRGRUPOFATURA, QTDIASVENCIMENTO,
                DTINICOMPET, DTFINCOMPET, NRPARCNEGOCIO, DTVENCIMENTO,
                DTEMISSAO, VRVENCIMENTO, IDFATURACONTR, CDMODPGTO,
                IDSITUVENCPREV, NRORG, VRFATURADO, VRFALTAFATURAR)
            VALUES (
                V_NRVENCPREVCONT, P_NRSEQCONTRATO, C_ITENS.NRGRUPOFATURA, C_ITENS.QTDIASVENCIMENTO,
                C_ITENS.DTINICOMPET, C_ITENS.DTFINCOMPET, C_ITENS.NRPARCNEGOCIO, C_ITENS.DTVENCIMENTO,
                C_ITENS.DTEMISSAO, C_ITENS.VRVENCIMENTO, C_ITENS.IDFATURACONTR, C_ITENS.CDMODPGTO,
                'P', P_NRORG, 0, C_ITENS.VRVENCIMENTO);

         NOVO_CODIGO_NT('FCT_ITVENCPREVCONT', V_NRITVENCPREVCONT, 1, P_NRORG);
         INSERT INTO FCT_ITVENCPREVCONT
                      (NRITVENCPREVCONT, NRVENCPREVCONT, NRSEQCONTRATO, NRITEMOCONTRATO,
                      IDFATURACONTR, CDMODPGTO, QTDIASVENCIMENTO, DTINICOMPET, DTFINCOMPET,
                      DTVENCIMENTO, DTEMISSAO, VRVENCIMENTO, QTITEMCONTRATO, CDTPMEDIDASERV,
                      QTMEDIDACONTR, VRUNITITEMCONT, VRTOTITEMCONT, IDALTUSUARIO, NRORG)
              VALUES (V_NRITVENCPREVCONT, V_NRVENCPREVCONT, P_NRSEQCONTRATO, C_ITENS.NRITEMOCONTRATO,
                     C_ITENS.IDFATURACONTR, C_ITENS.CDMODPGTO, C_ITENS.QTDIASVENCIMENTO, C_ITENS.DTINICOMPET, C_ITENS.DTFINCOMPET,
                     C_ITENS.DTVENCIMENTO, C_ITENS.DTEMISSAO, C_ITENS.VRVENCIMENTO, C_ITENS.QTITEMCONTRATO, C_ITENS.CDTPMEDIDASERV,
                     C_ITENS.QTMEDIDACONTR, C_ITENS.VRUNITITEMCONT, C_ITENS.VRTOTITEMCONT, 'N', P_NRORG );
        
         /*Caso o parÃ¢metro de geraÃ§Ã£o de rateio estiver marcado, serÃ£o inseridos os rateios para cada vencimento.  */
         IF (V_GERARATEIO = 'S') THEN

            FOR C_RATEIO IN (
                SELECT REL.NRESTRUTURAM,
                       ES.NMESTRUTURAM,
                       ES.CDCENTCUST,
                       REL.VRITEMRATEIO,
                       REL.VRPERCRATEIO
                  FROM FCT_RELACESTRUTURACONT REL
                 INNER JOIN ESTRUTURAM ES
                    ON ES.NRESTRUTURAM = REL.NRESTRUTURAM
                   AND ES.NRORG        = REL.NRORG
                 WHERE REL.NRSEQCONTRATO = P_NRSEQCONTRATO
                   AND REL.NRORG         = P_NRORG
                   AND REL.NRITEMOCONTRATO  = C_ITENS.NRITEMOCONTRATO
                   AND REL.IDRELACESTRUTURA = 'RATEIO'
            ) LOOP

                IF (C_RATEIO.CDCENTCUST IS NULL) THEN
                    --Erro: local de atendimento sem centro de custo
                    RAISE_APPLICATION_ERROR('-20002', 'LOCAL DE ATENDIMENTO SEM CENTRO DE CUSTO: @@' || C_RATEIO.NMESTRUTURAM || '@@');
                END IF;

                V_VRRATEADO := C_ITENS.VRVENCIMENTO * C_RATEIO.VRPERCRATEIO / 100;
                V_VRRATEADO := ROUND(V_VRRATEADO, 2);

                NOVO_CODIGO_NT('FCT_RATEIOITVENCIMENTO', V_NRRATEIOITEMVENC, 1, P_NRORG);

                INSERT INTO FCT_RATEIOITVENCIMENTO
                           (NRRATEIOITEMVENC, NRITVENCPREVCONT, NRVENCPREVCONT, NRSEQCONTRATO, NRITEMOCONTRATO,
                            NRESTRUTURAM, CDCENTCUST, VRPERCENTRATEIO, VRRATEADO, NRORG, IDATIVO, IDSITUVENCRATEIO)
                    VALUES (V_NRRATEIOITEMVENC, V_NRITVENCPREVCONT, V_NRVENCPREVCONT, P_NRSEQCONTRATO, C_ITENS.NRITEMOCONTRATO,
                            C_RATEIO.NRESTRUTURAM, C_RATEIO.CDCENTCUST, C_RATEIO.VRPERCRATEIO, V_VRRATEADO, P_NRORG, 'S', 'P');

            END LOOP;
         END IF;        

      END LOOP;
   END IF;

   /*
     INCLUSÃO DOS VENCIMENTOS SE O PARAMETRO
        'Consolidar na Parcela de Vencimento itens com o mesmo Grupo de Faturamento'
      ESTIVER MARCADO E O  PARÂMETRO
        'Consolidar tipos de faturamento que estejam no mesmo período de vencimento'
      ESTIVER DESMARCADO

      -> Neste caso, os itens com tipo de faturamento "Periódico" que estiverem a mesma data de vencimento deve ser mesclados
         e os itens com tipo de faturamento "Não Periódico" que estiverema mesma modalidade de pagamento e a mesma data de vencimento
         devem ser mesclados. Itens com tipos de faturamento diferentes não devem ser mesclados.

      -> Grupos de faturamento diferentes não devem ser mesclados.
   */

   IF((V_IDSOMAITGRUPFAT = 'S') AND (V_IDSOMAFATUCONT = 'N')) THEN
      FOR C_ITENS IN (SELECT SUM(VRVENCIMENTO) AS VRVENCIMENTO, IDFATURACONTR, CDMODPGTO, (MAX(DTFINCOMPET) - MIN(DTINICOMPET)) AS QTDIASVENCIMENTO,
                             MIN(DTINICOMPET) AS DTINICOMPET, MAX(DTFINCOMPET) AS DTFINCOMPET,
                             DTVENCIMENTO, DTEMISSAO, NRGRUPOFATURA, NRPARCNEGOCIO
                        FROM TRAB_ITVENCPREV
                       WHERE NRSEQOPERATRAB = V_NRSEQOPERACAO
                         AND NRORG = P_NRORG
                      GROUP BY IDFATURACONTR, CDMODPGTO, DTVENCIMENTO, DTEMISSAO, NRGRUPOFATURA, NRPARCNEGOCIO
                      ORDER BY DTVENCIMENTO ) LOOP

         NOVO_CODIGO_NT('FCT_VENCPREVCONT', V_NRVENCPREVCONT, 1, P_NRORG);
         INSERT INTO FCT_VENCPREVCONT (
              NRVENCPREVCONT, NRSEQCONTRATO, NRGRUPOFATURA, QTDIASVENCIMENTO,
              DTINICOMPET, DTFINCOMPET, NRPARCNEGOCIO, DTVENCIMENTO,
              DTEMISSAO, VRVENCIMENTO, IDFATURACONTR, CDMODPGTO,
              IDSITUVENCPREV, NRORG, VRFATURADO, VRFALTAFATURAR)
         VALUES (
              V_NRVENCPREVCONT, P_NRSEQCONTRATO, C_ITENS.NRGRUPOFATURA, C_ITENS.QTDIASVENCIMENTO,
              C_ITENS.DTINICOMPET, C_ITENS.DTFINCOMPET, C_ITENS.NRPARCNEGOCIO, C_ITENS.DTVENCIMENTO,
              C_ITENS.DTEMISSAO, C_ITENS.VRVENCIMENTO, C_ITENS.IDFATURACONTR, C_ITENS.CDMODPGTO,
              'P', P_NRORG, 0, C_ITENS.VRVENCIMENTO);


         FOR C_ITENS2 IN (SELECT NRITEMOCONTRATO, IDFATURACONTR, CDMODPGTO, QTDIASVENCIMENTO, DTINICOMPET, DTFINCOMPET,
                                 DTVENCIMENTO, DTEMISSAO, VRVENCIMENTO, QTITEMCONTRATO, CDTPMEDIDASERV,
                                 QTMEDIDACONTR, VRUNITITEMCONT, VRTOTITEMCONT, NRGRUPOFATURA
                            FROM TRAB_ITVENCPREV
                           WHERE NRGRUPOFATURA = C_ITENS.NRGRUPOFATURA
                             AND IDFATURACONTR = C_ITENS.IDFATURACONTR
                             AND NRPARCNEGOCIO = C_ITENS.NRPARCNEGOCIO
                             AND (((CDMODPGTO = C_ITENS.CDMODPGTO) AND (IDFATURACONTR = 'O')) OR ((IDFATURACONTR = 'A') AND (CDMODPGTO IS NULL)))
                             AND TRUNC(DTVENCIMENTO) = TRUNC(C_ITENS.DTVENCIMENTO)
                             AND NRSEQOPERATRAB = V_NRSEQOPERACAO
                             AND NRORG = P_NRORG
         )LOOP

            NOVO_CODIGO_NT('FCT_ITVENCPREVCONT', V_NRITVENCPREVCONT, 1, P_NRORG);
            INSERT INTO FCT_ITVENCPREVCONT
                        (NRITVENCPREVCONT, NRVENCPREVCONT, NRSEQCONTRATO, NRITEMOCONTRATO,
                        IDFATURACONTR, CDMODPGTO, QTDIASVENCIMENTO, DTINICOMPET, DTFINCOMPET,
                        DTVENCIMENTO, DTEMISSAO, VRVENCIMENTO, QTITEMCONTRATO, CDTPMEDIDASERV,
                        QTMEDIDACONTR, VRUNITITEMCONT, VRTOTITEMCONT, IDALTUSUARIO, NRORG)
                 VALUES (V_NRITVENCPREVCONT, V_NRVENCPREVCONT, P_NRSEQCONTRATO, C_ITENS2.NRITEMOCONTRATO,
                        C_ITENS2.IDFATURACONTR, C_ITENS2.CDMODPGTO, C_ITENS2.QTDIASVENCIMENTO, C_ITENS2.DTINICOMPET, C_ITENS2.DTFINCOMPET,
                        C_ITENS2.DTVENCIMENTO, C_ITENS2.DTEMISSAO, C_ITENS2.VRVENCIMENTO, C_ITENS2.QTITEMCONTRATO, C_ITENS2.CDTPMEDIDASERV,
                        C_ITENS2.QTMEDIDACONTR, C_ITENS2.VRUNITITEMCONT, C_ITENS2.VRTOTITEMCONT, 'N', P_NRORG);


            /*Caso o parÃ¢metro de geraÃ§Ã£o de rateio estiver marcado, serÃ£o inseridos os rateios para cada vencimento.  */
            IF (V_GERARATEIO = 'S') THEN

              FOR C_RATEIO IN (
                  SELECT REL.NRESTRUTURAM,
                       ES.NMESTRUTURAM,
                       ES.CDCENTCUST,
                       REL.VRITEMRATEIO,
                       REL.VRPERCRATEIO
                  FROM FCT_RELACESTRUTURACONT REL
                 INNER JOIN ESTRUTURAM ES
                    ON ES.NRESTRUTURAM = REL.NRESTRUTURAM
                   AND ES.NRORG        = REL.NRORG
                 WHERE REL.NRSEQCONTRATO = P_NRSEQCONTRATO
                   AND REL.NRORG         = P_NRORG
                   AND REL.NRITEMOCONTRATO  = C_ITENS2.NRITEMOCONTRATO
                   AND REL.IDRELACESTRUTURA = 'RATEIO'
              ) LOOP
  
                      IF (C_RATEIO.CDCENTCUST IS NULL) THEN
                          --Erro: local de atendimento sem centro de custo
                          RAISE_APPLICATION_ERROR('-20002', 'LOCAL DE ATENDIMENTO SEM CENTRO DE CUSTO: @@' || C_RATEIO.NMESTRUTURAM || '@@');
                      END IF;
                      
                      V_VRRATEADO := C_ITENS2.VRVENCIMENTO * C_RATEIO.VRPERCRATEIO / 100;
                      V_VRRATEADO := ROUND(V_VRRATEADO, 2);

                      NOVO_CODIGO_NT('FCT_RATEIOITVENCIMENTO', V_NRRATEIOITEMVENC, 1, P_NRORG);

                      INSERT INTO FCT_RATEIOITVENCIMENTO
                                (NRRATEIOITEMVENC, NRITVENCPREVCONT, NRVENCPREVCONT, NRSEQCONTRATO, NRITEMOCONTRATO,
                                  NRESTRUTURAM, CDCENTCUST, VRPERCENTRATEIO, VRRATEADO, NRORG, IDATIVO, IDSITUVENCRATEIO)
                          VALUES (V_NRRATEIOITEMVENC, V_NRITVENCPREVCONT, V_NRVENCPREVCONT, P_NRSEQCONTRATO, C_ITENS2.NRITEMOCONTRATO,
                                  C_RATEIO.NRESTRUTURAM, C_RATEIO.CDCENTCUST, C_RATEIO.VRPERCRATEIO, V_VRRATEADO, P_NRORG, 'S', 'P');

              END LOOP;
            END IF;

         END LOOP;
      END LOOP;
   END IF;


    /*
     INCLUSÃO DOS VENCIMENTOS SE AMBOS OS PARAMETROS ESTIVEREM  MARCADOS.

          -> Neste caso, que estiverem a mesma data de vencimento deve ser mesclados. A única exceção neste caso é que não podem ser mesclados
             em um vencimento itens com tipo de faturamento "Não Periódico" que estiverem a modalidade de pagamento diferentes.

          -> Grupos de faturamento diferentes não devem ser mesclados.
   */

   IF((V_IDSOMAITGRUPFAT = 'S') AND (V_IDSOMAFATUCONT = 'S')) THEN

      V_DTVENCANTE :=  'X'; /* Data de Vencimento do registro anterioior para comparação */
      V_CDMODPAGMTO := 'X'; /* Modalidade de Pagamento do registro anterioior para comparação */
      V_GRFATURAMEN := 'X'; /* Grupo de Faturamento do registro anterioior para comparação */
      V_NRPARCNEG := 'X'; /* Parceiro de negócio do registro anterioior para comparaÃ§Ã£o */

      IF (V_IDFATURACONTR = 'X') THEN
          V_IDSITUVENCPREVPAI := 'A';
      ELSE
          V_IDSITUVENCPREVPAI := 'P';
      END IF;

      FOR C_ITENS IN (SELECT NRITEMOCONTRATO, VRVENCIMENTO,QTDIASVENCIMENTO, DTVENCIMENTO, NRGRUPOFATURA, IDFATURACONTR, CDMODPGTO,
                             DTFINCOMPET, DTINICOMPET, DTEMISSAO, QTITEMCONTRATO, CDTPMEDIDASERV, QTMEDIDACONTR, VRUNITITEMCONT,
                             VRTOTITEMCONT, NRPARCNEGOCIO
                        FROM TRAB_ITVENCPREV
                       WHERE NRSEQOPERATRAB = V_NRSEQOPERACAO
                         AND NRORG = P_NRORG
                      ORDER BY DTVENCIMENTO, IDFATURACONTR, CDMODPGTO, NRGRUPOFATURA, NRPARCNEGOCIO) LOOP

        /* Os Ifs Abaixo definem se deve ser inserido um novo vencimento ou apenas updatado o vencimento criado para o registro
           anterior com os dados do registro atual. A regra para definição é a seguinte:

           - Se o grupo de faturamento for direfente ele cria um novo vencimento, se não ele testa adatade vencimento.
           - Se a data de vencimento for diferente ele cria um novo vencimento, se não ele testa o tipo de faturamento e a modalidadede pagamento.
           - Se for um registro de "Modalidade de pagamento" e a modalidade for diferente do registro anterior ele cria um novo registro.

           Tudo que for diferente dos pontos acima será updatado.

           OBS: Caso a ordenação do select do FOR C_ITENS seja alterada, o código abaixo deverá ser revisto.
           */

        IF (TO_CHAR(C_ITENS.NRGRUPOFATURA) <> V_GRFATURAMEN) THEN
            V_TIPO := 'INSERT';
        ELSE
            IF (TO_CHAR(TRUNC(C_ITENS.DTVENCIMENTO)) <> V_DTVENCANTE)  THEN
              V_TIPO := 'INSERT';
            ELSE
              IF ((C_ITENS.IDFATURACONTR = 'O') AND (C_ITENS.CDMODPGTO <> V_CDMODPAGMTO))  THEN
                  V_TIPO := 'INSERT';
              ELSE
                  IF (TO_CHAR(C_ITENS.NRPARCNEGOCIO) <> V_NRPARCNEG) THEN
                    V_TIPO := 'INSERT';
                  ELSE 
                    V_TIPO := 'UPDATE';
                  END IF;   
              END IF;
            END IF;
        END IF;

        IF (C_ITENS.IDFATURACONTR IS NULL) THEN
            V_IDSITUVENCPREV := V_IDSITUVENCPREVPAI;
        ELSIF (C_ITENS.IDFATURACONTR = 'X') THEN
            V_IDSITUVENCPREV := 'A';
        ELSE
            V_IDSITUVENCPREV := 'P';
        END IF;

        IF (V_TIPO = 'INSERT')  THEN

            NOVO_CODIGO_NT('FCT_VENCPREVCONT', V_NRVENCPREVCONT, 1, P_NRORG);
            INSERT INTO FCT_VENCPREVCONT (
                  NRVENCPREVCONT, NRSEQCONTRATO, NRGRUPOFATURA, QTDIASVENCIMENTO,
                  DTINICOMPET, DTFINCOMPET, NRPARCNEGOCIO, DTVENCIMENTO,
                  DTEMISSAO, VRVENCIMENTO, IDFATURACONTR, CDMODPGTO,
                  IDSITUVENCPREV, NRORG, VRFATURADO, VRFALTAFATURAR)
            VALUES (
                  V_NRVENCPREVCONT, P_NRSEQCONTRATO, C_ITENS.NRGRUPOFATURA, C_ITENS.QTDIASVENCIMENTO,
                  C_ITENS.DTINICOMPET, C_ITENS.DTFINCOMPET, C_ITENS.NRPARCNEGOCIO, C_ITENS.DTVENCIMENTO,
                  C_ITENS.DTVENCIMENTO, C_ITENS.VRVENCIMENTO, C_ITENS.IDFATURACONTR, C_ITENS.CDMODPGTO,
                  V_IDSITUVENCPREV, P_NRORG, 0, C_ITENS.VRVENCIMENTO);

         ELSE  /*UPDATE*/

            SELECT DTINICOMPET, DTFINCOMPET
              INTO V_DTINICOMPET, V_DTFINCOMPET
              FROM FCT_VENCPREVCONT
             WHERE NRVENCPREVCONT = V_NRVENCPREVCONT
               AND NRSEQCONTRATO = P_NRSEQCONTRATO
               AND NRORG = P_NRORG;

            IF C_ITENS.DTINICOMPET < V_DTINICOMPET THEN
               V_DTINICOMPET := C_ITENS.DTINICOMPET;
            END IF;

             IF C_ITENS.DTFINCOMPET > V_DTFINCOMPET THEN
                V_DTFINCOMPET := C_ITENS.DTFINCOMPET;
            END IF;

            UPDATE FCT_VENCPREVCONT
               SET VRVENCIMENTO   = VRVENCIMENTO + C_ITENS.VRVENCIMENTO,
                   VRFALTAFATURAR = VRVENCIMENTO + C_ITENS.VRVENCIMENTO,
                   IDFATURACONTR  = C_ITENS.IDFATURACONTR,
                   CDMODPGTO      = C_ITENS.CDMODPGTO,
                   DTEMISSAO      = C_ITENS.DTEMISSAO,
                   DTINICOMPET    = V_DTINICOMPET,
                   DTFINCOMPET    = V_DTFINCOMPET
             WHERE NRVENCPREVCONT = V_NRVENCPREVCONT
               AND NRSEQCONTRATO  = P_NRSEQCONTRATO
               AND NRORG          = P_NRORG;
         END IF;

         NOVO_CODIGO_NT('FCT_ITVENCPREVCONT', V_NRITVENCPREVCONT, 1, P_NRORG);
         INSERT INTO FCT_ITVENCPREVCONT
                     (NRITVENCPREVCONT, NRVENCPREVCONT, NRSEQCONTRATO, NRITEMOCONTRATO,
                      IDFATURACONTR, CDMODPGTO, QTDIASVENCIMENTO, DTINICOMPET, DTFINCOMPET,
                      DTVENCIMENTO, DTEMISSAO, VRVENCIMENTO, QTITEMCONTRATO, CDTPMEDIDASERV,
                      QTMEDIDACONTR, VRUNITITEMCONT, VRTOTITEMCONT, IDALTUSUARIO, NRORG)
              VALUES (V_NRITVENCPREVCONT, V_NRVENCPREVCONT, P_NRSEQCONTRATO, C_ITENS.NRITEMOCONTRATO,
                      C_ITENS.IDFATURACONTR,C_ITENS.CDMODPGTO, C_ITENS.QTDIASVENCIMENTO, C_ITENS.DTINICOMPET, C_ITENS.DTFINCOMPET,
                      C_ITENS.DTVENCIMENTO, C_ITENS.DTVENCIMENTO, C_ITENS.VRVENCIMENTO, C_ITENS.QTITEMCONTRATO, C_ITENS.CDTPMEDIDASERV,
                      C_ITENS.QTMEDIDACONTR, C_ITENS.VRUNITITEMCONT, C_ITENS.VRTOTITEMCONT, 'N', P_NRORG);

          /*--- Parâmetros para comparação ---*/
          V_DTVENCANTE := TO_CHAR(TRUNC(C_ITENS.DTVENCIMENTO));
          V_CDMODPAGMTO := C_ITENS.CDMODPGTO;
          V_GRFATURAMEN := TO_CHAR(C_ITENS.NRGRUPOFATURA);
          V_NRPARCNEG := TO_CHAR(C_ITENS.NRPARCNEGOCIO);

          /*Caso o parÃ¢metro de geraÃ§Ã£o de rateio estiver marcado, serÃ£o inseridos os rateios para cada vencimento.  */
          IF (V_GERARATEIO = 'S') THEN

          FOR C_RATEIO IN (
                SELECT REL.NRESTRUTURAM,
                       ES.NMESTRUTURAM,
                       ES.CDCENTCUST,
                       REL.VRITEMRATEIO,
                       REL.VRPERCRATEIO
                  FROM FCT_RELACESTRUTURACONT REL
                 INNER JOIN ESTRUTURAM ES
                    ON ES.NRESTRUTURAM = REL.NRESTRUTURAM
                   AND ES.NRORG        = REL.NRORG
                 WHERE REL.NRSEQCONTRATO = P_NRSEQCONTRATO
                   AND REL.NRORG         = P_NRORG
                   AND REL.NRITEMOCONTRATO  = C_ITENS.NRITEMOCONTRATO
                   AND REL.IDRELACESTRUTURA = 'RATEIO'
          ) LOOP
          
                  IF (C_RATEIO.CDCENTCUST IS NULL) THEN
                      --Erro: local de atendimento sem centro de custo
                      RAISE_APPLICATION_ERROR('-20002', 'LOCAL DE ATENDIMENTO SEM CENTRO DE CUSTO: @@' || C_RATEIO.NMESTRUTURAM || '@@');
                  END IF;
                  
                  V_VRRATEADO := C_ITENS.VRVENCIMENTO * C_RATEIO.VRPERCRATEIO / 100;
                  V_VRRATEADO := ROUND(V_VRRATEADO, 2);
                  
                  NOVO_CODIGO_NT('FCT_RATEIOITVENCIMENTO', V_NRRATEIOITEMVENC, 1, P_NRORG);

                  INSERT INTO FCT_RATEIOITVENCIMENTO
                            (NRRATEIOITEMVENC, NRITVENCPREVCONT, NRVENCPREVCONT, NRSEQCONTRATO, NRITEMOCONTRATO,
                              NRESTRUTURAM, CDCENTCUST, VRPERCENTRATEIO, VRRATEADO, NRORG, IDATIVO, IDSITUVENCRATEIO)
                      VALUES (V_NRRATEIOITEMVENC, V_NRITVENCPREVCONT, V_NRVENCPREVCONT, P_NRSEQCONTRATO, C_ITENS.NRITEMOCONTRATO,
                              C_RATEIO.NRESTRUTURAM, C_RATEIO.CDCENTCUST, C_RATEIO.VRPERCRATEIO, V_VRRATEADO, P_NRORG, 'S', 'P');

          END LOOP;
        END IF;

      END LOOP;
   END IF;

   DELETE FROM TRAB_ITVENCPREV
    WHERE NRSEQOPERATRAB = V_NRSEQOPERACAO
      AND NRORG = P_NRORG;
END;