CREATE OR REPLACE PROCEDURE CALCULA_PRECOM(
  P_IDINDICE         IN VARCHAR DEFAULT 'N', -- 'S' -> Da mensagem de erro na ausencia do indice para o calculo.
  P_CDFILIAL         IN FILIAL.CDFILIAL%TYPE,
  P_CDCIA            IN COMPANHIA.CDCIA%TYPE,
  P_NRVOO            IN VOOTRECHO.NRVOO%TYPE,
  P_CDTRECHO         IN VOOTRECHO.CDTRECHO%TYPE,
  P_NRSERVICOCIAFILI IN SERVPLANOM.NRSERVICOCIAFILI%TYPE,
  P_CDCLASSE         IN CLASSE.CDCLASSE%TYPE,
  P_CDCICLO          IN CICLO.CDCICLO%TYPE,
  P_DTHRPLAVOOPV     IN SERVPLANOM.DTHRPLAVOOPV%TYPE,
  P_DTHRABASTPV      IN PLANOVOOM.DTHRABASTPV%TYPE,
  P_QTTOTPAX_PAXSBY  IN PREVISAOPAXM.QTTOTPAXAT%TYPE,
  P_QTSERFATSP       IN SERVPLANOM.QTSERFATSP%TYPE,
  P_IDTIPMANUALSP    IN SERVPLANOM.IDTIPMANUALSP%TYPE,
  P_VRPRECORRENTE    IN OUT FLOAT,
  P_VRPREDOLAR       IN OUT FLOAT
) AS
  V_TESTE          NUMBER;
  V_NRTABPRECO     TABPRECOSEM.NRTABPRECO%TYPE;
  V_IDFATSE        SERVICOCIAFILI.IDFATSE%TYPE;
  V_IDTIPMANUAL    SERVICOCIAFILI.IDTIPMANUAL%TYPE;
  V_QUANTIDADE     SERVPLANOM.QTSERFATSP%TYPE;
  V_IDTPPRECO      SERVICOCIAFILI.IDTPPRECO%TYPE;
  V_SGCIA          COMPANHIA.SGCIA%TYPE;
  V_COUNT          NUMBER;
  V_VRPRUDOLSESP   SERVPLANOM.VRPRUDOLSESP%TYPE;
  V_VRPRURESESP    SERVPLANOM.VRPRURESESP%TYPE;
  V_NRITEMPLANSP   SERVPLANOM.NRITEMPLANSP%TYPE;
  V_NRSEQPRECO     NUMBER;
  V_VRINDICE       MOVINDICE.VRINDICE%TYPE;
  V_CDSERVICO      PRODUTO.CDARVPROD%TYPE;
  V_IDCALCPRECPROP PARAMCOMIS.IDCALCPRECPROP%TYPE;
  V_NRDECITOTANF   PARAMGERAL.NRDECITOTANF%TYPE;
  V_IDCALCPROPDLCOM PARAMCOMIS.IDCALCPROPDLCOM%TYPE;
  V_PROP            NUMBER;
  V_IDPROPORCAO     NUMBER;
  V_DSSERVICOCIAFILI VARCHAR2(250);
  V_SGCLASSE VARCHAR2(20);
  V_IDCICLO VARCHAR2(20);
  V_SERVICO VARCHAR2(500);
  V_DESC_VOO VARCHAR2(50);
