CREATE OR REPLACE FUNCTION QTDE_PRODUTO_LCEST(
   P_CDFILIAL     IN FILIAL.CDFILIAL%TYPE,
   P_CDPRODUTO    IN PRODUTO.CDPRODUTO%TYPE,
   P_DTREFERENCIA IN DATE,
   P_ALMOXARIFE   IN ALMOXARIFADO.CDALMOXARIFE%TYPE DEFAULT ' ',
   P_LOCALESTOQ   IN LOCALESTOQUE.CDLOCALESTOQ%TYPE DEFAULT ' ',
   P_NRLOTEESTQ   IN POSESTDIA.NRLOTEESTQ%TYPE DEFAULT ' ',
   P_NRSUBLOTE    IN POSESTDIA.NRSUBLOTE%TYPE  DEFAULT ' ') RETURN FLOAT
IS

   V_CDALMOXARIFE  ALMOXARIFADO.CDALMOXARIFE%TYPE;
   V_CDLOCALESTOQ  LOCALESTOQUE.CDLOCALESTOQ%TYPE;
   V_NRLOTEESTQ    POSESTDIA.NRLOTEESTQ%TYPE;
   V_NRSUBLOTE     POSESTDIA.NRSUBLOTE%TYPE;
   V_QTESTOQDIA    POSESTDIA.QTESTOQDIA%TYPE;

   FILIAL_IDCTRLESTQ    PARAMFILIAL.IDCTRLESTQ%TYPE;
   FILIAL_IDUTILALMOX   PARAMFILIAL.IDUTILALMOX%TYPE;
   FILIAL_IDUTILLCESTQ  PARAMFILIAL.IDUTILLCESTQ%TYPE;
   FILIAL_IDUTILLOTE    PARAMFILIAL.IDUTILLOTE%TYPE;
   FILIAL_CDALMOXARIFE  ALMOXARIFADO.CDALMOXARIFE%TYPE;
   FILIAL_CDLOCALESTOQ  LOCALESTOQUE.CDLOCALESTOQ%TYPE;

   PROD_IDUTCTRLLOTE    PRODFILI.IDUTCTRLLOTE%TYPE;
   PROD_CDALMOXARIFE    ALMOXARIFADO.CDALMOXARIFE%TYPE;
   PROD_CDLOCALESTOQ    LOCALESTOQUE.CDLOCALESTOQ%TYPE;
   PROD_IDUTILLOTE      PARAMFILIAL.IDUTILLOTE%TYPE;

   LOTE_CDFILIAL  FILIAL.CDFILIAL%TYPE;

   V_CDPRODESTO PRODUTO.CDPRODUTO%TYPE;
   V_VRFATOCONV FLOAT;
   V_MAX_DTPOSIESTQ DATE;

