CREATE OR REPLACE PROCEDURE GERA_PREVPAXVOO_PROD
(P_CDFILIAL IN VARCHAR2,
 P_CDFILIPROC IN VARCHAR2, 
 P_NRPREVISAOPROD IN NUMBER,
 P_SUBSTITUI_JA_GERADOS IN VARCHAR2,
 P_CDCIA IN VARCHAR2,
 P_NRVOO IN VARCHAR2,
 P_CDTRECHO IN VARCHAR2,
 P_CDOPERADOR IN VARCHAR2,
 P_NRORG IN NUMBER DEFAULT 1,
 P_NRLISTAERROS IN OUT NUMBER
)
AS
   V_NRVERSAO NUMBER;
   V_DATA DATE;      
   V_VOO VARCHAR2(200);
   V_CDEQUIP VARCHAR2(4);
   V_CDBASEDES VARCHAR2(4);
   V_HRKDT VARCHAR2(4);
   V_HRKRT VARCHAR2(4);
   V_HRETD VARCHAR2(4);
   V_HRQUEBRA VARCHAR2(4);
   V_HRQUEBRAFILI VARCHAR2(4);
   V_HRQUEBRACIA VARCHAR2(4);
   V_NRTURNOETD VARCHAR2(2);
   V_CONTADOR NUMBER;      
   V_NUM_PREVVOO NUMBER;
   V_SGCIA VARCHAR2(20);
   V_IDPREVISAOPROD VARCHAR2(1);
