CREATE OR REPLACE PROCEDURE GERA_PREVPAXCLAPROD
(P_CDFILIAL IN VARCHAR2,
 P_CDFILIPROC IN VARCHAR2, 
 P_NRPREVISAOPROD IN NUMBER,
 P_CDCIA IN VARCHAR2,
 P_NRVOO IN VARCHAR2,
 P_CDTRECHO IN VARCHAR2,
 P_CDEQUIP IN VARCHAR2,
 P_IDPADRAOCALC IN VARCHAR2,
 P_NRPADRAOGERPREVPAX IN NUMBER,
 P_CDOPERADOR IN VARCHAR2,
 P_NRORG IN NUMBER DEFAULT 1,
 P_NRLISTAERROS IN OUT NUMBER
)
AS
   V_NRORDEMERROS NUMBER;
   V_SEQ VARCHAR2(20);   
   V_SEQ_SERV VARCHAR2(20);
   V_QTPAXCALC FLOAT;
   V_QTITEM_PADRAO FLOAT;
   V_EXISTE_PREVPAXCLA NUMBER;
   V_EXISTE_PREVPAXSERV NUMBER;

   V_CDCLASSE VARCHAR2(4);
   V_DTPREVISAOPROD DATE;   

   V_NRTABPRECO VARCHAR2(3);
   v_NUM_TABPRECO_ATIVAS NUMBER;

   V_NRSEQPRECO NUMBER;
   V_NUM_PRECOS_ITEMFAT NUMBER;
   V_SGCIA VARCHAR2(20);

   V_NRNRPREVPAXSERVPROD NUMBER;
   V_HNRNRPREVPAXSERVPROD NUMBER;

   FUNCTION MEDIA_CLASSE
   (
   P_CDCLASSE IN VARCHAR2,
   P_QTPAXMAX IN FLOAT   
   ) RETURN FLOAT
   AS
      V_BLOCO1 FLOAT;
      V_MEDIABLOCO1 FLOAT;
      V_PERBLOCO1 FLOAT;
      V_BLOCO2 FLOAT;
      V_MEDIABLOCO2 FLOAT;
      V_PERBLOCO2 FLOAT;
      V_BLOCO3 FLOAT;
      V_MEDIABLOCO3 FLOAT;
      V_PERBLOCO3 FLOAT;

      V_QTPAX_ULTDIA FLOAT;
      V_QTPAX_PENULTDIA FLOAT;
      V_QTPAX FLOAT;
      
      V_NUM_DIAS_PENULTSEMANA NUMBER;      
      V_NUM_DIAS_ANTEPENULTSEMANA NUMBER;

      V_ULTDIA DATE;
      V_PENULTDIA DATE;
      V_PENULTSEMINI DATE;
      V_PENULTSEMFIM DATE;
      V_ANTPENULTDIA DATE;
      V_ANTPENULTSEMINI DATE;
      V_ANTPENULTSEMFIM DATE;
      V_DIA_SEMANA NUMBER;
   BEGIN   
      /*Se nao tiver quantidade maxima*/
      IF NVL(P_QTPAXMAX, 0) = 0 THEN RETURN 0; END IF;
      /*Calculo da media historica sobre dados do faturamento
         
         (Media de loading por dia dos 2 ultimos dias da semana iguais * Percentual fixo 1) + ( Media de loading da ultima semana, excluindo o dia da semana * Percentual fixo 2) + (Media da antepenultima semana, excluindo o dia da semana * Percentual fixo 3)

         Percentual bloco 1 => PARAMCOMIS.VRPER1CALCMEDIAPAX
         Percentual bloco 2 => PARAMCOMIS.VRPER2CALCMEDIAPAX
         Percentual bloco 3 => PARAMCOMIS.VRPER3CALCMEDIAPAX

      */

      V_DIA_SEMANA := TO_NUMBER(TO_CHAR(V_DTPREVISAOPROD, 'D'));
      V_ULTDIA := V_DTPREVISAOPROD - 7;
      V_PENULTDIA := V_DTPREVISAOPROD - 14;
      V_PENULTSEMINI := V_PENULTDIA - (V_DIA_SEMANA - 1);
      V_PENULTSEMFIM := V_PENULTDIA + (7 - V_DIA_SEMANA);
      V_ANTPENULTDIA := V_DTPREVISAOPROD - 21;
      V_ANTPENULTSEMINI := V_ANTPENULTDIA - (V_DIA_SEMANA - 1);
      V_ANTPENULTSEMFIM := V_ANTPENULTDIA + (7 - V_DIA_SEMANA);

      SELECT MAX(VRPER1CALCMEDIAPAX), MAX(VRPER2CALCMEDIAPAX), MAX(VRPER3CALCMEDIAPAX)
        INTO V_PERBLOCO1, V_PERBLOCO2, V_PERBLOCO3
        FROM PARAMCOMIS
       WHERE CDFILIAL = P_CDFILIAL;


      IF V_PERBLOCO1 IS NULL THEN
         /*Percentual do bloco $param[0] nao parametrizado nos parametros de producao da unidade.*/
         INSERE_LISTA_ERROS(P_CDFILIAL,
                            'APPERRMSGSTR' || 'APP-00150' || '$$' ||
                            '1'
                            || 'APPERRMSGEND',
                            P_CDOPERADOR, P_NRORG, P_NRLISTAERROS);
      END IF;


      IF V_PERBLOCO2 IS NULL THEN
         /*Percentual do bloco $param[0] nao parametrizado nos parametros de producao da unidade.*/
         INSERE_LISTA_ERROS(P_CDFILIAL,
                            'APPERRMSGSTR' || 'APP-00150' || '$$' ||
                            '2'
                            || 'APPERRMSGEND',
                            P_CDOPERADOR, P_NRORG, P_NRLISTAERROS);
      END IF;

      IF V_PERBLOCO3 IS NULL THEN
         /*Percentual do bloco $param[0] nao parametrizado nos parametros de producao da unidade.*/
         INSERE_LISTA_ERROS(P_CDFILIAL,
                            'APPERRMSGSTR' || 'APP-00150' || '$$' ||
                            '3'
                            || 'APPERRMSGEND',
                            P_CDOPERADOR, P_NRORG, P_NRLISTAERROS);
      END IF;

      IF V_PERBLOCO1 IS NULL OR
         V_PERBLOCO2 IS NULL OR
         V_PERBLOCO3 IS NULL THEN
         RETURN 0;
      END IF;

      /*********************************************************************
      BLOCO 1
      **********************************************************************/
      V_BLOCO1 := 0;
      V_MEDIABLOCO1 := 0;

      /*Quantidade da classe no ultimo dia de semana correspondente*/
      SELECT MAX(QTTOTPAXAT)
        INTO V_QTPAX_ULTDIA
        FROM PREVISAOPAXM
       WHERE CDFILIAL = P_CDFILIAL
         AND CDCIA = P_CDCIA
         AND NRVOO = P_NRVOO
         AND CDTRECHO = P_CDTRECHO
         AND DTHRPLAVOOPV = V_ULTDIA /*Ultima semana*/
         AND CDCLASSE = P_CDCLASSE;
      
      /*Quantidade da classe no penultimo dia de semana correspondente*/
      SELECT MAX(QTTOTPAXAT)
        INTO V_QTPAX_PENULTDIA
        FROM PREVISAOPAXM
       WHERE CDFILIAL = P_CDFILIAL
         AND CDCIA = P_CDCIA
         AND NRVOO = P_NRVOO
         AND CDTRECHO = P_CDTRECHO
         AND DTHRPLAVOOPV = V_PENULTDIA /*penultima semana*/
         AND CDCLASSE = P_CDCLASSE;

      V_MEDIABLOCO1 := (ROUND(NVL(V_QTPAX_ULTDIA, 0)/P_QTPAXMAX * 100) + 
                        ROUND(NVL(V_QTPAX_PENULTDIA, 0)/P_QTPAXMAX * 100)
                       )/2;

      V_BLOCO1 :=  V_MEDIABLOCO1 * V_PERBLOCO1;
      /***** FIM BLOCO 1 *****/
      
      /*********************************************************************
      BLOCO 2
      **********************************************************************/

      /*Quantidade da classe na ultima semana correspondente*/
      V_BLOCO2 := 0;
      V_NUM_DIAS_PENULTSEMANA := 0;
      V_MEDIABLOCO2 := 0;
      FOR CUR_DIAS_PENULTSEMANA IN
      (SELECT DTDATA
         FROM DATA
        WHERE DTDATA BETWEEN V_PENULTSEMINI AND V_PENULTSEMFIM
          AND DTDATA <> V_PENULTDIA) LOOP
         
         SELECT MAX(QTTOTPAXAT)
           INTO V_QTPAX
           FROM PREVISAOPAXM
          WHERE CDFILIAL = P_CDFILIAL
            AND CDCIA = P_CDCIA
            AND NRVOO = P_NRVOO
            AND CDTRECHO = P_CDTRECHO
            AND DTHRPLAVOOPV = CUR_DIAS_PENULTSEMANA.DTDATA /*Ultima semana*/
            AND CDCLASSE = P_CDCLASSE;
         IF V_QTPAX IS NOT NULL THEN
            V_MEDIABLOCO2 := V_MEDIABLOCO2 + ROUND(V_QTPAX/P_QTPAXMAX * 100);
            V_NUM_DIAS_PENULTSEMANA := V_NUM_DIAS_PENULTSEMANA + 1;
         END IF;
      END LOOP;

      IF V_NUM_DIAS_PENULTSEMANA = 0 THEN
         V_MEDIABLOCO2 := 0;
      ELSE
         V_MEDIABLOCO2 := V_MEDIABLOCO2 / V_NUM_DIAS_PENULTSEMANA;
      END IF;

      V_BLOCO2 := V_MEDIABLOCO2 * V_PERBLOCO2;
      /***** FIM BLOCO 2 *****/
      
      /*********************************************************************
      BLOCO 3
      **********************************************************************/      
      V_BLOCO3 := 0;
      V_NUM_DIAS_ANTEPENULTSEMANA := 0;
      V_MEDIABLOCO3 := 0;
      FOR CUR_DIAS_ANTULTSEMANA IN
      (SELECT DTDATA
         FROM DATA
        WHERE DTDATA BETWEEN V_ANTPENULTSEMINI AND V_ANTPENULTSEMFIM
          AND DTDATA <> V_ANTPENULTDIA) LOOP
         SELECT MAX(QTTOTPAXAT)
           INTO V_QTPAX
           FROM PREVISAOPAXM
          WHERE CDFILIAL = P_CDFILIAL
            AND CDCIA = P_CDCIA
            AND NRVOO = P_NRVOO
            AND CDTRECHO = P_CDTRECHO
            AND DTHRPLAVOOPV = CUR_DIAS_ANTULTSEMANA.DTDATA /*Ultima semana*/
            AND CDCLASSE = P_CDCLASSE;
         IF V_QTPAX IS NOT NULL THEN
            V_MEDIABLOCO3 := V_MEDIABLOCO3 + ROUND(V_QTPAX/P_QTPAXMAX * 100);
            V_NUM_DIAS_ANTEPENULTSEMANA := V_NUM_DIAS_ANTEPENULTSEMANA + 1;
         END IF;
      END LOOP;

      IF V_NUM_DIAS_PENULTSEMANA = 0 THEN
         V_MEDIABLOCO3 := 0;
      ELSE
         V_MEDIABLOCO3 := V_MEDIABLOCO3 / V_NUM_DIAS_PENULTSEMANA;
      END IF;

      V_BLOCO3 := V_MEDIABLOCO3 * V_PERBLOCO3;

      /***** FIM BLOCO 3 *****/

      RETURN ROUND((V_BLOCO1 + V_BLOCO2 + V_BLOCO3)/10000 * P_QTPAXMAX);
   END;