BEGIN

   SELECT MAX(SGCIA)
      INTO   V_SGCIA
      FROM   COMPANHIA
      WHERE  CDCIA = P_CDCIA;

   V_DESC_VOO := V_SGCIA || '-' || P_NRVOO;

   SELECT MAX(SCF.DSSERVICOCIAFILI), MAX(CL.SGCLASSE), MAX(CI.IDCICLO)
   INTO V_DSSERVICOCIAFILI, V_SGCLASSE, V_IDCICLO
   FROM SERVCICLO SC   
        INNER JOIN SERVICOCIAFILI SCF ON SCF.CDFILIAL = SC.CDFILIAL AND
                                         SCF.CDCIA = SC.CDCIA AND
                                         SCF.NRSERVICOCIAFILI = SC.NRSERVICOCIAFILI
        INNER JOIN CLASSE CL ON CL.CDCLASSE = SC.CDCLASSE
        INNER JOIN CICLO CI ON CI.CDCICLO = SC.CDCICLO
   WHERE (SC.CDFILIAL = P_CDFILIAL) AND
         (SC.CDCIA = P_CDCIA) AND
         (SC.NRSERVICOCIAFILI = P_NRSERVICOCIAFILI) AND
         (SC.CDCLASSE = P_CDCLASSE) AND
         (SC.CDCICLO = P_CDCICLO);
   
   V_SERVICO := '$$'||V_DSSERVICOCIAFILI||'$$'||V_SGCLASSE||'$$'||V_IDCICLO;
   
   SELECT COUNT(*)
   INTO V_COUNT
   FROM SERVPLANOM
   WHERE (CDFILIAL     = P_CDFILIAL    ) AND
         (CDCIA        = P_CDCIA       ) AND
         (NRVOO        = P_NRVOO       ) AND
         (CDTRECHO     = P_CDTRECHO    ) AND
         (DTHRPLAVOOPV = P_DTHRPLAVOOPV) AND
         (NRSERVICOCIAFILI = P_NRSERVICOCIAFILI) AND
         (CDCLASSE         = P_CDCLASSE) AND
         (CDCICLO          = P_CDCICLO) AND
         (IDSITSERSP  <> '3'           );

  BEGIN
     SELECT NVL(NRDECITOTANF, 2)
     INTO V_NRDECITOTANF
     FROM PARAMGERAL
     WHERE
        (CDFILIAL = P_CDFILIAL);
  EXCEPTION
     WHEN No_Data_Found THEN
      V_NRDECITOTANF := NULL;
  END;

  /* testa se possui preco proporcional / calcula proporcionalidade em deliv complementar / nao e qt 1 por pax nao deve permitir*/

   BEGIN
      SELECT NRTABPRECO
            INTO V_NRTABPRECO
            FROM TABPRECOSEM
            WHERE (CDFILIAL = P_CDFILIAL) AND
                  (CDCIA    = P_CDCIA)    AND
                  (P_DTHRABASTPV BETWEEN DTINIVIGTAB AND DTFIMVIGTAB);
   EXCEPTION
      WHEN No_Data_Found THEN
       V_NRTABPRECO := NULL;
   END;
   IF V_NRTABPRECO IS NULL THEN
     --Sem tabela de preco ativa na data
     RAISE_APPLICATION_ERROR(-20501, 'APPERRMSGSTR' || 'APP-00043' || '$$' || V_SGCIA || '$$' ||TO_CHAR(P_DTHRABASTPV, 'DD/MM/YYYY') || 'APPERRMSGEND');     
   END IF;

  SELECT MAX(IDCALCPROPDLCOM)
    INTO V_IDCALCPROPDLCOM
    FROM PARAMCOMIS
   WHERE (CDFILIAL = P_CDFILIAL);

  IF (V_COUNT > 0) AND (P_QTSERFATSP = 0) THEN
      DBMS_OUTPUT.PUT_LINE(V_COUNT||' - '||P_QTSERFATSP);

      SELECT NRITEMPLANSP,VRPRUDOLSESP,VRPRURESESP
      INTO V_NRITEMPLANSP,V_VRPRUDOLSESP,V_VRPRURESESP
      FROM  SERVPLANOM
      WHERE (CDFILIAL     = P_CDFILIAL    ) AND
            (CDCIA        = P_CDCIA       ) AND
            (NRVOO        = P_NRVOO       ) AND
            (CDTRECHO     = P_CDTRECHO    ) AND
            (DTHRPLAVOOPV = P_DTHRPLAVOOPV) AND
            (NRSERVICOCIAFILI = P_NRSERVICOCIAFILI) AND
            (CDCLASSE = P_CDCLASSE) AND
            (CDCICLO  = P_CDCICLO ) AND
            (IDSITSERSP  <> '3'           ) AND
            (NRITEMPLANSP = (SELECT MIN(NRITEMPLANSP)
                             FROM  SERVPLANOM
                             WHERE (CDFILIAL     = P_CDFILIAL    ) AND
                                   (CDCIA        = P_CDCIA       ) AND
                                   (NRVOO        = P_NRVOO       ) AND
                                   (CDTRECHO     = P_CDTRECHO    ) AND
                                   (DTHRPLAVOOPV = P_DTHRPLAVOOPV) AND
                                   (NRSERVICOCIAFILI = P_NRSERVICOCIAFILI) AND
                                   (CDCLASSE = P_CDCLASSE) AND
                                   (CDCICLO  = P_CDCICLO ) AND
                                   (IDSITSERSP  <> '3'           )));

      P_VRPRECORRENTE := V_VRPRURESESP;
      P_VRPREDOLAR    := V_VRPRUDOLSESP;

   ELSE     

      SELECT IDFATSE, IDTIPMANUAL,  IDTPPRECO
      INTO   V_IDFATSE, V_IDTIPMANUAL,V_IDTPPRECO
      FROM   SERVICOCIAFILI
      WHERE  CDFILIAL = P_CDFILIAL
        AND  CDCIA    = P_CDCIA
        AND  NRSERVICOCIAFILI = P_NRSERVICOCIAFILI;

      BEGIN
         SELECT NVL(IDCALCPRECPROP, '1')
         INTO V_IDCALCPRECPROP
         FROM PARAMCOMIS
         WHERE
           (CDFILIAL = P_CDFILIAL);
      EXCEPTION
         WHEN No_Data_Found THEN
            V_IDCALCPRECPROP := NULL;
      END;

       /* INCLUIDO POR LUCIANA DIA 14/06/2000 A PEDIDO DO SR. JULIANO GUERRA E RODRIGO */
       /* PARAMETRO CRIADO PARA CALCULO DE SERVICO COM PRECO PROPORCIONAL COM O PRECO TOTAL MARCADO */
      IF ((V_IDTPPRECO = '2') AND (V_IDCALCPRECPROP = '1')) THEN     /* PRECO TOTAL */
        V_QUANTIDADE := P_QTTOTPAX_PAXSBY;
      ELSE
        V_QUANTIDADE := P_QTSERFATSP;
      END IF;

      IF P_IDTIPMANUALSP IS NOT NULL THEN
         V_IDTIPMANUAL := P_IDTIPMANUALSP;
      END IF;

      IF V_IDFATSE = '1' THEN

         BEGIN
            SELECT COUNT(*)
            INTO V_TESTE
            FROM TABPRECOSEM
            WHERE (CDFILIAL = P_CDFILIAL) AND
                  (CDCIA    = P_CDCIA   ) AND
                  (P_DTHRABASTPV BETWEEN DTINIVIGTAB AND DTFIMVIGTAB);
         EXCEPTION
            WHEN No_Data_Found THEN
             V_TESTE := NULL;
         END;
         IF (V_TESTE > 1) THEN
               /*Geracao interrompida. Existe mais de uma tabela ativa no momento para a companhia $param[1]. Verifique a validade das tabelas de preco existentes e tente novamente.*/
               RAISE_APPLICATION_ERROR(-20501, 'APPERRMSGSTR' || 'APP-00009' || '$$' ||V_SGCIA || 'APPERRMSGEND', TRUE);
         END IF;


         IF (V_TESTE = 1) THEN
            BEGIN
               SELECT NRTABPRECO
               INTO V_NRTABPRECO
               FROM TABPRECOSEM
               WHERE (CDFILIAL = P_CDFILIAL) AND
                     (CDCIA    = P_CDCIA)    AND
                     (P_DTHRABASTPV BETWEEN DTINIVIGTAB AND DTFIMVIGTAB);
         EXCEPTION
            WHEN No_Data_Found THEN
             V_NRTABPRECO := NULL;
         END;

            SELECT COUNT(P.NRSEQPRECO),MIN(P.NRSEQPRECO),
                   NVL(MIN(P.VRPRESERV),0),NVL(MIN(P.VRPRESERVD),0), MAX(P.IDPROPORCAO)
            INTO V_TESTE,V_NRSEQPRECO,P_VRPRECORRENTE,P_VRPREDOLAR, V_IDPROPORCAO
            FROM PRECOSECIAM P
            WHERE (P.CDFILIAL   = P_CDFILIAL  ) AND
                  (P.CDCIA      = P_CDCIA     ) AND
                  (P.NRTABPRECO = V_NRTABPRECO) AND
                  (P.NRSERVICOCIAFILI  = P_NRSERVICOCIAFILI ) AND
                  (P.CDCLASSE  = P_CDCLASSE ) AND
                  (P.CDCICLO   = P_CDCICLO ) AND
                  (P_DTHRABASTPV BETWEEN P.DTINIVIGSE AND P.DTFIMVIGSE);

            IF (V_TESTE > 1) THEN
               /*Geracao interrompida. O item de faturamento $param[0] da classe: $param[1] e ciclo: $param[2] possui dois precos vigentes para o dia. Verifique a vigencia do item de faturamento na tabela de preco e tente novamente.*/
               RAISE_APPLICATION_ERROR(-20501, 'APPERRMSGSTR' || 'APP-00010'|| V_SERVICO || '$$' || V_DESC_VOO || 'APPERRMSGEND', TRUE);

            ELSIF (V_TESTE = 1) THEN
               SELECT COUNT(*)
               INTO V_TESTE
               FROM PROPRECOSEM
               WHERE (CDFILIAL   = P_CDFILIAL  ) AND
                     (CDCIA      = P_CDCIA     ) AND
                     (NRTABPRECO = V_NRTABPRECO) AND
                     (NRSERVICOCIAFILI   = P_NRSERVICOCIAFILI) AND
                     (CDCLASSE    = P_CDCLASSE) AND
                     (CDCICLO     = P_CDCICLO) AND
                     (NRSEQPRECO = V_NRSEQPRECO) AND
                     (V_QUANTIDADE BETWEEN QTPAXINICIAL AND QTPAXFINAL);

               IF (V_TESTE > 1) THEN
                  /*Geracao interrompida. Existe mais de um intervalo cadastrado para a quantidade de passageiros $param[0] para a companhia $param[1]. Verifique a tabela de preco proporcional e tente novamente.*/
                  RAISE_APPLICATION_ERROR(-20501, 'APPERRMSGSTR' || 'APP-00011'|| V_SERVICO || '$$' || TO_CHAR(V_QUANTIDADE) || 'APPERRMSGEND', TRUE);
               END IF;

               /* Testa se nao achou preco para o intervalo informado mas achou para outro intervalo */
               IF (V_TESTE = 0) THEN
                  SELECT COUNT(*)
                  INTO V_TESTE
                  FROM PROPRECOSEM
                  WHERE (CDFILIAL   = P_CDFILIAL  ) AND
                        (CDCIA      = P_CDCIA     ) AND
                        (NRTABPRECO = V_NRTABPRECO) AND
                        (NRSERVICOCIAFILI   = P_NRSERVICOCIAFILI) AND
                        (CDCLASSE    = P_CDCLASSE) AND
                        (CDCICLO     = P_CDCICLO) AND
                        (NRSEQPRECO = V_NRSEQPRECO);
                  IF (V_TESTE > 0) THEN
                     /*Geracao interrompida. O item de faturamento $param[0] da classe: $param[1] e ciclo: $param[2] possui preco proporcional, mas nao possui preco cadastrado para quantidade do item $param[3]. Verifique a tabela de preco proporcional e tente novamente.*/
                     RAISE_APPLICATION_ERROR(-20501, 'APPERRMSGSTR' || 'APP-00012'|| V_SERVICO || '$$' || TO_CHAR(V_QUANTIDADE) || 'APPERRMSGEND', TRUE);

                  END IF;
               END IF;

               IF (V_TESTE = 1) THEN
                  /*IF (V_IDCALCPROPDLCOM = 'S') AND (V_PROP > 0) AND (V_IDPROPORCAO <> '1') THEN
                    RAISE_APPLICATION_ERROR(-20501, 'APPERRMSGSTR' || 'APP-00019'|| V_SERVICO || 'APPERRMSGEND' , TRUE);
                 END IF;*/

                  SELECT VRPRESERVPRO, VRPRESERVDPRO
                  INTO P_VRPRECORRENTE, P_VRPREDOLAR
                  FROM PROPRECOSEM
                  WHERE (CDFILIAL   = P_CDFILIAL  ) AND
                        (CDCIA      = P_CDCIA     ) AND
                        (NRTABPRECO = V_NRTABPRECO) AND
                        (NRSERVICOCIAFILI   = P_NRSERVICOCIAFILI) AND
                        (CDCLASSE    = P_CDCLASSE) AND
                        (CDCICLO     = P_CDCICLO) AND
                        (NRSEQPRECO = V_NRSEQPRECO) AND
                        (V_QUANTIDADE BETWEEN QTPAXINICIAL AND QTPAXFINAL);
               END IF;
            END IF;
         END IF;
        --Raise_Application_Error(-20501, 'APP-00008'||V_SERVICO, TRUE);
         IF (P_VRPRECORRENTE IS NULL) THEN
           P_VRPRECORRENTE:= 0;
         END IF;
         IF (P_VRPREDOLAR    IS NULL) THEN
           P_VRPREDOLAR   := 0;
         END IF;

         /* Testa se ha indice cadastrado para o dia*/
         SELECT NVL(MIN(MI.VRINDICE),0)
         INTO V_VRINDICE
         FROM PARAMGERAL PA, MOVINDICE MI
         WHERE (MI.CDTPINDICE(+) = '1'   ) AND
               (MI.IDPERVALOR(+) = '2'   ) AND
               (MI.CDINDICE  (+) = '0002') AND
               (MI.DTREFIND  (+) = P_DTHRABASTPV);

         IF (P_VRPRECORRENTE =0) and (P_VRPREDOLAR = 0) then
            RAISE_APPLICATION_ERROR(-20501, 'APPERRMSGSTR' || 'APP-00008' || V_SERVICO || '$$' || V_DESC_VOO || 'APPERRMSGEND', TRUE);

         END IF;

         IF V_IDTIPMANUAL = '1'  THEN
            IF P_VRPRECORRENTE = 0 THEN
               IF V_VRINDICE <> 0 THEN
                   P_VRPRECORRENTE := P_VRPREDOLAR * V_VRINDICE;
               ELSIF P_IDINDICE = 'S' THEN
                  RAISE_APPLICATION_ERROR(-20501, 'APPERRMSGSTR' || 'APP-00013' || V_SERVICO || 'APPERRMSGEND', TRUE);

               END IF;
            ELSE
                P_VRPREDOLAR := 0; /* Zerar preco em dolar para servicos nacionais apenas qdo o preco em real nao for calculado com base nele */
            END IF;
         ELSE
            IF P_VRPREDOLAR = 0 THEN
               IF V_VRINDICE <> 0 THEN
                   P_VRPREDOLAR := P_VRPRECORRENTE / V_VRINDICE;
               ELSIF P_IDINDICE = 'S' THEN
                  RAISE_APPLICATION_ERROR(-20501, 'APPERRMSGSTR' || 'APP-00014' || V_SERVICO || 'APPERRMSGEND', TRUE);
               END IF;
            ELSE
               P_VRPRECORRENTE := 0; /* Zerar preco em real sempre para servicos internacionais */
            END IF;
         END IF;

      ELSE /* JOGA PRECO ZERO PARA SERVICOS DO TIPO NAO FATURADO */
         P_VRPRECORRENTE:= 0;
         P_VRPREDOLAR   := 0;
      END IF;
   END IF;

   IF (V_NRDECITOTANF = 0) THEN
      P_VRPRECORRENTE := ROUND(P_VRPRECORRENTE, 0);
      P_VRPREDOLAR := ROUND(P_VRPREDOLAR, 0);
   END IF;
   P_VRPRECORRENTE := ROUND(P_VRPRECORRENTE, 2);
   P_VRPREDOLAR := ROUND(P_VRPREDOLAR, 2);
END;
/