CREATE OR REPLACE PROCEDURE CUSTO_COMP_PROD(
P_CDPRODUTO     IN PRODUTO.CDPRODUTO%TYPE,
P_CDFILIAL      IN SALDOCAIXA.CDFILIAL%TYPE,
P_FILIPROC      IN SALDOCAIXA.CDFILIAL%TYPE,
P_TIPOCUSTO     IN NUMBER,
P_QTPRODUTO     IN NUMBER,
P_LOJA          IN LOJA.CDLOJA%TYPE DEFAULT NULL,
P_VRCUSTO       OUT NUMBER,
P_DATA          IN VENDA.DTVENDA%TYPE DEFAULT SYSDATE,
P_NIVEL         IN VARCHAR DEFAULT '%',
P_TIPOCOMP      IN VARCHAR DEFAULT NULL
)
AS
V_EXISTE_COMP_PADRAO  NUMBER;
V_EXISTE_COMP_LOCAL   NUMBER;
V_VRCUSTO             NUMBER;
V_NRPRODUTOS          NUMBER;
V_LOOP_PADRAO         VARCHAR2(1);
V_LOOP_LOCAL          VARCHAR2(1);
V_RESULT              FILIAL.CDFILIAL%TYPE;
V_ALMOX               VARCHAR2(6);
V_LOCAL               VARCHAR2(6);
V_DATA                VENDA.DTVENDA%TYPE;
V_IDUTCTRLLOTE        VARCHAR2(1); 
BEGIN
   V_LOOP_PADRAO := 'N';
   V_LOOP_LOCAL  := 'N';
   V_VRCUSTO     := 0;
   IF P_DATA IS NULL THEN
      V_DATA := SYSDATE;
   ELSE
      V_DATA := P_DATA;
   END IF;
   /* VERIFICA COMPOSICAO LOCAL */
   SELECT COUNT(*)
   INTO   V_NRPRODUTOS
   FROM   ROTFABLOCAL
   WHERE (CDFILIAL  = P_CDFILIAL ) AND
         (CDPRODUTO = P_CDPRODUTO);
   IF V_NRPRODUTOS > 0 THEN
      V_RESULT := P_CDFILIAL;
   ELSE
      V_RESULT := 'P';
   END IF;
   /* NO RELATORIO COMPOSICAO DO PRODUTO POR LOJA, CALCULA-SE O CUSTO CONSIDERANDO-SE APENAS A COMPOSICAO PADRAO, SE ESTA OPCAO ESTIVER MARCADA */
   IF P_TIPOCOMP = 'P' THEN
      V_RESULT := P_TIPOCOMP;
   END IF;
   IF V_RESULT = 'P' THEN
      FOR C_PADRAO IN
         (SELECT
            RB.CDPRODUTO,  RB.CDSUBPRODUTO, RB.QTSUBPRODROT,
            RB.NRHRFABPROD,RB.NRSEQPROD, RB.IDIMPPRODROT,
            PT.NMPRODUTO,  PT.SGUNIDADE,  DR.TXROTFAB as TXINSTR
         FROM
            ROTFABRICA RB, PRODUTO PT, DESCROTEIRO DR
         WHERE
            (RB.CDPRODUTO    = P_CDPRODUTO  ) AND
            (RB.CDSUBPRODUTO = PT.CDPRODUTO  ) AND
            (RB.CDPRODUTO    = DR.CDPRODUTO(+) AND
            (PT.CDARVPROD LIKE P_NIVEL||'%') )) LOOP
          /*Busca o almoxarifado e localizacao*/
          IF NOT P_LOJA IS NULL THEN
             SELECT MAX(CDALMOXARIFE), MAX(CDLOCALESTOQ)
             INTO  V_ALMOX, V_LOCAL
             FROM LOJA
             WHERE CDFILIAL = P_CDFILIAL AND
                   CDLOJA   = P_LOJA;
          END IF;
          IF V_ALMOX IS NULL THEN
             SELECT MAX(CDALMOXARIFE), MAX(CDLOCALESTOQ)
             INTO  V_ALMOX, V_LOCAL
             FROM PRODFILI
             WHERE CDFILIAL  = P_CDFILIAL AND
                   CDPRODUTO = C_PADRAO.CDSUBPRODUTO;
          END IF;
          IF V_ALMOX IS NULL THEN
             SELECT MAX(CDALMOXARIFE), MAX(CDLOCALESTOQ)
             INTO  V_ALMOX, V_LOCAL
             FROM PARAMFILIAL
             WHERE CDFILIAL = P_CDFILIAL;
          END IF;
          IF V_ALMOX IS NULL THEN
             V_ALMOX := ' ';
             V_LOCAL := ' ';
          END IF;
          IF V_LOCAL IS NULL THEN
             V_LOCAL := ' ';
          END IF;
          SELECT MAX(IDUTCTRLLOTE)
            INTO V_IDUTCTRLLOTE
            FROM PRODFILI
           WHERE CDFILIAL  = P_CDFILIAL
             AND CDPRODUTO = C_PADRAO.CDSUBPRODUTO;
          SELECT COUNT(*)
          INTO   V_EXISTE_COMP_PADRAO
          FROM   ROTFABRICA
          WHERE (CDPRODUTO = C_PADRAO.CDSUBPRODUTO);
          IF V_EXISTE_COMP_PADRAO > 0 THEN
             CUSTO_COMP_PROD(C_PADRAO.CDSUBPRODUTO,P_CDFILIAL,P_FILIPROC,P_TIPOCUSTO,(C_PADRAO.QTSUBPRODROT * P_QTPRODUTO),P_LOJA, P_VRCUSTO,V_DATA,P_NIVEL,P_TIPOCOMP);
             V_VRCUSTO := V_VRCUSTO + P_VRCUSTO;
             P_VRCUSTO := V_VRCUSTO;
          ELSE
             IF V_IDUTCTRLLOTE = 'S' THEN
                V_VRCUSTO := V_VRCUSTO + (CUSTO_PRODUTO(P_CDFILIAL,C_PADRAO.CDSUBPRODUTO,P_TIPOCUSTO,V_DATA,V_DATA) * C_PADRAO.QTSUBPRODROT * P_QTPRODUTO);
             ELSE
                V_VRCUSTO := V_VRCUSTO + (CUSTO_PROD(P_CDFILIAL,C_PADRAO.CDSUBPRODUTO,P_TIPOCUSTO,V_DATA, V_ALMOX, V_LOCAL, ' ', ' ') * C_PADRAO.QTSUBPRODROT * P_QTPRODUTO);
             END IF;
             P_VRCUSTO := V_VRCUSTO;
             V_ALMOX := '';
             V_LOCAL := '';
          END IF;
          V_LOOP_PADRAO := 'S';
      END LOOP;
      IF V_LOOP_PADRAO <> 'S' THEN
          IF NOT P_LOJA IS NULL THEN
             SELECT MAX(CDALMOXARIFE), MAX(CDLOCALESTOQ)
             INTO  V_ALMOX, V_LOCAL
             FROM LOJA
             WHERE CDFILIAL = P_CDFILIAL AND
                   CDLOJA   = P_LOJA;
          END IF;
          IF V_ALMOX IS NULL THEN
             SELECT MAX(CDALMOXARIFE), MAX(CDLOCALESTOQ)
             INTO  V_ALMOX, V_LOCAL
             FROM PRODFILI
             WHERE CDFILIAL  = P_CDFILIAL AND
                   CDPRODUTO = P_CDPRODUTO;
          END IF;
          IF V_ALMOX IS NULL THEN
             SELECT MAX(CDALMOXARIFE), MAX(CDLOCALESTOQ)
             INTO  V_ALMOX, V_LOCAL
             FROM PARAMFILIAL
             WHERE CDFILIAL = P_CDFILIAL;
          END IF;
          IF V_ALMOX IS NULL THEN
             V_ALMOX := ' ';
             V_LOCAL := ' ';
          END IF;
          IF V_LOCAL IS NULL THEN
             V_LOCAL := ' ';
          END IF;
          SELECT MAX(IDUTCTRLLOTE)
            INTO V_IDUTCTRLLOTE
            FROM PRODFILI
           WHERE CDFILIAL  = P_CDFILIAL
             AND CDPRODUTO = P_CDPRODUTO;
          IF V_IDUTCTRLLOTE = 'S' THEN
             V_VRCUSTO := V_VRCUSTO + (CUSTO_PRODUTO(P_CDFILIAL,P_CDPRODUTO,P_TIPOCUSTO,V_DATA,V_DATA) * P_QTPRODUTO);
          ELSE
             V_VRCUSTO := V_VRCUSTO + (CUSTO_PROD(P_CDFILIAL,P_CDPRODUTO,P_TIPOCUSTO,V_DATA, V_ALMOX, V_LOCAL,' ',' ') * P_QTPRODUTO);
          END IF;
          P_VRCUSTO := V_VRCUSTO;
      END IF;
   ELSE
      FOR C_LOCAL IN
         (SELECT
            RL.CDFILIAL, RL.CDPRODUTO, RL.CDSUBPRODLOC AS CDSUBPRODUTO,
            RL.QTSUBPRODLOC AS QTSUBPRODROT,
            RL.NRHRFABPRLOC AS NRHRFABPROD, RL.IDIMPPROTLOC AS IDIMPPRODROT,
            RL.NRSEQPRODLOC AS NRSEQPROD,
            PT.NMPRODUTO, PT.SGUNIDADE,
            DL.TXROTFABLOC AS TXINSTR
         FROM
            ROTFABLOCAL RL, PRODUTO PT, DESCROTLOCAL DL
         WHERE
            (RL.CDSUBPRODLOC = PT.CDPRODUTO   ) AND
            (RL.CDFILIAL     = DL.CDFILIAL(+) ) AND
            (RL.CDPRODUTO    = DL.CDPRODUTO(+)) AND
            (RL.CDFILIAL     = P_CDFILIAL     ) AND
            (RL.CDPRODUTO    = P_CDPRODUTO    ) AND
            (PT.CDARVPROD LIKE P_NIVEL||'%'   )) LOOP
         SELECT COUNT(*)
         INTO   V_EXISTE_COMP_LOCAL
         FROM   ROTFABLOCAL
         WHERE (CDFILIAL  = P_CDFILIAL          ) AND
               (CDPRODUTO = C_LOCAL.CDSUBPRODUTO);
          /*Busca o almoxarifado e localizacao*/
          IF NOT P_LOJA IS NULL THEN
             SELECT MAX(CDALMOXARIFE), MAX(CDLOCALESTOQ)
             INTO  V_ALMOX, V_LOCAL
             FROM LOJA
             WHERE CDFILIAL = P_CDFILIAL AND
                   CDLOJA   = P_LOJA;
          END IF;
          IF V_ALMOX IS NULL THEN
             SELECT MAX(CDALMOXARIFE), MAX(CDLOCALESTOQ)
             INTO  V_ALMOX, V_LOCAL
             FROM PRODFILI
             WHERE CDFILIAL  = P_CDFILIAL AND
                   CDPRODUTO = C_LOCAL.CDSUBPRODUTO;
          END IF;
          IF V_ALMOX IS NULL THEN
             SELECT MAX(CDALMOXARIFE), MAX(CDLOCALESTOQ)
             INTO  V_ALMOX, V_LOCAL
             FROM PARAMFILIAL
             WHERE CDFILIAL = P_CDFILIAL;
          END IF;
          IF V_ALMOX IS NULL THEN
             V_ALMOX := ' ';
             V_LOCAL := ' ';
          END IF;
          IF V_LOCAL IS NULL THEN
             V_LOCAL := ' ';
          END IF;
          SELECT MAX(IDUTCTRLLOTE)
            INTO V_IDUTCTRLLOTE
            FROM PRODFILI
           WHERE CDFILIAL  = P_CDFILIAL
             AND CDPRODUTO = C_LOCAL.CDSUBPRODUTO;
         IF V_EXISTE_COMP_LOCAL > 0 THEN
            CUSTO_COMP_PROD(C_LOCAL.CDSUBPRODUTO,P_CDFILIAL,P_FILIPROC,P_TIPOCUSTO,(C_LOCAL.QTSUBPRODROT * P_QTPRODUTO), P_LOJA, P_VRCUSTO,V_DATA,P_NIVEL,P_TIPOCOMP);
            V_VRCUSTO := V_VRCUSTO + P_VRCUSTO;
            P_VRCUSTO := V_VRCUSTO;
         ELSE
            IF V_IDUTCTRLLOTE = 'S' THEN
               V_VRCUSTO := V_VRCUSTO + (CUSTO_PRODUTO(P_CDFILIAL,C_LOCAL.CDSUBPRODUTO,P_TIPOCUSTO,V_DATA,V_DATA) * C_LOCAL.QTSUBPRODROT * P_QTPRODUTO);
            ELSE
               V_VRCUSTO := V_VRCUSTO + (CUSTO_PROD(P_CDFILIAL,C_LOCAL.CDSUBPRODUTO,P_TIPOCUSTO,V_DATA, V_ALMOX, V_LOCAL,' ',' ') * C_LOCAL.QTSUBPRODROT * P_QTPRODUTO);
            END IF;
            P_VRCUSTO := V_VRCUSTO;
            V_ALMOX := '';
            V_LOCAL := '';
         END IF;
         V_LOOP_LOCAL := 'S';
      END LOOP;
      IF V_LOOP_LOCAL <> 'S' THEN
         IF NOT P_LOJA IS NULL THEN
            SELECT MAX(CDALMOXARIFE), MAX(CDLOCALESTOQ)
            INTO  V_ALMOX, V_LOCAL
            FROM LOJA
            WHERE CDFILIAL = P_CDFILIAL AND
                  CDLOJA   = P_LOJA;
         END IF;
         IF V_ALMOX IS NULL THEN
            SELECT MAX(CDALMOXARIFE), MAX(CDLOCALESTOQ)
            INTO  V_ALMOX, V_LOCAL
            FROM PRODFILI
            WHERE CDFILIAL  = P_CDFILIAL AND
                  CDPRODUTO = P_CDPRODUTO;
         END IF;
         IF V_ALMOX IS NULL THEN
            SELECT MAX(CDALMOXARIFE), MAX(CDLOCALESTOQ)
            INTO  V_ALMOX, V_LOCAL
            FROM PARAMFILIAL
            WHERE CDFILIAL = P_CDFILIAL;
         END IF;
         IF V_ALMOX IS NULL THEN
            V_ALMOX := ' ';
            V_LOCAL := ' ';
         END IF;
         IF V_LOCAL IS NULL THEN
            V_LOCAL := ' ';
         END IF;
         SELECT MAX(IDUTCTRLLOTE)
           INTO V_IDUTCTRLLOTE
           FROM PRODFILI
          WHERE CDFILIAL  = P_CDFILIAL
            AND CDPRODUTO = P_CDPRODUTO;
         IF V_IDUTCTRLLOTE = 'S' THEN
            V_VRCUSTO := V_VRCUSTO + (CUSTO_PRODUTO(P_CDFILIAL,P_CDPRODUTO,P_TIPOCUSTO,V_DATA,V_DATA) * P_QTPRODUTO);
         ELSE
            V_VRCUSTO := V_VRCUSTO + (CUSTO_PROD(P_CDFILIAL,P_CDPRODUTO,P_TIPOCUSTO,V_DATA, V_ALMOX, V_LOCAL,' ',' ') * P_QTPRODUTO);
         END IF;
         P_VRCUSTO := V_VRCUSTO;
      END IF;
   END IF;
END;
/