/* Sistemas Integrados TECNISA
   Servicos

Nome: PEDCUST_COMP_PROD

Descricao:
   Traz o custo do produto de composicao
Criacao:
28/07/05 - Welbert G. Moitinha 
Alteracao:
30/06/2011 - Giancarlo V. Catsro
   - Inclusao da instrucao que atualiza o grupo de operadores das Filiais que utilizam parametrizacao pela Filial Padrao*/

create or replace FUNCTION PEDCUST_COMP_PROD (P_CDPRODUTO   IN PRODUTO.CDPRODUTO%TYPE,
                                             P_CDFILIAL     IN FILIAL.CDFILIAL%TYPE,
                                             P_TIPOCUSTO    IN NUMBER,
                                             P_QTDE         IN FLOAT,
                                             P_CDLOJA       IN VARCHAR2,
                                             P_DTREFERENCIA IN DATE DEFAULT SYSDATE,
                                             P_CDFATPRECO   IN PRODFATOR.CDFATPRECO%TYPE DEFAULT NULL,
                                             P_NRPEDIDO     IN PEDIDO.NRPEDIDO%TYPE DEFAULT NULL,
                                             P_NRITEMPED    IN COMPITEMPED.NRITEMPED%TYPE DEFAULT NULL
                                           )RETURN FLOAT
AS
   V_CUSTO          FLOAT;
   V_CDFILIAL       VARCHAR2(4);
   V_CDALMOXARIFE   VARCHAR2(6);
   V_CDLOCALESTOQ   VARCHAR2(6);
   V_INCTREG        INTEGER;

   V_CDPRODUTORF    ROTFABRICA.CDPRODUTO%TYPE;
   V_CDSUBPRODUTORF ROTFABRICA.CDSUBPRODUTO%TYPE;
   V_QTSUBPRODROTRF ROTFABRICA.QTSUBPRODROT%TYPE;

   V_CDFILIALRL     ROTFABLOCAL.CDFILIAL%TYPE;
   V_CDPRODUTORL    ROTFABLOCAL.CDPRODUTO%TYPE;
   V_CDSUBPRODUTORL ROTFABLOCAL.CDSUBPRODLOC%TYPE;
   V_QTSUBPRODROTRL ROTFABLOCAL.QTSUBPRODLOC%TYPE;

   V_IDUTILLOTE     PARAMFILIAL.IDUTILLOTE%TYPE;
   V_NRLOTEESTQ     LOTE.NRLOTEESTQ%TYPE;
   V_NRSUBLOTE      LOTE.NRSUBLOTE%TYPE;

   V_VRFATPRECO     PRODFATOR.VRFATPRECO%TYPE;
   V_IDTABPRECO     PARAMPEDIDO.IDTABPRECO%TYPE;
   V_IDCALCPRECFAT  PARAMPEDIDO.IDCALCPRECFAT%TYPE;
   V_IDGERPRODEST   PAREXPEDICAO.IDGERPRODEST%TYPE;

   CURSOR C_ROTFABRICA IS
   SELECT
      CDPRODUTO, CDSUBPRODUTO, QTSUBPRODROT
   FROM
      ROTFABRICA
   WHERE
      (CDPRODUTO = P_CDPRODUTO);

   CURSOR C_ROTFABLOCAL IS
   SELECT
      CDPRODUTO, CDSUBPRODLOC,  QTSUBPRODLOC
   FROM
      ROTFABLOCAL
   WHERE
      (CDFILIAL     = P_CDFILIAL)  AND
      (CDPRODUTO    = P_CDPRODUTO);

   CURSOR C_COMPITEMPED IS
   SELECT
      CDPRODUTO, CDPRODCOMPED, QTITCOMPPROD
   FROM
      COMPITEMPED
   WHERE
      (CDFILIAL     = P_CDFILIAL)  AND
      (NRPEDIDO     = P_NRPEDIDO)  AND
      (NRITEMPED    = P_NRITEMPED) AND
      (CDPRODUTO    = P_CDPRODUTO);
