SET DEFINE OFF;

create or replace FUNCTION FUNC_ADD_BUSCA_ESTOQUE_PRODUTO(
    p_dataPosicaoEstoque          IN DATE,
    p_gradeProduto                IN NUMBER,
    p_estabelecimento             IN NUMBER,
    p_indicadorPropriedadePosseIt IN CHAR,
    p_pessoaParticipante          IN NUMBER,
    p_localEstoque                IN NUMBER,
    p_personalizacao              IN NUMBER,
    p_idLoteEstoque               IN NUMBER,
    p_idEnderecoEstoque           IN NUMBER,
    p_idNumeroSerie               IN NUMBER,
    p_gradProd_produto            IN NUMBER,
    p_prod_controleEstoque        IN NUMBER,
    p_documentoDesconsiderar      IN CHAR, -- D = Documento Fiscal, I = Inventário Estoque, P = Pré-Documento
    p_idDocumentoDesconsiderar    IN NUMBER,
    p_estoqueFiscal               IN NUMBER)
  RETURN NUMBER
IS
  v_idInventarioEstoque       NUMBER;
  v_dataInventario            DATE;
  v_dataPosicaoEstoqueInicial DATE;
  v_quantidadeInventario      NUMBER;
  v_quantidadeEstoque         NUMBER;
  v_quantidadeDocumentoFiscal NUMBER;
  v_quantidadePreDocumento    NUMBER;
BEGIN
  v_quantidadeInventario      := 0;
  v_quantidadeEstoque         := 0;
  v_quantidadeDocumentoFiscal := 0;
  v_quantidadePreDocumento    := 0;
  -- KIT / COMBO
  IF p_prod_controleEstoque IN (3,4) THEN
    -- Busca estoque do item filho com menor estoque
    SELECT COALESCE((
      SELECT MIN (TRUNC((FUNC_ADD_BUSCA_ESTOQUE_PRODUTO(
        p_dataPosicaoEstoque,
        kit.gradeProdutoFilho,
        p_estabelecimento,
        p_indicadorPropriedadePosseIt,
        p_pessoaParticipante,
        p_localEstoque,
        0,
        0,
        p_idEnderecoEstoque,
        0,
        gradProdFilho.produto,
        prodFilho.controleEstoque,
        p_documentoDesconsiderar,
        p_idDocumentoDesconsiderar,
        p_estoqueFiscal) / kit.quantidade), uniMedPai.casasDecimaisUnidadeMedida))
      FROM CAGRADEPRODUTOXKITSCOMBOS kit
      JOIN CAGRADESPRODUTO gradProdFilho ON gradProdFilho.gradeProduto = kit.gradeProdutoFilho
      JOIN CAPRODUTOS prodFilho ON prodFilho.produto = gradProdFilho.produto
      JOIN CAGRADESPRODUTO gradProdPai ON gradProdPai.gradeProduto = kit.gradeProduto
      JOIN CAPRODUTOS prodPai ON prodPai.produto = gradProdPai.produto
      JOIN SIUNIDADESMEDIDA uniMedPai ON uniMedPai.unidadeMedida = prodPai.unidadeMedida
      WHERE kit.gradeProduto = p_gradeProduto
      AND kit.ativo = 1
      AND kit.quantidade > 0
      AND kit.gradeProduto <> kit.gradeProdutoFilho
      AND prodFilho.controleEstoque IN (1,3,4,5,11,12)),0)
    INTO v_quantidadeEstoque
    FROM DUAL;
  -- DEMAIS PRODUTOS (EXCETO KIT / COMBO)
  ELSIF p_prod_controleEstoque IN (1,5,11,12) THEN
    -- v_idInventarioEstoque / v_dataInventario
    SELECT
      TO_NUMBER(SUBSTR(a.ordenacao,9,14)), 
      TO_DATE(SUBSTR(a.ordenacao,1,8),'YYYYMMDD')
    INTO
      v_idInventarioEstoque,
      v_dataInventario
    FROM (
      SELECT
        COALESCE(MAX(TO_CHAR(TRUNC(inv.data),'YYYYMMDD')
          || LPAD (inv.inventarioEstoque,14,'0')),'1900010100000000000000') ordenacao
      FROM MOINVENTARIOSESTOQUE inv
      WHERE inv.estabelecimento = p_estabelecimento
      AND inv.inventarioEstoque <> 0
      AND (p_documentoDesconsiderar <> 'I'
        OR inv.inventarioEstoque <> p_idDocumentoDesconsiderar)
      AND TRUNC (inv.data) < TRUNC(p_dataPosicaoEstoque)
      AND inv.motivoInventarioEstoque = '01') a;
