create or replace FUNCTION CUSTO_SEMIACABADO(
   P_CDFILIAL     IN FILIAL.CDFILIAL%TYPE,
   P_CDPRODUTO   IN PRODUTO.CDPRODUTO%TYPE,
   P_NRTIPOCUSTO  IN NUMBER,
   P_DTREFERENCIA IN DATE,
   P_DTATUAL      IN DATE,
   P_TPRECEITA    IN FILIAL.CDFILIAL%TYPE,
   P_CDESPEPROD   IN COMPPROD.CDESPEPROD%TYPE,
   P_CDTIPOCOMP   IN COMPPROD.CDTIPOCOMP%TYPE,
   P_CDPROCFABRIC IN PROCFABRICA.CDPROCFABRIC%TYPE

) RETURN FLOAT
IS
   V_VRCUSTO       POSESTDIA.VRESTOQDIA%TYPE;
   V_VRCUSTOINSUMO POSESTDIA.VRESTOQDIA%TYPE;
   V_CDESPEPROD    COMPPROD.CDESPEPROD%TYPE;
   V_CDTIPOCOMP    COMPPROD.CDTIPOCOMP%TYPE;
   V_QTRENDINSU    TCOMPPRO.QTPRODTCOMP%TYPE;
   V_IDCUSTINSPROD PARAMAN.IDCUSTINSPROD%TYPE;
   V_CDALMOXARIFE  ALMOXARIFADO.CDALMOXARIFE%TYPE;
   V_CDLOCALESTOQ  LOCALESTOQUE.CDLOCALESTOQ%TYPE;
   V_CDPROCFABRIC  PROCFABRICA.CDPROCFABRIC%TYPE;