BEGIN
   V_CDFILIAL := P_CDFILIAL;
   V_CUSTO := 0;

   SELECT COUNT(*)
   INTO V_INCTREG
   FROM
      ROTFABRICA
   WHERE
      (CDPRODUTO = P_CDPRODUTO)AND
      (CDPRODUTO = CDSUBPRODUTO);

   IF(V_INCTREG = 0)THEN
      SELECT  COUNT(*)
      INTO V_INCTREG
      FROM
         ROTFABLOCAL
      WHERE
         (CDPRODUTO = P_CDPRODUTO)AND
         (CDPRODUTO = CDSUBPRODLOC);
   END IF;

   IF(V_INCTREG = 0)THEN
      SELECT  COUNT(*)
      INTO V_INCTREG
      FROM
         COMPITEMPED
      WHERE
         (CDFILIAL  = P_CDFILIAL)   AND
         (NRPEDIDO  = P_NRPEDIDO)   AND
         (NRITEMPED = P_NRITEMPED)  AND
         (CDPRODUTO = P_CDPRODUTO)  AND
         (CDPRODUTO = CDPRODCOMPED);
   END IF;

   SELECT IDTABPRECO, IDCALCPRECFAT
     INTO V_IDTABPRECO, V_IDCALCPRECFAT
     FROM PARAMPEDIDO
    WHERE CDFILIAL = P_CDFILIAL;

    SELECT IDGERPRODEST
      INTO V_IDGERPRODEST
      FROM PAREXPEDICAO
       WHERE CDFILIAL = P_CDFILIAL;

   IF(V_INCTREG = 0) THEN

      IF V_IDGERPRODEST = '3' THEN
         V_CDFILIAL :=  COMP_LOCAL( P_CDFILIAL,  P_CDPRODUTO, P_NRPEDIDO, P_NRITEMPED);
      ELSE
         V_CDFILIAL := 'N'; /* SE NAO TIVER PARAMETRIZADO PARA MOSTRAR OS SUBPRODUTO NA NOTA, RETORNA O CUSTO DO PRODUTO DO PEDIDO*/
      END IF;

      IF( V_CDFILIAL = 'C') THEN

         OPEN C_COMPITEMPED;
         LOOP
            FETCH C_COMPITEMPED INTO V_CDPRODUTORF, V_CDSUBPRODUTORF, V_QTSUBPRODROTRF;
            EXIT WHEN C_COMPITEMPED%NOTFOUND;

            V_CUSTO := V_CUSTO + ROUND((PEDCUST_COMP_PROD( V_CDSUBPRODUTORF, P_CDFILIAL, P_TIPOCUSTO, V_QTSUBPRODROTRF, P_CDLOJA, SYSDATE, P_CDFATPRECO)), 4);
         END LOOP;
         CLOSE C_COMPITEMPED;
         RETURN(V_CUSTO);
      ELSE

         IF( V_CDFILIAL = 'P') THEN

            OPEN C_ROTFABRICA;
            LOOP
               FETCH C_ROTFABRICA INTO V_CDPRODUTORF, V_CDSUBPRODUTORF, V_QTSUBPRODROTRF;
               EXIT WHEN C_ROTFABRICA%NOTFOUND;

               V_CUSTO := V_CUSTO + ROUND((PEDCUST_COMP_PROD( V_CDSUBPRODUTORF, P_CDFILIAL, P_TIPOCUSTO, V_QTSUBPRODROTRF, P_CDLOJA, SYSDATE, P_CDFATPRECO)), 4);
            END LOOP;
            CLOSE C_ROTFABRICA;
            RETURN(V_CUSTO);
         ELSE
            IF  V_CDFILIAL = P_CDFILIAL THEN
               OPEN C_ROTFABLOCAL;
               LOOP
                  FETCH C_ROTFABLOCAL INTO V_CDPRODUTORF, V_CDSUBPRODUTORF, V_QTSUBPRODROTRF;
                  EXIT WHEN C_ROTFABLOCAL%NOTFOUND;
                  V_CUSTO := V_CUSTO + ROUND((PEDCUST_COMP_PROD( V_CDSUBPRODUTORF, P_CDFILIAL, P_TIPOCUSTO, V_QTSUBPRODROTRF, P_CDLOJA, SYSDATE, P_CDFATPRECO)), 4);
               END LOOP;
               CLOSE C_ROTFABLOCAL;
               RETURN(V_CUSTO);
            ELSE
               IF V_CDFILIAL = 'N' THEN

                  V_CDALMOXARIFE := BUSCA_ALMOX(P_CDFILIAL, '', P_CDPRODUTO);
                  V_CDLOCALESTOQ := BUSCA_LOCAL(P_CDFILIAL, '', P_CDPRODUTO);

                  V_IDUTILLOTE := 'N';
                  V_NRLOTEESTQ := ' ';
                  V_NRSUBLOTE := ' ';

                  SELECT MAX(IDUTILLOTE)
                    INTO V_IDUTILLOTE
                    FROM PARAMFILIAL
                   WHERE CDFILIAL = P_CDFILIAL;

               /* Foi retirado o parametro de controle de lote por produto porque o relatorio posicao de estoque
               nao testa este parametro. Estava dando diferenca de custo do Pedido com o Estoque.
                  IF NVL(V_IDUTILLOTE, 'N') = 'S' THEN
                     SELECT MAX(IDUTCTRLLOTE)
                       INTO V_IDUTILLOTE
                       FROM PRODFILI
                      WHERE CDFILIAL = P_CDFILIAL
                        AND CDPRODUTO = P_CDPRODUTO;
                  END IF;   */


                  IF NVL(V_IDUTILLOTE, 'N') = 'S' THEN
                     /* Passa mais um dia para data no SQL 'P_DTREFERENCIA + 1' porque a POSESTDIA grava a
                        data com mais um dia. Na funcao de CUSTO nao e necessario fazer este controle. */
                     SELECT MIN(NRLOTEESTQ), MIN(NRSUBLOTE)
                       INTO V_NRLOTEESTQ, V_NRSUBLOTE
                       FROM POSESTDIA B
                      WHERE B.CDFILIAL = P_CDFILIAL
                        AND B.CDPRODUTO = P_CDPRODUTO
                        AND B.CDALMOXARIFE  = V_CDALMOXARIFE
                        AND B.CDLOCALESTOQ  = V_CDLOCALESTOQ
                        AND B.QTESTOQDIA > 0.00001
                        AND B.DTPOSIESTQ = (SELECT MAX(P.DTPOSIESTQ)
                                              FROM POSESTDIA P
                                             WHERE P.CDFILIAL = P_CDFILIAL
                                               AND P.CDPRODUTO = B.CDPRODUTO
                                               AND P.CDALMOXARIFE = V_CDALMOXARIFE
                                               AND P.CDLOCALESTOQ = V_CDLOCALESTOQ
                                               AND P.NRLOTEESTQ = B.NRLOTEESTQ
                                               AND P.NRSUBLOTE = B.NRSUBLOTE
                                               AND B.QTESTOQDIA > 0.00001
                                               AND P.DTPOSIESTQ <= P_DTREFERENCIA + 1);
                  END IF;

                  --SE ESTIVER PARAMETRIZADO PARA UTILIZAR FATOR DE PRECO E CASO TENHA PRODUTO COM COMPOSICAO,
                  --E VERIFICADO O FATOR DE CADA PRODUTO QUE COMPOE O PRODUTO DO PEDIDO PARA CALCULAR O CUSTO
                  IF (V_IDTABPRECO = '2') AND (V_IDCALCPRECFAT <> 'L' )THEN
                      BEGIN
                          SELECT NVL(VRFATPRECO,1)
                            INTO V_VRFATPRECO
                            FROM PRODFATOR F
                           WHERE F.CDFATPRECO   = P_CDFATPRECO
                             AND F.CDPRODUTO    = P_CDPRODUTO;
                      EXCEPTION
                         WHEN NO_DATA_FOUND THEN V_VRFATPRECO := 1;
                      END;

                     V_CUSTO := V_CUSTO + ROUND(CUSTO_PRODUTO_LCEST(P_CDFILIAL, P_CDPRODUTO, P_TIPOCUSTO, P_DTREFERENCIA, SYSDATE,
                                             V_CDALMOXARIFE, V_CDLOCALESTOQ, V_NRLOTEESTQ, V_NRSUBLOTE) * P_QTDE * V_VRFATPRECO, 4);
                  ELSE
                     V_CUSTO := V_CUSTO + ROUND(CUSTO_PRODUTO_LCEST(P_CDFILIAL, P_CDPRODUTO, P_TIPOCUSTO, P_DTREFERENCIA, SYSDATE,
                                             V_CDALMOXARIFE, V_CDLOCALESTOQ, V_NRLOTEESTQ, V_NRSUBLOTE) * P_QTDE, 4);
                  END IF;

               END IF;
            END IF;
         END IF;
      END IF;   
   END IF;
   RETURN(V_CUSTO);
END;
/