BEGIN
   SELECT MAX(DTPREVISAOPROD)
     INTO V_DTPREVISAOPROD
     FROM PREVPAXPRODM
    WHERE CDFILIAL = P_CDFILIAL
      AND NRPREVISAOPROD = P_NRPREVISAOPROD;
      
   DELETE FROM HPREVPAXSERVPRODM H
    WHERE EXISTS (SELECT 1
                    FROM PREVPAXSERVPRODM P
                   WHERE H.CDFILIAL = P.CDFILIAL                                      
                     AND H.NRPREVISAOPROD = P.NRPREVISAOPROD
                     AND H.NRPREVPAXSERVPROD = P.NRPREVPAXSERVPROD
                     AND P.CDFILIAL = P_CDFILIAL
                     AND P.NRPREVISAOPROD = P_NRPREVISAOPROD
                     AND P.CDCIA = P_CDCIA
                     AND P.NRVOO = P_NRVOO
                     AND P.CDTRECHO =  P_CDTRECHO);

  /* Deleta todos os Itens de Faturamento da Companhia/Voo/Previsao*/
      DELETE FROM PREVPAXSERVPRODM
       WHERE CDFILIAL = P_CDFILIAL
         AND NRPREVISAOPROD = P_NRPREVISAOPROD
         AND CDCIA = P_CDCIA
         AND NRVOO = P_NRVOO
         AND CDTRECHO = P_CDTRECHO;
         
   FOR CUR_CLASSES IN
   (
     SELECT CV.CDCLASSE, CL.SGCLASSE, CV.QTPAXVOO AS QTPAX
       FROM CONFIGVOO CV
      INNER JOIN CLASSE CL
      ON   CL.CDCLASSE = CV.CDCLASSE
      AND  CL.NRORG    = CV.NRORG
      WHERE CV.CDFILIAL = P_CDFILIAL
        AND CV.CDCIA = P_CDCIA
        AND CV.NRVOO = P_NRVOO
        AND CV.CDTRECHO = P_CDTRECHO
        AND EXISTS (SELECT CDCLASSE
                      FROM ORDCLASSEPROD
                     WHERE ORDCLASSEPROD.CDFILIAL = CV.CDFILIAL
                       AND ORDCLASSEPROD.CDCLASSE = CV.CDCLASSE)

      UNION ALL

     SELECT C.CDCLASSE, CL.SGCLASSE, C.QTPAXEQUI AS QTPAX
       FROM CONFIGEQUI C
      INNER JOIN CLASSE CL
      ON   CL.CDCLASSE = C.CDCLASSE
      AND  CL.NRORG    = C.NRORG
      WHERE C.CDFILIAL = P_CDFILIAL
        AND C.CDCIA = P_CDCIA
        AND C.CDEQUIP = P_CDEQUIP 
        AND NOT EXISTS (SELECT 1
                          FROM CONFIGVOO
                         WHERE CDFILIAL = P_CDFILIAL
                           AND CDCIA = P_CDCIA
                           AND NRVOO = P_NRVOO
                           AND CDTRECHO = P_CDTRECHO)
        AND EXISTS (SELECT CDCLASSE
                      FROM ORDCLASSEPROD
                     WHERE ORDCLASSEPROD.CDFILIAL = C.CDFILIAL
                       AND ORDCLASSEPROD.CDCLASSE = C.CDCLASSE)
   ) LOOP
      V_CDCLASSE := CUR_CLASSES.CDCLASSE;

      /*ZERADA*/
      IF P_IDPADRAOCALC = '1' THEN
         V_QTPAXCALC := 0;
      END IF;

      /*MAXIMA*/
      IF P_IDPADRAOCALC = '2' THEN
         V_QTPAXCALC := CUR_CLASSES.QTPAX;
      END IF;

      /*MEDIA H.*/
      IF P_IDPADRAOCALC = '3' THEN
         V_QTPAXCALC := MEDIA_CLASSE(CUR_CLASSES.CDCLASSE, CUR_CLASSES.QTPAX);
      END IF;
      
      /*PADRAO DE GERACAO*/
      IF P_IDPADRAOCALC = '4' THEN
         SELECT MAX(QTITEM)
           INTO V_QTITEM_PADRAO
           FROM ITPADRAOGERPREVPAX
          WHERE CDFILIAL = P_CDFILIAL
            AND NRPADRAOGERPREVPAX = P_NRPADRAOGERPREVPAX
            AND CDCIA = P_CDCIA
            AND NRVOO = P_NRVOO
            AND CDTRECHO = P_CDTRECHO
            AND CDEQUIP = P_CDEQUIP
            AND CDCLASSE = CUR_CLASSES.CDCLASSE;

         V_QTPAXCALC := ROUND(NVL(V_QTITEM_PADRAO, 0)/100 * CUR_CLASSES.QTPAX);
      END IF;

      /*PEDIDO*/
      IF P_IDPADRAOCALC = '5' THEN    
      /* Zera Quantidade de Passageiros e Inclui os Itens de Faturamento na tabela de PREVPAXSERVPRODM*/
         V_QTPAXCALC := 0;
         FOR CUR_ITENS_FAT IN (
            SELECT P.NRSERVICOCIAFILI, P.CDCICLO, S.DSSERVICOCIAFILI, CI.IDCICLO
                  FROM PAD_VOOEQUIPAMENTO P
                       INNER JOIN SERVICOCIAFILI S ON S.CDFILIAL = P.CDFILIAL AND
                                                      S.CDCIA = P.CDCIA AND
                                                      S.NRSERVICOCIAFILI = P.NRSERVICOCIAFILI
                       INNER JOIN CICLO CI ON CI.CDCICLO = P.CDCICLO
                       INNER JOIN SERVICOGEN G ON G.NRSERVICOGEN = S.NRSERVICOGEN
                 WHERE P.CDFILIAL = P_CDFILIAL
                   AND P.DTDATA = V_DTPREVISAOPROD
                   AND P.IDORIGEM = 'V'
                   AND P.CDCIA = P_CDCIA
                   AND P.NRVOO = P_NRVOO
                   AND P.CDTRECHO = P_CDTRECHO
                   AND P.CDCLASSE = CUR_CLASSES.CDCLASSE                   
                   AND P.CDCICLO = F_RETORNA_CICLOM(P.CDFILIAL,  P.CDCIA,  P.NRVOO,  P.CDTRECHO, V_DTPREVISAOPROD,
                                                    P.NRSERVICOCIAFILI, P.CDCLASSE, P.CDCICLO)
                   AND G.IDSERVICO NOT IN ('2', '3', '5')
         ) LOOP
              V_NRORDEMERROS := 1;
               /*Verifica se a companhia possui tabela de precos na data (por causa dos vinculos com subgrupos)*/
               SELECT MAX(NRTABPRECO), COUNT(1)
                 INTO V_NRTABPRECO, V_NUM_TABPRECO_ATIVAS
                 FROM TABPRECOSEM
                WHERE CDFILIAL = P_CDFILIAL
                  AND CDCIA = P_CDCIA
                  AND V_DTPREVISAOPROD BETWEEN DTINIVIGTAB AND DTFIMVIGTAB;

                /*Sigla da Companhia para a Lista de Erros*/
                SELECT MAX(SGCIA) 
                  INTO V_SGCIA
                  FROM COMPANHIA
                WHERE CDCIA = P_CDCIA
                AND   NRORG = P_NRORG;

               IF V_NUM_TABPRECO_ATIVAS = 0 THEN
                  /*Nao ha tabela de precos vigente para a companhia [SIGLA] na data [DATA]*/
                  INSERE_LISTA_ERROS(P_CDFILIAL, 'APPERRMSGSTR' || 'APP-00121' || '$$' || V_SGCIA || '$$' || V_DTPREVISAOPROD || 'APPERRMSGEND',
                                  P_CDOPERADOR, P_NRORG, P_NRLISTAERROS, V_NRORDEMERROS);
                  V_NRORDEMERROS := V_NRORDEMERROS + 1;
               END IF;

               IF V_NUM_TABPRECO_ATIVAS > 1 THEN
                  /*Ha mais de uma tabela de precos vigente para a companhia [SIGLA] na data [DATA]*/
                  INSERE_LISTA_ERROS(P_CDFILIAL, 'APPERRMSGSTR' || 'APP-00122' || '$$' || V_SGCIA || '$$' || V_DTPREVISAOPROD || 'APPERRMSGEND',
                                  P_CDOPERADOR, P_NRORG, P_NRLISTAERROS, V_NRORDEMERROS);
                  V_NRORDEMERROS := V_NRORDEMERROS + 1;
               END IF;

               IF V_NUM_TABPRECO_ATIVAS <> 1 THEN
                  CONTINUE;
               END IF;

                /*Verifica se o item possui preco na tabela de preco ativa da companhia*/
                  SELECT MAX(P.NRSEQPRECO), COUNT(1)
                    INTO V_NRSEQPRECO, V_NUM_PRECOS_ITEMFAT
                    FROM PRECOSECIAM P
                   WHERE P.CDFILIAL = P_CDFILIAL AND
                         P.CDCIA = P_CDCIA AND
                         P.NRTABPRECO = V_NRTABPRECO AND
                         P.NRSERVICOCIAFILI = CUR_ITENS_FAT.NRSERVICOCIAFILI AND
                         P.CDCLASSE = CUR_CLASSES.CDCLASSE AND
                         P.CDCICLO = CUR_ITENS_FAT.CDCICLO AND
                         V_DTPREVISAOPROD BETWEEN P.DTINIVIGSE AND P.DTFIMVIGSE;

                  IF V_NUM_PRECOS_ITEMFAT > 1 THEN
                     /*Ha mais de um preco para o item de faturamento [NOME] da classe [CLASSE] do ciclo [IDCICLO] na tabela ativa da companhia [SIGLA] na data [DATA]*/
                     INSERE_LISTA_ERROS(P_CDFILIAL, 
                                        'APPERRMSGSTR' || 'APP-00123' || '$$' ||
                                        CUR_ITENS_FAT.DSSERVICOCIAFILI || '$$' ||
                                        CUR_CLASSES.SGCLASSE || '$$' ||
                                        CUR_ITENS_FAT.IDCICLO || '$$' ||
                                        V_SGCIA || '$$' || 
                                        V_DTPREVISAOPROD
                                        || 'APPERRMSGEND',
                                        P_CDOPERADOR, P_NRORG, P_NRLISTAERROS, V_NRORDEMERROS);
                     V_NRORDEMERROS := V_NRORDEMERROS + 1;
                  END IF;

                  IF V_NUM_PRECOS_ITEMFAT = 0 THEN
                     /*Nao ha preco para o item de faturamento [NOME] da classe [CLASSE] do ciclo [IDCICLO] na tabela ativa da companhia [SIGLA] na data [DATA]*/
                     INSERE_LISTA_ERROS(P_CDFILIAL, 
                                        'APPERRMSGSTR' || 'APP-00124' || '$$' ||
                                        CUR_ITENS_FAT.DSSERVICOCIAFILI || '$$' ||
                                        CUR_CLASSES.SGCLASSE || '$$' ||
                                        CUR_ITENS_FAT.IDCICLO || '$$' ||
                                        V_SGCIA || '$$' || 
                                        V_DTPREVISAOPROD
                                        || 'APPERRMSGEND',
                                        P_CDOPERADOR, P_NRORG, P_NRLISTAERROS, V_NRORDEMERROS);
                     V_NRORDEMERROS := V_NRORDEMERROS + 1;
                  END IF;

                  IF V_NUM_PRECOS_ITEMFAT <> 1 THEN
                     CONTINUE;
                  END IF;
                  /*Insere ou atualiza os Itens de Faturamento na Previsao*/   
                  SELECT COUNT(1)
                    INTO V_EXISTE_PREVPAXSERV
                    FROM PREVPAXSERVPRODM
                   WHERE CDFILIAL = P_CDFILIAL
                     AND NRPREVISAOPROD = P_NRPREVISAOPROD
                     AND CDCIA = P_CDCIA
                     AND NRVOO = P_NRVOO
                     AND CDTRECHO = P_CDTRECHO
                     AND CDCLASSE = CUR_CLASSES.CDCLASSE
                     AND NRSERVICOCIAFILI = CUR_ITENS_FAT.NRSERVICOCIAFILI
                     AND CDCICLO  = CUR_ITENS_FAT.CDCICLO;

                  IF V_EXISTE_PREVPAXSERV > 0 THEN
                     UPDATE PREVPAXSERVPRODM
                        SET QTSERVICOVCALC = V_QTPAXCALC,
                            QTSERVICOINF = V_QTPAXCALC,
                            NRORGULTATU = P_NRORG,
                            CDOPERULTATU = P_CDOPERADOR, 
                            DTULTATU = SYSDATE
                      WHERE CDFILIAL = P_CDFILIAL
                        AND NRPREVISAOPROD = P_NRPREVISAOPROD
                        AND CDCIA = P_CDCIA
                        AND NRVOO = P_NRVOO
                        AND CDTRECHO = P_CDTRECHO
                        AND CDCLASSE = CUR_CLASSES.CDCLASSE
                        AND NRSERVICOCIAFILI = CUR_ITENS_FAT.NRSERVICOCIAFILI
                        AND CDCICLO  = CUR_ITENS_FAT.CDCICLO ;
                  ELSE
                    /*Sequencial da tabela de Itens de Faturamento da Previsao*/
                    NOVO_CODIGO_NT('PREVPAXSERVPRODM', V_SEQ);
                    V_NRNRPREVPAXSERVPROD := TO_NUMBER(V_SEQ);
                  
                    INSERT INTO PREVPAXSERVPRODM
                      (CDFILIAL, NRPREVISAOPROD, NRPREVPAXSERVPROD, CDCIA, NRVOO, CDTRECHO, CDCLASSE,
                        NRSERVICOCIAFILI, CDCICLO, NRTABPRECO, NRSEQPRECO, QTSERVICOVCALC, QTSERVICOINF,
                        NRORG, DTINCLUSAO, CDOPERINCLUSAO, DTULTATU, NRORGINCLUSAO, NRORGULTATU, CDOPERULTATU, IDATIVO)
                    VALUES(P_CDFILIAL, P_NRPREVISAOPROD, V_NRNRPREVPAXSERVPROD, P_CDCIA,
                            P_NRVOO, P_CDTRECHO, CUR_CLASSES.CDCLASSE, CUR_ITENS_FAT.NRSERVICOCIAFILI,
                            CUR_ITENS_FAT.CDCICLO, V_NRTABPRECO, V_NRSEQPRECO, V_QTPAXCALC,
                            V_QTPAXCALC, P_NRORG, SYSDATE, P_CDOPERADOR, SYSDATE, 
                            P_NRORG, P_NRORG, P_CDOPERADOR, 'S');

                    NOVO_CODIGO_NT('HPREVPAXSERVPRODM', V_SEQ);
                    V_HNRNRPREVPAXSERVPROD := TO_NUMBER(V_SEQ);

                    /*Insere o histo dos itens de pedido*/
                    INSERT INTO HPREVPAXSERVPRODM 
                    (CDFILIAL, NRPREVISAOPROD, NRPREVPAXSERVPROD, NRHPREVPAXSERVPRODM,
                     QTSERVICO,
                     NRORG, DTINCLUSAO, CDOPERINCLUSAO, DTULTATU, NRORGINCLUSAO, NRORGULTATU, CDOPERULTATU, IDATIVO)
                    VALUES
                    (P_CDFILIAL, P_NRPREVISAOPROD, V_NRNRPREVPAXSERVPROD, V_HNRNRPREVPAXSERVPROD,
                     V_QTPAXCALC,
                     P_NRORG, SYSDATE, P_CDOPERADOR, SYSDATE, P_NRORG, P_NRORG, P_CDOPERADOR, 'S');

                  END IF;
         END LOOP;
      END IF;

      SELECT COUNT(1)
        INTO V_EXISTE_PREVPAXCLA
        FROM PREVPAXCLAPRODM
       WHERE CDFILIAL = P_CDFILIAL
         AND NRPREVISAOPROD = P_NRPREVISAOPROD
         AND CDCIA = P_CDCIA
         AND NRVOO = P_NRVOO
         AND CDTRECHO = P_CDTRECHO
         AND CDCLASSE = CUR_CLASSES.CDCLASSE;

      /*Se ja existe na previsao apenas*/
      IF V_EXISTE_PREVPAXCLA > 0 THEN
         UPDATE PREVPAXCLAPRODM
            SET QTPAXPREVCALC = V_QTPAXCALC,
                QTPAXPREVINF = V_QTPAXCALC,
                NRORGULTATU = P_NRORG,
                CDOPERULTATU = P_CDOPERADOR,
                DTULTATU = SYSDATE
          WHERE CDFILIAL = P_CDFILIAL
            AND NRPREVISAOPROD = P_NRPREVISAOPROD
            AND CDCIA = P_CDCIA
            AND NRVOO = P_NRVOO
            AND CDTRECHO = P_CDTRECHO
            AND CDCLASSE = CUR_CLASSES.CDCLASSE;
      ELSE
         INSERT INTO PREVPAXCLAPRODM
         (CDFILIAL, NRPREVISAOPROD, CDCIA, NRVOO, CDTRECHO,
          CDCLASSE, QTPAXPREVCALC, QTPAXPREVINF,
          NRORG, NRORGINCLUSAO, NRORGULTATU,
          CDOPERINCLUSAO, CDOPERULTATU,
          DTINCLUSAO, DTULTATU, IDATIVO)
         VALUES
         (P_CDFILIAL, P_NRPREVISAOPROD, P_CDCIA, P_NRVOO, P_CDTRECHO,
          CUR_CLASSES.CDCLASSE, V_QTPAXCALC, V_QTPAXCALC,
          P_NRORG, P_NRORG, P_NRORG,
          P_CDOPERADOR, P_CDOPERADOR,
          SYSDATE, SYSDATE, 'S');
      END IF;

      NOVO_CODIGO_NT('LOGPREVPAXCLAPROD', V_SEQ);

      /* Insere a linha no log correspondente a inclusao */
      INSERT INTO LOGPREVPAXCLAPROD
      (CDFILIAL, NRPREVISAOPROD, CDCIA, NRVOO, CDTRECHO,
       CDCLASSE, NRSEQUENCIAL, QTPAXPREVCALC, QTPAXPREVINF,
       NRORG, NRORGINCLUSAO, NRORGULTATU,
       CDOPERINCLUSAO, CDOPERULTATU,
       DTINCLUSAO, DTULTATU, IDATIVO)
      VALUES
      (P_CDFILIAL, P_NRPREVISAOPROD, P_CDCIA, P_NRVOO, P_CDTRECHO,
       CUR_CLASSES.CDCLASSE, TO_NUMBER(V_SEQ), V_QTPAXCALC, V_QTPAXCALC,
       P_NRORG, P_NRORG, P_NRORG,
       P_CDOPERADOR, P_CDOPERADOR,
       SYSDATE, SYSDATE, 'S');
   END LOOP;

   FOR CUR_CLASSES_A_EXCLUIR IN
   (
   SELECT CDCLASSE
     FROM PREVPAXCLAPRODM
    WHERE CDFILIAL = P_CDFILIAL
         AND NRPREVISAOPROD = P_NRPREVISAOPROD
         AND CDCIA = P_CDCIA
         AND NRVOO = P_NRVOO
         AND CDTRECHO = P_CDTRECHO
         AND CDCLASSE NOT IN  (
                              SELECT CDCLASSE
                                FROM CONFIGVOO
                               WHERE CDFILIAL = P_CDFILIAL
                                 AND CDCIA = P_CDCIA
                                 AND NRVOO = P_NRVOO
                                 AND CDTRECHO = P_CDTRECHO
                                 AND EXISTS (SELECT CDCLASSE
                                               FROM ORDCLASSEPROD
                                              WHERE ORDCLASSEPROD.CDFILIAL = CONFIGVOO.CDFILIAL
                                                AND ORDCLASSEPROD.CDCLASSE = CONFIGVOO.CDCLASSE)

                               UNION ALL

                              SELECT CDCLASSE
                                FROM CONFIGEQUI C
                               WHERE CDFILIAL = P_CDFILIAL
                                 AND CDCIA = P_CDCIA
                                 AND CDEQUIP = P_CDEQUIP 
                                 AND NOT EXISTS (SELECT 1
                                                   FROM CONFIGVOO
                                                  WHERE CDFILIAL = P_CDFILIAL
                                                    AND CDCIA = P_CDCIA
                                                    AND NRVOO = P_NRVOO
                                                    AND CDTRECHO = P_CDTRECHO)
                                 AND EXISTS (SELECT CDCLASSE
                                               FROM ORDCLASSEPROD
                                              WHERE ORDCLASSEPROD.CDFILIAL = C.CDFILIAL
                                                AND ORDCLASSEPROD.CDCLASSE = C.CDCLASSE)
                              )
   ) LOOP
      DELETE FROM LOGPREVPAXCLAPROD
       WHERE CDFILIAL = P_CDFILIAL
         AND NRPREVISAOPROD = P_NRPREVISAOPROD
         AND CDCIA = P_CDCIA
         AND NRVOO = P_NRVOO
         AND CDTRECHO = P_CDTRECHO
         AND CDCLASSE = CUR_CLASSES_A_EXCLUIR.CDCLASSE;

      DELETE FROM PREVPAXCLAPRODM
       WHERE CDFILIAL = P_CDFILIAL
         AND NRPREVISAOPROD = P_NRPREVISAOPROD
         AND CDCIA = P_CDCIA
         AND NRVOO = P_NRVOO
         AND CDTRECHO = P_CDTRECHO
         AND CDCLASSE = CUR_CLASSES_A_EXCLUIR.CDCLASSE;

   END LOOP;


   /*Atualiza a previsao do voo com o calculo de quantidades utilizado*/
   UPDATE PREVPAXVOOPRODM
      SET IDPADRAOCALC = P_IDPADRAOCALC,
          NRPADRAOGERPREVPAX = CASE WHEN P_IDPADRAOCALC = '4' THEN P_NRPADRAOGERPREVPAX ELSE NULL END,
          NRORGULTATU = P_NRORG,
          CDOPERULTATU = P_CDOPERADOR,
          DTULTATU = SYSDATE
    WHERE CDFILIAL = P_CDFILIAL
      AND NRPREVISAOPROD = P_NRPREVISAOPROD
      AND CDCIA = P_CDCIA
      AND NRVOO = P_NRVOO
      AND CDTRECHO = P_CDTRECHO;

END;
/