create or replace
function CUSTO_PRATO
   (P_CDFILIAL     IN FILIAL.CDFILIAL%TYPE,
    P_CDFILICUSTO  IN FILIAL.CDFILIAL%TYPE,
    P_NRTIPOCUSTO  IN NUMBER,
    P_DTREFERENCIA IN DATE,
    P_CDFILAUXPRAT IN PRATO.CDFILAUXPRAT%TYPE,
    P_CDPRATO      IN PRATO.CDPRATO%TYPE,
    P_CDSERVFILI   IN SERVICO.CDSERVFILI%TYPE,
    P_VERIFICAPRODZERO IN VARCHAR2 DEFAULT 'N') RETURN FLOAT
 IS
    V_IDUTILFATCOR    PARAMPLANEJA.IDUTILFATCOR%TYPE;
    V_IDUTILFATCOC    PARAMPLANEJA.IDUTILFATCOC%TYPE;
    V_IDTIPCALCFAT    PARAMPLANEJA.IDTIPCALCFAT%TYPE;
    V_CDPRODUTO   PRODUTO.CDPRODUTO%TYPE;
    V_QTPRODUTO   NUMBER;
    V_CUSTO_PRATO NUMBER;
    V_UNIDADE_ESTOQUE NUMBER;
    V_CUSTO_DO_PRODUTO NUMBER;
    V_QTPRODRECSER NUMBER;
    V_SGUNIDADE    NUMBER;
    V_VRPEFATCOCSE NUMBER;
    V_VRPEFATCORSE NUMBER;
    V_QTPRODZERODESATU CHAR;
    CURSOR C_CUSTO_DO_PRATO IS 
     (SELECT 
         CDPRODUTO, 
         QTBRUTASE AS QTPRODUTO 
      FROM 
         RECESERV 
      WHERE 
         (CDFILAUXPRAT = P_CDFILAUXPRAT) AND 
         (CDPRATO      = P_CDPRATO)      AND
         (CDFILIAL     = P_CDFILIAL)     AND 
         (CDSERVFILI   = P_CDSERVFILI) 
      UNION 
      SELECT 
         CDPRODUTO, 
         QTBRUTALO AS QTPRODUTO 
      FROM 
         RECEFILI 
      WHERE 
         (CDFILAUXPRAT = P_CDFILAUXPRAT) AND 
         (CDPRATO      = P_CDPRATO)      AND 
         (CDFILIAL     = P_CDFILIAL)     AND 
          NOT EXISTS (SELECT 
                         CDPRATO 
                      FROM 
                         RECESERV 
                      WHERE 
                         (CDFILAUXPRAT = P_CDFILAUXPRAT) AND 
                         (CDPRATO      = P_CDPRATO)                        AND 
                         (CDFILIAL     = P_CDFILIAL)                       AND 
                         (CDSERVFILI   = P_CDSERVFILI) 
                      )
      UNION 
      SELECT 
         CDPRODUTO, 
         QTBRUTAPR  AS QTPRODUTO 
      FROM 
         RECEPADR 
      WHERE 
         (CDFILAUXPRAT = P_CDFILAUXPRAT) AND 
         (CDPRATO      = P_CDPRATO)      AND 
          NOT EXISTS (SELECT 
                         CDPRATO 
                      FROM 
                         RECEFILI 
                      WHERE 
                         (CDFILAUXPRAT = P_CDFILAUXPRAT) AND 
                         (CDPRATO      = P_CDPRATO)      AND 
                         (CDFILIAL     = P_CDFILIAL) 
                      ) AND 
          NOT EXISTS (SELECT 
                         CDPRATO 
                      FROM 
                         RECESERV 
                      WHERE 
                         (CDFILAUXPRAT = P_CDFILAUXPRAT) AND 
                         (CDPRATO      = P_CDPRATO)      AND 
                         (CDFILIAL     = P_CDFILIAL)     AND 
                         (CDSERVFILI   = P_CDSERVFILI) 
                      ) 
      ); 
 BEGIN 
    SELECT
       MAX(IDUTILFATCOR), 
       MAX(IDUTILFATCOC), 
       MAX(IDTIPCALCFAT) 
    INTO 
       V_IDUTILFATCOR, 
       V_IDUTILFATCOC, 
       V_IDTIPCALCFAT 
    FROM 
       PARAMPLANEJA 
    WHERE 
       CDFILIAL = P_CDFILIAL;
    IF V_IDUTILFATCOR IS NULL THEN
       V_IDUTILFATCOC := 'S';
       V_IDUTILFATCOR := 'S';
       V_IDTIPCALCFAT := 'T';
    END IF;
    V_CUSTO_PRATO := 0;
    V_QTPRODZERODESATU := 'N';
    OPEN C_CUSTO_DO_PRATO;
    LOOP
       FETCH C_CUSTO_DO_PRATO
       INTO V_CDPRODUTO,
            V_QTPRODUTO;
       EXIT WHEN C_CUSTO_DO_PRATO%NOTFOUND;
       V_CUSTO_DO_PRODUTO := CUSTO_PRODUTO(P_CDFILICUSTO, V_CDPRODUTO, P_NRTIPOCUSTO, P_DTREFERENCIA, sysdate);
       V_CUSTO_PRATO := V_CUSTO_PRATO + (ROUND(V_QTPRODUTO, 5) * ROUND(V_CUSTO_DO_PRODUTO, 5));

       IF (P_VERIFICAPRODZERO = 'S') AND (V_QTPRODZERODESATU = 'N') THEN
          IF (V_CUSTO_DO_PRODUTO = 0) THEN
             V_QTPRODZERODESATU := 'S';
          ELSE
             IF CUSTO_PROD_LISTADESATU(P_CDFILICUSTO, V_CDPRODUTO, P_NRTIPOCUSTO, P_DTREFERENCIA) = 'S' THEN
                V_QTPRODZERODESATU := 'S';
             END IF;
          END IF;
       END IF;

    END LOOP;
    CLOSE C_CUSTO_DO_PRATO;

    IF (P_VERIFICAPRODZERO = 'S') AND (V_QTPRODZERODESATU = 'S') THEN
       V_CUSTO_PRATO := V_CUSTO_PRATO * (-1);
    END IF;

    return(ROUND(V_CUSTO_PRATO, 5));
END;