BEGIN

   V_CDALMOXARIFE  := P_ALMOXARIFE;
   V_CDLOCALESTOQ  := P_LOCALESTOQ;
   V_NRLOTEESTQ    := P_NRLOTEESTQ;
   V_NRSUBLOTE     := P_NRSUBLOTE;

   /*Verifica se produto esta na filial e pega seus parametros especificos por filial*/
   BEGIN
      SELECT NVL(PF.IDUTCTRLLOTE,'N'), PF.CDALMOXARIFE, PF.CDLOCALESTOQ, P.CDPRODESTO, P.VRFATOCONV
        INTO PROD_IDUTCTRLLOTE, PROD_CDALMOXARIFE, PROD_CDLOCALESTOQ, V_CDPRODESTO, V_VRFATOCONV
        FROM PRODFILI PF, PRODUTO P
       WHERE (PF.CDFILIAL  = P_CDFILIAL)  AND
             (P.CDPRODUTO = P_CDPRODUTO) AND
             (PF.CDPRODUTO = P.CDPRODESTO);
   EXCEPTION
      WHEN NO_DATA_FOUND THEN
      /*Se produto nao vinculado a filial ou produto inexistente, retorna a quantidade 0 */
         RETURN 0.0;
   END;

   IF V_CDPRODESTO IS NULL THEN
      RETURN 0.0;
   END IF;

   /*Tratativa para campo vazio ou zero (erros de cadastro) */
   V_VRFATOCONV := CASE WHEN NVL(V_VRFATOCONV, 0) = 0 THEN 1 ELSE V_VRFATOCONV END;

   /*CASO O PARAMETRO DE ALMOXARIFADO NAO TENHA SIDO PASSADO, AI VERIFICA O ALMOXARIFADO, LOCALIZACAO E LOTE PADRAO. NO CASO O N INDICA QUE NAO FOI DEFINIDO*/
   IF P_ALMOXARIFE = 'N' THEN

      /*PARAMETRO POR FILIAL*/
      BEGIN
         SELECT NVL(IDCTRLESTQ,'N'), NVL(IDUTILALMOX,'N'), NVL(IDUTILLCESTQ,'N'), NVL(IDUTILLOTE,'N'), NVL(CDALMOXARIFE,'N'), NVL(CDLOCALESTOQ,'N')
           INTO FILIAL_IDCTRLESTQ, FILIAL_IDUTILALMOX, FILIAL_IDUTILLCESTQ, FILIAL_IDUTILLOTE, FILIAL_CDALMOXARIFE, FILIAL_CDLOCALESTOQ
           FROM PARAMFILIAL
          WHERE CDFILIAL = P_CDFILIAL;
      EXCEPTION
            WHEN NO_DATA_FOUND THEN
               FILIAL_IDCTRLESTQ   := 'N';
               FILIAL_IDUTILALMOX  := 'N';
               FILIAL_IDUTILLCESTQ := 'N';
               FILIAL_IDUTILLOTE   := 'N';
               FILIAL_CDALMOXARIFE := ' ';
               FILIAL_CDLOCALESTOQ := ' ';
      END;

      /*VERIFICA SE A FILIAL CONTROLA ESTOQUE*/
      IF NVL(FILIAL_IDCTRLESTQ,'N') <> 'N' THEN
          /*VERIFICA SE A FILIAL UTILIZA ALMOXARIFADO (ALMOXARIFADO_PADRAO)*/
          IF NVL(FILIAL_IDUTILALMOX,'N') = 'S' THEN
             IF NVL(PROD_CDALMOXARIFE,'N') = 'N' THEN
                V_CDALMOXARIFE := FILIAL_CDALMOXARIFE;
             ELSE
                V_CDALMOXARIFE := PROD_CDALMOXARIFE;
             END IF;
          ELSE
             V_CDALMOXARIFE := ' ';
          END IF;

          /*VERIFICA SE A FILIAL UTILIZA LOCALIZACAO  (LOCALESTOQUE_PADRAO)*/
          IF NVL(FILIAL_IDUTILLCESTQ,'N') = 'S' THEN
             IF NVL(PROD_CDLOCALESTOQ,'N') = 'N' THEN
                V_CDLOCALESTOQ := FILIAL_CDLOCALESTOQ;
             ELSE
                V_CDLOCALESTOQ := PROD_CDLOCALESTOQ;
             END IF;
          ELSE
             V_CDLOCALESTOQ := ' ';
          END IF;
      ELSE
         V_CDALMOXARIFE  := ' ';
         V_CDLOCALESTOQ  := ' ';
      END IF;

      /*CASO O PRODUTO POSSUA MAIS DE UM LOTE, E SOMADA A QTDE DE TODOS OS LOTES DO PRODUTO*/
      BEGIN
         SELECT SUM((D.QTESTOQDIA/V_VRFATOCONV)) AS QTESTOQDIA
          INTO  V_QTESTOQDIA
          FROM POSESTDIA D
          WHERE (D.CDFILIAL     = P_CDFILIAL)      AND
                (D.CDALMOXARIFE = V_CDALMOXARIFE)  AND
                (D.CDLOCALESTOQ = V_CDLOCALESTOQ)  AND
                (D.CDPRODUTO    = V_CDPRODESTO)    AND                
                (D.DTPOSIESTQ = (SELECT MAX(DTPOSIESTQ)
                               FROM POSESTDIA
                               WHERE (CDFILIAL     = P_CDFILIAL)      AND
                                     (CDALMOXARIFE = V_CDALMOXARIFE)  AND
                                     (CDLOCALESTOQ = V_CDLOCALESTOQ)  AND
                                     (CDPRODUTO    = V_CDPRODESTO)    AND
                                     (CDFILIAL     = D.CDFILIAL)     AND
                                     (CDALMOXARIFE = D.CDALMOXARIFE) AND
                                     (CDLOCALESTOQ = D.CDLOCALESTOQ) AND
                                     (NRLOTEESTQ   = D.NRLOTEESTQ)   AND
                                     (NRSUBLOTE    = D.NRSUBLOTE)    AND
                                     (CDPRODUTO    = D.CDPRODUTO)    AND
                                     (DTPOSIESTQ  <= P_DTREFERENCIA+1)));
      EXCEPTION
         WHEN NO_DATA_FOUND THEN
            V_QTESTOQDIA := 0;
      END;
   END IF;

   /*VERIFICA A QDTDE DO PRODUTO, PARA O ALMOXARIFADO, LOCALIZACAO, LOTE E SUBLOTE PASSADOS COMO PARAMETRO*/
   IF P_ALMOXARIFE <> 'N' THEN
      BEGIN
         SELECT (D.QTESTOQDIA/V_VRFATOCONV) AS QTESTOQDIA
          INTO  V_QTESTOQDIA
          FROM POSESTDIA D
          WHERE (D.CDFILIAL     = P_CDFILIAL)     AND
                (D.CDALMOXARIFE = V_CDALMOXARIFE) AND
                (D.CDLOCALESTOQ = V_CDLOCALESTOQ) AND
                (D.NRLOTEESTQ   = V_NRLOTEESTQ)   AND
                (D.NRSUBLOTE    = V_NRSUBLOTE)    AND
                (D.CDPRODUTO    = V_CDPRODESTO)    AND                
                (D.DTPOSIESTQ = (SELECT MAX(DTPOSIESTQ)
                               FROM POSESTDIA
                               WHERE (CDFILIAL     = P_CDFILIAL)     AND
                                     (CDALMOXARIFE = V_CDALMOXARIFE) AND
                                     (CDLOCALESTOQ = V_CDLOCALESTOQ) AND
                                     (NRLOTEESTQ   = V_NRLOTEESTQ)   AND
                                     (NRSUBLOTE    = V_NRSUBLOTE)    AND
                                     (CDPRODUTO    = V_CDPRODESTO)   AND                
                                     (CDFILIAL     = D.CDFILIAL)     AND
                                     (CDALMOXARIFE = D.CDALMOXARIFE) AND
                                     (CDLOCALESTOQ = D.CDLOCALESTOQ) AND
                                     (NRLOTEESTQ   = D.NRLOTEESTQ)   AND
                                     (NRSUBLOTE    = D.NRSUBLOTE)    AND
                                     (CDPRODUTO    = D.CDPRODUTO)    AND
                                     (DTPOSIESTQ  <= P_DTREFERENCIA+1)));
      EXCEPTION
         WHEN NO_DATA_FOUND THEN
            V_QTESTOQDIA := 0;
      END;
   END IF;

   RETURN(NVL(V_QTESTOQDIA, 0.0));
END;
/