BEGIN
   V_VRCUSTO       := 0;
   V_VRCUSTOINSUMO := 0;
   BEGIN
      SELECT NVL(IDCUSTINSPROD,'N')
        INTO V_IDCUSTINSPROD
        FROM PARAMAN
       WHERE CDFILIAL = P_CDFILIAL;
   EXCEPTION
      WHEN NO_DATA_FOUND THEN
         V_IDCUSTINSPROD := 'N';
   END;
   IF P_TPRECEITA = 'ESP' THEN
      V_CDESPEPROD := P_CDESPEPROD;
      V_CDTIPOCOMP := P_CDTIPOCOMP;
      BEGIN
         SELECT QTPRODTCOMP
           INTO V_QTRENDINSU
           FROM TCOMPPRO TC
          WHERE (TC.CDPRODUTO  = P_CDPRODUTO)
            AND (TC.CDESPEPROD = V_CDESPEPROD)
            AND (TC.CDTIPOCOMP = V_CDTIPOCOMP);
      EXCEPTION
         WHEN NO_DATA_FOUND THEN BEGIN
            V_QTRENDINSU := 1;
         END;
      END;
      IF (V_CDESPEPROD IS NULL) THEN
         SELECT MAX(CDESPEPROD)
           INTO V_CDESPEPROD
           FROM ESPEPROD
          WHERE (CDFILIAL = P_CDFILIAL)
            AND (CDPRODUTO  = P_CDPRODUTO)
            AND (DTVALESPEPRO = (SELECT MAX(DTVALESPEPRO)
                                   FROM ESPEPROD
                                  WHERE (CDFILIAL = P_CDFILIAL)
                                    AND (CDPRODUTO  = P_CDPRODUTO)
                                    AND (DTVALESPEPRO < SYSDATE)));
         IF V_CDESPEPROD IS NULL THEN
            SELECT MAX(E1.CDESPEPROD)
              INTO V_CDESPEPROD
              FROM ESPEPROD E1
             WHERE (E1.CDPRODUTO  = P_CDPRODUTO)
               AND (E1.DTVALESPEPRO = (SELECT MAX(E2.DTVALESPEPRO)
                                         FROM ESPEPROD E2
                                        WHERE (E1.CDFILIAL = E2.CDFILIAL)
                                          AND (E1.CDPRODUTO  = E2.CDPRODUTO)
                                          AND (E2.DTVALESPEPRO < SYSDATE)));
         END IF;

         BEGIN
            SELECT CDTIPOCOMP,   QTPRODTCOMP
              INTO V_CDTIPOCOMP, V_QTRENDINSU
              FROM TCOMPPRO TC
             WHERE (TC.CDPRODUTO  = P_CDPRODUTO)
               AND (TC.CDESPEPROD = V_CDESPEPROD)
               AND (NVL(TC.IDTCOMPPROC,'N') = 'S');
         EXCEPTION
             WHEN NO_DATA_FOUND THEN BEGIN
                V_CDTIPOCOMP := NULL; V_QTRENDINSU := 1;
             END;
         END;
      END IF;

      FOR C_INSUMOS IN (SELECT IDSEMIACCOMP, CDPRODINSUMO, QTINSUMO
                          FROM COMPPROD
                         WHERE CDESPEPROD = V_CDESPEPROD
                           AND CDTIPOCOMP = V_CDTIPOCOMP
                           AND CDPRODUTO  = P_CDPRODUTO)
      LOOP
         BEGIN
            SELECT NVL(CDALMOXARIFE,' '),NVL(CDLOCALESTOQ,' ')
              INTO V_CDALMOXARIFE, V_CDLOCALESTOQ
              FROM PRODFILI
             WHERE CDFILIAL = P_CDFILIAL
               AND CDPRODUTO = C_INSUMOS.CDPRODINSUMO;
         EXCEPTION
            WHEN NO_DATA_FOUND THEN BEGIN
               V_CDALMOXARIFE := NULL; V_CDLOCALESTOQ := NULL;
            END;
         END;

         IF C_INSUMOS.IDSEMIACCOMP = 'S' THEN
            V_VRCUSTOINSUMO := V_VRCUSTOINSUMO + CUSTO_SEMIACABADO(P_CDFILIAL, C_INSUMOS.CDPRODINSUMO, P_NRTIPOCUSTO, P_DTREFERENCIA, P_DTATUAL, 'ESP', NULL, NULL, NULL);
         ELSE
            IF NVL(V_IDCUSTINSPROD,'N') = 'N' THEN
               V_VRCUSTOINSUMO := V_VRCUSTOINSUMO + ROUND(ROUND(CUSTO_PRODUTO(P_CDFILIAL, C_INSUMOS.CDPRODINSUMO, P_NRTIPOCUSTO, SYSDATE, SYSDATE),2)*C_INSUMOS.QTINSUMO,2);
            ELSE
               V_VRCUSTOINSUMO := V_VRCUSTOINSUMO + ROUND(ROUND(CUSTO_PRODUTO_ALMOX(P_CDFILIAL,C_INSUMOS.CDPRODINSUMO,P_NRTIPOCUSTO, SYSDATE, SYSDATE,V_CDALMOXARIFE,V_CDLOCALESTOQ),2)*C_INSUMOS.QTINSUMO,2);
            END IF;
         END IF;
      END LOOP;
      V_VRCUSTO := ROUND(V_VRCUSTOINSUMO/V_QTRENDINSU,2);
   ELSE
      V_CDPROCFABRIC := P_CDPROCFABRIC;
      IF V_CDPROCFABRIC IS NULL THEN
         BEGIN
            SELECT CDPROCFABRIC
              INTO V_CDPROCFABRIC
              FROM PROCFABRICA
             WHERE CDFILIAL = P_CDFILIAL
               AND CDPRODUTO = P_CDPRODUTO
               AND NVL(IDPROFABPADR, 'N') = 'S';
         EXCEPTION
            WHEN NO_DATA_FOUND THEN BEGIN
               V_CDPROCFABRIC := NULL;
            END;
         END;
      END IF;
      V_QTRENDINSU := RENDIMENTO_RECEITA_CDP(P_CDFILIAL,P_CDPRODUTO);
      IF V_QTRENDINSU = 0 THEN
         V_QTRENDINSU := 1;
      END IF;
      FOR C_INSUMOS IN (SELECT CDFILIAL, CDPRODUTO, IDSEMIACETAP, CDPRODINSUMO, SUM(QTINSUMETAPA) QTINSUMETAPA
                          FROM INSUMETAPA
                         WHERE CDFILIAL = P_CDFILIAL
                           AND CDPROCFABRIC = V_CDPROCFABRIC
                           AND CDPRODUTO  = P_CDPRODUTO
                        GROUP BY CDFILIAL, CDPRODUTO, IDSEMIACETAP, CDPRODINSUMO)
      LOOP
         BEGIN
            SELECT NVL(CDALMOXARIFE,' '),NVL(CDLOCALESTOQ,' ')
              INTO V_CDALMOXARIFE, V_CDLOCALESTOQ
              FROM PRODFILI
             WHERE CDFILIAL = P_CDFILIAL
               AND CDPRODUTO = C_INSUMOS.CDPRODINSUMO;
         EXCEPTION
            WHEN NO_DATA_FOUND THEN BEGIN
               V_CDALMOXARIFE := NULL; V_CDLOCALESTOQ := NULL;
            END;
         END;

         IF C_INSUMOS.IDSEMIACETAP = 'S' THEN
            V_VRCUSTOINSUMO := V_VRCUSTOINSUMO + CUSTO_SEMIACABADO(P_CDFILIAL, C_INSUMOS.CDPRODINSUMO, P_NRTIPOCUSTO, P_DTREFERENCIA, P_DTATUAL, 'PRO', NULL, NULL, NULL);
         ELSE
            IF NVL(V_IDCUSTINSPROD,'N') = 'N' THEN
               V_VRCUSTOINSUMO := V_VRCUSTOINSUMO + ROUND(ROUND(CUSTO_PRODUTO(P_CDFILIAL, C_INSUMOS.CDPRODINSUMO, P_NRTIPOCUSTO, SYSDATE, SYSDATE),2)*C_INSUMOS.QTINSUMETAPA,2);
            ELSE
               V_VRCUSTOINSUMO := V_VRCUSTOINSUMO + ROUND(ROUND(CUSTO_PRODUTO_ALMOX(P_CDFILIAL,C_INSUMOS.CDPRODINSUMO,P_NRTIPOCUSTO, SYSDATE, SYSDATE,V_CDALMOXARIFE,V_CDLOCALESTOQ),2)*C_INSUMOS.QTINSUMETAPA,2);
            END IF;
         END IF;
      END LOOP;
      V_VRCUSTO := ROUND(V_VRCUSTOINSUMO/V_QTRENDINSU,2);
   END IF;
   RETURN(V_VRCUSTO);
END;
/