BEGIN

   /*Busca a previsao existente para o numero informado*/
   SELECT MAX(P.DTPREVISAOPROD), MAX(PV.NRVERSAOPROD), MAX(PV.IDPREVISAOPROD)
    INTO V_DATA, V_NRVERSAO, V_IDPREVISAOPROD
    FROM PREVPAXPRODM P 
         INNER JOIN PREVPAXCIAPRODM PC ON PC.CDFILIAL = P.CDFILIAL AND
                                         PC.NRPREVISAOPROD = P.NRPREVISAOPROD
         LEFT JOIN PREVPAXVOOPRODM PV ON PV.CDFILIAL = PC.CDFILIAL AND
                                        PV.NRPREVISAOPROD = PC.NRPREVISAOPROD AND
                                        PV.CDCIA = PC.CDCIA AND
                                        PV.NRVOO = P_NRVOO AND
                                        PV.CDTRECHO = P_CDTRECHO
   WHERE P.CDFILIAL = P_CDFILIAL
     AND P.NRPREVISAOPROD = P_NRPREVISAOPROD
     AND PC.CDCIA = P_CDCIA;

   IF V_DATA IS NULL THEN
      /*Operacao bloqueada. Numero de previsao invalido.*/
      INSERE_LISTA_ERROS(P_CDFILIPROC, 'APPERRMSGSTR' || 'APP-00058' || 'APPERRMSGEND',
                         P_CDOPERADOR, P_NRORG, P_NRLISTAERROS);
      RETURN;
   END IF;

   /*Apaga a previsao do voo para regeracao (se solicitado)*/
   IF V_NRVERSAO IS NOT NULL THEN
      IF P_SUBSTITUI_JA_GERADOS = 'S' THEN
         APAGA_PREVPAXVOO_PROD(P_CDFILIAL, P_CDFILIPROC, P_NRPREVISAOPROD, P_CDCIA, P_NRVOO, P_CDTRECHO, P_CDOPERADOR, P_NRORG, P_NRLISTAERROS);
      ELSE
         RETURN;         
      END IF;      
   END IF;

   V_NRVERSAO := 1;


   /* Verifica se a previsao do voo para a data foi apagada (se solicitado). Se nao, cancela inclusao do voo*/
   SELECT COUNT(1)
     INTO V_NUM_PREVVOO
     FROM PREVPAXVOOPRODM
    WHERE CDFILIAL = P_CDFILIAL
      AND NRPREVISAOPROD = P_NRPREVISAOPROD
      AND CDCIA = P_CDCIA
      AND NRVOO = P_NRVOO
      AND CDTRECHO = P_CDTRECHO;
   IF V_NUM_PREVVOO > 0 AND P_SUBSTITUI_JA_GERADOS = 'S' THEN
      RETURN;
   END IF;
   
   /* Busca os parametros do voo */
   SELECT MAX(VD.CDEQUIP) CDEQUIP, MAX(VT.CDBASEDES) CDBASEDES, MAX(VD.HRKDT) HRKDT, MAX(VD.HRKRT) HRKRT, MAX(VD.HRETD) HRETD, MAX(C.SGCIA)          
     INTO V_CDEQUIP, V_CDBASEDES, V_HRKDT, V_HRKRT, V_HRETD, V_SGCIA
     FROM VOOTRECHODATA VD INNER JOIN VOOTRECHO VT ON VT.CDFILIAL = VD.CDFILIAL AND
                                                      VT.CDCIA = VD.CDCIA AND
                                                      VT.NRVOO = VD.NRVOO AND
                                                      VT.CDTRECHO = VD.CDTRECHO
          INNER JOIN COMPANHIA C ON C.CDCIA = VT.CDCIA
    WHERE VD.CDFILIAL = P_CDFILIAL      
      AND VD.CDCIA = P_CDCIA
      AND VD.NRVOO = P_NRVOO
      AND VD.CDTRECHO = P_CDTRECHO
      AND V_DATA BETWEEN VD.DTINIVIGENCIA AND NVL(VD.DTFIMVIGENCIA, V_DATA);

   SELECT MAX(HRQUEBRAETD)
     INTO V_HRQUEBRACIA
     FROM CIAFILI
    WHERE CDFILIAL = P_CDFILIAL
      AND CDCIA = P_CDCIA;

   V_HRQUEBRA := V_HRQUEBRACIA;

   IF V_HRQUEBRA IS NULL THEN
      SELECT MAX(HRQUEBRAETD)
        INTO V_HRQUEBRAFILI
        FROM PARAMCOMIS
       WHERE CDFILIAL = P_CDFILIAL;   

      V_HRQUEBRA := V_HRQUEBRAFILI;
   END IF;


   IF V_HRQUEBRA IS NULL THEN
      /*Nao ha horario de quebra definido para companhia [SGCIA]*/
      INSERE_LISTA_ERROS(P_CDFILIPROC, 'APPERRMSGSTR' || 'APP-00142' || '$$' || V_SGCIA || 'APPERRMSGEND',
                         P_CDOPERADOR, P_NRORG, P_NRLISTAERROS);
      RETURN;
   END IF;

   IF V_HRETD IS NULL THEN
      /*Nao ha horario de decolagem definido para o voo [VOO]*/
      INSERE_LISTA_ERROS(P_CDFILIPROC, 'APPERRMSGSTR' || 'APP-00143' || '$$' || V_SGCIA || '-' || P_NRVOO ||  'APPERRMSGEND',
                         P_CDOPERADOR, P_NRORG, P_NRLISTAERROS);
      RETURN;
   END IF;

   IF NVL(V_HRETD, '0000') BETWEEN '0000' AND V_HRQUEBRA THEN
      V_NRTURNOETD := '01';
   ELSE
      V_NRTURNOETD := '02';
   END IF;
   
   
   /* Insere na tabela PREVPAXVOOPROD com a versao atualizada */
   INSERT INTO PREVPAXVOOPRODM
   (CDFILIAL, NRPREVISAOPROD, CDCIA, NRVOO, CDTRECHO, IDPREVISAOPROD, NRVERSAOPROD,
    NRTURNOETD, CDBASEDES, CDEQUIP,
    HRKDT, HRKRT, HRETD, HRQUEBRA, 
    NRORG, NRORGINCLUSAO, NRORGULTATU,
    CDOPERINCLUSAO, CDOPERULTATU,
    DTINCLUSAO, DTULTATU, IDATIVO, IDPADRAOCALC, NRPADRAOGERPREVPAX)
   VALUES
   (P_CDFILIAL, P_NRPREVISAOPROD, P_CDCIA, P_NRVOO, P_CDTRECHO, 'P', V_NRVERSAO,
    V_NRTURNOETD, V_CDBASEDES, V_CDEQUIP,
    V_HRKDT, V_HRKRT, V_HRETD, V_HRQUEBRA,
    P_NRORG, P_NRORG, P_NRORG,
    P_CDOPERADOR, P_CDOPERADOR,
    SYSDATE, SYSDATE, 'S', 1, NULL);

   /* Percorre as classes do voo na malha aerea incluindo-as uma a uma */
   GERA_PREVPAXCLAPROD(P_CDFILIAL, P_CDFILIPROC, P_NRPREVISAOPROD, P_CDCIA, P_NRVOO, P_CDTRECHO, V_CDEQUIP, 
                       1, NULL, P_CDOPERADOR, P_NRORG, P_NRLISTAERROS);

   /* Verifica se foram incluidas classes para a data */
   SELECT COUNT(1)
     INTO V_CONTADOR
     FROM PREVPAXCLAPRODM
    WHERE CDFILIAL = P_CDFILIAL
      AND NRPREVISAOPROD = P_NRPREVISAOPROD
      AND CDCIA = P_CDCIA
      AND NRVOO = P_NRVOO
      AND CDTRECHO = P_CDTRECHO;
  
   /* Apaga o dia caso nao existam previsoes de companhias */
   IF V_CONTADOR <= 0 THEN
      DELETE FROM PREVPAXVOOPRODM
       WHERE CDFILIAL = P_CDFILIAL
         AND NRPREVISAOPROD = P_NRPREVISAOPROD
         AND CDCIA = P_CDCIA
         AND NRVOO = P_NRVOO
         AND CDTRECHO = P_CDTRECHO;
   END IF;  

END;
/