--      AND (inv.motivoInventarioEstoque = '01'
--        OR EXISTS(
--          SELECT 1
--          FROM MOINVENTARIOESTOQUEXITENS itemInv
--          JOIN CAGRADESPRODUTO gradProd ON gradProd.gradeProduto = itemInv.gradeProduto
--          WHERE itemInv.inventarioEstoque = inv.inventarioEstoque
--          AND gradProd.produto = p_gradProd_produto))) a;
    -- v_dataPosicaoEstoqueInicial
    SELECT COALESCE((
      SELECT MAX (est.data)
        FROM MOESTOQUES est
        JOIN CAGRADESPRODUTO gradProd ON gradProd.gradeProduto = est.gradeProduto
        WHERE gradProd.produto = p_gradProd_produto
        AND est.estabelecimento = p_estabelecimento
        AND est.operacaoInternaEstoque = 1
        AND TRUNC(est.data) <= TRUNC (p_dataPosicaoEstoque)
        AND (v_idInventarioEstoque <= 0
		  OR TRUNC(est.data) > TRUNC(v_dataInventario))),
      CASE
        WHEN v_idInventarioEstoque > 0 AND NOT (v_dataInventario IS NULL)
        THEN TRUNC (v_dataInventario) + 1
        ELSE TO_DATE ('01/01/1900','DD/MM/YYYY')
      END)
    INTO v_dataPosicaoEstoqueInicial
    FROM DUAL;
    -- v_quantidadeInventario
    IF v_idInventarioEstoque > 0 THEN
      SELECT COALESCE((
        SELECT SUM (CASE WHEN p_estoqueFiscal = 1 THEN est.quantidadeFiscal ELSE est.quantidadeGerencial END)
        FROM MOINVENTARIOESTOQUEXITENS est
        JOIN PALOCAISESTOQUE locEst ON locEst.localEstoque = est.localEstoque
        JOIN CAGRADESPRODUTO gradProd ON gradProd.gradeProduto = est.gradeProduto
        WHERE est.inventarioEstoque = v_idInventarioEstoque
        AND est.gradeProduto = p_gradeProduto
        AND (p_documentoDesconsiderar <> 'I'
          AND (p_indicadorPropriedadePosseIt IS NULL
		        OR p_indicadorPropriedadePosseIt = ' ')
		      OR est.indicadorPropriedadePosseItem = '' || p_indicadorPropriedadePosseIt || '')
        AND (p_documentoDesconsiderar <> 'I'
          AND p_pessoaParticipante = 0
		      OR est.pessoaParticipante = p_pessoaParticipante)
        AND (p_documentoDesconsiderar <> 'I'
          AND p_localEstoque = 0
		      AND locEst.validoEstoqueTotal = 1
		      OR est.localEstoque = p_localEstoque)
        AND (p_documentoDesconsiderar <> 'I'
          AND p_personalizacao = 0
		      OR est.personalizacao = p_personalizacao)
        AND (p_documentoDesconsiderar <> 'I'
          AND p_idLoteEstoque = 0
		      OR est.idLoteEstoque = p_idLoteEstoque)
        AND (p_documentoDesconsiderar <> 'I'
          AND p_idEnderecoEstoque = 0
		      OR est.idEnderecoEstoque = p_idEnderecoEstoque)
        AND (p_idNumeroSerie = 0
		      OR est.idNumeroSerie = CASE WHEN p_idNumeroSerie < 0 THEN 0 ELSE p_idNumeroSerie END)),0)
      INTO v_quantidadeInventario
      FROM DUAL;
    ELSE
      v_quantidadeInventario := 0;
    END IF;
    -- v_quantidadeEstoque
    IF TRUNC (v_dataPosicaoEstoqueInicial) <= TRUNC (p_dataPosicaoEstoque) THEN
      SELECT COALESCE((
        SELECT SUM (est.quantidade * CASE WHEN est.entradaSaida = 'S' THEN (-1) ELSE 1 END)
        FROM MOESTOQUES est
        JOIN PALOCAISESTOQUE locEst ON locEst.localEstoque = est.localEstoque
        WHERE est.gradeProduto = p_gradeProduto
        AND est.estabelecimento = p_estabelecimento
        AND TRUNC(est.data) BETWEEN TRUNC (v_dataPosicaoEstoqueInicial) AND TRUNC (p_dataPosicaoEstoque)
        AND (p_indicadorPropriedadePosseIt IS NULL
		  OR p_indicadorPropriedadePosseIt = ' '
		  OR est.indicadorPropriedadePosseItem = '' || p_indicadorPropriedadePosseIt || '')
        AND (p_pessoaParticipante = 0
		  OR est.pessoaParticipante = p_pessoaParticipante)
        AND (p_localEstoque = 0
		  AND locEst.validoEstoqueTotal = 1
		  OR est.localEstoque = p_localEstoque)
         AND (p_personalizacao = 0
		  OR est.personalizacao = p_personalizacao)
       AND (p_idLoteEstoque = 0
		  OR est.idLoteEstoque = p_idLoteEstoque)
        AND (p_idEnderecoEstoque = 0
		  OR est.idEnderecoEstoque = p_idEnderecoEstoque)
        AND (p_idNumeroSerie = 0
		  OR est.idNumeroSerie = CASE WHEN p_idNumeroSerie < 0 THEN 0 ELSE p_idNumeroSerie END)
        AND (p_estoqueFiscal = 0
		  OR est.operacaoInternaEstoque <> 101)),0)
      INTO v_quantidadeEstoque
      FROM DUAL;
    ELSE
      v_quantidadeEstoque := 0;
    END IF;
    -- v_quantidadeDocumentoFiscal
    IF p_documentoDesconsiderar = 'D' AND p_idDocumentoDesconsiderar > 0 THEN
      SELECT COALESCE((
        SELECT SUM (est.quantidade * CASE WHEN est.entradaSaida = 'S' THEN (-1) ELSE 1 END)
        FROM MODOCFISCALXITENS itemDoc
        JOIN MODOCFISCALXESTOQUE docXEst ON docXEst.idItemDocFiscal = itemDoc.idItemDocFiscal
        JOIN MOESTOQUES est ON est.idEstoque = docXEst.idEstoque
        JOIN PALOCAISESTOQUE locEst ON locEst.localEstoque = est.localEstoque
        WHERE itemDoc.idDocumentoFiscal = p_idDocumentoDesconsiderar
        AND est.gradeProduto = p_gradeProduto
        AND est.estabelecimento = p_estabelecimento
        AND TRUNC(est.data) <= TRUNC (p_dataPosicaoEstoque)
        AND (p_documentoDesconsiderar <> 'I'
          AND (p_indicadorPropriedadePosseIt IS NULL
		        OR p_indicadorPropriedadePosseIt = ' ')
		      OR est.indicadorPropriedadePosseItem = '' || p_indicadorPropriedadePosseIt || '')
        AND (p_documentoDesconsiderar <> 'I'
          AND p_pessoaParticipante = 0
		      OR est.pessoaParticipante = p_pessoaParticipante)
        AND (p_documentoDesconsiderar <> 'I'
          AND p_localEstoque = 0
		      AND locEst.validoEstoqueTotal = 1
		      OR est.localEstoque = p_localEstoque)
        AND (p_documentoDesconsiderar <> 'I'
          AND p_personalizacao = 0
		      OR est.personalizacao = p_personalizacao)
        AND (p_documentoDesconsiderar <> 'I'
          AND p_idLoteEstoque = 0
		      OR est.idLoteEstoque = p_idLoteEstoque)
        AND (p_documentoDesconsiderar <> 'I'
          AND p_idEnderecoEstoque = 0
		      OR est.idEnderecoEstoque = p_idEnderecoEstoque)
        AND (p_idNumeroSerie = 0
		      OR est.idNumeroSerie = CASE WHEN p_idNumeroSerie < 0 THEN 0 ELSE p_idNumeroSerie END)
        AND (p_estoqueFiscal = 0
		      OR est.operacaoInternaEstoque <> 101)),0)
      INTO v_quantidadeDocumentoFiscal
      FROM DUAL;
    ELSE
      v_quantidadeDocumentoFiscal := 0;
    END IF;
    -- v_quantidadePreDocumento
    IF p_documentoDesconsiderar = 'P' AND p_idDocumentoDesconsiderar > 0 THEN
      SELECT COALESCE((
        SELECT SUM (est.quantidade * CASE WHEN est.entradaSaida = 'S' THEN (-1) ELSE 1 END)
        FROM MOPREDOCUMXITENS itemDoc
        JOIN MOPREDOCUMXESTOQUE docXEst ON docXEst.idItemPreDocumento = itemDoc.idItemPreDocumento
        JOIN MOESTOQUES est ON est.idEstoque = docXEst.idEstoque
        JOIN PALOCAISESTOQUE locEst ON locEst.localEstoque = est.localEstoque
        WHERE itemDoc.preDocumento = p_idDocumentoDesconsiderar
        AND est.gradeProduto = p_gradeProduto
        AND est.estabelecimento = p_estabelecimento
        AND TRUNC(est.data) <= TRUNC (p_dataPosicaoEstoque)
        AND (p_documentoDesconsiderar <> 'I'
          AND (p_indicadorPropriedadePosseIt IS NULL
		        OR p_indicadorPropriedadePosseIt = ' ')
		      OR est.indicadorPropriedadePosseItem = '' || p_indicadorPropriedadePosseIt || '')
        AND (p_documentoDesconsiderar <> 'I'
          AND p_pessoaParticipante = 0
		      OR est.pessoaParticipante = p_pessoaParticipante)
        AND (p_documentoDesconsiderar <> 'I'
          AND p_localEstoque = 0
		      AND locEst.validoEstoqueTotal = 1
		      OR est.localEstoque = p_localEstoque)
        AND (p_documentoDesconsiderar <> 'I'
          AND p_personalizacao = 0
		      OR est.personalizacao = p_personalizacao)
        AND (p_documentoDesconsiderar <> 'I'
          AND p_idLoteEstoque = 0
		      OR est.idLoteEstoque = p_idLoteEstoque)
        AND (p_documentoDesconsiderar <> 'I'
          AND p_idEnderecoEstoque = 0
		      OR est.idEnderecoEstoque = p_idEnderecoEstoque)
        AND (p_idNumeroSerie = 0
		      OR est.idNumeroSerie = CASE WHEN p_idNumeroSerie < 0 THEN 0 ELSE p_idNumeroSerie END)
        AND (p_estoqueFiscal = 0
		      OR est.operacaoInternaEstoque <> 101)),0)
      INTO v_quantidadePreDocumento
      FROM DUAL;
    ELSE
      v_quantidadePreDocumento := 0;
    END IF;
  END IF;
  RETURN
    v_quantidadeInventario
    + v_quantidadeEstoque
    - v_quantidadeDocumentoFiscal
    - v_quantidadePreDocumento;
END;

/

INSERT INTO SICONFIGURACOES (configuracao, descricao, ativo, subcategoriaConfiguracao, tipoCampo, mascara, exibirCampo, tipoArquivo, conteudoSugestao, tabelaSistema, observacoes) values (390, 'Validar "Valor máximo documentos sem cliente cadastrado" (configuração 167) para orçamentos com situação "Orçamento".', 1, 30001, 'L', '1', 'E', 0, 'N', ' ', ' ');

COMMIT;

INSERT INTO SIVERSOESSISTEMA (idVersaoSistema, versaoAplicativo, dataLiberacaoVersao, possuiConversaoTabelas, atualizada, dataAtualizacaoVersao, observacoes) VALUES (2022002021, '2022.2.21', sysdate, 1, 1, sysdate, ' ');

COMMIT;

--exec dbms_utility.compile_schema('ADDERI');
--exec dbms_stats.gather_schema_stats('ADDERI');

/*
*/