SET DEFINE OFF;

create or replace FUNCTION FUNC_ADD_BUSCA_PRECO_MEDIO_INT(
    p_config_209_filtrarGrupoEcon  IN NUMBER,
    p_config_362_calcCustoPorGrade IN NUMBER,
    p_estabelecimento              IN NUMBER,
    p_data                         IN DATE,
    p_item_personalizacao          IN NUMBER,
    p_gradProd_produto             IN NUMBER,
    p_gradProd_cor                 IN NUMBER,
    p_gradProd_tamanho             IN VARCHAR,
    p_indicadorPropriedadePosseIt  IN CHAR,
    p_pessoaParticipante           IN NUMBER,
    p_buscarPrecoGerencial         IN NUMBER,
    p_gerandoInventario            IN NUMBER,
    p_dataInicialEstoque           IN DATE
  )
  RETURN NUMBER
IS 
  v_data               DATE;
  v_quantidadeEstoque  NUMBER(15,6);
  v_precoCustoMedio    NUMBER(15,7);
  v_totalCustoMedio    NUMBER(15,2);
CURSOR c_precoMedio IS
  SELECT a.data,
    a.idEstoque,
    a.entradaSaida,
    a.atualizaCustoMedio,
    a.operacaoInternaEstoque,
    a.quantidade,
    (a.precoCustoOperacao - CASE WHEN a.quantidade = 0 THEN 0 ELSE a.valorAcrescimoExtempTotal / a.quantidade END) precoCustoOperacao,
    (a.totalCustoOperacao - a.valorAcrescimoExtempTotal) totalCustoOperacao
  FROM
    (    
    -- Itens último inventário
    SELECT invEst.data,
      0 idEstoque,
      'E' entradaSaida,
      1 atualizaCustoMedio,
      1 operacaoInternaEstoque,
      CASE WHEN p_buscarPrecoGerencial = 1 THEN itemEst.quantidadeGerencial ELSE itemEst.quantidadeFiscal END quantidade,
      CASE WHEN p_buscarPrecoGerencial = 1 THEN itemEst.precoUnitarioCMVGerencial ELSE itemEst.precoUnitarioCMVFiscal END precoCustoOperacao,
      ROUND(CASE WHEN p_buscarPrecoGerencial = 1 THEN itemEst.quantidadeGerencial*itemEst.precoUnitarioCMVGerencial ELSE itemEst.quantidadeFiscal*itemEst.precoUnitarioCMVFiscal END,2) totalCustoOperacao,
      0 valorAcrescimoExtempTotal
    FROM MOINVENTARIOESTOQUEXITENS itemEst
    JOIN CAGRADESPRODUTO gradProd ON gradProd.gradeProduto = itemEst.gradeProduto
    JOIN MOINVENTARIOSESTOQUE invEst ON invEst.inventarioEstoque = itemEst.inventarioEstoque
    WHERE gradProd.produto = p_gradProd_produto
    AND (p_config_362_calcCustoPorGrade = 0 OR p_gradProd_cor = 0 OR gradProd.cor = p_gradProd_cor)
    AND (p_config_362_calcCustoPorGrade = 0 OR p_gradProd_tamanho = '' OR p_gradProd_tamanho = ' ' OR gradProd.tamanho = p_gradProd_tamanho)
    AND (p_config_362_calcCustoPorGrade = 0 OR p_item_personalizacao = 0 OR itemEst.personalizacao = p_item_personalizacao)
    AND itemEst.indicadorPropriedadePosseItem = '' || CASE WHEN p_indicadorPropriedadePosseIt IS NULL OR p_indicadorPropriedadePosseIt = '' OR p_indicadorPropriedadePosseIt = ' ' THEN '0' ELSE p_indicadorPropriedadePosseIt END || ''
    AND itemEst.pessoaParticipante = p_pessoaParticipante
    AND TRUNC(invEst.data) = p_dataInicialEstoque - 1
    AND (p_estabelecimento = 0
      OR p_estabelecimento <> 0
      AND p_config_209_filtrarGrupoEcon = 0
      AND EXISTS (
        SELECT 1
        FROM PAESTABELECIMENTOS est
        JOIN PAESTABELECIMENTOS est2 ON est2.pessoaEstabelecimento = est.pessoaEstabelecimento
        WHERE est.estabelecimento = invEst.estabelecimento
        AND (est.estabelecimento = p_estabelecimento
          OR est2.estabelecimento = p_estabelecimento))
      OR p_estabelecimento <> 0
      AND p_config_209_filtrarGrupoEcon = 1
      AND EXISTS (
        SELECT 1
        FROM PAESTABELECIMENTOS est
        JOIN CAPESSOAS pessEst ON pessEst.pessoa = est.pessoaEstabelecimento
        JOIN CAPESSOAS pessEst2 ON pessEst2.grupoEconomico = pessEst.grupoEconomico
        JOIN PAESTABELECIMENTOS est2 ON est2.pessoaEstabelecimento = pessEst2.pessoa
        WHERE est.estabelecimento = invEst.estabelecimento
        AND (est.estabelecimento = p_estabelecimento
          OR est2.estabelecimento = p_estabelecimento)))
    -- Movimentos pós último inventário
    UNION ALL
    SELECT itemEst.data,
      itemEst.idEstoque,
      itemEst.entradaSaida,
      itemEst.atualizaCustoMedio,
      itemEst.operacaoInternaEstoque,
      itemEst.quantidade,
      itemEst.precoCustoOperacao,
      itemEst.totalCustoOperacao,
      CASE
        WHEN itemEst.atualizaCustoMedio = 0
        THEN 0
        ELSE COALESCE((
          SELECT
            CASE
              WHEN itemDoc.quantidade = 0
                OR prod.controleEstoque IN (3,4)
                AND COALESCE(kit.ativo,0) = 1
                AND COALESCE(kit.manterUltimoCusto,0) = 1
              THEN 0
              ELSE ROUND(itemDoc.valorAcrescimoExtempTotal * itemEst.quantidade / itemDoc.quantidade,2)
            END
          FROM MODOCFISCALXESTOQUE estXDoc
          JOIN MOESTOQUES itemEst2 ON itemEst2.idEstoque = estXDoc.idEstoque
          JOIN MODOCFISCALXITENS itemDoc ON itemDoc.idItemDocFiscal = estXDoc.idItemDocFiscal
          LEFT JOIN CAGRADEPRODUTOXKITSCOMBOS kit ON kit.gradeProduto = itemDoc.gradeProduto AND kit.gradeProdutoFilho = itemEst2.gradeProduto
          WHERE estXDoc.idEstoque = itemEst.idEstoque),COALESCE((
          SELECT
            CASE
              WHEN itemDoc.quantidade = 0
                OR prod.controleEstoque IN (3,4)
                AND COALESCE(kit.ativo,0) = 1
                AND COALESCE(kit.manterUltimoCusto,0) = 1
              THEN 0
              ELSE ROUND(itemDoc.valorAcrescimoExtempTotal * itemEst.quantidade / itemDoc.quantidade,2)
            END
          FROM MOPREDOCUMXESTOQUE estXDoc
          JOIN MOESTOQUES itemEst2 ON itemEst2.idEstoque = estXDoc.idEstoque
          JOIN MOPREDOCUMXITENS itemDoc ON itemDoc.idItemPreDocumento = estXDoc.idItemPreDocumento
          LEFT JOIN CAGRADEPRODUTOXKITSCOMBOS kit ON kit.gradeProduto = itemDoc.gradeProduto AND kit.gradeProdutoFilho = itemEst2.gradeProduto
          WHERE estXDoc.idEstoque = itemEst.idEstoque),0))
      END valorAcrescimoExtempTotal
    FROM MOESTOQUES itemEst
    JOIN CAGRADESPRODUTO gradProd ON gradProd.gradeProduto = itemEst.gradeProduto
    JOIN CAPRODUTOS prod ON prod.produto = gradProd.produto
    WHERE gradProd.produto = p_gradProd_produto
    AND (p_config_362_calcCustoPorGrade = 0 OR p_gradProd_cor = 0 OR gradProd.cor = p_gradProd_cor)
    AND (p_config_362_calcCustoPorGrade = 0 OR p_gradProd_tamanho = '' OR p_gradProd_tamanho = ' ' OR gradProd.tamanho = p_gradProd_tamanho)
    AND (p_config_362_calcCustoPorGrade = 0 OR p_item_personalizacao = 0 OR itemEst.personalizacao = p_item_personalizacao)
    AND itemEst.indicadorPropriedadePosseItem = '' || CASE WHEN p_indicadorPropriedadePosseIt IS NULL OR p_indicadorPropriedadePosseIt = '' OR p_indicadorPropriedadePosseIt = ' ' THEN '0' ELSE p_indicadorPropriedadePosseIt END || ''
    AND itemEst.pessoaParticipante = p_pessoaParticipante
    AND (p_buscarPrecoGerencial = 1 OR itemEst.operacaoInternaEstoque <> 101)
    AND TRUNC(itemEst.data) BETWEEN p_dataInicialEstoque AND TRUNC(p_data)
    AND (p_estabelecimento = 0
      OR p_estabelecimento <> 0
      AND p_config_209_filtrarGrupoEcon = 0
      AND EXISTS (
        SELECT 1
        FROM PAESTABELECIMENTOS est
        JOIN PAESTABELECIMENTOS est2 ON est2.pessoaEstabelecimento = est.pessoaEstabelecimento
        WHERE est.estabelecimento = itemEst.estabelecimento
        AND (est.estabelecimento = p_estabelecimento
          OR est2.estabelecimento = p_estabelecimento))
      OR p_estabelecimento <> 0
      AND p_config_209_filtrarGrupoEcon = 1
      AND EXISTS (
        SELECT 1
        FROM PAESTABELECIMENTOS est
        JOIN CAPESSOAS pessEst ON pessEst.pessoa = est.pessoaEstabelecimento
        JOIN CAPESSOAS pessEst2 ON pessEst2.grupoEconomico = pessEst.grupoEconomico
        JOIN PAESTABELECIMENTOS est2 ON est2.pessoaEstabelecimento = pessEst2.pessoa
        WHERE est.estabelecimento = itemEst.estabelecimento
        AND (est.estabelecimento = p_estabelecimento
          OR est2.estabelecimento = p_estabelecimento)))
    ) a
  ORDER BY TRUNC(a.data),
    a.operacaoInternaEstoque DESC,
    a.atualizaCustoMedio DESC,
    a.data,
    a.idEstoque;
BEGIN
  v_data := TO_DATE('01/01/1900','DD/MM/YYYY');
  v_quantidadeEstoque := 0;
  v_precoCustoMedio := 0;
  v_totalCustoMedio := 0;
  FOR precoMedio IN c_precoMedio
  LOOP
    -- Saldo inicial, zera apenas no primeiro registro da grade...
    IF precoMedio.operacaoInternaEstoque = 1 AND (v_data IS NULL OR precoMedio.data > v_data)
    THEN
      v_quantidadeEstoque := 0;
      v_precoCustoMedio := 0;
      v_totalCustoMedio := 0;
    END IF;
    v_data := precoMedio.data;
    -- Se atualiza custo médio
    IF precoMedio.atualizaCustoMedio = 1 THEN
      IF precoMedio.entradaSaida = 'E' THEN
        v_quantidadeEstoque := v_quantidadeEstoque + precoMedio.quantidade;
        IF v_quantidadeEstoque <= 0 THEN
          v_totalCustoMedio := 0;
        ELSE
          IF v_quantidadeEstoque > precoMedio.quantidade THEN
            IF v_totalCustoMedio + precoMedio.totalCustoOperacao > 9999999999999.99 THEN
               v_totalCustoMedio := 9999999999999.99;
            ELSE
               v_totalCustoMedio := v_totalCustoMedio + precoMedio.totalCustoOperacao;
            END IF;
          ELSE
            IF ROUND ((precoMedio.totalCustoOperacao * v_quantidadeEstoque / precoMedio.quantidade),2) > 9999999999999.99 THEN
               v_totalCustoMedio := 9999999999999.99;
            ELSE
               v_totalCustoMedio := ROUND ((precoMedio.totalCustoOperacao * v_quantidadeEstoque / precoMedio.quantidade),2);
            END IF;
          END IF;
        END IF;
     ELSE
        v_quantidadeEstoque := v_quantidadeEstoque - precoMedio.quantidade;
        v_totalCustoMedio := v_totalCustoMedio - precoMedio.totalCustoOperacao;
        IF v_totalCustoMedio < 0 OR v_quantidadeEstoque <= 0 THEN
          v_totalCustoMedio := 0;
        END IF;
      END IF;
      IF v_totalCustoMedio > 0 AND v_quantidadeEstoque >= 0 AND ROUND(v_totalCustoMedio / CASE WHEN v_quantidadeEstoque = 0 THEN 1 ELSE v_quantidadeEstoque END, 7) > 99999999.9999999 THEN
        v_precoCustoMedio := 99999999.9999999;
      ELSE
        IF v_totalCustoMedio > 0 AND v_quantidadeEstoque >= 0 THEN
          v_precoCustoMedio := ROUND(v_totalCustoMedio / CASE WHEN v_quantidadeEstoque = 0 THEN 1 ELSE v_quantidadeEstoque END, 7);
        END IF;
      END IF;
    -- Se não atualiza custo médio
    ELSE
      IF precoMedio.entradaSaida = 'E' THEN
        v_quantidadeEstoque := v_quantidadeEstoque + precoMedio.quantidade;
        IF v_quantidadeEstoque <= 0 THEN
          v_totalCustoMedio := 0;
        ELSE
          IF v_quantidadeEstoque > precoMedio.quantidade THEN
            IF v_totalCustoMedio + ROUND((precoMedio.quantidade * v_precoCustoMedio),2) > 9999999999999.99 THEN
               v_totalCustoMedio := 9999999999999.99;
            ELSE
               v_totalCustoMedio := v_totalCustoMedio + precoMedio.totalCustoOperacao;
            END IF;
          ELSE
            IF ROUND((v_quantidadeEstoque * v_precoCustoMedio),2) > 9999999999999.99 THEN
               v_totalCustoMedio := 9999999999999.99;
            ELSE
               v_totalCustoMedio := ROUND((v_quantidadeEstoque * v_precoCustoMedio),2);
            END IF;
          END IF;
        END IF;
      ELSE
        v_quantidadeEstoque := v_quantidadeEstoque - precoMedio.quantidade;
        v_totalCustoMedio := v_totalCustoMedio - precoMedio.quantidade * v_precoCustoMedio;
        IF v_totalCustoMedio < 0 OR v_quantidadeEstoque <= 0 THEN
          v_totalCustoMedio := 0;
        END IF;
      END IF;
    END IF;
  END LOOP;
  IF v_precoCustoMedio = 0 THEN
    SELECT COALESCE(MAX(preco.precoMedioInicial),0)
    INTO v_precoCustoMedio      
    FROM CAPRODUTOXESTABELECIMENTO preco
    WHERE preco.produto = p_gradProd_produto
    AND preco.estabelecimento = p_estabelecimento
    AND preco.ativo = 1;
    IF p_estabelecimento <> 0 AND v_precoCustoMedio = 0 THEN
      SELECT COALESCE(MAX(preco.precoMedioInicial),0)
      INTO v_precoCustoMedio      
      FROM CAPRODUTOXESTABELECIMENTO preco
      WHERE preco.produto = p_gradProd_produto
      AND preco.ativo = 1
      AND (p_estabelecimento = 0
        OR p_estabelecimento <> 0
        AND p_config_209_filtrarGrupoEcon = 0
        AND EXISTS (
          SELECT 1
          FROM PAESTABELECIMENTOS est
          JOIN PAESTABELECIMENTOS est2 ON est2.pessoaEstabelecimento = est.pessoaEstabelecimento
          WHERE est.estabelecimento = preco.estabelecimento
          AND (est.estabelecimento = p_estabelecimento
            OR est2.estabelecimento = p_estabelecimento))
        OR p_estabelecimento <> 0
        AND p_config_209_filtrarGrupoEcon = 1
        AND EXISTS (
          SELECT 1
          FROM PAESTABELECIMENTOS est
          JOIN CAPESSOAS pessEst ON pessEst.pessoa = est.pessoaEstabelecimento
          JOIN CAPESSOAS pessEst2 ON pessEst2.grupoEconomico = pessEst.grupoEconomico
          JOIN PAESTABELECIMENTOS est2 ON est2.pessoaEstabelecimento = pessEst2.pessoa
          WHERE est.estabelecimento = preco.estabelecimento
          AND (est.estabelecimento = p_estabelecimento
            OR est2.estabelecimento = p_estabelecimento)));
    END IF;
    IF p_estabelecimento <> 0 AND v_precoCustoMedio = 0 THEN
      SELECT COALESCE(MAX(preco.precoMedioInicial),0)
      INTO v_precoCustoMedio      
      FROM CAPRODUTOXESTABELECIMENTO preco
      WHERE preco.produto = p_gradProd_produto
      AND preco.estabelecimento = 0
      AND preco.ativo = 1;
    END IF;
  END IF;
  RETURN v_precoCustoMedio;  
END;

/

create or replace PROCEDURE ADD_DOC_FISC_ITEM_EST_KIT(
    p_config_209_filtrarGrupoEcon  IN NUMBER,
    p_config_362_calcCustoPorGrade IN NUMBER,
    p_bufferIdEstoque              IN VARCHAR2,
    p_estabelecimentoAtivo         IN NUMBER,
    p_cab_modeloDocumento          IN NUMBER,
    p_cab_atualizaCustoMedio       IN NUMBER,
    p_cab_atualizaUltimaCompra     IN NUMBER,
    p_cab_entradaSaida             IN CHAR,
    p_cab_estabelecimento          IN NUMBER,
    p_cab_dataEmissao              IN DATE,
    p_cab_dataEntradaSaida         IN DATE,
    p_modDoc_geraTransferencia     IN NUMBER,
    p_modDoc_geraOperacaoEmTransit IN NUMBER,
    p_modDoc_transitoLocalEstoque  IN NUMBER,
    p_locEstTransito_indicProprPos IN CHAR,
    p_item_idItemDocFiscal         IN NUMBER,
    p_item_gradeProduto            IN NUMBER,
    p_item_localEstoque            IN NUMBER,
    p_item_pessoaParticipante      IN NUMBER,
    p_item_quantidade              IN NUMBER,
    p_item_valorCustoOperacao      IN NUMBER,
    p_item_observacoes             IN VARCHAR2,
    p_endEst_idEnderecoEstoqueDocF IN NUMBER,
    p_idEnderecoEstoque            IN NUMBER,
    p_locEst_indicProprPosseItem   IN CHAR,
    p_docTransf_estabelecEntrada   IN NUMBER,
    p_docTransf_estabelecSaida     IN NUMBER,
    r_bufferIdEstoque              OUT VARCHAR2)
IS  
  v_quantidadeNumerosSerie NUMBER;
  v_quantidadeRateioTotal  NUMBER;
  v_quantSaldoRateioTotal  NUMBER;
  v_valorSaldoRateioTotal  NUMBER;
  v_valorCustoManter       NUMBER;
  v_precoCustoKit          NUMBER;
  v_valorCustoKit          NUMBER;
  CURSOR c_kit IS 
    SELECT 
      kit.gradeProdutoFilho,
      kit.manterUltimoCusto,
      gradProdFilho.produto,
      prodFilho.controleEstoque,
      prodFilho.controlaNumeroSerie,
      ROUND(p_item_quantidade * kit.quantidade, uniFilho.casasDecimaisUnidadeMedida) quantidade
    FROM CAGRADEPRODUTOXKITSCOMBOS kit 
    JOIN CAGRADESPRODUTO gradProdFilho ON gradProdFilho.gradeProduto = kit.gradeProdutoFilho
    JOIN CAPRODUTOS prodFilho ON prodFilho.produto = gradProdFilho.produto
    JOIN SIUNIDADESMEDIDA uniFilho ON uniFilho.unidadeMedida = prodFilho.unidadeMedida
    WHERE kit.gradeProduto = p_item_gradeProduto
    AND kit.ativo = 1
    AND kit.gradeProduto <> kit.gradeProdutoFilho
    AND ROUND(p_item_quantidade * kit.quantidade, uniFilho.casasDecimaisUnidadeMedida) > 0;
BEGIN
  r_bufferIdEstoque := p_bufferIdEstoque;
  IF p_cab_atualizaCustoMedio = 1 THEN
    SELECT COALESCE(SUM(ROUND(p_item_quantidade * kit.quantidade, uniFilho.casasDecimaisUnidadeMedida)),0)
    INTO v_quantidadeRateioTotal
    FROM CAGRADEPRODUTOXKITSCOMBOS kit 
    JOIN CAGRADESPRODUTO gradProdFilho ON gradProdFilho.gradeProduto = kit.gradeProdutoFilho
    JOIN CAPRODUTOS prodFilho ON prodFilho.produto = gradProdFilho.produto
    JOIN SIUNIDADESMEDIDA uniFilho ON uniFilho.unidadeMedida = prodFilho.unidadeMedida
    WHERE kit.gradeProduto = p_item_gradeProduto
    AND kit.ativo = 1
    AND kit.manterUltimoCusto = 0
    AND kit.gradeProduto <> kit.gradeProdutoFilho;
    SELECT ROUND((COALESCE(SUM(ROUND(p_item_quantidade * kit.quantidade, uniFilho.casasDecimaisUnidadeMedida)
      * FUNC_ADD_BUSCA_PRECO_ULT_CUSTO(
          p_config_209_filtrarGrupoEcon,
          p_config_362_calcCustoPorGrade,
          p_cab_estabelecimento,
          TO_DATE ('01/01/1900','DD/MM/YYYY'),
          CASE WHEN p_cab_dataEntradaSaida IS NULL OR p_cab_dataEntradaSaida < p_cab_dataEmissao THEN p_cab_dataEmissao ELSE p_cab_dataEntradaSaida END - 1,
          0,
          gradProdFilho.produto,
          0,
          ' ',
          p_locEst_indicProprPosseItem,
          p_item_pessoaParticipante)),0)),2)
    INTO v_valorCustoManter
    FROM CAGRADEPRODUTOXKITSCOMBOS kit 
    JOIN CAGRADESPRODUTO gradProdFilho ON gradProdFilho.gradeProduto = kit.gradeProdutoFilho
    JOIN CAPRODUTOS prodFilho ON prodFilho.produto = gradProdFilho.produto
    JOIN SIUNIDADESMEDIDA uniFilho ON uniFilho.unidadeMedida = prodFilho.unidadeMedida
    WHERE kit.gradeProduto = p_item_gradeProduto
    AND kit.ativo = 1
    AND kit.manterUltimoCusto = 1
    AND kit.gradeProduto <> kit.gradeProdutoFilho;
  ELSE
    v_quantidadeRateioTotal := 0;
    v_valorCustoManter      := 0;
  END IF;
  v_quantSaldoRateioTotal := v_quantidadeRateioTotal;
  v_valorSaldoRateioTotal := p_item_valorCustoOperacao - v_valorCustoManter;
  FOR kit IN c_kit
  LOOP  
    IF p_cab_atualizaCustoMedio = 1 AND kit.manterUltimoCusto = 1 THEN
      v_precoCustoKit := FUNC_ADD_BUSCA_PRECO_ULT_CUSTO(
          p_config_209_filtrarGrupoEcon,
          p_config_362_calcCustoPorGrade,
          p_cab_estabelecimento,
          TO_DATE ('01/01/1900','DD/MM/YYYY'),
          CASE WHEN p_cab_dataEntradaSaida IS NULL OR p_cab_dataEntradaSaida < p_cab_dataEmissao THEN p_cab_dataEmissao ELSE p_cab_dataEntradaSaida END - 1,
          0,
          kit.produto,
          0,
          ' ',
          p_locEst_indicProprPosseItem,
          p_item_pessoaParticipante);
      v_valorCustoKit := ROUND (kit.quantidade * v_precoCustoKit,2);
    ELSIF p_cab_atualizaCustoMedio = 1 AND p_item_valorCustoOperacao > v_valorCustoManter AND v_quantSaldoRateioTotal > kit.quantidade THEN
      v_valorCustoKit := ROUND((p_item_valorCustoOperacao - v_valorCustoManter) * kit.quantidade / v_quantidadeRateioTotal,2);
      v_precoCustoKit := ROUND(v_valorCustoKit / kit.quantidade,7);
      v_quantSaldoRateioTotal := v_quantSaldoRateioTotal - kit.quantidade;
      v_valorSaldoRateioTotal := v_valorSaldoRateioTotal - v_valorCustoKit;
    ELSIF p_cab_atualizaCustoMedio = 1 AND v_valorSaldoRateioTotal > 0 THEN
      v_valorCustoKit := v_valorSaldoRateioTotal;
      v_precoCustoKit := ROUND(v_valorCustoKit / kit.quantidade,7);
      v_quantSaldoRateioTotal := 0;
      v_valorSaldoRateioTotal := 0;
    ELSE
      v_precoCustoKit := 0;
      v_valorCustoKit := 0;
    END IF;
    IF kit.controleEstoque IN (3,4) THEN
      ADD_DOC_FISC_ITEM_EST_KIT(
        p_config_209_filtrarGrupoEcon,
        p_config_362_calcCustoPorGrade,
        r_bufferIdEstoque,
        p_estabelecimentoAtivo,
        p_cab_modeloDocumento,
        p_cab_atualizaCustoMedio,
        p_cab_atualizaUltimaCompra,
        p_cab_entradaSaida,
        p_cab_estabelecimento,
        p_cab_dataEmissao,
        p_cab_dataEntradaSaida,
        p_modDoc_geraTransferencia,
        p_modDoc_geraOperacaoEmTransit,
        p_modDoc_transitoLocalEstoque,
        p_locEstTransito_indicProprPos,
        p_item_idItemDocFiscal,
        kit.gradeProdutoFilho,
        p_item_localEstoque,
        p_item_pessoaParticipante,
        kit.quantidade,
        v_valorCustoKit,
        p_item_observacoes,
        p_endEst_idEnderecoEstoqueDocF,
        p_idEnderecoEstoque,
        p_locEst_indicProprPosseItem,
        p_docTransf_estabelecEntrada,
        p_docTransf_estabelecSaida,
        r_bufferIdEstoque);
    ELSIF kit.controleEstoque IN(1,5,11,12) THEN
      v_quantidadeNumerosSerie := 0;
      IF kit.controlaNumeroSerie > 0 THEN
        ADD_DOC_FISC_ITEM_EST_N_SERIE(
          r_bufferIdEstoque,
          p_estabelecimentoAtivo,
          p_cab_modeloDocumento,
          p_cab_atualizaCustoMedio,
          p_cab_atualizaUltimaCompra,
          p_cab_entradaSaida,
          p_cab_estabelecimento,
          p_cab_dataEmissao,
          p_cab_dataEntradaSaida,
          p_modDoc_geraTransferencia,
          p_modDoc_geraOperacaoEmTransit,
          p_modDoc_transitoLocalEstoque,
          p_locEstTransito_indicProprPos,
          p_item_idItemDocFiscal,
          kit.gradeProdutoFilho,
          0, -- p_item_idFormulaTinta
          0, -- p_item_personalizacao
          0, -- p_item_idLoteEstoque
          p_item_localEstoque,
          p_item_pessoaParticipante,
          v_precoCustoKit, -- p_item_precoCustoOperacao,
          0, -- p_item_precoCMV,
          p_item_observacoes,
          p_endEst_idEnderecoEstoqueDocF,
          p_idEnderecoEstoque,
          p_locEst_indicProprPosseItem,
          p_docTransf_estabelecEntrada,
          p_docTransf_estabelecSaida,
          r_bufferIdEstoque,
          v_quantidadeNumerosSerie);
      END IF;    
      IF kit.quantidade > v_quantidadeNumerosSerie THEN
        ADD_ESTOQUE_INSERE(
          r_bufferIdEstoque,
          p_estabelecimentoAtivo,
          p_cab_estabelecimento,
          CASE WHEN p_cab_dataEntradaSaida IS NULL OR p_cab_dataEntradaSaida < p_cab_dataEmissao THEN p_cab_dataEmissao ELSE p_cab_dataEntradaSaida END, --p_data
          kit.gradeProdutoFilho,
          p_cab_modeloDocumento,
          100, --p_cab_operacaoInternaEstoque
          p_cab_atualizaCustoMedio,
          p_cab_atualizaUltimaCompra,
          p_cab_entradaSaida,
          p_locEst_indicProprPosseItem,
          p_item_pessoaParticipante,
          p_item_localEstoque,
          0, -- p_personalizacao
          0, -- p_idLoteEstoque
          p_idEnderecoEstoque,
          0, -- p_idNumeroSerie
          kit.quantidade - v_quantidadeNumerosSerie,
          v_precoCustoKit, -- p_precoCustoOperacao
          CASE WHEN v_quantidadeNumerosSerie = 0 THEN v_valorCustoKit WHEN kit.quantidade = 0 THEN 0 ELSE ROUND ((v_valorCustoKit * (kit.quantidade - v_quantidadeNumerosSerie) / kit.quantidade), 2) END, -- p_totalCustoOperacao
          0, -- p_precoCMV
          0, -- p_valorCMV
          p_item_observacoes,
          0, -- p_idItemPreDocumento,
          p_item_idItemDocFiscal,
          0, -- p_idItemSeparacao,
          0, -- p_divergenciaBalanco,
          0, -- p_idItemDocTransferencia,
          r_bufferIdEstoque);
        IF p_modDoc_geraTransferencia = 1 AND p_modDoc_geraOperacaoEmTransit = 1 AND p_modDoc_transitoLocalEstoque > 0 AND p_docTransf_estabelecEntrada > 0 AND p_docTransf_estabelecSaida > 0 THEN
          ADD_ESTOQUE_INSERE(
            r_bufferIdEstoque, 
            p_estabelecimentoAtivo, 
            p_docTransf_estabelecSaida,
            CASE WHEN p_cab_dataEntradaSaida IS NULL OR p_cab_dataEntradaSaida < p_cab_dataEmissao THEN p_cab_dataEmissao ELSE p_cab_dataEntradaSaida END, --p_data
            kit.gradeProdutoFilho,
            p_cab_modeloDocumento,
            900,
            0,
            0,
            CASE WHEN p_cab_entradaSaida='S' THEN 'E' ELSE 'S' END,
            p_locEstTransito_indicProprPos,
            p_item_pessoaParticipante,
            p_modDoc_transitoLocalEstoque,
            0, -- p_personalizacao
            0, -- p_idLoteEstoque
            p_idEnderecoEstoque,
            0, -- p_idNumeroSerie
            kit.quantidade - v_quantidadeNumerosSerie,
            v_precoCustoKit, -- p_precoCustoOperacao
            CASE WHEN v_quantidadeNumerosSerie = 0 THEN v_valorCustoKit WHEN kit.quantidade = 0 THEN 0 ELSE ROUND ((v_valorCustoKit * (kit.quantidade - v_quantidadeNumerosSerie) / kit.quantidade), 2) END, -- p_totalCustoOperacao
            0, -- p_precoCMV
            0, -- p_valorCMV
            p_item_observacoes,
            0, -- p_idItemPreDocumento,
            p_item_idItemDocFiscal,
            0, -- p_idItemSeparacao,
            0, -- p_divergenciaBalanco,
            0, -- p_idItemDocTransferencia,
            r_bufferIdEstoque);
        END IF;    
      END IF;    
    END IF;
  END LOOP;
END ADD_DOC_FISC_ITEM_EST_KIT;

/

create or replace PROCEDURE ADD_PRE_DOC_ITEM_EST_KIT(
    p_config_209_filtrarGrupoEcon  IN NUMBER,
    p_config_362_calcCustoPorGrade IN NUMBER,
    p_bufferIdEstoque              IN VARCHAR2,
    p_estabelecimentoAtivo         IN NUMBER,
    p_cab_modeloDocumento          IN NUMBER,
    p_cab_atualizaCustoMedio       IN NUMBER,
    p_cab_atualizaUltimaCompra     IN NUMBER,
    p_cab_entradaSaida             IN CHAR,
    p_cab_estabelecimento          IN NUMBER,
    p_cab_dataEmissao              IN DATE,
    p_cab_dataEntradaSaida         IN DATE,
    p_modDoc_geraTransferencia     IN NUMBER,
    p_modDoc_geraOperacaoEmTransit IN NUMBER,
    p_modDoc_transitoLocalEstoque  IN NUMBER,
    p_locEstTransito_indicProprPos IN CHAR,
    p_item_idItemPreDocumento      IN NUMBER,
    p_item_gradeProduto            IN NUMBER,
    p_item_localEstoque            IN NUMBER,
    p_item_pessoaParticipante      IN NUMBER,
    p_item_quantidade              IN NUMBER,
    p_item_valorCustoOperacao      IN NUMBER,
    p_item_observacoes             IN VARCHAR2,
    p_endEst_idEnderecoEstoquePreD IN NUMBER,
    p_idEnderecoEstoque            IN NUMBER,
    p_locEst_indicProprPosseItem   IN CHAR,
    p_docTransf_estabelecEntrada   IN NUMBER,
    p_docTransf_estabelecSaida     IN NUMBER,
    r_bufferIdEstoque              OUT VARCHAR2)
IS  
  v_quantidadeNumerosSerie NUMBER;
  v_quantidadeRateioTotal  NUMBER;
  v_quantSaldoRateioTotal  NUMBER;
  v_valorSaldoRateioTotal  NUMBER;
  v_valorCustoManter       NUMBER;
  v_precoCustoKit          NUMBER;
  v_valorCustoKit          NUMBER;
  CURSOR c_kit
  IS 
    SELECT 
      kit.gradeProdutoFilho,
      kit.manterUltimoCusto,
      gradProdFilho.produto,
      prodFilho.controleEstoque,
      prodFilho.controlaNumeroSerie,
      ROUND(p_item_quantidade * kit.quantidade, uniFilho.casasDecimaisUnidadeMedida) quantidade
    FROM CAGRADEPRODUTOXKITSCOMBOS kit 
    JOIN CAGRADESPRODUTO gradProdFilho ON gradProdFilho.gradeProduto = kit.gradeProdutoFilho
    JOIN CAPRODUTOS prodFilho ON prodFilho.produto = gradProdFilho.produto
    JOIN SIUNIDADESMEDIDA uniFilho ON uniFilho.unidadeMedida = prodFilho.unidadeMedida
    WHERE kit.gradeProduto = p_item_gradeProduto
    AND kit.ativo = 1
    AND kit.gradeProduto <> kit.gradeProdutoFilho
    AND ROUND(p_item_quantidade * kit.quantidade, uniFilho.casasDecimaisUnidadeMedida) > 0;
BEGIN
  r_bufferIdEstoque := p_bufferIdEstoque;
  IF p_cab_atualizaCustoMedio = 1 THEN
    SELECT COALESCE(SUM(ROUND(p_item_quantidade * kit.quantidade, uniFilho.casasDecimaisUnidadeMedida)),0)
    INTO v_quantidadeRateioTotal
    FROM CAGRADEPRODUTOXKITSCOMBOS kit 
    JOIN CAGRADESPRODUTO gradProdFilho ON gradProdFilho.gradeProduto = kit.gradeProdutoFilho
    JOIN CAPRODUTOS prodFilho ON prodFilho.produto = gradProdFilho.produto
    JOIN SIUNIDADESMEDIDA uniFilho ON uniFilho.unidadeMedida = prodFilho.unidadeMedida
    WHERE kit.gradeProduto = p_item_gradeProduto
    AND kit.ativo = 1
    AND kit.manterUltimoCusto = 0
    AND kit.gradeProduto <> kit.gradeProdutoFilho;
    SELECT ROUND((COALESCE(SUM(ROUND(p_item_quantidade * kit.quantidade, uniFilho.casasDecimaisUnidadeMedida)
      * FUNC_ADD_BUSCA_PRECO_ULT_CUSTO(
          p_config_209_filtrarGrupoEcon,
          p_config_362_calcCustoPorGrade,
          p_cab_estabelecimento,
          TO_DATE ('01/01/1900','DD/MM/YYYY'),
          CASE WHEN p_cab_dataEntradaSaida IS NULL OR p_cab_dataEntradaSaida < p_cab_dataEmissao THEN p_cab_dataEmissao ELSE p_cab_dataEntradaSaida END - 1,
          0,
          gradProdFilho.produto,
          0,
          ' ',
          p_locEst_indicProprPosseItem,
          p_item_pessoaParticipante)),0)),2)
    INTO v_valorCustoManter
    FROM CAGRADEPRODUTOXKITSCOMBOS kit 
    JOIN CAGRADESPRODUTO gradProdFilho ON gradProdFilho.gradeProduto = kit.gradeProdutoFilho
    JOIN CAPRODUTOS prodFilho ON prodFilho.produto = gradProdFilho.produto
    JOIN SIUNIDADESMEDIDA uniFilho ON uniFilho.unidadeMedida = prodFilho.unidadeMedida
    WHERE kit.gradeProduto = p_item_gradeProduto
    AND kit.ativo = 1
    AND kit.manterUltimoCusto = 1
    AND kit.gradeProduto <> kit.gradeProdutoFilho;
  ELSE
    v_quantidadeRateioTotal := 0;
    v_valorCustoManter      := 0;
  END IF;
  v_quantSaldoRateioTotal := v_quantidadeRateioTotal;
  v_valorSaldoRateioTotal := p_item_valorCustoOperacao - v_valorCustoManter;
  FOR kit IN c_kit
  LOOP  
    IF p_cab_atualizaCustoMedio = 1 AND kit.manterUltimoCusto = 1 THEN
      v_precoCustoKit := FUNC_ADD_BUSCA_PRECO_ULT_CUSTO(
          p_config_209_filtrarGrupoEcon,
          p_config_362_calcCustoPorGrade,
          p_cab_estabelecimento,
          TO_DATE ('01/01/1900','DD/MM/YYYY'),
          CASE WHEN p_cab_dataEntradaSaida IS NULL OR p_cab_dataEntradaSaida < p_cab_dataEmissao THEN p_cab_dataEmissao ELSE p_cab_dataEntradaSaida END - 1,
          0,
          kit.produto,
          0,
          ' ',
          p_locEst_indicProprPosseItem,
          p_item_pessoaParticipante);
      v_valorCustoKit := ROUND (kit.quantidade * v_precoCustoKit,2);
    ELSIF p_cab_atualizaCustoMedio = 1 AND p_item_valorCustoOperacao > v_valorCustoManter AND v_quantSaldoRateioTotal > kit.quantidade THEN
      v_valorCustoKit := ROUND((p_item_valorCustoOperacao - v_valorCustoManter) * kit.quantidade / v_quantidadeRateioTotal,2);
      v_precoCustoKit := ROUND(v_valorCustoKit / kit.quantidade,7);
      v_quantSaldoRateioTotal := v_quantSaldoRateioTotal - kit.quantidade;
      v_valorSaldoRateioTotal := v_valorSaldoRateioTotal - v_valorCustoKit;
    ELSIF p_cab_atualizaCustoMedio = 1 AND v_valorSaldoRateioTotal > 0 THEN
      v_valorCustoKit := v_valorSaldoRateioTotal;
      v_precoCustoKit := ROUND(v_valorCustoKit / kit.quantidade,7);
      v_quantSaldoRateioTotal := 0;
      v_valorSaldoRateioTotal := 0;
    ELSE
      v_precoCustoKit := 0;
      v_valorCustoKit := 0;
    END IF;
    IF kit.controleEstoque IN (3,4) THEN
      ADD_PRE_DOC_ITEM_EST_KIT(
        p_config_209_filtrarGrupoEcon,
        p_config_362_calcCustoPorGrade,
        r_bufferIdEstoque,
        p_estabelecimentoAtivo,
        p_cab_modeloDocumento,
        p_cab_atualizaCustoMedio,
        p_cab_atualizaUltimaCompra,
        p_cab_entradaSaida,
        p_cab_estabelecimento,
        p_cab_dataEmissao,
        p_cab_dataEntradaSaida,
        p_modDoc_geraTransferencia,
        p_modDoc_geraOperacaoEmTransit,
        p_modDoc_transitoLocalEstoque,
        p_locEstTransito_indicProprPos,
        p_item_idItemPreDocumento,
        kit.gradeProdutoFilho,
        p_item_localEstoque,
        p_item_pessoaParticipante,
        kit.quantidade,
        v_valorCustoKit,
        p_item_observacoes,
        p_endEst_idEnderecoEstoquePreD,
        p_idEnderecoEstoque,
        p_locEst_indicProprPosseItem,
        p_docTransf_estabelecEntrada,
        p_docTransf_estabelecSaida,
        r_bufferIdEstoque);
    ELSIF kit.controleEstoque IN(1,5,11,12) THEN
      v_quantidadeNumerosSerie := 0;
      IF kit.controlaNumeroSerie > 0 THEN
        ADD_PRE_DOC_ITEM_EST_N_SERIE(
          r_bufferIdEstoque,
          p_estabelecimentoAtivo,
          p_cab_modeloDocumento,
          p_cab_atualizaCustoMedio,
          p_cab_atualizaUltimaCompra,
          p_cab_entradaSaida,
          p_cab_estabelecimento,
          p_cab_dataEmissao,
          p_cab_dataEntradaSaida,
          p_modDoc_geraTransferencia,
          p_modDoc_geraOperacaoEmTransit,
          p_modDoc_transitoLocalEstoque,
          p_locEstTransito_indicProprPos,
          p_item_idItemPreDocumento,
          kit.gradeProdutoFilho,
          0, -- p_item_idFormulaTinta
          0, -- p_item_personalizacao
          0, -- p_item_idLoteEstoque
          p_item_localEstoque,
          p_item_pessoaParticipante,
          v_precoCustoKit, -- p_item_precoCustoOperacao,
          0, -- p_item_precoCMV,
          p_item_observacoes,
          p_endEst_idEnderecoEstoquePreD,
          p_idEnderecoEstoque,
          p_locEst_indicProprPosseItem,
          p_docTransf_estabelecEntrada,
          p_docTransf_estabelecSaida,
          r_bufferIdEstoque,
          v_quantidadeNumerosSerie);
      END IF;    
      IF kit.quantidade > v_quantidadeNumerosSerie THEN
        ADD_ESTOQUE_INSERE(
          r_bufferIdEstoque,
          p_estabelecimentoAtivo,
          p_cab_estabelecimento,
          CASE WHEN p_cab_dataEntradaSaida IS NULL OR p_cab_dataEntradaSaida < p_cab_dataEmissao THEN p_cab_dataEmissao ELSE p_cab_dataEntradaSaida END, --p_data
          kit.gradeProdutoFilho,
          p_cab_modeloDocumento,
          101, --p_cab_operacaoInternaEstoque
          p_cab_atualizaCustoMedio,
          p_cab_atualizaUltimaCompra,
          p_cab_entradaSaida,
          p_locEst_indicProprPosseItem,
          p_item_pessoaParticipante,
          p_item_localEstoque,
          0, -- p_personalizacao
          0, -- p_idLoteEstoque
          p_idEnderecoEstoque,
          0, -- p_idNumeroSerie
          kit.quantidade - v_quantidadeNumerosSerie,
          v_precoCustoKit, -- p_precoCustoOperacao
          CASE WHEN v_quantidadeNumerosSerie = 0 THEN v_valorCustoKit WHEN kit.quantidade = 0 THEN 0 ELSE ROUND ((v_valorCustoKit * (kit.quantidade - v_quantidadeNumerosSerie) / kit.quantidade), 2) END, -- p_totalCustoOperacao
          0, -- p_precoCMV
          0, -- p_valorCMV
          p_item_observacoes,
          p_item_idItemPreDocumento,
          0, -- p_idItemDocFiscal,
          0, -- p_idItemSeparacao,
          0, -- p_divergenciaBalanco,
          0, -- p_idItemDocTransferencia,
          r_bufferIdEstoque);
        IF p_modDoc_geraTransferencia = 1 AND p_modDoc_geraOperacaoEmTransit = 1 AND p_modDoc_transitoLocalEstoque > 0 AND p_docTransf_estabelecEntrada > 0 AND p_docTransf_estabelecSaida > 0 THEN
          ADD_ESTOQUE_INSERE(
            r_bufferIdEstoque, 
            p_estabelecimentoAtivo, 
            p_docTransf_estabelecSaida,
            CASE WHEN p_cab_dataEntradaSaida IS NULL OR p_cab_dataEntradaSaida < p_cab_dataEmissao THEN p_cab_dataEmissao ELSE p_cab_dataEntradaSaida END, --p_data
            kit.gradeProdutoFilho,
            p_cab_modeloDocumento,
            900,
            0,
            0,
            CASE WHEN p_cab_entradaSaida='S' THEN 'E' ELSE 'S' END,
            p_locEstTransito_indicProprPos,
            p_item_pessoaParticipante,
            p_modDoc_transitoLocalEstoque,
            0, -- p_personalizacao
            0, -- p_idLoteEstoque
            p_idEnderecoEstoque,
            0, -- p_idNumeroSerie
            kit.quantidade - v_quantidadeNumerosSerie,
            v_precoCustoKit, -- p_precoCustoOperacao
            CASE WHEN v_quantidadeNumerosSerie = 0 THEN v_valorCustoKit WHEN kit.quantidade = 0 THEN 0 ELSE ROUND ((v_valorCustoKit * (kit.quantidade - v_quantidadeNumerosSerie) / kit.quantidade), 2) END, -- p_totalCustoOperacao
            0, -- p_precoCMV
            0, -- p_valorCMV
            p_item_observacoes,
            p_item_idItemPreDocumento,
            0, -- p_idItemDocFiscal,
            0, -- p_idItemSeparacao,
            0, -- p_divergenciaBalanco,
            0, -- p_idItemDocTransferencia,
            r_bufferIdEstoque);
        END IF;    
      END IF;    
    END IF;
  END LOOP;
END ADD_PRE_DOC_ITEM_EST_KIT;

/

UPDATE SITIPOSPRECO SET descricao = 'CMV - Custo Médio da Venda' WHERE tipoPreco = 'C';
UPDATE SITIPOSPRECO SET descricao = 'Custo Formação de Preço'    WHERE tipoPreco = 'F';
UPDATE SITIPOSPRECO SET descricao = 'Último Preço de Custo'      WHERE tipoPreco = 'P';
UPDATE SITIPOSPRECO SET descricao = 'Último Preço de Compra'     WHERE tipoPreco = 'U';

COMMIT;

INSERT INTO SITIPOSPRECO (tipoPreco, descricao, ativo, validoCusto, observacoes) values ('G', 'CMVG - Custo Médio Gerencial', 1, 1, ' ');

COMMIT;

UPDATE MOPREDOCUMXITENS item
SET item.quantidadeDevolvidaRetornada =
  ( COALESCE((
      SELECT SUM (
        CASE
          WHEN itemDev.quantidade <=
            ( COALESCE((
                SELECT SUM (itemDev2.quantidade)
                FROM MOPREDOCUMXPREDOCUM docXDoc2
                JOIN MOPREDOCUMXITENS itemDev2 ON itemDev2.idItemPreDocumento = docXDoc2.idItemPreDocumento
                JOIN MOPREDOCUMENTOS cabDev2 ON cabDev2.preDocumento = itemDev2.preDocumento
                WHERE docXDoc2.idItemPreDocReferenciado = itemDev.idItemPreDocumento
                AND itemDev2.cancelado = 0
                AND cabDev2.origemDocumento = 4
                AND cabDev2.statusPreDocumento <> 'C'),0)
            + COALESCE((
                SELECT SUM (itemDev2.quantidade)
                FROM MODOCFISCALXPREDOCUM docXDoc2
                JOIN MODOCFISCALXITENS itemDev2 ON itemDev2.idItemDocFiscal = docXDoc2.idItemDocFiscal
                JOIN MODOCUMENTOSFISCAIS cabDev2 ON cabDev2.idDocumentoFiscal = itemDev2.idDocumentoFiscal
                WHERE docXDoc2.idItemPreDocReferenciado = itemDev.idItemPreDocumento
                AND itemDev2.cancelado = 0
                AND cabDev2.origemDocumento = 4
                AND cabDev2.situacaoDocumentoFiscal <= 23),0))
          THEN 0
          ELSE itemDev.quantidade -
            ( COALESCE((
                SELECT SUM (itemDev2.quantidade)
                FROM MOPREDOCUMXPREDOCUM docXDoc2
                JOIN MOPREDOCUMXITENS itemDev2 ON itemDev2.idItemPreDocumento = docXDoc2.idItemPreDocumento
                JOIN MOPREDOCUMENTOS cabDev2 ON cabDev2.preDocumento = itemDev2.preDocumento
                WHERE docXDoc2.idItemPreDocReferenciado = itemDev.idItemPreDocumento
                AND itemDev2.cancelado = 0
                AND cabDev2.origemDocumento = 4
                AND cabDev2.statusPreDocumento <> 'C'),0)
            + COALESCE((
                SELECT SUM (itemDev2.quantidade)
                FROM MODOCFISCALXPREDOCUM docXDoc2
                JOIN MODOCFISCALXITENS itemDev2 ON itemDev2.idItemDocFiscal = docXDoc2.idItemDocFiscal
                JOIN MODOCUMENTOSFISCAIS cabDev2 ON cabDev2.idDocumentoFiscal = itemDev2.idDocumentoFiscal
                WHERE docXDoc2.idItemPreDocReferenciado = itemDev.idItemPreDocumento
                AND itemDev2.cancelado = 0
                AND cabDev2.origemDocumento = 4
                AND cabDev2.situacaoDocumentoFiscal <= 23),0))
        END)
      FROM MOPREDOCUMXPREDOCUM docXDoc
      JOIN MOPREDOCUMXITENS itemDev ON itemDev.idItemPreDocumento = docXDoc.idItemPreDocumento
      JOIN MOPREDOCUMENTOS cabDev ON cabDev.preDocumento = itemDev.preDocumento
      WHERE docXDoc.idItemPreDocReferenciado = item.idItemPreDocumento
      AND itemDev.cancelado = 0
      AND cabDev.origemDocumento <> 6
      AND cabDev.statusPreDocumento <> 'C'),0)
  + COALESCE((
      SELECT SUM (
        CASE
          WHEN itemDev.quantidade <=
            ( COALESCE((
                SELECT SUM (itemDev2.quantidade)
                FROM MODOCFISCALXDOCFISCAL docXDoc2
                JOIN MODOCFISCALXITENS itemDev2 ON itemDev2.idItemDocFiscal = docXDoc2.idItemDocFiscal
                JOIN MODOCUMENTOSFISCAIS cabDev2 ON cabDev2.idDocumentoFiscal = itemDev2.idDocumentoFiscal
                WHERE docXDoc2.idItemDocFiscalReferenciado = itemDev.idItemDocFiscal
                AND itemDev2.cancelado = 0
                AND cabDev2.origemDocumento = 4
                AND cabDev2.situacaoDocumentoFiscal <= 23),0)
            + COALESCE((
                SELECT SUM (itemDev2.quantidade)
                FROM MOPREDOCUMXDOCFISCAL docXDoc2
                JOIN MOPREDOCUMXITENS itemDev2 ON itemDev2.idItemPreDocumento = docXDoc2.idItemPreDocumento
                JOIN MOPREDOCUMENTOS cabDev2 ON cabDev2.preDocumento = itemDev2.preDocumento
                WHERE docXDoc2.idItemDocFiscalReferenciado = itemDev.idItemDocFiscal
                AND itemDev2.cancelado = 0
                AND cabDev2.origemDocumento = 4
                AND cabDev2.statusPreDocumento <> 'C'),0))
          THEN 0
          ELSE itemDev.quantidade -
            ( COALESCE((
                SELECT SUM (itemDev2.quantidade)
                FROM MODOCFISCALXDOCFISCAL docXDoc2
                JOIN MODOCFISCALXITENS itemDev2 ON itemDev2.idItemDocFiscal = docXDoc2.idItemDocFiscal
                JOIN MODOCUMENTOSFISCAIS cabDev2 ON cabDev2.idDocumentoFiscal = itemDev2.idDocumentoFiscal
                WHERE docXDoc2.idItemDocFiscalReferenciado = itemDev.idItemDocFiscal
                AND itemDev2.cancelado = 0
                AND cabDev2.origemDocumento = 4
                AND cabDev2.situacaoDocumentoFiscal <= 23),0)
            + COALESCE((
                SELECT SUM (itemDev2.quantidade)
                FROM MOPREDOCUMXDOCFISCAL docXDoc2
                JOIN MOPREDOCUMXITENS itemDev2 ON itemDev2.idItemPreDocumento = docXDoc2.idItemPreDocumento
                JOIN MOPREDOCUMENTOS cabDev2 ON cabDev2.preDocumento = itemDev2.preDocumento
                WHERE docXDoc2.idItemDocFiscalReferenciado = itemDev.idItemDocFiscal
                AND itemDev2.cancelado = 0
                AND cabDev2.origemDocumento = 4
                AND cabDev2.statusPreDocumento <> 'C'),0))
        END)
      FROM MODOCFISCALXPREDOCUM docXDoc
      JOIN MODOCFISCALXITENS itemDev ON itemDev.idItemDocFiscal = docXDoc.idItemDocFiscal
      JOIN MODOCUMENTOSFISCAIS cabDev ON cabDev.idDocumentoFiscal = itemDev.idDocumentoFiscal
      WHERE docXDoc.idItemPreDocReferenciado = item.idItemPreDocumento
      AND itemDev.cancelado = 0
      AND cabDev.origemDocumento <> 6
      AND cabDev.situacaoDocumentoFiscal <= 23),0))
WHERE item.idItemPreDocumento <> 0
AND item.cancelado = 0
AND item.quantidadeDevolvidaRetornada <> 
  ( COALESCE((
      SELECT SUM (
        CASE
          WHEN itemDev.quantidade <=
            ( COALESCE((
                SELECT SUM (itemDev2.quantidade)
                FROM MOPREDOCUMXPREDOCUM docXDoc2
                JOIN MOPREDOCUMXITENS itemDev2 ON itemDev2.idItemPreDocumento = docXDoc2.idItemPreDocumento
                JOIN MOPREDOCUMENTOS cabDev2 ON cabDev2.preDocumento = itemDev2.preDocumento
                WHERE docXDoc2.idItemPreDocReferenciado = itemDev.idItemPreDocumento
                AND itemDev2.cancelado = 0
                AND cabDev2.origemDocumento = 4
                AND cabDev2.statusPreDocumento <> 'C'),0)
            + COALESCE((
                SELECT SUM (itemDev2.quantidade)
                FROM MODOCFISCALXPREDOCUM docXDoc2
                JOIN MODOCFISCALXITENS itemDev2 ON itemDev2.idItemDocFiscal = docXDoc2.idItemDocFiscal
                JOIN MODOCUMENTOSFISCAIS cabDev2 ON cabDev2.idDocumentoFiscal = itemDev2.idDocumentoFiscal
                WHERE docXDoc2.idItemPreDocReferenciado = itemDev.idItemPreDocumento
                AND itemDev2.cancelado = 0
                AND cabDev2.origemDocumento = 4
                AND cabDev2.situacaoDocumentoFiscal <= 23),0))
          THEN 0
          ELSE itemDev.quantidade -
            ( COALESCE((
                SELECT SUM (itemDev2.quantidade)
                FROM MOPREDOCUMXPREDOCUM docXDoc2
                JOIN MOPREDOCUMXITENS itemDev2 ON itemDev2.idItemPreDocumento = docXDoc2.idItemPreDocumento
                JOIN MOPREDOCUMENTOS cabDev2 ON cabDev2.preDocumento = itemDev2.preDocumento
                WHERE docXDoc2.idItemPreDocReferenciado = itemDev.idItemPreDocumento
                AND itemDev2.cancelado = 0
                AND cabDev2.origemDocumento = 4
                AND cabDev2.statusPreDocumento <> 'C'),0)
            + COALESCE((
                SELECT SUM (itemDev2.quantidade)
                FROM MODOCFISCALXPREDOCUM docXDoc2
                JOIN MODOCFISCALXITENS itemDev2 ON itemDev2.idItemDocFiscal = docXDoc2.idItemDocFiscal
                JOIN MODOCUMENTOSFISCAIS cabDev2 ON cabDev2.idDocumentoFiscal = itemDev2.idDocumentoFiscal
                WHERE docXDoc2.idItemPreDocReferenciado = itemDev.idItemPreDocumento
                AND itemDev2.cancelado = 0
                AND cabDev2.origemDocumento = 4
                AND cabDev2.situacaoDocumentoFiscal <= 23),0))
        END)
      FROM MOPREDOCUMXPREDOCUM docXDoc
      JOIN MOPREDOCUMXITENS itemDev ON itemDev.idItemPreDocumento = docXDoc.idItemPreDocumento
      JOIN MOPREDOCUMENTOS cabDev ON cabDev.preDocumento = itemDev.preDocumento
      WHERE docXDoc.idItemPreDocReferenciado = item.idItemPreDocumento
      AND itemDev.cancelado = 0
      AND cabDev.origemDocumento <> 6
      AND cabDev.statusPreDocumento <> 'C'),0)
  + COALESCE((
      SELECT SUM (
        CASE
          WHEN itemDev.quantidade <=
            ( COALESCE((
                SELECT SUM (itemDev2.quantidade)
                FROM MODOCFISCALXDOCFISCAL docXDoc2
                JOIN MODOCFISCALXITENS itemDev2 ON itemDev2.idItemDocFiscal = docXDoc2.idItemDocFiscal
                JOIN MODOCUMENTOSFISCAIS cabDev2 ON cabDev2.idDocumentoFiscal = itemDev2.idDocumentoFiscal
                WHERE docXDoc2.idItemDocFiscalReferenciado = itemDev.idItemDocFiscal
                AND itemDev2.cancelado = 0
                AND cabDev2.origemDocumento = 4
                AND cabDev2.situacaoDocumentoFiscal <= 23),0)
            + COALESCE((
                SELECT SUM (itemDev2.quantidade)
                FROM MOPREDOCUMXDOCFISCAL docXDoc2
                JOIN MOPREDOCUMXITENS itemDev2 ON itemDev2.idItemPreDocumento = docXDoc2.idItemPreDocumento
                JOIN MOPREDOCUMENTOS cabDev2 ON cabDev2.preDocumento = itemDev2.preDocumento
                WHERE docXDoc2.idItemDocFiscalReferenciado = itemDev.idItemDocFiscal
                AND itemDev2.cancelado = 0
                AND cabDev2.origemDocumento = 4
                AND cabDev2.statusPreDocumento <> 'C'),0))
          THEN 0
          ELSE itemDev.quantidade -
            ( COALESCE((
                SELECT SUM (itemDev2.quantidade)
                FROM MODOCFISCALXDOCFISCAL docXDoc2
                JOIN MODOCFISCALXITENS itemDev2 ON itemDev2.idItemDocFiscal = docXDoc2.idItemDocFiscal
                JOIN MODOCUMENTOSFISCAIS cabDev2 ON cabDev2.idDocumentoFiscal = itemDev2.idDocumentoFiscal
                WHERE docXDoc2.idItemDocFiscalReferenciado = itemDev.idItemDocFiscal
                AND itemDev2.cancelado = 0
                AND cabDev2.origemDocumento = 4
                AND cabDev2.situacaoDocumentoFiscal <= 23),0)
            + COALESCE((
                SELECT SUM (itemDev2.quantidade)
                FROM MOPREDOCUMXDOCFISCAL docXDoc2
                JOIN MOPREDOCUMXITENS itemDev2 ON itemDev2.idItemPreDocumento = docXDoc2.idItemPreDocumento
                JOIN MOPREDOCUMENTOS cabDev2 ON cabDev2.preDocumento = itemDev2.preDocumento
                WHERE docXDoc2.idItemDocFiscalReferenciado = itemDev.idItemDocFiscal
                AND itemDev2.cancelado = 0
                AND cabDev2.origemDocumento = 4
                AND cabDev2.statusPreDocumento <> 'C'),0))
        END)
      FROM MODOCFISCALXPREDOCUM docXDoc
      JOIN MODOCFISCALXITENS itemDev ON itemDev.idItemDocFiscal = docXDoc.idItemDocFiscal
      JOIN MODOCUMENTOSFISCAIS cabDev ON cabDev.idDocumentoFiscal = itemDev.idDocumentoFiscal
      WHERE docXDoc.idItemPreDocReferenciado = item.idItemPreDocumento
      AND itemDev.cancelado = 0
      AND cabDev.origemDocumento <> 6
      AND cabDev.situacaoDocumentoFiscal <= 23),0));

COMMIT;

UPDATE MOPREDOCUMENTOS cab
SET cab.quantidadeDevolvidaRetornada = COALESCE((
  SELECT SUM (item.quantidadeDevolvidaRetornada)
  FROM MOPREDOCUMXITENS item
  WHERE item.preDocumento = cab.preDocumento
  AND item.cancelado = 0),0)
WHERE cab.preDocumento <> 0
AND cab.statusPreDocumento <> 'C'
AND cab.quantidadeDevolvidaRetornada <> COALESCE((
  SELECT SUM (item.quantidadeDevolvidaRetornada)
  FROM MOPREDOCUMXITENS item
  WHERE item.preDocumento = cab.preDocumento
  AND item.cancelado = 0),0);

COMMIT;

UPDATE MODOCFISCALXITENS item
SET item.quantidadeDevolvidaRetornada =
  ( COALESCE((
      SELECT SUM (
        CASE
          WHEN itemDev.quantidade <=
            ( COALESCE((
                SELECT SUM (itemDev2.quantidade)
                FROM MODOCFISCALXDOCFISCAL docXDoc2
                JOIN MODOCFISCALXITENS itemDev2 ON itemDev2.idItemDocFiscal = docXDoc2.idItemDocFiscal
                JOIN MODOCUMENTOSFISCAIS cabDev2 ON cabDev2.idDocumentoFiscal = itemDev2.idDocumentoFiscal
                WHERE docXDoc2.idItemDocFiscalReferenciado = itemDev.idItemDocFiscal
                AND itemDev2.cancelado = 0
                AND cabDev2.origemDocumento = 4
                AND cabDev2.situacaoDocumentoFiscal <= 23),0)
            + COALESCE((
                SELECT SUM (itemDev2.quantidade)
                FROM MOPREDOCUMXDOCFISCAL docXDoc2
                JOIN MOPREDOCUMXITENS itemDev2 ON itemDev2.idItemPreDocumento = docXDoc2.idItemPreDocumento
                JOIN MOPREDOCUMENTOS cabDev2 ON cabDev2.preDocumento = itemDev2.preDocumento
                WHERE docXDoc2.idItemDocFiscalReferenciado = itemDev.idItemDocFiscal
                AND itemDev2.cancelado = 0
                AND cabDev2.origemDocumento = 4
                AND cabDev2.statusPreDocumento <> 'C'),0))
          THEN 0
          ELSE itemDev.quantidade -
            ( COALESCE((
                SELECT SUM (itemDev2.quantidade)
                FROM MODOCFISCALXDOCFISCAL docXDoc2
                JOIN MODOCFISCALXITENS itemDev2 ON itemDev2.idItemDocFiscal = docXDoc2.idItemDocFiscal
                JOIN MODOCUMENTOSFISCAIS cabDev2 ON cabDev2.idDocumentoFiscal = itemDev2.idDocumentoFiscal
                WHERE docXDoc2.idItemDocFiscalReferenciado = itemDev.idItemDocFiscal
                AND itemDev2.cancelado = 0
                AND cabDev2.origemDocumento = 4
                AND cabDev2.situacaoDocumentoFiscal <= 23),0)
            + COALESCE((
                SELECT SUM (itemDev2.quantidade)
                FROM MOPREDOCUMXDOCFISCAL docXDoc2
                JOIN MOPREDOCUMXITENS itemDev2 ON itemDev2.idItemPreDocumento = docXDoc2.idItemPreDocumento
                JOIN MOPREDOCUMENTOS cabDev2 ON cabDev2.preDocumento = itemDev2.preDocumento
                WHERE docXDoc2.idItemDocFiscalReferenciado = itemDev.idItemDocFiscal
                AND itemDev2.cancelado = 0
                AND cabDev2.origemDocumento = 4
                AND cabDev2.statusPreDocumento <> 'C'),0))
        END)
      FROM MODOCFISCALXDOCFISCAL docXDoc
      JOIN MODOCFISCALXITENS itemDev ON itemDev.idItemDocFiscal = docXDoc.idItemDocFiscal
      JOIN MODOCUMENTOSFISCAIS cabDev ON cabDev.idDocumentoFiscal = itemDev.idDocumentoFiscal
      WHERE docXDoc.idItemDocFiscalReferenciado = item.idItemDocFiscal
      AND itemDev.cancelado = 0
      AND cabDev.origemDocumento <> 6
      AND cabDev.situacaoDocumentoFiscal <= 23),0)
  + COALESCE((
      SELECT SUM (
        CASE
          WHEN itemDev.quantidade <=
            ( COALESCE((
                SELECT SUM (itemDev2.quantidade)
                FROM MOPREDOCUMXPREDOCUM docXDoc2
                JOIN MOPREDOCUMXITENS itemDev2 ON itemDev2.idItemPreDocumento = docXDoc2.idItemPreDocumento
                JOIN MOPREDOCUMENTOS cabDev2 ON cabDev2.preDocumento = itemDev2.preDocumento
                WHERE docXDoc2.idItemPreDocReferenciado = itemDev.idItemPreDocumento
                AND itemDev2.cancelado = 0
                AND cabDev2.origemDocumento = 4
                AND cabDev2.statusPreDocumento <> 'C'),0)
            + COALESCE((
                SELECT SUM (itemDev2.quantidade)
                FROM MODOCFISCALXPREDOCUM docXDoc2
                JOIN MODOCFISCALXITENS itemDev2 ON itemDev2.idItemDocFiscal = docXDoc2.idItemDocFiscal
                JOIN MODOCUMENTOSFISCAIS cabDev2 ON cabDev2.idDocumentoFiscal = itemDev2.idDocumentoFiscal
                WHERE docXDoc2.idItemPreDocReferenciado = itemDev.idItemPreDocumento
                AND itemDev2.cancelado = 0
                AND cabDev2.origemDocumento = 4
                AND cabDev2.situacaoDocumentoFiscal <= 23),0))
          THEN 0
          ELSE itemDev.quantidade -
            ( COALESCE((
                SELECT SUM (itemDev2.quantidade)
                FROM MOPREDOCUMXPREDOCUM docXDoc2
                JOIN MOPREDOCUMXITENS itemDev2 ON itemDev2.idItemPreDocumento = docXDoc2.idItemPreDocumento
                JOIN MOPREDOCUMENTOS cabDev2 ON cabDev2.preDocumento = itemDev2.preDocumento
                WHERE docXDoc2.idItemPreDocReferenciado = itemDev.idItemPreDocumento
                AND itemDev2.cancelado = 0
                AND cabDev2.origemDocumento = 4
                AND cabDev2.statusPreDocumento <> 'C'),0)
            + COALESCE((
                SELECT SUM (itemDev2.quantidade)
                FROM MODOCFISCALXPREDOCUM docXDoc2
                JOIN MODOCFISCALXITENS itemDev2 ON itemDev2.idItemDocFiscal = docXDoc2.idItemDocFiscal
                JOIN MODOCUMENTOSFISCAIS cabDev2 ON cabDev2.idDocumentoFiscal = itemDev2.idDocumentoFiscal
                WHERE docXDoc2.idItemPreDocReferenciado = itemDev.idItemPreDocumento
                AND itemDev2.cancelado = 0
                AND cabDev2.origemDocumento = 4
                AND cabDev2.situacaoDocumentoFiscal <= 23),0))
        END)
      FROM MOPREDOCUMXDOCFISCAL docXDoc
      JOIN MOPREDOCUMXITENS itemDev ON itemDev.idItemPreDocumento = docXDoc.idItemPreDocumento
      JOIN MOPREDOCUMENTOS cabDev ON cabDev.preDocumento = itemDev.preDocumento
      WHERE docXDoc.idItemDocFiscalReferenciado = item.idItemDocFiscal
      AND itemDev.cancelado = 0
      AND cabDev.origemDocumento <> 6
      AND cabDev.statusPreDocumento <> 'C'),0))
WHERE item.idItemDocFiscal <> 0
AND item.cancelado = 0
AND item.quantidadeDevolvidaRetornada <> 
  ( COALESCE((
      SELECT SUM (
        CASE
          WHEN itemDev.quantidade <=
            ( COALESCE((
                SELECT SUM (itemDev2.quantidade)
                FROM MODOCFISCALXDOCFISCAL docXDoc2
                JOIN MODOCFISCALXITENS itemDev2 ON itemDev2.idItemDocFiscal = docXDoc2.idItemDocFiscal
                JOIN MODOCUMENTOSFISCAIS cabDev2 ON cabDev2.idDocumentoFiscal = itemDev2.idDocumentoFiscal
                WHERE docXDoc2.idItemDocFiscalReferenciado = itemDev.idItemDocFiscal
                AND itemDev2.cancelado = 0
                AND cabDev2.origemDocumento = 4
                AND cabDev2.situacaoDocumentoFiscal <= 23),0)
            + COALESCE((
                SELECT SUM (itemDev2.quantidade)
                FROM MOPREDOCUMXDOCFISCAL docXDoc2
                JOIN MOPREDOCUMXITENS itemDev2 ON itemDev2.idItemPreDocumento = docXDoc2.idItemPreDocumento
                JOIN MOPREDOCUMENTOS cabDev2 ON cabDev2.preDocumento = itemDev2.preDocumento
                WHERE docXDoc2.idItemDocFiscalReferenciado = itemDev.idItemDocFiscal
                AND itemDev2.cancelado = 0
                AND cabDev2.origemDocumento = 4
                AND cabDev2.statusPreDocumento <> 'C'),0))
          THEN 0
          ELSE itemDev.quantidade -
            ( COALESCE((
                SELECT SUM (itemDev2.quantidade)
                FROM MODOCFISCALXDOCFISCAL docXDoc2
                JOIN MODOCFISCALXITENS itemDev2 ON itemDev2.idItemDocFiscal = docXDoc2.idItemDocFiscal
                JOIN MODOCUMENTOSFISCAIS cabDev2 ON cabDev2.idDocumentoFiscal = itemDev2.idDocumentoFiscal
                WHERE docXDoc2.idItemDocFiscalReferenciado = itemDev.idItemDocFiscal
                AND itemDev2.cancelado = 0
                AND cabDev2.origemDocumento = 4
                AND cabDev2.situacaoDocumentoFiscal <= 23),0)
            + COALESCE((
                SELECT SUM (itemDev2.quantidade)
                FROM MOPREDOCUMXDOCFISCAL docXDoc2
                JOIN MOPREDOCUMXITENS itemDev2 ON itemDev2.idItemPreDocumento = docXDoc2.idItemPreDocumento
                JOIN MOPREDOCUMENTOS cabDev2 ON cabDev2.preDocumento = itemDev2.preDocumento
                WHERE docXDoc2.idItemDocFiscalReferenciado = itemDev.idItemDocFiscal
                AND itemDev2.cancelado = 0
                AND cabDev2.origemDocumento = 4
                AND cabDev2.statusPreDocumento <> 'C'),0))
        END)
      FROM MODOCFISCALXDOCFISCAL docXDoc
      JOIN MODOCFISCALXITENS itemDev ON itemDev.idItemDocFiscal = docXDoc.idItemDocFiscal
      JOIN MODOCUMENTOSFISCAIS cabDev ON cabDev.idDocumentoFiscal = itemDev.idDocumentoFiscal
      WHERE docXDoc.idItemDocFiscalReferenciado = item.idItemDocFiscal
      AND itemDev.cancelado = 0
      AND cabDev.origemDocumento <> 6
      AND cabDev.situacaoDocumentoFiscal <= 23),0)
  + COALESCE((
      SELECT SUM (
        CASE
          WHEN itemDev.quantidade <=
            ( COALESCE((
                SELECT SUM (itemDev2.quantidade)
                FROM MOPREDOCUMXPREDOCUM docXDoc2
                JOIN MOPREDOCUMXITENS itemDev2 ON itemDev2.idItemPreDocumento = docXDoc2.idItemPreDocumento
                JOIN MOPREDOCUMENTOS cabDev2 ON cabDev2.preDocumento = itemDev2.preDocumento
                WHERE docXDoc2.idItemPreDocReferenciado = itemDev.idItemPreDocumento
                AND itemDev2.cancelado = 0
                AND cabDev2.origemDocumento = 4
                AND cabDev2.statusPreDocumento <> 'C'),0)
            + COALESCE((
                SELECT SUM (itemDev2.quantidade)
                FROM MODOCFISCALXPREDOCUM docXDoc2
                JOIN MODOCFISCALXITENS itemDev2 ON itemDev2.idItemDocFiscal = docXDoc2.idItemDocFiscal
                JOIN MODOCUMENTOSFISCAIS cabDev2 ON cabDev2.idDocumentoFiscal = itemDev2.idDocumentoFiscal
                WHERE docXDoc2.idItemPreDocReferenciado = itemDev.idItemPreDocumento
                AND itemDev2.cancelado = 0
                AND cabDev2.origemDocumento = 4
                AND cabDev2.situacaoDocumentoFiscal <= 23),0))
          THEN 0
          ELSE itemDev.quantidade -
            ( COALESCE((
                SELECT SUM (itemDev2.quantidade)
                FROM MOPREDOCUMXPREDOCUM docXDoc2
                JOIN MOPREDOCUMXITENS itemDev2 ON itemDev2.idItemPreDocumento = docXDoc2.idItemPreDocumento
                JOIN MOPREDOCUMENTOS cabDev2 ON cabDev2.preDocumento = itemDev2.preDocumento
                WHERE docXDoc2.idItemPreDocReferenciado = itemDev.idItemPreDocumento
                AND itemDev2.cancelado = 0
                AND cabDev2.origemDocumento = 4
                AND cabDev2.statusPreDocumento <> 'C'),0)
            + COALESCE((
                SELECT SUM (itemDev2.quantidade)
                FROM MODOCFISCALXPREDOCUM docXDoc2
                JOIN MODOCFISCALXITENS itemDev2 ON itemDev2.idItemDocFiscal = docXDoc2.idItemDocFiscal
                JOIN MODOCUMENTOSFISCAIS cabDev2 ON cabDev2.idDocumentoFiscal = itemDev2.idDocumentoFiscal
                WHERE docXDoc2.idItemPreDocReferenciado = itemDev.idItemPreDocumento
                AND itemDev2.cancelado = 0
                AND cabDev2.origemDocumento = 4
                AND cabDev2.situacaoDocumentoFiscal <= 23),0))
        END)
      FROM MOPREDOCUMXDOCFISCAL docXDoc
      JOIN MOPREDOCUMXITENS itemDev ON itemDev.idItemPreDocumento = docXDoc.idItemPreDocumento
      JOIN MOPREDOCUMENTOS cabDev ON cabDev.preDocumento = itemDev.preDocumento
      WHERE docXDoc.idItemDocFiscalReferenciado = item.idItemDocFiscal
      AND itemDev.cancelado = 0
      AND cabDev.origemDocumento <> 6
      AND cabDev.statusPreDocumento <> 'C'),0));

COMMIT;

UPDATE MODOCUMENTOSFISCAIS cab
SET cab.quantidadeDevolvidaRetornada = COALESCE((
  SELECT SUM (item.quantidadeDevolvidaRetornada)
  FROM MODOCFISCALXITENS item
  WHERE item.idDocumentoFiscal = cab.idDocumentoFiscal
  AND item.cancelado = 0),0)
WHERE cab.idDocumentoFiscal <> 0
AND cab.situacaoDocumentoFiscal <= 23
AND cab.quantidadeDevolvidaRetornada <> COALESCE((
  SELECT SUM (item.quantidadeDevolvidaRetornada)
  FROM MODOCFISCALXITENS item
  WHERE item.idDocumentoFiscal = cab.idDocumentoFiscal
  AND item.cancelado = 0),0);

COMMIT;

create or replace FUNCTION FUNC_ADD_BUSCA_PRECO_DATA_INI(
    p_config_209_filtrarGrupoEcon IN NUMBER,
    p_estabelecimento             IN NUMBER,
    p_data                        IN DATE,
    p_produto                     IN NUMBER,
    p_indicadorPropriedadePosseIt IN CHAR,
    p_pessoaParticipante          IN NUMBER,
    p_gerandoInventario           IN NUMBER
  )
  RETURN DATE
IS 
  v_data DATE;
BEGIN
  SELECT COALESCE(MAX(a.data),TO_DATE('01/01/1900','DD/MM/YYYY'))
  INTO v_data
  FROM (
    SELECT MAX(TRUNC(invEst.data)+1) data
    FROM MOINVENTARIOESTOQUEXITENS itemEst
    JOIN CAGRADESPRODUTO gradProd ON gradProd.gradeProduto = itemEst.gradeProduto
    JOIN MOINVENTARIOSESTOQUE invEst ON invEst.inventarioEstoque = itemEst.inventarioEstoque
    WHERE gradProd.produto = p_produto
    AND itemEst.indicadorPropriedadePosseItem = '' || CASE WHEN p_indicadorPropriedadePosseIt IS NULL OR p_indicadorPropriedadePosseIt = '' OR p_indicadorPropriedadePosseIt = ' ' THEN '0' ELSE p_indicadorPropriedadePosseIt END || ''
    AND itemEst.pessoaParticipante = p_pessoaParticipante
    AND TRUNC(invEst.data) <= (TRUNC(p_data) - CASE WHEN p_gerandoInventario = 1 THEN 1 ELSE 0 END)
    AND (p_estabelecimento = 0
      OR p_estabelecimento <> 0
      AND p_config_209_filtrarGrupoEcon = 0
      AND EXISTS (
        SELECT 1
        FROM PAESTABELECIMENTOS est
        JOIN PAESTABELECIMENTOS est2 ON est2.pessoaEstabelecimento = est.pessoaEstabelecimento
        WHERE est.estabelecimento = invEst.estabelecimento
        AND (est.estabelecimento = p_estabelecimento
          OR est2.estabelecimento = p_estabelecimento))
      OR p_estabelecimento <> 0
      AND p_config_209_filtrarGrupoEcon = 1
      AND EXISTS (
        SELECT 1
        FROM PAESTABELECIMENTOS est
        JOIN CAPESSOAS pessEst ON pessEst.pessoa = est.pessoaEstabelecimento
        JOIN CAPESSOAS pessEst2 ON pessEst2.grupoEconomico = pessEst.grupoEconomico
        JOIN PAESTABELECIMENTOS est2 ON est2.pessoaEstabelecimento = pessEst2.pessoa
        WHERE est.estabelecimento = invEst.estabelecimento
        AND (est.estabelecimento = p_estabelecimento
          OR est2.estabelecimento = p_estabelecimento)))
    UNION ALL
    SELECT MAX(TRUNC(itemEst.data)) data
    FROM MOESTOQUES itemEst
    JOIN CAGRADESPRODUTO gradProd ON gradProd.gradeProduto = itemEst.gradeProduto
    WHERE gradProd.produto = p_produto
    AND itemEst.indicadorPropriedadePosseItem = '' || CASE WHEN p_indicadorPropriedadePosseIt IS NULL OR p_indicadorPropriedadePosseIt = '' OR p_indicadorPropriedadePosseIt = ' ' THEN '0' ELSE p_indicadorPropriedadePosseIt END || ''
    AND itemEst.pessoaParticipante = p_pessoaParticipante
    AND itemEst.operacaoInternaEstoque = 1
    AND TRUNC(itemEst.data) <= TRUNC(p_data)
    AND (p_estabelecimento = 0
      OR p_estabelecimento <> 0
      AND p_config_209_filtrarGrupoEcon = 0
      AND EXISTS (
        SELECT 1
        FROM PAESTABELECIMENTOS est
        JOIN PAESTABELECIMENTOS est2 ON est2.pessoaEstabelecimento = est.pessoaEstabelecimento
        WHERE est.estabelecimento = itemEst.estabelecimento
        AND (est.estabelecimento = p_estabelecimento
          OR est2.estabelecimento = p_estabelecimento))
      OR p_estabelecimento <> 0
      AND p_config_209_filtrarGrupoEcon = 1
      AND EXISTS (
        SELECT 1
        FROM PAESTABELECIMENTOS est
        JOIN CAPESSOAS pessEst ON pessEst.pessoa = est.pessoaEstabelecimento
        JOIN CAPESSOAS pessEst2 ON pessEst2.grupoEconomico = pessEst.grupoEconomico
        JOIN PAESTABELECIMENTOS est2 ON est2.pessoaEstabelecimento = pessEst2.pessoa
        WHERE est.estabelecimento = itemEst.estabelecimento
        AND (est.estabelecimento = p_estabelecimento
          OR est2.estabelecimento = p_estabelecimento)))
  ) a;
  RETURN v_data;
END;

/

create or replace PROCEDURE ADD_GERA_TEMP_ESTOQUE (
  p_uniqueMachineID     IN VARCHAR2,
  p_contadorSessao      IN NUMBER,
  p_dataPosicaoEstoque  IN DATE,
  p_inEstabelecimentos  IN VARCHAR2,
  p_inLocaisEstoque     IN VARCHAR2,
  p_joinProdutos        IN VARCHAR2,
  p_andWhereProdutos    IN VARCHAR2,
  p_joinInventarios     IN VARCHAR2,
  p_andWhereInventarios IN VARCHAR2,
  p_joinMovimentos      IN VARCHAR2,
  p_andWhereMovimentos  IN VARCHAR2)
IS
BEGIN
  DELETE TEMPESTOQUE
  WHERE  uniqueMachineID = p_uniqueMachineID
  AND contadorSessao = p_contadorSessao;
  EXECUTE IMMEDIATE 'INSERT INTO TEMPESTOQUE (
    uniqueMachineID,
    contadorSessao,
    gradeProduto,
    estabelecimento,
    localEstoque,
    indicadorPropriedadePosseItem,
    pessoaParticipante,
    personalizacao,
    idLoteEstoque,
    idEnderecoEstoque,
    idNumeroSerie,
    quantidadeFiscal,
    quantidadeGerencial)
  WITH ESTABELECIMENTOS AS (
    SELECT
      a.estabelecimento,
      a.dataInventario,
      COALESCE ((
      SELECT MAX (inv.inventarioEstoque)
      FROM MOINVENTARIOSESTOQUE inv
      WHERE inv.estabelecimento = a.estabelecimento
      AND TRUNC (inv.data) = TRUNC(a.dataInventario)),0) inventarioEstoque
    FROM (
      SELECT
        est.estabelecimento,
        COALESCE(
          ( SELECT MAX(TRUNC(inv.data))
            FROM MOINVENTARIOSESTOQUE inv
            WHERE inv.estabelecimento = est.estabelecimento
            AND TRUNC (inv.data) <= ' || CASE WHEN  p_dataPosicaoEstoque IS NULL THEN 'TRUNC (SYSDATE)' ELSE 'TO_DATE(''' || TO_CHAR(p_dataPosicaoEstoque, 'DD/MM/YYYY') || ''', ''DD/MM/YYYY'')' END || '
          ),
          TO_DATE (''01/01/1900'',''DD/MM/YYYY'')) dataInventario
      FROM PAESTABELECIMENTOS est'
|| CASE
     WHEN p_inEstabelecimentos IS NULL OR p_inEstabelecimentos = ' ' OR p_inEstabelecimentos = '0'
     THEN ''
     WHEN INSTR(p_inEstabelecimentos,',') = 0
     THEN '
      WHERE est.estabelecimento = ' || TRIM(TO_CHAR(p_inEstabelecimentos))
     ELSE '
      WHERE INSTR('',' || RTRIM(p_inEstabelecimentos) || ','','','' || TRIM(TO_CHAR(est.estabelecimento)) || '','') > 0'
   END
|| ') a)
  SELECT
    ''' || CASE WHEN p_uniqueMachineID IS NULL OR p_uniqueMachineID = ' ' THEN ' ' ELSE RTRIM(p_uniqueMachineID) END || ''',
    ' || TO_CHAR(p_contadorSessao) || ',
    a.gradeProduto,
    a.estabelecimento,
    a.localEstoque,
    a.indicadorPropriedadePosseItem,
    a.pessoaParticipante,
    a.personalizacao,
    a.idLoteEstoque,
    a.idEnderecoEstoque,
    a.idNumeroSerie,
    SUM(a.quantidadeFiscal) quantidadeFiscal,
    SUM(a.quantidadeGerencial) quantidadeGerencial
  FROM (
    SELECT DISTINCT
      itemInv.inventarioEstoque id,
      itemInv.gradeProduto,
      est.estabelecimento,
      itemInv.localEstoque,
      itemInv.indicadorPropriedadePosseItem,
      itemInv.pessoaParticipante,
      itemInv.personalizacao,
      itemInv.idLoteEstoque,
      itemInv.idEnderecoEstoque,
      itemInv.idNumeroSerie,
      itemInv.quantidadeFiscal,
      itemInv.quantidadeGerencial
    FROM MOINVENTARIOESTOQUEXITENS itemInv
    JOIN ESTABELECIMENTOS est ON est.inventarioEstoque = itemInv.inventarioEstoque
    JOIN CAGRADESPRODUTO gradProd ON gradProd.gradeProduto = itemInv.gradeProduto
    JOIN CAPRODUTOS prod ON prod.produto = gradProd.produto'
|| CASE
     WHEN p_joinProdutos IS NULL OR p_joinProdutos = ' '
     THEN ''
     ELSE '
    ' || RTRIM(p_joinProdutos)
   END
|| CASE
     WHEN p_joinInventarios IS NULL OR p_joinInventarios = ' '
     THEN ''
     ELSE '
    ' || RTRIM(p_joinInventarios)
   END
|| '
    WHERE itemInv.inventarioEstoque > 0
    AND itemInv.gradeProduto > 0'
|| CASE
     WHEN p_inLocaisEstoque IS NULL OR p_inLocaisEstoque = ' ' OR p_inLocaisEstoque = '0'
     THEN ''
     WHEN INSTR(p_inLocaisEstoque,',') = 0
     THEN '
    AND itemInv.localEstoque = ' || TRIM(TO_CHAR(p_inLocaisEstoque))
     ELSE '
    AND INSTR('',' || RTRIM(p_inLocaisEstoque) || ','','','' || TRIM(TO_CHAR(itemInv.localEstoque)) || '','') > 0'
   END
|| CASE
     WHEN p_andWhereProdutos IS NULL OR p_andWhereProdutos = ' '
     THEN ''
     ELSE '
    ' || RTRIM(p_andWhereProdutos)
   END
|| '
    AND NOT (EXISTS(
      SELECT 1
      FROM MOESTOQUES mov
      JOIN CAGRADESPRODUTO gradProdMov ON gradProdMov.gradeProduto = mov.gradeProduto
      WHERE gradProdMov.produto = gradProd.produto
      AND mov.estabelecimento = est.estabelecimento
      AND mov.operacaoInternaEstoque = 1
      AND TRUNC(mov.data) BETWEEN TRUNC(est.dataInventario) + 1 AND ' || CASE WHEN  p_dataPosicaoEstoque IS NULL THEN 'TRUNC (SYSDATE)' ELSE 'TO_DATE(''' || TO_CHAR(p_dataPosicaoEstoque, 'DD/MM/YYYY') || ''', ''DD/MM/YYYY'')' END || '
      ))'
|| CASE
     WHEN p_andWhereInventarios IS NULL OR p_andWhereInventarios = ' '
     THEN ''
     ELSE '
    ' || RTRIM(p_andWhereInventarios)
   END
|| '
    UNION ALL
    SELECT DISTINCT
      mov.idEstoque id,
      mov.gradeProduto,
      mov.estabelecimento,
      mov.localEstoque,
      mov.indicadorPropriedadePosseItem,
      mov.pessoaParticipante,
      mov.personalizacao,
      mov.idLoteEstoque,
      mov.idEnderecoEstoque,
      mov.idNumeroSerie,
      CASE WHEN operacaoInternaEstoque = 101 THEN 0 ELSE mov.quantidade * CASE WHEN mov.entradaSaida = ''S'' THEN -1 ELSE 1 END END quantidadeFiscal,
      mov.quantidade * CASE WHEN mov.entradaSaida = ''S'' THEN -1 ELSE 1 END quantidadeGerencial
    FROM MOESTOQUES mov
    JOIN ESTABELECIMENTOS est ON est.estabelecimento = mov.estabelecimento
    JOIN CAGRADESPRODUTO gradProd ON gradProd.gradeProduto = mov.gradeProduto
    JOIN CAPRODUTOS prod ON prod.produto = gradProd.produto'
|| CASE
     WHEN p_joinProdutos IS NULL OR p_joinProdutos = ' '
     THEN ''
     ELSE '
   ' || RTRIM(p_joinProdutos)
   END
|| CASE
     WHEN p_joinMovimentos IS NULL OR p_joinMovimentos = ' '
     THEN ''
     ELSE '
    ' || RTRIM(p_joinMovimentos)
   END
|| '
    WHERE mov.idEstoque > 0
    AND mov.gradeProduto > 0'
|| CASE
     WHEN p_inLocaisEstoque IS NULL OR p_inLocaisEstoque = ' ' OR p_inLocaisEstoque = '0'
     THEN ''
     WHEN INSTR(p_inLocaisEstoque,',') = 0
     THEN '
    AND mov.localEstoque = ' || TRIM(TO_CHAR(p_inLocaisEstoque))
     ELSE '
    AND INSTR('',' || RTRIM(p_inLocaisEstoque) || ','','','' || TRIM(TO_CHAR(mov.localEstoque)) || '','') > 0'
   END
|| CASE
     WHEN p_andWhereProdutos IS NULL OR p_andWhereProdutos = ' '
     THEN ''
     ELSE '
    ' || RTRIM(p_andWhereProdutos)
   END
|| '
    AND TRUNC(mov.data) BETWEEN COALESCE(
      ( SELECT MAX (movIni.data)
        FROM MOESTOQUES movIni
        JOIN CAGRADESPRODUTO gradProdIni ON gradProdIni.gradeProduto = movIni.gradeProduto
        WHERE gradProdIni.produto = gradProd.produto
        AND movIni.estabelecimento = mov.estabelecimento
        AND movIni.operacaoInternaEstoque = 1
        AND TRUNC(movIni.data) BETWEEN
          CASE
            WHEN est.inventarioEstoque > 0 AND NOT (est.dataInventario IS NULL)
            THEN TRUNC (est.dataInventario) + 1
            ELSE TO_DATE (''01/01/1900'',''DD/MM/YYYY'')
          END
          AND ' || CASE WHEN  p_dataPosicaoEstoque IS NULL THEN 'TRUNC (SYSDATE)' ELSE 'TO_DATE(''' || TO_CHAR(p_dataPosicaoEstoque, 'DD/MM/YYYY') || ''', ''DD/MM/YYYY'')' END || '
      ),
      ( CASE
          WHEN est.inventarioEstoque > 0 AND NOT (est.dataInventario IS NULL)
          THEN TRUNC (est.dataInventario) + 1
          ELSE TO_DATE (''01/01/1900'',''DD/MM/YYYY'')
        END))
      AND ' || CASE WHEN  p_dataPosicaoEstoque IS NULL THEN 'TRUNC (SYSDATE)' ELSE 'TO_DATE(''' || TO_CHAR(p_dataPosicaoEstoque, 'DD/MM/YYYY') || ''', ''DD/MM/YYYY'')' END
|| CASE
     WHEN p_andWhereMovimentos IS NULL OR p_andWhereMovimentos = ' '
     THEN ''
     ELSE '
   ' || RTRIM(p_andWhereMovimentos)
   END
|| '
  ) a
  GROUP BY
    a.gradeProduto,
    a.estabelecimento,
    a.localEstoque,
    a.indicadorPropriedadePosseItem,
    a.pessoaParticipante,
    a.personalizacao,
    a.idLoteEstoque,
    a.idEnderecoEstoque,
    a.idNumeroSerie';
END ADD_GERA_TEMP_ESTOQUE;

/

create or replace FUNCTION FUNC_ADD_BUSCA_ESTOQUE_PRODUTO(
    p_dataPosicaoEstoque          IN DATE,
    p_gradeProduto                IN NUMBER,
    p_estabelecimento             IN NUMBER,
    p_idInventarioEstoque         IN NUMBER,
    p_dataInventario              IN DATE,
    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, P = Pré-Documento
    p_idDocumentoDesconsiderar    IN NUMBER,
    p_estoqueFiscal               IN NUMBER)
  RETURN NUMBER
IS
  v_dataPosicaoEstoqueInicial DATE;
  v_quantidadeInventario      NUMBER (15,6);
  v_quantidadeEstoque         NUMBER (15,6);
  v_quantidadeDocFisc         NUMBER (15,6);
  v_quantidadePreDoc          NUMBER (15,6);
BEGIN
  v_quantidadeInventario      := 0;
  v_quantidadeEstoque         := 0;
  v_quantidadeDocFisc         := 0;
  v_quantidadePreDoc          := 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_idInventarioEstoque,
        p_dataInventario,
        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_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 (p_idInventarioEstoque <= 0
		  OR TRUNC(est.data) > TRUNC(p_dataInventario))),
      CASE
        WHEN p_idInventarioEstoque > 0 AND NOT (p_dataInventario IS NULL)
        THEN TRUNC (p_dataInventario) + 1
        ELSE TO_DATE ('01/01/1900','DD/MM/YYYY')
      END)
    INTO v_dataPosicaoEstoqueInicial
    FROM DUAL;
    -- v_quantidadeInventario
    IF p_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 = p_idInventarioEstoque
        AND est.gradeProduto = p_gradeProduto
        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 = p_idNumeroSerie)),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 = p_idNumeroSerie)
        AND (p_estoqueFiscal = 0
		  OR est.operacaoInternaEstoque <> 101)),0)
      INTO v_quantidadeEstoque
      FROM DUAL;
    ELSE
      v_quantidadeEstoque := 0;
    END IF;
    -- v_quantidadeDocFisc
    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_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 = p_idNumeroSerie)
        AND (p_estoqueFiscal = 0
		  OR est.operacaoInternaEstoque <> 101)),0)
      INTO v_quantidadeDocFisc
      FROM DUAL;
    ELSE
      v_quantidadeDocFisc := 0;
    END IF;
    -- v_quantidadePreDoc
    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_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 = p_idNumeroSerie)
        AND (p_estoqueFiscal = 0
		  OR est.operacaoInternaEstoque <> 101)),0)
      INTO v_quantidadePreDoc
      FROM DUAL;
    ELSE
      v_quantidadePreDoc := 0;
    END IF;
  END IF;
  RETURN v_quantidadeInventario + v_quantidadeEstoque - v_quantidadeDocFisc - v_quantidadePreDoc;
END;

/

create or replace FUNCTION FUNC_ADD_BUSCA_PRECO_KIT(
    p_config_209_filtrarGrupoEcon  IN NUMBER,
    p_config_362_calcCustoPorGrade IN NUMBER,
    p_perfilUsuarioLogado          IN NUMBER,
    p_usuarioLogado                IN NUMBER,
    p_cab_entradaSaida             IN CHAR,
    p_cab_devolucaoAnulacaoRetorno IN NUMBER,
    p_cab_estabelecimento          IN NUMBER,
    p_cab_dataPrecoInicial         IN DATE,
    p_cab_dataPrecoFinal           IN DATE,
    p_cab_pessoa                   IN NUMBER,
    p_modDoc_capituloNaturezaFisc  IN NUMBER,
    p_endPessEst_uf                IN CHAR,
    p_endPess_uf                   IN CHAR,
    p_item_vendedor                IN NUMBER,
    p_item_personalizacao          IN NUMBER,
    p_item_localEstoque            IN NUMBER,
    p_item_pessoaParticipante      IN NUMBER,
    p_item_quantidade              IN NUMBER,
    p_gradProd_produto             IN NUMBER,
    p_locEst_indicadorPropPosseIt  IN CHAR,
    p_manterPreco                  IN NUMBER,
    p_tipoPreco                    IN CHAR,
    p_tabelaPreco                  IN VARCHAR
  )
  RETURN NUMBER
IS 
  v_preco      NUMBER;
  v_precoFilho NUMBER;

  CURSOR c_kit
  IS 
    SELECT 
      kit.quantidade,
      gradProdFilho.produto,
      gradProdFilho.cor,
      gradProdFilho.tamanho,
      prodFilho.controleEstoque
    FROM CAGRADEPRODUTOXKITSCOMBOS kit
    JOIN CAGRADESPRODUTO gradProdPai ON gradProdPai.gradeProduto = kit.gradeProduto
    JOIN CAGRADESPRODUTO gradProdFilho ON gradProdFilho.gradeProduto = kit.gradeProdutoFilho
    JOIN CAPRODUTOS prodFilho ON prodFilho.produto = gradProdFilho.produto
    WHERE gradProdPai.produto = p_gradProd_produto
    AND kit.gradeProdutoFilho > 0
    AND kit.ativo = 1
    AND kit.quantidade > 0
    AND kit.gradeProduto <> kit.gradeProdutoFilho;

BEGIN
  v_preco := 0;
  FOR kit IN c_kit LOOP
    v_precoFilho := 0;
    -- A Tabela de Preço Anterior
    IF p_tipoPreco = 'A' THEN
      v_precoFilho := FUNC_ADD_BUSCA_PRECO_ANTERIOR(
        p_perfilUsuarioLogado,
        p_usuarioLogado,
        p_cab_entradaSaida,
        p_cab_devolucaoAnulacaoRetorno,
        p_cab_estabelecimento,
        p_cab_dataPrecoFinal,
        p_cab_pessoa,
        p_modDoc_capituloNaturezaFisc,
        p_endPessEst_uf,
        p_endPess_uf,
        p_item_vendedor,
        p_item_personalizacao,
        p_item_localEstoque,
        kit.quantidade * p_item_quantidade,
        kit.produto,
        kit.cor,
        kit.tamanho,
        p_manterPreco,
        p_tabelaPreco);
    -- C Custo Médio da Venda (CMV)
    ELSIF p_tipoPreco = 'C' AND NOT(kit.controleEstoque IN (3,4)) THEN
      v_precoFilho := FUNC_ADD_BUSCA_PRECO_MEDIO(
        p_config_209_filtrarGrupoEcon,
        p_config_362_calcCustoPorGrade,
        p_cab_estabelecimento,
        p_cab_dataPrecoFinal,
        0, -- p_item_personalizacao
        kit.produto,
        kit.cor,
        kit.tamanho,
        p_locEst_indicadorPropPosseIt,
        p_item_pessoaParticipante,
        0,
        0);
    -- F Formação Preço (Custo)
    ELSIF p_tipoPreco = 'F' THEN
      v_precoFilho := FUNC_ADD_BUSCA_PRECO_FORMACAO(
        p_config_209_filtrarGrupoEcon,
        p_config_362_calcCustoPorGrade,
        p_cab_estabelecimento,
        p_cab_dataPrecoInicial,
        p_cab_dataPrecoFinal,
        0, -- p_item_personalizacao
        kit.produto,
        kit.cor,
        kit.tamanho);
    -- G Custo Médio da Venda Gerencial (CMV)
    ELSIF p_tipoPreco = 'G' AND NOT(kit.controleEstoque IN (3,4)) THEN
      v_precoFilho := FUNC_ADD_BUSCA_PRECO_MEDIO(
        p_config_209_filtrarGrupoEcon,
        p_config_362_calcCustoPorGrade,
        p_cab_estabelecimento,
        p_cab_dataPrecoFinal,
        0, -- p_item_personalizacao
        kit.produto,
        kit.cor,
        kit.tamanho,
        p_locEst_indicadorPropPosseIt,
        p_item_pessoaParticipante,
        1,
        0);
    -- P Preço de Custo (Último Custo)
    ELSIF p_tipoPreco = 'P' THEN
      v_precoFilho := FUNC_ADD_BUSCA_PRECO_ULT_CUSTO(
        p_config_209_filtrarGrupoEcon,
        p_config_362_calcCustoPorGrade,
        p_cab_estabelecimento,
        p_cab_dataPrecoInicial,
        p_cab_dataPrecoFinal,
        0, -- p_item_personalizacao
        kit.produto,
        kit.cor,
        kit.tamanho,
        p_locEst_indicadorPropPosseIt,
        p_item_pessoaParticipante);
    -- T Tabela de Preço
    ELSIF p_tipoPreco = 'T' THEN
      v_precoFilho := FUNC_ADD_BUSCA_PRECO_TABELA(
        p_perfilUsuarioLogado,
        p_usuarioLogado,
        p_cab_entradaSaida,
        p_cab_devolucaoAnulacaoRetorno,
        p_cab_estabelecimento,
        p_cab_dataPrecoFinal,
        p_cab_pessoa,
        p_modDoc_capituloNaturezaFisc,
        p_endPessEst_uf,
        p_endPess_uf,
        p_item_vendedor,
        p_item_personalizacao,
        p_item_localEstoque,
        kit.quantidade * p_item_quantidade,
        kit.produto,
        kit.cor,
        kit.tamanho,
        p_manterPreco,
        p_tabelaPreco);
    -- U Última Compra
    ELSIF p_tipoPreco = 'U' THEN
      v_precoFilho := FUNC_ADD_BUSCA_PRECO_ULT_COMPR(
        p_config_209_filtrarGrupoEcon,
        p_config_362_calcCustoPorGrade,
        p_cab_estabelecimento,
        p_cab_dataPrecoInicial,
        p_cab_dataPrecoFinal,
        0, -- p_item_personalizacao
        kit.produto,
        kit.cor,
        kit.tamanho,
        0);
    -- 2 Última Compra Bruto
    ELSIF p_tipoPreco = '2' THEN
      v_precoFilho := FUNC_ADD_BUSCA_PRECO_ULT_COMPR(
        p_config_209_filtrarGrupoEcon,
        p_config_362_calcCustoPorGrade,
        p_cab_estabelecimento,
        p_cab_dataPrecoInicial,
        p_cab_dataPrecoFinal,
        0, -- p_item_personalizacao
        kit.produto,
        kit.cor,
        kit.tamanho,
        1);
    END IF;
    -- 3 = Combo / 4 = Kit
    IF v_precoFilho = 0 AND kit.controleEstoque IN (3,4) THEN
      v_precoFilho := FUNC_ADD_BUSCA_PRECO_KIT(
        p_config_209_filtrarGrupoEcon,
        p_config_362_calcCustoPorGrade,
        p_perfilUsuarioLogado,
        p_usuarioLogado,
        p_cab_entradaSaida,
        p_cab_devolucaoAnulacaoRetorno,
        p_cab_estabelecimento,
        p_cab_dataPrecoInicial,
        p_cab_dataPrecoFinal,
        p_cab_pessoa,
        p_modDoc_capituloNaturezaFisc,
        p_endPessEst_uf,
        p_endPess_uf,
        p_item_vendedor,
        p_item_personalizacao,
        p_item_localEstoque,
        p_item_pessoaParticipante,
        kit.quantidade * p_item_quantidade,
        kit.produto,
        p_locEst_indicadorPropPosseIt,
        p_manterPreco,
        p_tipoPreco,
        p_tabelaPreco);
    END IF;
    IF v_precoFilho <> 0 THEN
      v_preco := v_preco + kit.quantidade * v_precoFilho;
    ELSE
      v_preco := 0;
    END IF;        
    EXIT WHEN v_preco = 0;
  END LOOP;
  RETURN v_preco;
END;

/

create or replace FUNCTION FUNC_ADD_BUSCA_TABELA_PRECO(
    p_perfilUsuarioLogado          IN NUMBER,
    p_usuarioLogado                IN NUMBER,
    p_cab_estabelecimento          IN NUMBER,
    p_cab_dataPreco                IN DATE,
    p_cab_pessoa                   IN NUMBER,
    p_endPessEst_uf                IN CHAR,
    p_endPess_uf                   IN CHAR,
    p_item_vendedor                IN NUMBER,
    p_grade_produto                IN NUMBER,
    p_grade_cor                    IN NUMBER,
    p_grade_tamanho                IN VARCHAR,
    p_prod_controleEstoque         IN NUMBER
  )
  RETURN CHAR
IS
  v_tabelaPreco CHAR(10);

  CURSOR c_kit
  IS 
    SELECT 
      kit.quantidade,
      gradProdFilho.produto,
      gradProdFilho.cor,
      gradProdFilho.tamanho,
      prodFilho.controleEstoque
    FROM CAGRADEPRODUTOXKITSCOMBOS kit
    JOIN CAGRADESPRODUTO gradProdPai ON gradProdPai.gradeProduto = kit.gradeProduto
    JOIN CAGRADESPRODUTO gradProdFilho ON gradProdFilho.gradeProduto = kit.gradeProdutoFilho
    JOIN CAPRODUTOS prodFilho ON prodFilho.produto = gradProdFilho.produto
    WHERE gradProdPai.produto = p_grade_produto
    AND kit.gradeProdutoFilho > 0
    AND kit.ativo = 1
    AND kit.quantidade > 0
    AND kit.gradeProduto <> kit.gradeProdutoFilho;

BEGIN
  IF p_prod_controleEstoque IN (3,4) THEN
  FOR kit IN c_kit LOOP
    v_tabelaPreco := FUNC_ADD_BUSCA_TABELA_PRECO(
      p_perfilUsuarioLogado,
      p_usuarioLogado,
      p_cab_estabelecimento,
      p_cab_dataPreco,
      p_cab_pessoa,
      p_endPessEst_uf,
      p_endPess_uf,
      p_item_vendedor,
      kit.produto,
      kit.cor,
      kit.tamanho,
      kit.controleEstoque);    
    EXIT WHEN v_tabelaPreco = ' ';
  END LOOP;
  ELSE
    SELECT COALESCE(MAX(a.tabelaPreco),' ') tabelaPreco
    INTO v_tabelaPreco
    FROM(
      SELECT a.tabelaPreco
      FROM (
        SELECT 
          a.tabelaPreco,
          ROW_NUMBER() OVER (ORDER BY tabela.ordenacao, a.tabelaPreco, a.ordenacao, a.idPrecoTabela) ordenacao
        FROM CATABELAPRECOXPRECOS a
        JOIN PATABELASPRECO tabela ON tabela.tabelaPreco = a.tabelaPreco
        JOIN PAFILTROSCABECALHO filtroCab ON filtroCab.filtroCabecalho = tabela.filtroCabecalho
        WHERE a.produto = p_grade_produto
        AND a.tabelaPreco <> ' '
        AND a.ativo = 1
        AND a.quantidadeMinima <= 1
        AND a.quantidadeMaxima >= 1
        AND a.dataValidadeInicial <= p_cab_dataPreco
        AND a.dataValidadeFinal >= p_cab_dataPreco
        AND (p_grade_cor = 0 AND a.filtrarCores = 0 OR p_grade_cor > 0 AND (a.filtrarCores = 0 OR EXISTS (SELECT 1 FROM CATABELAPRECOXCORES tabcor WHERE tabcor.idPrecoTabela = a.idPrecoTabela AND tabcor.cor = p_grade_cor AND tabcor.ativo = 1)))
        AND (p_grade_tamanho = ' ' AND a.filtrarTamanhos = 0 OR p_grade_tamanho <> ' ' AND (a.filtrarTamanhos = 0 OR EXISTS (SELECT 1 FROM CATABELAPRECOXTAMANHOS tabtam WHERE tabtam.idPrecoTabela = a.idPrecoTabela AND tabtam.tamanho = p_grade_tamanho AND tabtam.ativo = 1)))
        AND a.filtrarPersonalizacoes = 0
        AND tabela.ativo = 1 
        AND tabela.validoParaVenda = 1
        AND (tabela.filtrarVendedores = 0 OR EXISTS (SELECT 1 FROM PATABELAPRECOXVENDEDORES tabVend WHERE tabVend.tabelaPreco = tabela.tabelaPreco AND tabVend.vendedor = p_item_vendedor AND tabVend.ativo = 1))
        AND tabela.filtrarLocaisEstoque = 0
        AND (filtroCab.filtrarEstabelecimentos = 0 OR EXISTS (SELECT 1 FROM PAFILTROCABECXESTABELEC filCabEst WHERE filCabEst.filtroCabecalho = tabela.filtroCabecalho AND filCabEst.estabelecimento = p_cab_estabelecimento AND filCabEst.ativo = 1))
        AND (filtroCab.filtrarUfs = 0 OR EXISTS (SELECT 1 FROM PAFILTROCABECXUFS filCabUf WHERE filCabUf.filtroCabecalho = tabela.filtroCabecalho AND filCabUf.uf = CASE WHEN p_cab_pessoa = 0 THEN p_endPessEst_uf ELSE p_endPess_uf END AND filCabUf.ativo = 1))
        AND (filtroCab.filtrarPessoas = 0 OR EXISTS (SELECT 1 FROM PAFILTROCABECXPESSOAS filCabPess WHERE filCabPess.filtroCabecalho = tabela.filtroCabecalho AND filCabPess.pessoa = p_cab_pessoa AND filCabPess.ativo = 1))
        AND (filtroCab.filtrarPerfisUsuario = 0 AND filtroCab.filtrarUsuarios = 0
          OR filtroCab.filtrarPerfisUsuario = 1 AND EXISTS (SELECT 1 FROM PAFILTROCABECXPERFISUSUAR filCabPerfUs WHERE filCabPerfUs.filtroCabecalho = tabela.filtroCabecalho AND filCabPerfUs.perfilUsuario = p_perfilUsuarioLogado AND filCabPerfUs.ativo = 1)
          OR filtroCab.filtrarUsuarios = 1 AND EXISTS (SELECT 1 FROM PAFILTROCABECXUSUARIOS filCabUs WHERE filCabUs.filtroCabecalho = tabela.filtroCabecalho AND filCabUs.usuario = p_usuarioLogado AND filCabUs.ativo = 1))
      ) a
      WHERE a.ordenacao = 1  
    ) a;
  END IF;
  RETURN v_tabelaPreco;
END;

/

create or replace PROCEDURE ADD_BUSCA_PRECO_INTERNO_KIT(
    p_config_209_filtrarGrupoEcon  IN NUMBER,
    p_config_362_calcCustoPorGrade IN NUMBER,
    p_perfilUsuarioLogado          IN NUMBER,
    p_usuarioLogado                IN NUMBER,
    p_cab_entradaSaida             IN CHAR,
    p_cab_devolucaoAnulacaoRetorno IN NUMBER,
    p_cab_estabelecimento          IN NUMBER,
    p_cab_dataPrecoInicial         IN DATE,
    p_cab_dataPrecoFinal           IN DATE,
    p_cab_pessoa                   IN NUMBER,
    p_modDoc_capituloNaturezaFisc  IN NUMBER,
    p_endPessEst_uf                IN CHAR,
    p_endPess_uf                   IN CHAR,
    p_item_vendedor                IN NUMBER,
    p_item_personalizacao          IN NUMBER,
    p_item_localEstoque            IN NUMBER,
    p_item_pessoaParticipante      IN NUMBER,
    p_item_quantidade              IN NUMBER,
    p_gradProd_produto                IN NUMBER,
    p_locEst_indicadorPropPosseIt  IN CHAR,
    p_manterPreco                  IN NUMBER,
    p_tipoPreco                    IN CHAR,
    p_tabelaPreco                  IN VARCHAR,
    r_tabelaPreco                  OUT VARCHAR,
    r_precoSugestaoAPrazo          OUT NUMBER,
    r_precoSugestaoAVista          OUT NUMBER,
    r_precoDesconto                OUT NUMBER,
    r_precoMinimo                  OUT NUMBER,
    r_informarPrecoManualmente     OUT NUMBER,
    r_precoAPrazo                  OUT NUMBER,
    r_precoAVista                  OUT NUMBER,
    r_promocao                     OUT NUMBER,
    r_precoPromocaoAPrazo          OUT NUMBER,
    r_precoPromocaoAVista          OUT NUMBER,
    r_precoIndexadoAPrazo          OUT NUMBER,
    r_precoIndexadoAVista          OUT NUMBER)

IS
  v_tabelaPreco              VARCHAR (10);
  v_precoSugestaoAPrazo      NUMBER;
  v_precoSugestaoAVista      NUMBER;
  v_precoDesconto            NUMBER;
  v_precoMinimo              NUMBER;
  v_informarPrecoManualmente NUMBER;
  v_precoAPrazo              NUMBER;
  v_precoAVista              NUMBER;
  v_promocao                 NUMBER;
  v_precoPromocaoAPrazo      NUMBER;
  v_precoPromocaoAVista      NUMBER;
  v_precoIndexadoAPrazo      NUMBER;
  v_precoIndexadoAVista      NUMBER;

  CURSOR c_kit
  IS 
    SELECT 
      kit.quantidade,
      gradProdFilho.produto,
      gradProdFilho.cor,
      gradProdFilho.tamanho,
      prodFilho.controleEstoque
    FROM CAGRADEPRODUTOXKITSCOMBOS kit
    JOIN CAGRADESPRODUTO gradProdPai ON gradProdPai.gradeProduto = kit.gradeProduto
    JOIN CAGRADESPRODUTO gradProdFilho ON gradProdFilho.gradeProduto = kit.gradeProdutoFilho
    JOIN CAPRODUTOS prodFilho ON prodFilho.produto = gradProdFilho.produto
    WHERE gradProdPai.produto = p_gradProd_produto
    AND kit.gradeProdutoFilho > 0
    AND kit.ativo = 1
    AND kit.quantidade > 0
    AND kit.gradeProduto <> kit.gradeProdutoFilho;

BEGIN
  r_tabelaPreco := ' ';
  r_precoSugestaoAPrazo := 0;
  r_precoSugestaoAVista := 0;
  r_precoDesconto := 0;
  r_precoMinimo := 0;
  r_informarPrecoManualmente := 0;
  r_precoAPrazo := 0;
  r_precoAVista := 0;
  r_promocao := 0;
  r_precoPromocaoAPrazo := 0;
  r_precoPromocaoAVista := 0;
  r_precoIndexadoAPrazo := 0;
  r_precoIndexadoAVista := 0;

  FOR kit IN c_kit LOOP
    v_tabelaPreco              := ' ';
    v_precoSugestaoAPrazo      := 0;
    v_precoSugestaoAVista      := 0;
    v_precoDesconto            := 0;
    v_precoMinimo              := 0;
    v_informarPrecoManualmente := 0;
    v_precoAPrazo              := 0;
    v_precoAVista              := 0;
    v_promocao                 := 0;
    v_precoPromocaoAPrazo      := 0;
    v_precoPromocaoAVista      := 0;
    v_precoIndexadoAPrazo      := 0;
    v_precoIndexadoAVista      := 0;
    -- A Tabela de Preço Anterior
    IF p_tipoPreco = 'A' THEN
      ADD_BUSCA_PRECO_INTERNO_ANTER(
        p_perfilUsuarioLogado,
        p_usuarioLogado,
        p_cab_entradaSaida,
        p_cab_devolucaoAnulacaoRetorno,
        p_cab_estabelecimento,
        p_cab_dataPrecoFinal,
        p_cab_pessoa,
        p_modDoc_capituloNaturezaFisc,
        p_endPessEst_uf,
        p_endPess_uf,
        p_item_vendedor,
        p_item_personalizacao,
        p_item_localEstoque,
        kit.quantidade * p_item_quantidade,
        kit.produto,
        kit.cor,
        kit.tamanho,
        p_manterPreco,
        0, --p_precoSugestaoAPrazoOriginal,
        0, --p_precoSugestaoAVistaOriginal,
        p_tabelaPreco,
        v_tabelaPreco,
        v_precoSugestaoAPrazo,
        v_precoSugestaoAVista,
        v_precoDesconto,
        v_precoMinimo,
        v_informarPrecoManualmente,
        v_precoAPrazo,
        v_precoAVista,
        v_promocao,
        v_precoPromocaoAPrazo,
        v_precoPromocaoAVista,
        v_precoIndexadoAPrazo,
        v_precoIndexadoAVista);
    -- C Custo Médio da Venda (CMV)
    ELSIF p_tipoPreco = 'C' AND NOT(kit.controleEstoque IN (3,4)) THEN
      v_precoSugestaoAPrazo := FUNC_ADD_BUSCA_PRECO_MEDIO(
        p_config_209_filtrarGrupoEcon,
        p_config_362_calcCustoPorGrade,
        p_cab_estabelecimento,
        p_cab_dataPrecoFinal,
        0, --p_item_personalizacao
        kit.produto,
        kit.cor,
        kit.tamanho,
        p_locEst_indicadorPropPosseIt,
        p_item_pessoaParticipante,
        0,
        0);
    -- F Formação Preço (Custo)
    ELSIF p_tipoPreco = 'F' THEN
      v_precoSugestaoAPrazo := FUNC_ADD_BUSCA_PRECO_FORMACAO(
        p_config_209_filtrarGrupoEcon,
        p_config_362_calcCustoPorGrade,
        p_cab_estabelecimento,
        p_cab_dataPrecoInicial,
        p_cab_dataPrecoFinal,
        0, --p_item_personalizacao
        kit.produto,
        kit.cor,
        kit.tamanho);
    -- G Custo Médio da Venda Gerencial (CMV)
    ELSIF p_tipoPreco = 'G' AND NOT(kit.controleEstoque IN (3,4)) THEN
      v_precoSugestaoAPrazo := FUNC_ADD_BUSCA_PRECO_MEDIO(
        p_config_209_filtrarGrupoEcon,
        p_config_362_calcCustoPorGrade,
        p_cab_estabelecimento,
        p_cab_dataPrecoFinal,
        0, --p_item_personalizacao
        kit.produto,
        kit.cor,
        kit.tamanho,
        p_locEst_indicadorPropPosseIt,
        p_item_pessoaParticipante,
        1,
        0);
    -- P Preço de Custo (Último Custo)
    ELSIF p_tipoPreco = 'P' THEN
      v_precoSugestaoAPrazo := FUNC_ADD_BUSCA_PRECO_ULT_CUSTO(
        p_config_209_filtrarGrupoEcon,
        p_config_362_calcCustoPorGrade,
        p_cab_estabelecimento,
        p_cab_dataPrecoInicial,
        p_cab_dataPrecoFinal,
        0, --p_item_personalizacao
        kit.produto,
        kit.cor,
        kit.tamanho,
        p_locEst_indicadorPropPosseIt,
        p_item_pessoaParticipante);
    -- T Tabela de Preço
    ELSIF p_tipoPreco = 'T' THEN
      ADD_BUSCA_PRECO_INTERNO_TABELA(
        p_perfilUsuarioLogado,
        p_usuarioLogado,
        p_cab_entradaSaida,
        p_cab_devolucaoAnulacaoRetorno,
        p_cab_estabelecimento,
        p_cab_dataPrecoFinal,
        p_cab_pessoa,
        p_modDoc_capituloNaturezaFisc,
        p_endPessEst_uf,
        p_endPess_uf,
        p_item_vendedor,
        p_item_personalizacao,
        p_item_localEstoque,
        kit.quantidade * p_item_quantidade,
        kit.produto,
        kit.cor,
        kit.tamanho,
        p_manterPreco,
        0, --p_precoSugestaoAPrazoOriginal,
        0, --p_precoSugestaoAVistaOriginal,
        p_tabelaPreco,
        v_tabelaPreco,
        v_precoSugestaoAPrazo,
        v_precoSugestaoAVista,
        v_precoDesconto,
        v_precoMinimo,
        v_informarPrecoManualmente,
        v_precoAPrazo,
        v_precoAVista,
        v_promocao,
        v_precoPromocaoAPrazo,
        v_precoPromocaoAVista,
        v_precoIndexadoAPrazo,
        v_precoIndexadoAVista);
    -- U Última Compra
    ELSIF p_tipoPreco = 'U' THEN
      v_precoSugestaoAPrazo := FUNC_ADD_BUSCA_PRECO_ULT_COMPR(
        p_config_209_filtrarGrupoEcon,
        p_config_362_calcCustoPorGrade,
        p_cab_estabelecimento,
        p_cab_dataPrecoInicial,
        p_cab_dataPrecoFinal,
        0, --p_item_personalizacao
        kit.produto,
        kit.cor,
        kit.tamanho,
        0);
    -- 2 Última Compra Bruto
    ELSIF p_tipoPreco = '2' THEN
      v_precoSugestaoAPrazo := FUNC_ADD_BUSCA_PRECO_ULT_COMPR(
        p_config_209_filtrarGrupoEcon,
        p_config_362_calcCustoPorGrade,
        p_cab_estabelecimento,
        p_cab_dataPrecoInicial,
        p_cab_dataPrecoFinal,
        0, --p_item_personalizacao
        kit.produto,
        kit.cor,
        kit.tamanho,
        1);
    END IF;
    IF NOT(p_tipoPreco IN ('A','T')) THEN
      v_tabelaPreco              := ' ';
      v_precoSugestaoAVista      := v_precoSugestaoAPrazo;
      v_precoDesconto            := 0;
      v_precoMinimo              := 0;
      v_informarPrecoManualmente := 0;
      v_precoAPrazo              := v_precoSugestaoAPrazo;
      v_precoAVista              := v_precoSugestaoAPrazo;
      v_promocao                 := 0;
      v_precoPromocaoAPrazo      := v_precoSugestaoAPrazo;
      v_precoPromocaoAVista      := v_precoSugestaoAPrazo;
      v_precoIndexadoAPrazo      := v_precoSugestaoAPrazo;
      v_precoIndexadoAVista      := v_precoSugestaoAPrazo;
    END IF;  
    -- 3 = Combo / 4 = Kit
    IF v_precoSugestaoAPrazo = 0 AND kit.controleEstoque IN (3,4) THEN
      ADD_BUSCA_PRECO_INTERNO_KIT(
        p_config_209_filtrarGrupoEcon,
        p_config_362_calcCustoPorGrade,
        p_perfilUsuarioLogado,
        p_usuarioLogado,
        p_cab_entradaSaida,
        p_cab_devolucaoAnulacaoRetorno,
        p_cab_estabelecimento,
        p_cab_dataPrecoInicial,
        p_cab_dataPrecoFinal,
        p_cab_pessoa,
        p_modDoc_capituloNaturezaFisc,
        p_endPessEst_uf,
        p_endPess_uf,
        p_item_vendedor,
        p_item_personalizacao,
        p_item_localEstoque,
        p_item_pessoaParticipante,
        kit.quantidade * p_item_quantidade,
        kit.produto,
        p_locEst_indicadorPropPosseIt,
        p_manterPreco,
        p_tipoPreco,
        p_tabelaPreco,
        v_tabelaPreco,
        v_precoSugestaoAPrazo,
        v_precoSugestaoAVista,
        v_precoDesconto,
        v_precoMinimo,
        v_informarPrecoManualmente,
        v_precoAPrazo,
        v_precoAVista,
        v_promocao,
        v_precoPromocaoAPrazo,
        v_precoPromocaoAVista,
        v_precoIndexadoAPrazo,
        v_precoIndexadoAVista);
    END IF;
    IF v_precoSugestaoAPrazo <> 0 THEN
      r_tabelaPreco         := v_tabelaPreco;
      r_precoSugestaoAPrazo := r_precoSugestaoAPrazo + kit.quantidade * v_precoSugestaoAPrazo;
      r_precoSugestaoAVista := r_precoSugestaoAVista + kit.quantidade * v_precoSugestaoAVista;
      r_precoDesconto       := r_precoDesconto       + kit.quantidade * v_precoDesconto;
      r_precoMinimo         := r_precoMinimo         + kit.quantidade * v_precoMinimo;
      r_precoAPrazo         := r_precoAPrazo         + kit.quantidade * v_precoAPrazo;
      r_precoAVista         := r_precoAVista         + kit.quantidade * v_precoAVista;
      IF v_promocao = 1 THEN
        r_promocao          := 1;
      END IF;  
      r_precoPromocaoAPrazo := r_precoPromocaoAPrazo + kit.quantidade * v_precoPromocaoAPrazo;
      r_precoPromocaoAVista := r_precoPromocaoAVista + kit.quantidade * v_precoPromocaoAVista;
      r_precoIndexadoAPrazo := r_precoIndexadoAPrazo + kit.quantidade * v_precoIndexadoAPrazo;
      r_precoIndexadoAVista := r_precoIndexadoAVista + kit.quantidade * v_precoIndexadoAVista;
    ELSE
      r_tabelaPreco         := ' ';
      r_precoSugestaoAPrazo := 0;
      r_precoSugestaoAVista := 0;
      r_precoDesconto       := 0;
      r_precoMinimo         := 0;
      r_precoAPrazo         := 0;
      r_precoAVista         := 0;
      r_promocao            := 0;
      r_precoPromocaoAPrazo := 0;
      r_precoPromocaoAVista := 0;
      r_precoIndexadoAPrazo := 0;
      r_precoIndexadoAVista := 0;
    END IF;        
    EXIT WHEN r_precoSugestaoAPrazo = 0;
  END LOOP;
END ADD_BUSCA_PRECO_INTERNO_KIT;

/

create or replace PROCEDURE ADD_ESTOQUE_KIT(
    p_config_209_filtrarGrupoEcon  IN NUMBER,
    p_config_362_calcCustoPorGrade IN NUMBER,
    p_bufferIdEstoque              IN VARCHAR2,
    p_estabelecimentoAtivo         IN NUMBER,
    p_cab_modeloDocumento          IN NUMBER,
    p_cab_operacaoInternaEstoque   IN NUMBER,
    p_cab_atualizaCustoMedio       IN NUMBER,
    p_cab_atualizaUltimaCompra     IN NUMBER,
    p_cab_entradaSaida             IN CHAR,
    p_cab_estabelecimento          IN NUMBER,
    p_cab_dataEmissao              IN DATE,
    p_cab_dataEntradaSaida         IN DATE,
    p_modDoc_geraTransferencia     IN NUMBER,
    p_modDoc_geraOperacaoEmTransit IN NUMBER,
    p_modDoc_transitoLocalEstoque  IN NUMBER,
    p_locEstTransito_indicProprPos IN CHAR,
    p_item_gradeProduto            IN NUMBER,
    p_item_localEstoque            IN NUMBER,
    p_item_pessoaParticipante      IN NUMBER,
    p_item_quantidade              IN NUMBER,
    p_item_valorCustoOperacao      IN NUMBER,
    p_item_observacoes             IN VARCHAR2,
    p_idEnderecoEstoque            IN NUMBER,
    p_locEst_indicProprPosseItem   IN CHAR,
    p_idItemPreDocumento           IN NUMBER,
    p_idItemDocFiscal              IN NUMBER,
    p_idItemSeparacao              IN NUMBER,
    p_divergenciaBalanco           IN NUMBER,
    p_idItemDocTransferencia       IN NUMBER,
    p_docTransf_estabelecEntrada   IN NUMBER,
    p_docTransf_estabelecSaida     IN NUMBER,
    r_bufferIdEstoque              OUT VARCHAR2)
IS
  v_quantidadeRateioTotal NUMBER;
  v_quantSaldoRateioTotal NUMBER;
  v_valorSaldoRateioTotal NUMBER;
  v_valorCustoManter      NUMBER;
  v_precoCustoKit         NUMBER;
  v_valorCustoKit         NUMBER;
  CURSOR c_kit IS 
    SELECT 
      kit.gradeProdutoFilho,
      kit.manterUltimoCusto,
      gradProdFilho.produto,
      prodFilho.controleEstoque,
      ROUND(p_item_quantidade * kit.quantidade, uniFilho.casasDecimaisUnidadeMedida) quantidade
    FROM CAGRADEPRODUTOXKITSCOMBOS kit 
    JOIN CAGRADESPRODUTO gradProdFilho ON gradProdFilho.gradeProduto = kit.gradeProdutoFilho
    JOIN CAPRODUTOS prodFilho ON prodFilho.produto = gradProdFilho.produto
    JOIN SIUNIDADESMEDIDA uniFilho ON uniFilho.unidadeMedida = prodFilho.unidadeMedida
    WHERE kit.gradeProduto = p_item_gradeProduto
    AND kit.ativo = 1
    AND kit.gradeProduto <> kit.gradeProdutoFilho
    AND ROUND(p_item_quantidade * kit.quantidade, uniFilho.casasDecimaisUnidadeMedida) > 0;
BEGIN
  r_bufferIdEstoque := p_bufferIdEstoque;
  
  IF p_cab_atualizaCustoMedio = 1 THEN
    SELECT COALESCE(SUM(ROUND(p_item_quantidade * kit.quantidade, uniFilho.casasDecimaisUnidadeMedida)),0)
    INTO v_quantidadeRateioTotal
    FROM CAGRADEPRODUTOXKITSCOMBOS kit 
    JOIN CAGRADESPRODUTO gradProdFilho ON gradProdFilho.gradeProduto = kit.gradeProdutoFilho
    JOIN CAPRODUTOS prodFilho ON prodFilho.produto = gradProdFilho.produto
    JOIN SIUNIDADESMEDIDA uniFilho ON uniFilho.unidadeMedida = prodFilho.unidadeMedida
    WHERE kit.gradeProduto = p_item_gradeProduto
    AND kit.ativo = 1
    AND kit.manterUltimoCusto = 0
    AND kit.gradeProduto <> kit.gradeProdutoFilho;
    SELECT ROUND((COALESCE(SUM(ROUND(p_item_quantidade * kit.quantidade, uniFilho.casasDecimaisUnidadeMedida)
      * FUNC_ADD_BUSCA_PRECO_ULT_CUSTO(
          p_config_209_filtrarGrupoEcon,
          p_config_362_calcCustoPorGrade,
          p_cab_estabelecimento,
          TO_DATE ('01/01/1900','DD/MM/YYYY'),
          CASE WHEN p_cab_dataEntradaSaida IS NULL OR p_cab_dataEntradaSaida < p_cab_dataEmissao THEN p_cab_dataEmissao ELSE p_cab_dataEntradaSaida END,
          0,
          gradProdFilho.produto,
          0,
          ' ',
          p_locEst_indicProprPosseItem,
          p_item_pessoaParticipante)),0)),2)
    INTO v_valorCustoManter
    FROM CAGRADEPRODUTOXKITSCOMBOS kit 
    JOIN CAGRADESPRODUTO gradProdFilho ON gradProdFilho.gradeProduto = kit.gradeProdutoFilho
    JOIN CAPRODUTOS prodFilho ON prodFilho.produto = gradProdFilho.produto
    JOIN SIUNIDADESMEDIDA uniFilho ON uniFilho.unidadeMedida = prodFilho.unidadeMedida
    WHERE kit.gradeProduto = p_item_gradeProduto
    AND kit.ativo = 1
    AND kit.manterUltimoCusto = 1
    AND kit.gradeProduto <> kit.gradeProdutoFilho;
  ELSE
    v_quantidadeRateioTotal := 0;
    v_valorCustoManter      := 0;
  END IF;
  v_quantSaldoRateioTotal := v_quantidadeRateioTotal;
  v_valorSaldoRateioTotal := p_item_valorCustoOperacao - v_valorCustoManter;
  FOR kit IN c_kit
  LOOP
    IF p_cab_atualizaCustoMedio = 1 AND kit.manterUltimoCusto = 1 THEN
      v_precoCustoKit := FUNC_ADD_BUSCA_PRECO_ULT_CUSTO(
          p_config_209_filtrarGrupoEcon,
          p_config_362_calcCustoPorGrade,
          p_cab_estabelecimento,
          TO_DATE ('01/01/1900','DD/MM/YYYY'),
          CASE WHEN p_cab_dataEntradaSaida IS NULL OR p_cab_dataEntradaSaida < p_cab_dataEmissao THEN p_cab_dataEmissao ELSE p_cab_dataEntradaSaida END,
          0,
          kit.produto,
          0,
          ' ',
          p_locEst_indicProprPosseItem,
          p_item_pessoaParticipante);
      v_valorCustoKit := ROUND (kit.quantidade * v_precoCustoKit,2);
    ELSIF p_cab_atualizaCustoMedio = 1 AND p_item_valorCustoOperacao > v_valorCustoManter AND v_quantSaldoRateioTotal > kit.quantidade THEN
      v_valorCustoKit := ROUND((p_item_valorCustoOperacao - v_valorCustoManter) * kit.quantidade / v_quantidadeRateioTotal,2);
      v_precoCustoKit := ROUND(v_valorCustoKit / kit.quantidade,7);
      v_quantSaldoRateioTotal := v_quantSaldoRateioTotal - kit.quantidade;
      v_valorSaldoRateioTotal := v_valorSaldoRateioTotal - v_valorCustoKit;
    ELSIF p_cab_atualizaCustoMedio = 1 AND v_valorSaldoRateioTotal > 0 THEN
      v_valorCustoKit := v_valorSaldoRateioTotal;
      v_precoCustoKit := ROUND(v_valorCustoKit / kit.quantidade,7);
      v_quantSaldoRateioTotal := 0;
      v_valorSaldoRateioTotal := 0;
    ELSE
      v_precoCustoKit := 0;
      v_valorCustoKit := 0;
    END IF;
    IF kit.controleEstoque IN (3,4) THEN
      ADD_ESTOQUE_KIT(
        p_config_209_filtrarGrupoEcon,
        p_config_362_calcCustoPorGrade,
        r_bufferIdEstoque,
        p_estabelecimentoAtivo,
        p_cab_modeloDocumento,
        p_cab_operacaoInternaEstoque,
        p_cab_atualizaCustoMedio,
        p_cab_atualizaUltimaCompra,
        p_cab_entradaSaida,
        p_cab_estabelecimento,
        p_cab_dataEmissao,
        p_cab_dataEntradaSaida,
        p_modDoc_geraTransferencia,
        p_modDoc_geraOperacaoEmTransit,
        p_modDoc_transitoLocalEstoque,
        p_locEstTransito_indicProprPos,
        kit.gradeProdutoFilho,
        p_item_localEstoque,
        p_item_pessoaParticipante,
        kit.quantidade,
        v_valorCustoKit,
        p_item_observacoes,
        p_idEnderecoEstoque,
        p_locEst_indicProprPosseItem,
        p_idItemPreDocumento,
        p_idItemDocFiscal,
        p_idItemSeparacao,
        p_divergenciaBalanco,
        p_idItemDocTransferencia,
        p_docTransf_estabelecEntrada,
        p_docTransf_estabelecSaida,
        r_bufferIdEstoque);
    ELSIF kit.controleEstoque IN(1,5,11,12) THEN
      ADD_ESTOQUE_INSERE(
        r_bufferIdEstoque, 
        p_estabelecimentoAtivo, 
        p_cab_estabelecimento,
        CASE WHEN p_cab_dataEntradaSaida IS NULL OR p_cab_dataEntradaSaida < p_cab_dataEmissao THEN p_cab_dataEmissao ELSE p_cab_dataEntradaSaida END, --p_data
        kit.gradeProdutoFilho,
        p_cab_modeloDocumento,
        p_cab_operacaoInternaEstoque,
        p_cab_atualizaCustoMedio,
        p_cab_atualizaUltimaCompra,
        p_cab_entradaSaida,
        p_locEst_indicProprPosseItem,
        p_item_pessoaParticipante,
        p_item_localEstoque,
        0, -- p_personalizacao
        0, -- p_idLoteEstoque
        p_idEnderecoEstoque,
        0, -- p_idNumeroSerie
        kit.quantidade,
        v_precoCustoKit, -- p_precoCustoOperacao
        v_valorCustoKit, -- p_totalCustoOperacao
        0, -- p_precoCMV
        0, -- p_valorCMV
        p_item_observacoes,
        p_idItemPreDocumento,
        p_idItemDocFiscal,
        p_idItemSeparacao,
        p_divergenciaBalanco,
        p_idItemDocTransferencia,
        r_bufferIdEstoque);
      IF p_modDoc_geraTransferencia = 1 AND p_modDoc_geraOperacaoEmTransit = 1 AND p_modDoc_transitoLocalEstoque > 0 AND p_docTransf_estabelecEntrada > 0 AND p_docTransf_estabelecSaida > 0 THEN
        ADD_ESTOQUE_INSERE(
          r_bufferIdEstoque, 
          p_estabelecimentoAtivo, 
          p_docTransf_estabelecSaida,
          CASE WHEN p_cab_dataEntradaSaida IS NULL OR p_cab_dataEntradaSaida < p_cab_dataEmissao THEN p_cab_dataEmissao ELSE p_cab_dataEntradaSaida END, --p_data
          kit.gradeProdutoFilho,
          p_cab_modeloDocumento,
          900,
          0,
          0,
          CASE WHEN p_cab_entradaSaida='S' THEN 'E' ELSE 'S' END,
          p_locEstTransito_indicProprPos,
          p_item_pessoaParticipante,
          p_modDoc_transitoLocalEstoque,
          0, -- p_personalizacao
          0, -- p_idLoteEstoque
          p_idEnderecoEstoque,
          0, -- p_idNumeroSerie
          kit.quantidade,
          v_precoCustoKit, -- p_precoCustoOperacao
          v_valorCustoKit, -- p_totalCustoOperacao
          0, -- p_precoCMV
          0, -- p_valorCMV
          p_item_observacoes,
          p_idItemPreDocumento,
          p_idItemDocFiscal,
          p_idItemSeparacao,
          p_divergenciaBalanco,
          p_idItemDocTransferencia,
          r_bufferIdEstoque);
      END IF;    
    END IF;
  END LOOP;
END ADD_ESTOQUE_KIT;

/

create or replace FUNCTION BUSCA_RESERVAS_ESTOQUE(
    p_config_82_considLenteDispon IN NUMBER,
    p_config_83_considLenteEstoqu IN NUMBER,
    p_config_160_permiteTransfSem IN CHAR,
    p_produto                     IN NUMBER,
    p_cor                         IN NUMBER,
    p_tamanho                     IN VARCHAR,
    p_gradeProduto                IN NUMBER,
    p_idLoteEstoque               IN NUMBER,
    p_estabelecimento             IN NUMBER,
    p_indicadorPropriedadePosseIt IN CHAR,
    p_pessoaParticipante          IN NUMBER,
    p_localEstoque                IN NUMBER,
    p_idEnderecoEstoque           IN NUMBER,
    p_idNumeroSerie               IN NUMBER,
    p_orcamentoDesconsiderar      IN NUMBER,
    p_transferenciaDesconsiderar  IN NUMBER,
    p_entradaSaida                IN CHAR)
RETURN NUMBER
IS
  v_quantidadeReservas           NUMBER(15,6);
  v_quantidadeOrcamento          NUMBER(15,6);
  v_quantidadeTransferencia      NUMBER(15,6);
  v_quantidadeTransfDigitacao    NUMBER(15,6);
BEGIN
  v_quantidadeReservas           := 0;
  v_quantidadeOrcamento          := 0;
  v_quantidadeTransferencia      := 0;
  v_quantidadeTransfDigitacao    := 0;
  SELECT COALESCE((
    SELECT SUM(a.quantidadeSaldo)
    FROM (
      SELECT
        CASE
          WHEN prod.controleEstoque IN (3,4)
          THEN 
            TRUNC ((
              SELECT MIN (a.quantidadeSaldo / a.quantidadeKit)
              FROM (
                SELECT kit.gradeProduto,
                  kit.gradeProdutoFilho,
                  kit.quantidade quantidadeKit,
                  BUSCA_RESERVAS_ESTOQUE(
                    p_config_82_considLenteDispon,
                    p_config_83_considLenteEstoqu,
                    p_config_160_permiteTransfSem,
                    0, -- p_produto,
                    0, -- p_cor,
                    ' ', -- p_tamanho,
                    kit.gradeProdutoFilho,
                    0, -- p_idLoteEstoque,
                    p_estabelecimento,
                    p_indicadorPropriedadePosseIt,
                    p_pessoaParticipante,
                    p_localEstoque,
                    p_idEnderecoEstoque,
                    0, -- p_idNumeroSerie
                    p_orcamentoDesconsiderar,
                    p_transferenciaDesconsiderar,
                    p_entradaSaida) quantidadeSaldo
                FROM CAGRADEPRODUTOXKITSCOMBOS kit
                JOIN CAGRADESPRODUTO gradProdFilho ON gradProdFilho.gradeProduto = kit.gradeProdutoFilho
                JOIN CAPRODUTOS prodFilho ON prodFilho.produto = gradProdFilho.produto
                WHERE kit.quantidade > 0
                AND kit.gradeProduto <> kit.gradeProdutoFilho
                AND prodFilho.controleEstoque IN (1,3,4,5,11,12)
                GROUP BY kit.gradeProduto, kit.gradeProdutoFilho, kit.quantidade
              ) a
              WHERE a.gradeProduto = gradProd.gradeProduto
            ), uniMed.casasDecimaisUnidadeMedida)
          WHEN prod.controleEstoque IN (1,5,11,12)
          THEN
            COALESCE((
              SELECT SUM(a.quantidadeSaldo)
              FROM MORESERVASESTOQUE a
              JOIN PALOCAISESTOQUE locEst ON locEst.localEstoque = a.localEstoque
              WHERE a.entradaSaida = '' || p_entradaSaida || ''
              AND a.gradeProduto = gradProd.gradeProduto
              AND (p_idLoteEstoque = 0 OR a.idLoteEstoque = p_idLoteEstoque)
              AND (p_estabelecimento = 0 OR a.estabelecimento = p_estabelecimento)
              AND (p_indicadorPropriedadePosseIt IS NULL OR p_indicadorPropriedadePosseIt = ' ' OR a.indicadorPropriedadePosseItem = '' || p_indicadorPropriedadePosseIt || '')
              AND (p_pessoaParticipante = 0 OR a.pessoaParticipante = p_pessoaParticipante)
              AND (p_localEstoque = 0 AND locEst.validoEstoqueTotal = 1 OR a.localEstoque = p_localEstoque)
              AND (p_idEnderecoEstoque = 0 OR a.idEnderecoEstoque = p_idEnderecoEstoque)
              AND (p_idNumeroSerie = 0 OR a.idNumeroSerie = p_idNumeroSerie)
            ),0)
          ELSE 0
        END quantidadeSaldo
      FROM CAGRADESPRODUTO gradProd
      JOIN CAPRODUTOS prod ON prod.produto = gradProd.produto
      JOIN SIUNIDADESMEDIDA uniMed ON uniMed.unidadeMedida = prod.unidadeMedida
      WHERE p_gradeProduto = 0
      AND gradProd.produto = p_produto
      AND (p_cor = 0 OR gradProd.cor = p_cor)
      AND (p_tamanho IS NULL OR p_tamanho = ' ' OR gradProd.tamanho = '' || TRIM(p_tamanho) || '')
      OR p_gradeProduto <> 0
      AND gradProd.gradeProduto = p_gradeProduto
    ) a
  ),0) INTO v_quantidadeReservas FROM DUAL;
  IF p_orcamentoDesconsiderar > 0 THEN
    SELECT COALESCE((
      SELECT SUM(a.quantidadeSaldo)
      FROM (
        SELECT
          CASE
            WHEN prod.controleEstoque IN (3,4)
            THEN 
              TRUNC ((
                SELECT MIN (a.quantidadeSaldo / a.quantidadeKit)
                FROM (
                  SELECT kit.gradeProduto,
                    kit.gradeProdutoFilho,
                    kit.quantidade quantidadeKit,
                    ( SELECT SUM (a.quantidadeSaldo)
                      FROM MORESERVASESTOQUE a
                      JOIN MOORCAMENTOXRESERVAESTOQ b ON b.idReservaEstoque = a.idReservaEstoque
                      JOIN PALOCAISESTOQUE locEst ON locEst.localEstoque = a.localEstoque
                      JOIN MOORCAMENTOXITENS itemOrc ON itemOrc.idItemOrcamento = b.idItemOrcamento
                      WHERE a.entradaSaida = '' || p_entradaSaida || ''
                      AND a.gradeProduto = kit.gradeProdutoFilho
                      AND itemOrc.orcamento = p_orcamentoDesconsiderar
                      AND (p_idLoteEstoque = 0 OR a.idLoteEstoque = p_idLoteEstoque)
                      AND (p_estabelecimento = 0 OR a.estabelecimento = p_estabelecimento)
                      AND (p_indicadorPropriedadePosseIt IS NULL OR p_indicadorPropriedadePosseIt = ' ' OR a.indicadorPropriedadePosseItem = '' || p_indicadorPropriedadePosseIt || '')
                      AND (p_pessoaParticipante = 0 OR a.pessoaParticipante = p_pessoaParticipante)
                      AND (p_localEstoque = 0 AND locEst.validoEstoqueTotal = 1 OR a.localEstoque = p_localEstoque)
                      AND (p_idEnderecoEstoque = 0 OR a.idEnderecoEstoque = p_idEnderecoEstoque)
                      AND (p_idNumeroSerie = 0 OR a.idNumeroSerie = p_idNumeroSerie)
                    ) quantidadeSaldo
                  FROM CAGRADEPRODUTOXKITSCOMBOS kit
                  JOIN CAGRADESPRODUTO gradProdFilho ON gradProdFilho.gradeProduto = kit.gradeProdutoFilho
                  JOIN CAPRODUTOS prodFilho ON prodFilho.produto = gradProdFilho.produto
                  WHERE kit.quantidade > 0
                  AND kit.gradeProduto <> kit.gradeProdutoFilho
                  AND prodFilho.controleEstoque IN (1,5,11,12)
                  GROUP BY kit.gradeProduto, kit.gradeProdutoFilho, kit.quantidade
                ) a
                WHERE a.gradeProduto = gradProd.gradeProduto
              ), uniMed.casasDecimaisUnidadeMedida)
            WHEN prod.controleEstoque IN (1,5,11,12)
            THEN
              COALESCE((
                SELECT SUM(a.quantidadeSaldo)
                FROM MORESERVASESTOQUE a
                JOIN MOORCAMENTOXRESERVAESTOQ b ON b.idReservaEstoque = a.idReservaEstoque
                JOIN PALOCAISESTOQUE locEst ON locEst.localEstoque = a.localEstoque
                JOIN MOORCAMENTOXITENS itemOrc ON itemOrc.idItemOrcamento = b.idItemOrcamento
                WHERE a.entradaSaida = '' || p_entradaSaida || ''
                AND a.gradeProduto = gradProd.gradeProduto
                AND itemOrc.orcamento = p_orcamentoDesconsiderar
                AND (p_idLoteEstoque = 0 OR a.idLoteEstoque = p_idLoteEstoque)
                AND (p_estabelecimento = 0 OR a.estabelecimento = p_estabelecimento)
                AND (p_indicadorPropriedadePosseIt IS NULL OR p_indicadorPropriedadePosseIt = ' ' OR a.indicadorPropriedadePosseItem = '' || p_indicadorPropriedadePosseIt || '')
                AND (p_pessoaParticipante = 0 OR a.pessoaParticipante = p_pessoaParticipante)
                AND (p_localEstoque = 0 AND locEst.validoEstoqueTotal = 1 OR a.localEstoque = p_localEstoque)
                AND (p_idEnderecoEstoque = 0 OR a.idEnderecoEstoque = p_idEnderecoEstoque)
                AND (p_idNumeroSerie = 0 OR a.idNumeroSerie = p_idNumeroSerie)
              ),0)
            ELSE 0
          END quantidadeSaldo
        FROM CAGRADESPRODUTO gradProd
        JOIN CAPRODUTOS prod ON prod.produto = gradProd.produto
        JOIN SIUNIDADESMEDIDA uniMed ON uniMed.unidadeMedida = prod.unidadeMedida
        WHERE p_gradeProduto = 0
        AND gradProd.produto = p_produto
        AND (p_cor = 0 OR gradProd.cor = p_cor)
        AND (p_tamanho IS NULL OR p_tamanho = ' ' OR gradProd.tamanho = '' || TRIM(p_tamanho) || '')
        OR p_gradeProduto <> 0
        AND gradProd.gradeProduto = p_gradeProduto
      ) a
    ),0) INTO v_quantidadeOrcamento FROM DUAL;
  END IF;
  IF p_transferenciaDesconsiderar > 0 THEN
    SELECT COALESCE((
      SELECT SUM(a.quantidadeSaldo)
      FROM (
        SELECT
          CASE
            WHEN prod.controleEstoque IN (3,4)
            THEN 
              TRUNC ((
                SELECT MIN (a.quantidadeSaldo / a.quantidadeKit)
                FROM (
                  SELECT kit.gradeProduto,
                    kit.gradeProdutoFilho,
                    kit.quantidade quantidadeKit,
                    ( SELECT SUM (a.quantidadeSaldo)
                      FROM MORESERVASESTOQUE a
                      JOIN MODOCTRANSFXRESERVAESTOQ b ON b.idReservaEstoque = a.idReservaEstoque
                      JOIN PALOCAISESTOQUE locEst ON locEst.localEstoque = a.localEstoque
                      JOIN MODOCUMENTOTRANSFXITENS itemTransf ON itemTransf.idItemDocTransferencia = b.idItemDocTransferencia
                      WHERE a.entradaSaida = '' || p_entradaSaida || ''
                      AND a.gradeProduto = kit.gradeProdutoFilho
                      AND itemTransf.documentoTransferencia = p_transferenciaDesconsiderar
                      AND (p_idLoteEstoque = 0 OR a.idLoteEstoque = p_idLoteEstoque)
                      AND (p_estabelecimento = 0 OR a.estabelecimento = p_estabelecimento)
                      AND (p_indicadorPropriedadePosseIt IS NULL OR p_indicadorPropriedadePosseIt = ' ' OR a.indicadorPropriedadePosseItem = '' || p_indicadorPropriedadePosseIt || '')
                      AND (p_pessoaParticipante = 0 OR a.pessoaParticipante = p_pessoaParticipante)
                      AND (p_localEstoque = 0 AND locEst.validoEstoqueTotal = 1 OR a.localEstoque = p_localEstoque)
                      AND (p_idEnderecoEstoque = 0 OR a.idEnderecoEstoque = p_idEnderecoEstoque)
                      AND (p_idNumeroSerie = 0 OR a.idNumeroSerie = p_idNumeroSerie)
                    ) quantidadeSaldo
                  FROM CAGRADEPRODUTOXKITSCOMBOS kit
                  JOIN CAGRADESPRODUTO gradProdFilho ON gradProdFilho.gradeProduto = kit.gradeProdutoFilho
                  JOIN CAPRODUTOS prodFilho ON prodFilho.produto = gradProdFilho.produto
                  WHERE kit.quantidade > 0
                  AND kit.gradeProduto <> kit.gradeProdutoFilho
                  AND prodFilho.controleEstoque IN (1,5,11,12)
                  GROUP BY kit.gradeProduto, kit.gradeProdutoFilho, kit.quantidade
                ) a
                WHERE a.gradeProduto = gradProd.gradeProduto
              ), uniMed.casasDecimaisUnidadeMedida)
            WHEN prod.controleEstoque IN (1,5,11,12)
            THEN
              COALESCE((
                SELECT SUM(a.quantidadeSaldo)
                FROM MORESERVASESTOQUE a
                JOIN MODOCTRANSFXRESERVAESTOQ b ON b.idReservaEstoque = a.idReservaEstoque
                JOIN PALOCAISESTOQUE locEst ON locEst.localEstoque = a.localEstoque
                JOIN MODOCUMENTOTRANSFXITENS itemTransf ON itemTransf.idItemDocTransferencia = b.idItemDocTransferencia
                WHERE a.entradaSaida = '' || p_entradaSaida || ''
                AND a.gradeProduto = gradProd.gradeProduto
                AND itemTransf.documentoTransferencia = p_transferenciaDesconsiderar
                AND (p_idLoteEstoque = 0 OR a.idLoteEstoque = p_idLoteEstoque)
                AND (p_estabelecimento = 0 OR a.estabelecimento = p_estabelecimento)
                AND (p_indicadorPropriedadePosseIt IS NULL OR p_indicadorPropriedadePosseIt = ' ' OR a.indicadorPropriedadePosseItem = '' || p_indicadorPropriedadePosseIt || '')
                AND (p_pessoaParticipante = 0 OR a.pessoaParticipante = p_pessoaParticipante)
                AND (p_localEstoque = 0 AND locEst.validoEstoqueTotal = 1 OR a.localEstoque = p_localEstoque)
                AND (p_idEnderecoEstoque = 0 OR a.idEnderecoEstoque = p_idEnderecoEstoque)
                AND (p_idNumeroSerie = 0 OR a.idNumeroSerie = p_idNumeroSerie)
              ),0)
            ELSE 0
          END quantidadeSaldo
        FROM CAGRADESPRODUTO gradProd
        JOIN CAPRODUTOS prod ON prod.produto = gradProd.produto
        JOIN SIUNIDADESMEDIDA uniMed ON uniMed.unidadeMedida = prod.unidadeMedida
        WHERE p_gradeProduto = 0
        AND gradProd.produto = p_produto
        AND (p_cor = 0 OR gradProd.cor = p_cor)
        AND (p_tamanho IS NULL OR p_tamanho = ' ' OR gradProd.tamanho = '' || TRIM(p_tamanho) || '')
        OR p_gradeProduto <> 0
        AND gradProd.gradeProduto = p_gradeProduto
      ) a
    ),0) INTO v_quantidadeTransferencia FROM DUAL;
  END IF;
  IF p_config_160_permiteTransfSem IN ('A','B') AND p_entradaSaida = 'S' AND p_idEnderecoEstoque = 0 AND p_idNumeroSerie = 0 THEN
    SELECT COALESCE((
      SELECT SUM(a.quantidadeSaldo)
      FROM (
        SELECT
          CASE
            WHEN prod.controleEstoque IN (1,5,11,12)
            THEN
              COALESCE((
                SELECT SUM(a.quantidadeSaldo)
                FROM MODOCUMENTOTRANSFXITENS a
                JOIN MODOCUMENTOSTRANSFERENCIA docTransf ON docTransf.documentoTransferencia = a.documentoTransferencia
                JOIN PAMODELOSDOCUMENTO modDoc on modDoc.modeloDocumento = docTransf.modeloDocumento
                JOIN PALOCAISESTOQUE locEst ON locEst.localEstoque = a.localEstoqueSaida
                WHERE a.validoSaida = 1
                AND a.documentoTransferencia <> p_transferenciaDesconsiderar
                AND a.gradeProduto = gradProd.gradeProduto
                AND docTransf.tipoDocumentoSaida > 100
                AND docTransf.situacaoDocTransferencia = 'E'
                AND modDoc.movimentaEstoque = 1
                AND (p_idLoteEstoque = 0 OR a.idLoteEstoque = p_idLoteEstoque)
                AND (p_estabelecimento = 0 OR docTransf.estabelecimentoSaida = p_estabelecimento)
                AND (p_indicadorPropriedadePosseIt IS NULL OR p_indicadorPropriedadePosseIt = ' ' OR locEst.indicadorPropriedadePosseItem = '' || p_indicadorPropriedadePosseIt || '')
                AND (p_pessoaParticipante = 0 OR a.pessoaParticipanteSaida = p_pessoaParticipante)
                AND (p_localEstoque = 0 AND locEst.validoEstoqueTotal = 1 OR a.localEstoqueSaida = p_localEstoque)
                AND (prod.controleEstoque IN (1,12) OR prod.controleEstoque = 11 AND CASE WHEN docTransf.tipoDocumentoSaida = 101 THEN p_config_82_considLenteDispon ELSE p_config_83_considLenteEstoqu END = 1)
              ),0)
            WHEN prod.controleEstoque IN (3,4)
            THEN 
              TRUNC ((
                SELECT MIN (a.quantidadeSaldo / a.quantidadeKit)
                FROM (
                  SELECT kit.gradeProduto,
                    kit.gradeProdutoFilho,
                    kit.quantidade quantidadeKit,
                    ( SELECT SUM (a.quantidadeSaldo)
                      FROM MODOCUMENTOTRANSFXITENS a
                      JOIN MODOCUMENTOSTRANSFERENCIA docTransf ON docTransf.documentoTransferencia = a.documentoTransferencia
                      JOIN PAMODELOSDOCUMENTO modDoc on modDoc.modeloDocumento = docTransf.modeloDocumento
                      JOIN PALOCAISESTOQUE locEst ON locEst.localEstoque = a.localEstoqueSaida
                      WHERE a.validoSaida = 1
                      AND a.documentoTransferencia <> p_transferenciaDesconsiderar
                      AND a.gradeProduto = kit.gradeProdutoFilho
                      AND docTransf.tipoDocumentoSaida > 100
                      AND docTransf.situacaoDocTransferencia = 'E'
                      AND modDoc.movimentaEstoque = 1
                      AND (p_idLoteEstoque = 0 OR a.idLoteEstoque = p_idLoteEstoque)
                      AND (p_estabelecimento = 0 OR docTransf.estabelecimentoSaida = p_estabelecimento)
                      AND (p_indicadorPropriedadePosseIt IS NULL OR p_indicadorPropriedadePosseIt = ' ' OR locEst.indicadorPropriedadePosseItem = '' || p_indicadorPropriedadePosseIt || '')
                      AND (p_pessoaParticipante = 0 OR a.pessoaParticipanteSaida = p_pessoaParticipante)
                      AND (p_localEstoque = 0 AND locEst.validoEstoqueTotal = 1 OR a.localEstoqueSaida = p_localEstoque)
                    ) quantidadeSaldo
                  FROM CAGRADEPRODUTOXKITSCOMBOS kit
                  WHERE kit.quantidade > 0
                  AND kit.gradeProduto <> kit.gradeProdutoFilho
                  GROUP BY kit.gradeProduto, kit.gradeProdutoFilho, kit.quantidade
                ) a
                WHERE a.gradeProduto = gradProd.gradeProduto
              ), uniMed.casasDecimaisUnidadeMedida)
            ELSE 0
          END quantidadeSaldo
        FROM CAGRADESPRODUTO gradProd
        JOIN CAPRODUTOS prod ON prod.produto = gradProd.produto
        JOIN SIUNIDADESMEDIDA uniMed ON uniMed.unidadeMedida = prod.unidadeMedida
        WHERE p_gradeProduto = 0
        AND gradProd.produto = p_produto
        AND (p_cor = 0 OR gradProd.cor = p_cor)
        AND (p_tamanho IS NULL OR p_tamanho = ' ' OR gradProd.tamanho = '' || TRIM(p_tamanho) || '')
        OR p_gradeProduto <> 0
        AND gradProd.gradeProduto = p_gradeProduto
      ) a
    ),0) INTO v_quantidadeTransfDigitacao FROM DUAL;
  END IF;
  RETURN v_quantidadeReservas - v_quantidadeOrcamento - v_quantidadeTransferencia + v_quantidadeTransfDigitacao;
END;

/

create or replace FUNCTION FUNC_ADD_BUSCA_RESERVAS_PROD(
    p_config_82_considLenteDispon IN NUMBER,
    p_config_83_considLenteEstoqu IN NUMBER,
    p_config_160_permiteTransfSem IN CHAR,
    p_produto                     IN NUMBER,
    p_cor                         IN NUMBER,
    p_tamanho                     IN VARCHAR,
    p_gradeProduto                IN NUMBER,
    p_idLoteEstoque               IN NUMBER,
    p_estabelecimento             IN NUMBER,
    p_indicadorPropriedadePosseIt IN CHAR,
    p_pessoaParticipante          IN NUMBER,
    p_localEstoque                IN NUMBER,
    p_personalizacao              IN NUMBER,
    p_idEnderecoEstoque           IN NUMBER,
    p_idNumeroSerie               IN NUMBER,
    p_documentoDesconsiderar      IN CHAR, -- O = Orçamento, T = Transferencia
    p_idDocumentoDesconsiderar    IN NUMBER,
    p_entradaSaida                IN CHAR)
RETURN NUMBER

IS
  v_quantidadeReservas           NUMBER(15,6);
  v_quantidadeOrcamento          NUMBER(15,6);
  v_quantidadeTransferencia      NUMBER(15,6);
  v_quantidadeTransfDigitacao    NUMBER(15,6);

BEGIN
  v_quantidadeReservas           := 0;
  v_quantidadeOrcamento          := 0;
  v_quantidadeTransferencia      := 0;
  v_quantidadeTransfDigitacao    := 0;
  
  SELECT COALESCE((
    SELECT SUM(a.quantidadeSaldo)
    FROM (
      SELECT
        CASE
          WHEN prod.controleEstoque IN (1,5,11)
          THEN
            COALESCE((
              SELECT SUM(a.quantidadeSaldo)
              FROM MORESERVASESTOQUE a
              JOIN PALOCAISESTOQUE locEst ON locEst.localEstoque = a.localEstoque
              WHERE a.entradaSaida = '' || p_entradaSaida || ''
              AND a.gradeProduto = gradProd.gradeProduto
              AND (p_idLoteEstoque = 0 OR a.idLoteEstoque = p_idLoteEstoque)
              AND (p_estabelecimento = 0 OR a.estabelecimento = p_estabelecimento)
              AND (p_indicadorPropriedadePosseIt IS NULL OR p_indicadorPropriedadePosseIt = ' ' OR a.indicadorPropriedadePosseItem = '' || p_indicadorPropriedadePosseIt || '')
              AND (p_pessoaParticipante = 0 OR a.pessoaParticipante = p_pessoaParticipante)
              AND (p_localEstoque = 0 AND locEst.validoEstoqueTotal = 1 OR a.localEstoque = p_localEstoque)
              AND (p_personalizacao = 0 OR a.personalizacao = p_personalizacao)
              AND (p_idEnderecoEstoque = 0 OR a.idEnderecoEstoque = p_idEnderecoEstoque)
              AND (p_idNumeroSerie = 0 OR a.idNumeroSerie = p_idNumeroSerie)
            ),0)
          WHEN prod.controleEstoque IN (3,4)
          THEN 
            TRUNC ((
              SELECT MIN (a.quantidadeSaldo / a.quantidadeKit)
              FROM (
                SELECT kit.gradeProduto,
                  kit.gradeProdutoFilho,
                  kit.quantidade quantidadeKit,
                  ( SELECT SUM (a.quantidadeSaldo)
                    FROM MORESERVASESTOQUE a
                    JOIN PALOCAISESTOQUE locEst ON locEst.localEstoque = a.localEstoque
                    WHERE a.entradaSaida = '' || p_entradaSaida || ''
                    AND a.gradeProduto = kit.gradeProdutoFilho
                    AND (p_idLoteEstoque = 0 OR a.idLoteEstoque = p_idLoteEstoque)
                    AND (p_estabelecimento = 0 OR a.estabelecimento = p_estabelecimento)
                    AND (p_indicadorPropriedadePosseIt IS NULL OR p_indicadorPropriedadePosseIt = ' ' OR a.indicadorPropriedadePosseItem = '' || p_indicadorPropriedadePosseIt || '')
                    AND (p_pessoaParticipante = 0 OR a.pessoaParticipante = p_pessoaParticipante)
                    AND (p_localEstoque = 0 AND locEst.validoEstoqueTotal = 1 OR a.localEstoque = p_localEstoque)
                    AND (p_personalizacao = 0 OR a.personalizacao = p_personalizacao)
                    AND (p_idEnderecoEstoque = 0 OR a.idEnderecoEstoque = p_idEnderecoEstoque)
                    AND (p_idNumeroSerie = 0 OR a.idNumeroSerie = p_idNumeroSerie)
                  ) quantidadeSaldo
                FROM CAGRADEPRODUTOXKITSCOMBOS kit
                WHERE kit.quantidade > 0
                AND kit.gradeProduto <> kit.gradeProdutoFilho
                GROUP BY kit.gradeProduto, kit.gradeProdutoFilho, kit.quantidade
              ) a
              WHERE a.gradeProduto = gradProd.gradeProduto
            ), uniMed.casasDecimaisUnidadeMedida)
          ELSE 0
        END quantidadeSaldo
      FROM CAGRADESPRODUTO gradProd
      JOIN CAPRODUTOS prod ON prod.produto = gradProd.produto
      JOIN SIUNIDADESMEDIDA uniMed ON uniMed.unidadeMedida = prod.unidadeMedida
      WHERE p_gradeProduto = 0
      AND gradProd.produto = p_produto
      AND (p_cor = 0 OR gradProd.cor = p_cor)
      AND (p_tamanho IS NULL OR p_tamanho = ' ' OR gradProd.tamanho = '' || TRIM(p_tamanho) || '')
      OR p_gradeProduto <> 0
      AND gradProd.gradeProduto = p_gradeProduto
    ) a
  ),0) INTO v_quantidadeReservas FROM DUAL;

  IF p_documentoDesconsiderar = 'O' AND p_idDocumentoDesconsiderar > 0 THEN
    SELECT COALESCE((
      SELECT SUM(a.quantidadeSaldo)
      FROM (
        SELECT
          CASE
            WHEN prod.controleEstoque IN (1,5,11)
            THEN
              COALESCE((
                SELECT SUM(a.quantidadeSaldo)
                FROM MORESERVASESTOQUE a
                JOIN MOORCAMENTOXRESERVAESTOQ b ON b.idReservaEstoque = a.idReservaEstoque
                JOIN PALOCAISESTOQUE locEst ON locEst.localEstoque = a.localEstoque
                JOIN MOORCAMENTOXITENS itemOrc ON itemOrc.idItemOrcamento = b.idItemOrcamento
                WHERE a.entradaSaida = '' || p_entradaSaida || ''
                AND a.gradeProduto = gradProd.gradeProduto
                AND itemOrc.orcamento = p_idDocumentoDesconsiderar
                AND (p_idLoteEstoque = 0 OR a.idLoteEstoque = p_idLoteEstoque)
                AND (p_estabelecimento = 0 OR a.estabelecimento = p_estabelecimento)
                AND (p_indicadorPropriedadePosseIt IS NULL OR p_indicadorPropriedadePosseIt = ' ' OR a.indicadorPropriedadePosseItem = '' || p_indicadorPropriedadePosseIt || '')
                AND (p_pessoaParticipante = 0 OR a.pessoaParticipante = p_pessoaParticipante)
                AND (p_localEstoque = 0 AND locEst.validoEstoqueTotal = 1 OR a.localEstoque = p_localEstoque)
                AND (p_personalizacao = 0 OR a.personalizacao = p_personalizacao)
                AND (p_idEnderecoEstoque = 0 OR a.idEnderecoEstoque = p_idEnderecoEstoque)
                AND (p_idNumeroSerie = 0 OR a.idNumeroSerie = p_idNumeroSerie)
              ),0)
            WHEN prod.controleEstoque IN (3,4)
            THEN 
              TRUNC ((
                SELECT MIN (a.quantidadeSaldo / a.quantidadeKit)
                FROM (
                  SELECT kit.gradeProduto,
                    kit.gradeProdutoFilho,
                    kit.quantidade quantidadeKit,
                    ( SELECT SUM (a.quantidadeSaldo)
                      FROM MORESERVASESTOQUE a
                      JOIN MOORCAMENTOXRESERVAESTOQ b ON b.idReservaEstoque = a.idReservaEstoque
                      JOIN PALOCAISESTOQUE locEst ON locEst.localEstoque = a.localEstoque
                      JOIN MOORCAMENTOXITENS itemOrc ON itemOrc.idItemOrcamento = b.idItemOrcamento
                      WHERE a.entradaSaida = '' || p_entradaSaida || ''
                      AND a.gradeProduto = kit.gradeProdutoFilho
                      AND itemOrc.orcamento = p_idDocumentoDesconsiderar
                      AND (p_idLoteEstoque = 0 OR a.idLoteEstoque = p_idLoteEstoque)
                      AND (p_estabelecimento = 0 OR a.estabelecimento = p_estabelecimento)
                      AND (p_indicadorPropriedadePosseIt IS NULL OR p_indicadorPropriedadePosseIt = ' ' OR a.indicadorPropriedadePosseItem = '' || p_indicadorPropriedadePosseIt || '')
                      AND (p_pessoaParticipante = 0 OR a.pessoaParticipante = p_pessoaParticipante)
                      AND (p_localEstoque = 0 AND locEst.validoEstoqueTotal = 1 OR a.localEstoque = p_localEstoque)
                      AND (p_personalizacao = 0 OR a.personalizacao = p_personalizacao)
                      AND (p_idEnderecoEstoque = 0 OR a.idEnderecoEstoque = p_idEnderecoEstoque)
                      AND (p_idNumeroSerie = 0 OR a.idNumeroSerie = p_idNumeroSerie)
                    ) quantidadeSaldo
                  FROM CAGRADEPRODUTOXKITSCOMBOS kit
                  WHERE kit.quantidade > 0
                  AND kit.gradeProduto <> kit.gradeProdutoFilho
                  GROUP BY kit.gradeProduto, kit.gradeProdutoFilho, kit.quantidade
                ) a
                WHERE a.gradeProduto = gradProd.gradeProduto
              ), uniMed.casasDecimaisUnidadeMedida)
            ELSE 0
          END quantidadeSaldo
        FROM CAGRADESPRODUTO gradProd
        JOIN CAPRODUTOS prod ON prod.produto = gradProd.produto
        JOIN SIUNIDADESMEDIDA uniMed ON uniMed.unidadeMedida = prod.unidadeMedida
        WHERE p_gradeProduto = 0
        AND gradProd.produto = p_produto
        AND (p_cor = 0 OR gradProd.cor = p_cor)
        AND (p_tamanho IS NULL OR p_tamanho = ' ' OR gradProd.tamanho = '' || TRIM(p_tamanho) || '')
        OR p_gradeProduto <> 0
        AND gradProd.gradeProduto = p_gradeProduto
      ) a
    ),0) INTO v_quantidadeOrcamento FROM DUAL;
  END IF;

  IF p_documentoDesconsiderar = 'T' AND p_idDocumentoDesconsiderar > 0 THEN
    SELECT COALESCE((
      SELECT SUM(a.quantidadeSaldo)
      FROM (
        SELECT
          CASE
            WHEN prod.controleEstoque IN (1,5,11)
            THEN
              COALESCE((
                SELECT SUM(a.quantidadeSaldo)
                FROM MORESERVASESTOQUE a
                JOIN MODOCTRANSFXRESERVAESTOQ b ON b.idReservaEstoque = a.idReservaEstoque
                JOIN PALOCAISESTOQUE locEst ON locEst.localEstoque = a.localEstoque
                JOIN MODOCUMENTOTRANSFXITENS itemTransf ON itemTransf.idItemDocTransferencia = b.idItemDocTransferencia
                WHERE a.entradaSaida = '' || p_entradaSaida || ''
                AND a.gradeProduto = gradProd.gradeProduto
                AND itemTransf.documentoTransferencia = p_idDocumentoDesconsiderar
                AND (p_idLoteEstoque = 0 OR a.idLoteEstoque = p_idLoteEstoque)
                AND (p_estabelecimento = 0 OR a.estabelecimento = p_estabelecimento)
                AND (p_indicadorPropriedadePosseIt IS NULL OR p_indicadorPropriedadePosseIt = ' ' OR a.indicadorPropriedadePosseItem = '' || p_indicadorPropriedadePosseIt || '')
                AND (p_pessoaParticipante = 0 OR a.pessoaParticipante = p_pessoaParticipante)
                AND (p_localEstoque = 0 AND locEst.validoEstoqueTotal = 1 OR a.localEstoque = p_localEstoque)
                AND (p_personalizacao = 0 OR a.personalizacao = p_personalizacao)
                AND (p_idEnderecoEstoque = 0 OR a.idEnderecoEstoque = p_idEnderecoEstoque)
                AND (p_idNumeroSerie = 0 OR a.idNumeroSerie = p_idNumeroSerie)
              ),0)
            WHEN prod.controleEstoque IN (3,4)
            THEN 
              TRUNC ((
                SELECT MIN (a.quantidadeSaldo / a.quantidadeKit)
                FROM (
                  SELECT kit.gradeProduto,
                    kit.gradeProdutoFilho,
                    kit.quantidade quantidadeKit,
                    ( SELECT SUM (a.quantidadeSaldo)
                      FROM MORESERVASESTOQUE a
                      JOIN MODOCTRANSFXRESERVAESTOQ b ON b.idReservaEstoque = a.idReservaEstoque
                      JOIN PALOCAISESTOQUE locEst ON locEst.localEstoque = a.localEstoque
                      JOIN MODOCUMENTOTRANSFXITENS itemTransf ON itemTransf.idItemDocTransferencia = b.idItemDocTransferencia
                      WHERE a.entradaSaida = '' || p_entradaSaida || ''
                      AND a.gradeProduto = kit.gradeProdutoFilho
                      AND itemTransf.documentoTransferencia = p_idDocumentoDesconsiderar
                      AND (p_idLoteEstoque = 0 OR a.idLoteEstoque = p_idLoteEstoque)
                      AND (p_estabelecimento = 0 OR a.estabelecimento = p_estabelecimento)
                      AND (p_indicadorPropriedadePosseIt IS NULL OR p_indicadorPropriedadePosseIt = ' ' OR a.indicadorPropriedadePosseItem = '' || p_indicadorPropriedadePosseIt || '')
                      AND (p_pessoaParticipante = 0 OR a.pessoaParticipante = p_pessoaParticipante)
                      AND (p_localEstoque = 0 AND locEst.validoEstoqueTotal = 1 OR a.localEstoque = p_localEstoque)
                      AND (p_personalizacao = 0 OR a.personalizacao = p_personalizacao)
                      AND (p_idEnderecoEstoque = 0 OR a.idEnderecoEstoque = p_idEnderecoEstoque)
                      AND (p_idNumeroSerie = 0 OR a.idNumeroSerie = p_idNumeroSerie)
                    ) quantidadeSaldo
                  FROM CAGRADEPRODUTOXKITSCOMBOS kit
                  WHERE kit.quantidade > 0
                  AND kit.gradeProduto <> kit.gradeProdutoFilho
                  GROUP BY kit.gradeProduto, kit.gradeProdutoFilho, kit.quantidade
                ) a
                WHERE a.gradeProduto = gradProd.gradeProduto
              ), uniMed.casasDecimaisUnidadeMedida)
            ELSE 0
          END quantidadeSaldo
        FROM CAGRADESPRODUTO gradProd
        JOIN CAPRODUTOS prod ON prod.produto = gradProd.produto
        JOIN SIUNIDADESMEDIDA uniMed ON uniMed.unidadeMedida = prod.unidadeMedida
        WHERE p_gradeProduto = 0
        AND gradProd.produto = p_produto
        AND (p_cor = 0 OR gradProd.cor = p_cor)
        AND (p_tamanho IS NULL OR p_tamanho = ' ' OR gradProd.tamanho = '' || TRIM(p_tamanho) || '')
        OR p_gradeProduto <> 0
        AND gradProd.gradeProduto = p_gradeProduto
      ) a
    ),0) INTO v_quantidadeTransferencia FROM DUAL;
  END IF;

  IF p_config_160_permiteTransfSem IN ('A','B') AND p_entradaSaida = 'S' AND p_idEnderecoEstoque = 0 AND p_idNumeroSerie = 0 THEN
    SELECT COALESCE((
      SELECT SUM(a.quantidadeSaldo)
      FROM (
        SELECT
          CASE
            WHEN prod.controleEstoque IN (1,5,11)
            THEN
              COALESCE((
                SELECT SUM(a.quantidadeSaldo)
                FROM MODOCUMENTOTRANSFXITENS a
                JOIN MODOCUMENTOSTRANSFERENCIA docTransf ON docTransf.documentoTransferencia = a.documentoTransferencia
                JOIN PAMODELOSDOCUMENTO modDoc on modDoc.modeloDocumento = docTransf.modeloDocumento
                JOIN PALOCAISESTOQUE locEst ON locEst.localEstoque = a.localEstoqueSaida
                WHERE a.validoSaida = 1
                AND a.documentoTransferencia <> p_idDocumentoDesconsiderar
                AND a.gradeProduto = gradProd.gradeProduto
                AND docTransf.tipoDocumentoSaida > 100
                AND docTransf.situacaoDocTransferencia = 'E'
                AND modDoc.movimentaEstoque = 1
                AND (p_idLoteEstoque = 0 OR a.idLoteEstoque = p_idLoteEstoque)
                AND (p_estabelecimento = 0 OR docTransf.estabelecimentoSaida = p_estabelecimento)
                AND (p_indicadorPropriedadePosseIt IS NULL OR p_indicadorPropriedadePosseIt = ' ' OR locEst.indicadorPropriedadePosseItem = '' || p_indicadorPropriedadePosseIt || '')
                AND (p_pessoaParticipante = 0 OR a.pessoaParticipanteSaida = p_pessoaParticipante)
                AND (p_localEstoque = 0 AND locEst.validoEstoqueTotal = 1 OR a.localEstoqueSaida = p_localEstoque)
                AND (p_personalizacao = 0 OR a.personalizacao = p_personalizacao)
                AND (prod.controleEstoque IN (1,5) OR prod.controleEstoque = 11 AND CASE WHEN docTransf.tipoDocumentoSaida = 101 THEN p_config_82_considLenteDispon ELSE p_config_83_considLenteEstoqu END = 1)
              ),0)
            WHEN prod.controleEstoque IN (3,4)
            THEN 
              TRUNC ((
                SELECT MIN (a.quantidadeSaldo / a.quantidadeKit)
                FROM (
                  SELECT kit.gradeProduto,
                    kit.gradeProdutoFilho,
                    kit.quantidade quantidadeKit,
                    ( SELECT SUM (a.quantidadeSaldo)
                      FROM MODOCUMENTOTRANSFXITENS a
                      JOIN MODOCUMENTOSTRANSFERENCIA docTransf ON docTransf.documentoTransferencia = a.documentoTransferencia
                      JOIN PAMODELOSDOCUMENTO modDoc on modDoc.modeloDocumento = docTransf.modeloDocumento
                      JOIN PALOCAISESTOQUE locEst ON locEst.localEstoque = a.localEstoqueSaida
                      WHERE a.validoSaida = 1
                      AND a.documentoTransferencia <> p_idDocumentoDesconsiderar
                      AND a.gradeProduto = kit.gradeProdutoFilho
                      AND docTransf.tipoDocumentoSaida > 100
                      AND docTransf.situacaoDocTransferencia = 'E'
                      AND modDoc.movimentaEstoque = 1
                      AND (p_idLoteEstoque = 0 OR a.idLoteEstoque = p_idLoteEstoque)
                      AND (p_estabelecimento = 0 OR docTransf.estabelecimentoSaida = p_estabelecimento)
                      AND (p_indicadorPropriedadePosseIt IS NULL OR p_indicadorPropriedadePosseIt = ' ' OR locEst.indicadorPropriedadePosseItem = '' || p_indicadorPropriedadePosseIt || '')
                      AND (p_pessoaParticipante = 0 OR a.pessoaParticipanteSaida = p_pessoaParticipante)
                      AND (p_localEstoque = 0 AND locEst.validoEstoqueTotal = 1 OR a.localEstoqueSaida = p_localEstoque)
                      AND (p_personalizacao = 0 OR a.personalizacao = p_personalizacao)
                    ) quantidadeSaldo
                  FROM CAGRADEPRODUTOXKITSCOMBOS kit
                  WHERE kit.quantidade > 0
                  AND kit.gradeProduto <> kit.gradeProdutoFilho
                  GROUP BY kit.gradeProduto, kit.gradeProdutoFilho, kit.quantidade
                ) a
                WHERE a.gradeProduto = gradProd.gradeProduto
              ), uniMed.casasDecimaisUnidadeMedida)
            ELSE 0
          END quantidadeSaldo
        FROM CAGRADESPRODUTO gradProd
        JOIN CAPRODUTOS prod ON prod.produto = gradProd.produto
        JOIN SIUNIDADESMEDIDA uniMed ON uniMed.unidadeMedida = prod.unidadeMedida
        WHERE p_gradeProduto = 0
        AND gradProd.produto = p_produto
        AND (p_cor = 0 OR gradProd.cor = p_cor)
        AND (p_tamanho IS NULL OR p_tamanho = ' ' OR gradProd.tamanho = '' || TRIM(p_tamanho) || '')
        OR p_gradeProduto <> 0
        AND gradProd.gradeProduto = p_gradeProduto
      ) a
    ),0) INTO v_quantidadeTransfDigitacao FROM DUAL;
  END IF;

  RETURN v_quantidadeReservas - v_quantidadeOrcamento - v_quantidadeTransferencia + v_quantidadeTransfDigitacao;

END;

/

create or replace PROCEDURE ADD_ORCAMENTO_ITEM_INSERE_COMB (
    p_uniqueMachineID              IN VARCHAR2,
    p_usuarioLogado                IN NUMBER,
    p_perfilUsuarioLogado          IN NUMBER,
    p_estabelecimentoAtivo         IN NUMBER,
    p_config_64_casasDecSaidas     IN CHAR,
    p_config_65_casasDecEntrada    IN CHAR,
    p_config_209_filtrarGrupoEcon  IN NUMBER,
    p_config_330_redIcmsBasePisCof IN NUMBER,
    p_config_362_calcCustoPorGrade IN NUMBER,
    p_regMarg_tipoPreco            IN CHAR,
    p_regMarg_tabelaPreco          IN VARCHAR2,
    p_regMarg_fatorMultiplicador   IN NUMBER,
    p_regMarg_tipoPrecoB           IN CHAR,
    p_regMarg_tabelaPrecoB         IN VARCHAR2,
    p_regMarg_fatorMultiplicadorB  IN NUMBER,
    p_regMarg_reduzirImpostos      IN NUMBER,
    p_regMarg_reduzirTarifaCartao  IN NUMBER,
    p_regMarg_taxaCapitacaoCustoFi IN NUMBER,
    p_regMarg_exibPercMargemCab    IN NUMBER,
    p_regMarg_exibImagemMargemCab  IN NUMBER,
    p_regMarg_regraImagemCab       IN NUMBER,
    p_regMarg_exibPercMargemItem   IN NUMBER,
    p_regMarg_exibImagemMargemItem IN NUMBER,
    p_regMarg_regraImagemItem      IN NUMBER,
    p_regMarg_exibDetMargemItem    IN NUMBER,
    p_obrigaFinalizar              IN NUMBER,
    p_cab_orcamento                IN NUMBER,
    p_cab_origemDocumento          IN NUMBER,
    p_cab_tipoDocumento            IN NUMBER,
    p_cab_modeloDocumento          IN NUMBER,
    p_cab_entradaSaida             IN CHAR,
    p_cab_atualizaCustoMedio       IN NUMBER,
    p_cab_estabelecimento          IN NUMBER,
    p_cab_dataEmissao              IN DATE,
    p_cab_dataPreco                IN DATE,
    p_cab_pessoa                   IN NUMBER,
    p_cab_dataEntrega              IN DATE,
    p_cab_municipioFatoGerador     IN NUMBER,
    p_cab_localDestinoOperacao     IN CHAR,
    p_cab_indicadorConsumidorFinal IN CHAR,
    p_cab_tipoPagamentoFrete       IN CHAR,
    p_cab_quantidade               IN NUMBER,
    p_cab_quantidadeConvertida     IN NUMBER,
    p_cab_quantidadeSaldo          IN NUMBER,
    p_cab_pesoLiquido              IN NUMBER,
    p_cab_pesoBruto                IN NUMBER,
    p_cab_valorProdutosBruto       IN NUMBER,
    p_cab_valorProdutos            IN NUMBER,
    p_cab_valorDescontoProdutos    IN NUMBER,
    p_cab_valorAcrescimoProdutos   IN NUMBER,
    p_cab_valorServicosBruto       IN NUMBER,
    p_cab_valorServicos            IN NUMBER,
    p_cab_valorDescontoServicos    IN NUMBER,
    p_cab_valorAcrescimoServicos   IN NUMBER,
    p_cab_prazoMedioPonderado      IN NUMBER,
    p_cab_valorBasePagamento       IN NUMBER,
    p_cab_valorAVistaMinimo        IN NUMBER,
    p_cab_valorDescontoTotal       IN NUMBER,
    p_cab_valorOutrasDespTotal     IN NUMBER,
    p_cab_valorFreteTotal          IN NUMBER,
    p_cab_valorSeguroTotal         IN NUMBER,
    p_cab_valorAdicFreteMarTotal   IN NUMBER,
    p_cab_valorDespesasAduanTotal  IN NUMBER,
    p_cab_valorImpostosSomaPag     IN NUMBER,
    p_cab_valorImpostosDiminuiPag  IN NUMBER,
    p_cab_valorLiquidoItem         IN NUMBER,
    p_cab_valorTarifaCartao        IN NUMBER,
    p_cab_valorMargem              IN NUMBER,
    p_modDoc_capituloNatFiscal     IN NUMBER,
    p_modDoc_habilitaAmbiente      IN NUMBER,
    p_modDoc_tipoPreco             IN CHAR,
    p_modDoc_tabelaPreco           IN VARCHAR2,
    p_modDoc_fatorMultipPreco      IN NUMBER,
    p_modDoc_tipoPrecoB            IN CHAR,
    p_modDoc_tabelaPrecoB          IN VARCHAR2,
    p_modDoc_fatorMultipPrecoB     IN NUMBER,
    p_modDoc_diminuiDescontoPrUnit IN NUMBER,
    p_modDoc_somaAcrescimosPrUnit  IN NUMBER,
    p_modDoc_somaFreteSeguroPrUnit IN NUMBER,
    p_est_grupoFiscal              IN NUMBER,
    p_pessEst_regimeTributario     IN CHAR,
    p_munEndEst_uf                 IN CHAR,
    p_pess_indicadorInscricaoEstad IN CHAR,
    p_munEndPess_uf                IN CHAR,
    p_etOrc_situacaoOrcamento      IN NUMBER,
    p_item_vendedor                IN NUMBER,
    p_item_gradeProduto            IN NUMBER,
    p_item_movimentaEstoque        IN NUMBER,
    p_item_geraFinanceiro          IN NUMBER,
    p_item_localEstoque            IN NUMBER,
    p_item_pessoaParticipante      IN NUMBER,
    p_item_dataEntrega             IN DATE,
    p_item_quantidade              IN NUMBER,
    p_item_controleEntrega         IN NUMBER,
    p_item_usarPrecoAVista         IN NUMBER,
    p_item_percDescontoItem        IN NUMBER,
    p_item_percAcrescimoItem       IN NUMBER,
    p_item_observacoesDigitadas    IN VARCHAR2,
    p_idEnderecoEstoque            IN NUMBER,
    p_item_ambiente                IN NUMBER,
    p_item_amb_observacoes         IN VARCHAR2,
    p_atualizarTempMargem          IN NUMBER,
    p_idItemOrcamentoReferenciado  IN NUMBER,
    p_idItemDocTransferencia       IN NUMBER,
    /* Retornos */
    r_obrigaFinalizar              OUT NUMBER,
    r_cab_quantidade               OUT NUMBER,
    r_cab_quantidadeConvertida     OUT NUMBER,
    r_cab_quantidadeSaldo          OUT NUMBER,
    r_cab_pesoLiquido              OUT NUMBER,
    r_cab_pesoBruto                OUT NUMBER,
    r_cab_valorProdutosBruto       OUT NUMBER,
    r_cab_valorProdutos            OUT NUMBER,
    r_cab_valorDescontoProdutos    OUT NUMBER,
    r_cab_valorAcrescimoProdutos   OUT NUMBER,
    r_cab_valorServicosBruto       OUT NUMBER,
    r_cab_valorServicos            OUT NUMBER,
    r_cab_valorDescontoServicos    OUT NUMBER,
    r_cab_valorAcrescimoServicos   OUT NUMBER,
    r_cab_valorBasePagamento       OUT NUMBER,
    r_cab_valorAVistaMinimo        OUT NUMBER,
    r_cab_valorDescontoTotal       OUT NUMBER,
    r_cab_valorOutrasDespTotal     OUT NUMBER,
    r_cab_valorImpostosSomaPag     OUT NUMBER,
    r_cab_valorImpostosDiminuiPag  OUT NUMBER,
    r_cab_valorLiquidoItem         OUT NUMBER,
    r_cab_valorMargem              OUT NUMBER,
    r_cab_percentualMargem         OUT NUMBER,
    r_cab_imagemMargem             OUT VARCHAR2)
IS
    v_auxNumber                    NUMBER;
    v_auxVarchar                   VARCHAR2(256);
    v_item_idItemOrcamento         NUMBER;
    v_item_sequencia               NUMBER;
    v_item_servico                 NUMBER;
    v_item_operacaoFiscal          NUMBER;
    v_item_controleQuantidade      NUMBER;
    v_item_unidadeMedidaConversao  VARCHAR2(6);
    v_item_conversorQuantidade     NUMBER;
    v_item_loteMinimo              NUMBER;
    v_item_loteMultiplo            NUMBER;
    v_item_altura                  NUMBER;
    v_item_largura                 NUMBER;
    v_item_comprimento             NUMBER;
    v_item_pecas                   NUMBER;
    v_item_quantidade              NUMBER;
    v_item_quantidadeConvertida    NUMBER;
    v_item_pesoLiquido             NUMBER;
    v_item_pesoBruto               NUMBER;
    v_item_tipoPreco               CHAR(1);
    v_item_tabelaPreco             VARCHAR2(10);
    v_item_precoSugestaoAPrazo     NUMBER;
    v_item_precoSugestaoAVista     NUMBER;
    v_item_precoDesconto           NUMBER;
    v_item_precoMinimo             NUMBER;
    v_item_precoPautaTabelado      NUMBER;
    v_item_precoUnitarioBruto      NUMBER;
    v_item_precoUnitario           NUMBER;
    v_item_precoUnitarioConvertido NUMBER;
    v_item_valorProdutoServicoBrut NUMBER;
    v_item_valorProdutoServico     NUMBER;
    v_item_valorDescontoItem       NUMBER;
    v_item_valorAcrescimoItem      NUMBER;
    v_item_valorBasePagamento      NUMBER;
    v_item_valorDescontoTotal      NUMBER;
    v_item_valorOutrasDespTotal    NUMBER;
    v_item_cfop                    NUMBER;
    v_item_indicadorISSQN          CHAR(1);
    v_item_aliquotaISSQN           NUMBER;
    v_item_baseISSQN               NUMBER;
    v_item_valorISSQN              NUMBER;
    v_item_aliquotaIRRF            NUMBER;
    v_item_baseIRRF                NUMBER;
    v_item_valorIRRF               NUMBER;
    v_item_aliquotaINSS            NUMBER;
    v_item_baseINSS                NUMBER;
    v_item_valorINSS               NUMBER;
    v_item_retencaoPIS             NUMBER;
    v_item_baseRetPIS              NUMBER;
    v_item_valorRetPIS             NUMBER;
    v_item_retencaoCOFINS          NUMBER;
    v_item_baseRetCOFINS           NUMBER;
    v_item_valorRetCOFINS          NUMBER;
    v_item_retencaoCSLL            NUMBER;
    v_item_baseRetCSLL             NUMBER;
    v_item_valorRetCSLL            NUMBER;
    v_item_aliquotaII              NUMBER;
    v_item_baseII                  NUMBER;
    v_item_valorII                 NUMBER;
    v_item_aliquotaIOF             NUMBER;
    v_item_baseIOF                 NUMBER;
    v_item_valorIOF                NUMBER;
    v_item_codigoEnquadramentoIPI  NUMBER;
    v_item_stIPI                   CHAR(2);
    v_item_aliquotaIPI             NUMBER;
    v_item_valorAliquotaIPI        NUMBER;
    v_item_baseIPI                 NUMBER;
    v_item_valorIPI                NUMBER;
    v_item_stPIS                   CHAR(2);
    v_item_aliquotaPIS             NUMBER;
    v_item_valorAliquotaPIS        NUMBER;
    v_item_basePIS                 NUMBER;
    v_item_valorPIS                NUMBER;
    v_item_aliquotaPISST           NUMBER;
    v_item_valorAliquotaPISST      NUMBER;
    v_item_basePISST               NUMBER;
    v_item_valorPISST              NUMBER;
    v_item_stCOFINS                CHAR(2);
    v_item_aliquotaCOFINS          NUMBER;
    v_item_valorAliquotaCOFINS     NUMBER;
    v_item_baseCOFINS              NUMBER;
    v_item_valorCOFINS             NUMBER;
    v_item_aliquotaCOFINSST        NUMBER;
    v_item_valorAliquotaCOFINSST   NUMBER;
    v_item_baseCOFINSST            NUMBER;
    v_item_valorCOFINSST           NUMBER;
    v_item_stSimplesNacional       CHAR(3);
    v_item_creditoSimplesNacional  NUMBER;
    v_item_baseCreditoSimplesNac   NUMBER;
    v_item_valorCreditoSimplesNac  NUMBER;
    v_item_stICMS                  CHAR(2);
    v_item_modalBaseCalcICMS       CHAR(1);
    v_item_reducaoBaseICMS         NUMBER;
    v_item_aliquotaICMS            NUMBER;
    v_item_diferimentoICMS         NUMBER;
    v_item_motivoDesoneracaoICMS   CHAR(2);
    v_item_baseICMS                NUMBER;
    v_item_valorICMSOperacao       NUMBER;
    v_item_valorICMSDiferido       NUMBER;
    v_item_valorICMS               NUMBER;
    v_item_valorICMSDesoneracao    NUMBER;
    v_item_modalBaseCalcICMSST     CHAR(1);
    v_item_margemValorAdicST       NUMBER;
    v_item_reducaoBaseST           NUMBER;
    v_item_aliquotaICMSST          NUMBER;
    v_item_aliquotaSTSuportConsFin NUMBER;
    v_item_reducaoBaseICMSEfetivo  NUMBER;
    v_item_baseICMSST              NUMBER;
    v_item_valorICMSST             NUMBER;
    v_item_baseICMSSTAnteriormente NUMBER;
    v_item_valorICMSSTAnteriorment NUMBER;
    v_item_valorICMSProprioSubstit NUMBER;
    v_item_aliquotaICMSEfetivo     NUMBER;
    v_item_baseICMSEfetivo         NUMBER;
    v_item_valorICMSEfetivo        NUMBER;
    v_item_aliquotaICMSUFDestinat  NUMBER;
    v_item_aliquotaICMSInterestad  NUMBER;
    v_item_partilhaICMSInterestad  NUMBER;
    v_item_baseICMSUFDestinatario  NUMBER;
    v_item_valorICMSUFDestinatario NUMBER;
    v_item_baseICMSUFRemetente     NUMBER;
    v_item_valorICMSUFRemetente    NUMBER;
    v_item_aliquotaFCP             NUMBER;
    v_item_baseFCP                 NUMBER;
    v_item_valorFCP                NUMBER;
    v_item_aliquotaFCPST           NUMBER;
    v_item_baseFCPST               NUMBER;
    v_item_valorFCPST              NUMBER;
    v_item_aliquotaFCPSTAnteriorm  NUMBER;
    v_item_aliquotaFCPUFDestinat   NUMBER;
    v_item_baseFCPSTAnteriormente  NUMBER;
    v_item_valorFCPSTAnteriormente NUMBER;
    v_item_baseFCPUFDestinatario   NUMBER;
    v_item_valorFCPUFDestinatario  NUMBER;
    v_item_aliquotaEstImpFederais  NUMBER;
    v_item_aliquotaEstImpEstaduais NUMBER;
    v_item_aliquotaEstImpMunicipai NUMBER;
    v_item_baseEstimadaImpostos    NUMBER;
    v_item_valorEstImpFederais     NUMBER;
    v_item_valorEstImpEstaduais    NUMBER;
    v_item_valorEstImpMunicipais   NUMBER;
    v_item_valorImpostosSomaPag    NUMBER;
    v_item_valorImpostosDiminuiPag NUMBER;
    v_item_valorLiquidoItem        NUMBER;
    v_item_observacoes             VARCHAR2(4000);
    v_locEst_indicadorPropPosseIt CHAR(1);    
    CURSOR c_comb IS
      SELECT
        comb.gradeProdutoFilho,
        comb.quantidade,
        gradProd.produto,
        gradProd.cor,
        gradProd.tamanho,
        prod.controleEstoque,
        prod.unidadeMedida,
        prod.controleQuantidadeVenda,
        prod.unidadeMedidaVenda,
        prod.conversorQuantidadeVenda,
        prod.loteMinimoVenda,
        prod.loteMultiploVenda,
        prod.pesoLiquido,
        prod.pesoBruto,
        prod.altura,
        prod.largura,
        prod.comprimento,
        prod.tipoProduto,
        prod.origemMercadoria,
        prod.idNcm,
        prod.listaServicos,
        prod.precoPautaTabelado,
        unMed.casasDecimaisUnidadeMedida
      FROM CAGRADEPRODUTOXKITSCOMBOS comb
      JOIN CAGRADESPRODUTO gradProd ON gradProd.gradeProduto = comb.gradeProdutoFilho
      JOIN CAPRODUTOS prod ON prod.produto = gradProd.produto
      JOIN SIUNIDADESMEDIDA unMed ON unMed.unidadeMedida = prod.unidadeMedida
      WHERE comb.gradeProduto = p_item_gradeProduto
      AND comb.ativo = 1
      AND comb.gradeProduto <> comb.gradeProdutoFilho;
BEGIN
  r_obrigaFinalizar              := p_obrigaFinalizar;
  r_cab_quantidade               := p_cab_quantidade;
  r_cab_quantidadeConvertida     := p_cab_quantidadeConvertida;
  r_cab_quantidadeSaldo          := p_cab_quantidadeSaldo;
  r_cab_pesoLiquido              := p_cab_pesoLiquido;
  r_cab_pesoBruto                := p_cab_pesoBruto;
  r_cab_valorProdutosBruto       := p_cab_valorProdutosBruto;
  r_cab_valorProdutos            := p_cab_valorProdutos;
  r_cab_valorDescontoProdutos    := p_cab_valorDescontoProdutos;
  r_cab_valorAcrescimoProdutos   := p_cab_valorAcrescimoProdutos;
  r_cab_valorServicosBruto       := p_cab_valorServicosBruto;
  r_cab_valorServicos            := p_cab_valorServicos;
  r_cab_valorDescontoServicos    := p_cab_valorDescontoServicos;
  r_cab_valorAcrescimoServicos   := p_cab_valorAcrescimoServicos;
  r_cab_valorBasePagamento       := p_cab_valorBasePagamento;
  r_cab_valorAVistaMinimo        := p_cab_valorAVistaMinimo;
  r_cab_valorDescontoTotal       := p_cab_valorDescontoTotal;
  r_cab_valorOutrasDespTotal     := p_cab_valorOutrasDespTotal;
  r_cab_valorImpostosSomaPag     := p_cab_valorImpostosSomaPag;
  r_cab_valorImpostosDiminuiPag  := p_cab_valorImpostosDiminuiPag;
  r_cab_valorLiquidoItem         := p_cab_valorLiquidoItem;
  r_cab_valorMargem              := p_cab_valorMargem;
  SELECT locEst.indicadorPropriedadePosseItem
  INTO v_locEst_indicadorPropPosseIt
  FROM PALOCAISESTOQUE locEst
  WHERE locEst.localEstoque = p_item_localEstoque;
  FOR comb IN c_comb LOOP
    v_item_quantidade := ROUND (p_item_quantidade * comb.quantidade, comb.casasDecimaisUnidadeMedida);
    IF comb.controleEstoque = 3 THEN
      ADD_ORCAMENTO_ITEM_INSERE_COMB (
        p_uniqueMachineID,
        p_usuarioLogado,
        p_perfilUsuarioLogado,
        p_estabelecimentoAtivo,
        p_config_64_casasDecSaidas,
        p_config_65_casasDecEntrada,
        p_config_209_filtrarGrupoEcon,
        p_config_330_redIcmsBasePisCof,
        p_config_362_calcCustoPorGrade,
        p_regMarg_tipoPreco,
        p_regMarg_tabelaPreco,
        p_regMarg_fatorMultiplicador,
        p_regMarg_tipoPrecoB,
        p_regMarg_tabelaPrecoB,
        p_regMarg_fatorMultiplicadorB,
        p_regMarg_reduzirImpostos,
        p_regMarg_reduzirTarifaCartao,
        p_regMarg_taxaCapitacaoCustoFi,
        p_regMarg_exibPercMargemCab,
        p_regMarg_exibImagemMargemCab,
        p_regMarg_regraImagemCab,
        p_regMarg_exibPercMargemItem,
        p_regMarg_exibImagemMargemItem,
        p_regMarg_regraImagemItem,
        p_regMarg_exibDetMargemItem,
        r_obrigaFinalizar,
        p_cab_orcamento,
        p_cab_origemDocumento,
        p_cab_tipoDocumento,
        p_cab_modeloDocumento,
        p_cab_entradaSaida,
        p_cab_atualizaCustoMedio,
        p_cab_estabelecimento,
        p_cab_dataEmissao,
        p_cab_dataPreco,
        p_cab_pessoa,
        p_cab_dataEntrega,
        p_cab_municipioFatoGerador,
        p_cab_localDestinoOperacao,
        p_cab_indicadorConsumidorFinal,
        p_cab_tipoPagamentoFrete,
        r_cab_quantidade,
        r_cab_quantidadeConvertida,
        r_cab_quantidadeSaldo,
        r_cab_pesoLiquido,
        r_cab_pesoBruto,
        r_cab_valorProdutosBruto,
        r_cab_valorProdutos,
        r_cab_valorDescontoProdutos,
        r_cab_valorAcrescimoProdutos,
        r_cab_valorServicosBruto,
        r_cab_valorServicos,
        r_cab_valorDescontoServicos,
        r_cab_valorAcrescimoServicos,
        p_cab_prazoMedioPonderado,
        r_cab_valorBasePagamento,
        r_cab_valorAVistaMinimo,
        r_cab_valorDescontoTotal,
        r_cab_valorOutrasDespTotal,
        p_cab_valorFreteTotal,
        p_cab_valorSeguroTotal,
        p_cab_valorAdicFreteMarTotal,
        p_cab_valorDespesasAduanTotal,
        r_cab_valorImpostosSomaPag,
        r_cab_valorImpostosDiminuiPag,
        r_cab_valorLiquidoItem,
        p_cab_valorTarifaCartao,
        r_cab_valorMargem,
        p_modDoc_capituloNatFiscal,
        p_modDoc_habilitaAmbiente,
        p_modDoc_tipoPreco,
        p_modDoc_tabelaPreco,
        p_modDoc_fatorMultipPreco,
        p_modDoc_tipoPrecoB,
        p_modDoc_tabelaPrecoB,
        p_modDoc_fatorMultipPrecoB,
        p_modDoc_diminuiDescontoPrUnit,
        p_modDoc_somaAcrescimosPrUnit,
        p_modDoc_somaFreteSeguroPrUnit,
        p_est_grupoFiscal,
        p_pessEst_regimeTributario,
        p_munEndEst_uf,
        p_pess_indicadorInscricaoEstad,
        p_munEndPess_uf,
        p_etOrc_situacaoOrcamento,
        p_item_vendedor,
        comb.gradeProdutoFilho,
        p_item_movimentaEstoque,
        p_item_geraFinanceiro,
        p_item_localEstoque,
        p_item_pessoaParticipante,
        p_item_dataEntrega,
        v_item_quantidade,
        p_item_controleEntrega,
        p_item_usarPrecoAVista,
        p_item_percDescontoItem,
        p_item_percAcrescimoItem,
        p_item_observacoesDigitadas,
        p_idEnderecoEstoque,
        p_item_ambiente,
        p_item_amb_observacoes,
        p_atualizarTempMargem,
        p_idItemOrcamentoReferenciado,
        p_idItemDocTransferencia,
        /* Retornos */
        r_obrigaFinalizar,
        r_cab_quantidade,
        r_cab_quantidadeConvertida,
        r_cab_quantidadeSaldo,
        r_cab_pesoLiquido,
        r_cab_pesoBruto,
        r_cab_valorProdutosBruto,
        r_cab_valorProdutos,
        r_cab_valorDescontoProdutos,
        r_cab_valorAcrescimoProdutos,
        r_cab_valorServicosBruto,
        r_cab_valorServicos,
        r_cab_valorDescontoServicos,
        r_cab_valorAcrescimoServicos,
        r_cab_valorBasePagamento,
        r_cab_valorAVistaMinimo,
        r_cab_valorDescontoTotal,
        r_cab_valorOutrasDespTotal,
        r_cab_valorImpostosSomaPag,
        r_cab_valorImpostosDiminuiPag,
        r_cab_valorLiquidoItem,
        r_cab_valorMargem,
        r_cab_percentualMargem,
        r_cab_imagemMargem
      );
    ELSE
      v_item_idItemOrcamento := 0;
      ADD_ITEM_PROD_DADOS_BUSCA (
        p_cab_entradaSaida,
        0,
        p_cab_pessoa,
        v_item_quantidade,
        comb.produto,
        comb.unidadeMedida,
        comb.controleQuantidadeVenda,
        comb.unidadeMedidaVenda,
        comb.conversorQuantidadeVenda,
        comb.loteMinimoVenda,
        comb.loteMultiploVenda,
        comb.pesoLiquido,
        comb.pesoBruto,
        comb.altura,
        comb.largura,
        comb.comprimento,
        comb.tipoProduto,
        comb.precoPautaTabelado,
        comb.casasDecimaisUnidadeMedida,
        /* Retornos */
        v_item_servico,
        v_item_controleQuantidade,
        v_item_unidadeMedidaConversao,
        v_item_conversorQuantidade,
        v_item_loteMinimo,
        v_item_loteMultiplo,
        v_item_altura,
        v_item_largura,
        v_item_comprimento,
        v_item_pecas,
        v_item_quantidadeConvertida,
        v_item_pesoLiquido,
        v_item_pesoBruto,
        v_item_precoPautaTabelado
      );
      ADD_BUSCA_PRECO (
        p_config_64_casasDecSaidas,
        p_config_65_casasDecEntrada,
        p_config_209_filtrarGrupoEcon,
        p_config_362_calcCustoPorGrade,
        p_perfilUsuarioLogado,
        p_usuarioLogado,
        p_cab_entradaSaida,
        0,
        p_cab_estabelecimento,
        NULL,
        p_cab_dataPreco,
        p_cab_pessoa,
        p_modDoc_capituloNatFiscal,
        p_modDoc_tipoPreco,
        p_modDoc_tabelaPreco,
        p_modDoc_fatorMultipPreco,
        p_modDoc_tipoPrecoB,
        p_modDoc_tabelaPrecoB,
        p_modDoc_fatorMultipPrecoB,
        p_munEndEst_uf,
        p_munEndPess_uf,
        p_item_vendedor,
        0,
        0,
        p_item_localEstoque,
        p_item_pessoaParticipante,
        v_item_quantidade,
        comb.produto,
        comb.cor,
        comb.tamanho,
        comb.controleEstoque,
        v_locEst_indicadorPropPosseIt,
        0,
        v_item_precoSugestaoAPrazo,
        v_item_precoSugestaoAVista,
        v_item_tipoPreco,
        v_item_tabelaPreco,
        /* Retornos */
        v_item_tipoPreco,
        v_item_tabelaPreco,
        v_item_precoSugestaoAPrazo,
        v_item_precoSugestaoAVista,
        v_item_precoDesconto,
        v_item_precoMinimo,
        v_auxNumber,
        v_auxNumber,
        v_auxNumber,
        v_auxNumber,
        v_auxNumber,
        v_auxNumber,
        v_auxNumber,
        v_auxNumber);
      v_item_precoUnitarioBruto      := CASE WHEN p_item_usarPrecoAVista = 1 THEN v_item_precoSugestaoAVista ELSE v_item_precoSugestaoAPrazo END;
      v_item_precoUnitario           := v_item_precoUnitarioBruto;
      v_item_valorProdutoServicoBrut := ROUND ((v_item_quantidade * v_item_precoUnitarioBruto), 2);
      v_item_valorProdutoServico     := v_item_valorProdutoServicoBrut;
      v_item_valorDescontoItem       := ROUND ((v_item_valorProdutoServico * p_item_percDescontoItem / 100), 2);
      v_item_valorAcrescimoItem      := ROUND ((v_item_valorProdutoServico * p_item_percAcrescimoItem / 100), 2);
      v_item_operacaoFiscal          := FUNC_ADD_BUSCA_OPERACAO_FISCAL (
        p_cab_modeloDocumento,
        p_cab_entradaSaida,
        p_cab_pessoa,
        0,
        p_cab_municipioFatoGerador,
        p_cab_indicadorConsumidorFinal,
        p_est_grupoFiscal,
        p_pessEst_regimeTributario,
        p_munEndEst_uf,
        p_pess_indicadorInscricaoEstad,
        p_munEndPess_uf,
        comb.produto
      );
      ADD_ITEM_OPERACAO_FISCAL_BUSCA (
        1,
        p_cab_origemDocumento,
        p_cab_tipoDocumento,
        p_cab_entradaSaida,
        0,
        p_cab_estabelecimento,
        0,
        TRUNC(SYSDATE),
        p_cab_pessoa,
        0,
        p_cab_indicadorConsumidorFinal,
        p_item_movimentaEstoque,
        p_item_geraFinanceiro,
        p_munEndEst_uf,
        p_munEndPess_uf,
        v_item_operacaoFiscal,
        comb.produto,
        comb.tipoProduto,
        comb.origemMercadoria,
        comb.idNcm,
        comb.listaServicos,
        0,
        0,
        v_item_cfop,
        1,
        v_item_indicadorISSQN,
        v_item_aliquotaISSQN,
        1,
        v_item_aliquotaIRRF,
        1,
        v_item_aliquotaINSS,
        1,
        v_item_retencaoPIS,
        1,
        v_item_retencaoCOFINS,
        1,
        v_item_retencaoCSLL,
        1,
        v_item_aliquotaII,
        1,
        v_item_aliquotaIOF,
        1,
        v_item_codigoEnquadramentoIPI,
        v_item_stIPI,
        v_item_aliquotaIPI,
        v_item_valorAliquotaIPI,
        1,
        v_item_stPIS,
        v_item_aliquotaPIS,
        v_item_valorAliquotaPIS,
        1,
        v_item_aliquotaPISST,
        v_item_valorAliquotaPISST,
        1,
        v_item_stCOFINS,
        v_item_aliquotaCOFINS,
        v_item_valorAliquotaCOFINS,
        1,
        v_item_aliquotaCOFINSST,
        v_item_valorAliquotaCOFINSST,
        1,
        v_item_stSimplesNacional,
        v_item_creditoSimplesNacional,
        1,
        v_item_stICMS,
        v_item_modalBaseCalcICMS,
        v_item_reducaoBaseICMS,
        v_item_aliquotaICMS,
        v_item_diferimentoICMS,
        v_item_motivoDesoneracaoICMS,
        0,
        1,
        v_item_modalBaseCalcICMSST,
        v_item_margemValorAdicST,
        v_item_reducaoBaseST,
        v_item_aliquotaICMSST,
        1,
        v_item_aliquotaSTSuportConsFin,
        v_item_reducaoBaseICMSEfetivo,
        v_item_aliquotaICMSEfetivo,
        0,
        '  ',
        0,
        0,
        0,
        0,
        0,
        0,
        0,
        1,
        v_item_aliquotaICMSUFDestinat,
        v_item_aliquotaICMSInterestad,
        v_item_partilhaICMSInterestad,
        1,
        v_item_aliquotaFCP,
        v_item_aliquotaFCPST,
        v_item_aliquotaFCPSTAnteriorm,
        v_item_aliquotaFCPUFDestinat,
        1,
        v_item_aliquotaEstImpFederais,
        v_item_aliquotaEstImpEstaduais,
        v_item_aliquotaEstImpMunicipai,
        /* Retornos */
        v_auxNumber,
        v_auxNumber,
        v_auxNumber,
        v_item_cfop,
        v_item_indicadorISSQN,
        v_item_aliquotaISSQN,
        v_item_aliquotaIRRF,
        v_item_aliquotaINSS,
        v_item_retencaoPIS,
        v_item_retencaoCOFINS,
        v_item_retencaoCSLL,
        v_item_aliquotaII,
        v_item_aliquotaIOF,
        v_item_codigoEnquadramentoIPI,
        v_item_stIPI,
        v_item_aliquotaIPI,
        v_item_valorAliquotaIPI,
        v_item_stPIS,
        v_item_aliquotaPIS,
        v_item_valorAliquotaPIS,
        v_item_aliquotaPISST,
        v_item_valorAliquotaPISST,
        v_item_stCOFINS,
        v_item_aliquotaCOFINS,
        v_item_valorAliquotaCOFINS,
        v_item_aliquotaCOFINSST,
        v_item_valorAliquotaCOFINSST,
        v_item_stSimplesNacional,
        v_item_creditoSimplesNacional,
        v_item_stICMS,
        v_item_modalBaseCalcICMS,
        v_item_reducaoBaseICMS,
        v_item_aliquotaICMS,
        v_item_diferimentoICMS,
        v_item_motivoDesoneracaoICMS,
        v_auxNumber,
        v_item_modalBaseCalcICMSST,
        v_item_margemValorAdicST,
        v_item_reducaoBaseST,
        v_item_aliquotaICMSST,
        v_item_aliquotaSTSuportConsFin,
        v_item_reducaoBaseICMSEfetivo,
        v_item_aliquotaICMSEfetivo,
        v_auxVarchar,
        v_auxNumber,
        v_auxNumber,
        v_auxNumber,
        v_auxNumber,
        v_auxNumber,
        v_auxNumber,
        v_item_aliquotaICMSUFDestinat,
        v_item_aliquotaICMSInterestad,
        v_item_partilhaICMSInterestad,
        v_item_aliquotaFCP,
        v_item_aliquotaFCPST,
        v_item_aliquotaFCPSTAnteriorm,
        v_item_aliquotaFCPUFDestinat,
        v_item_aliquotaEstImpFederais,
        v_item_aliquotaEstImpEstaduais,
        v_item_aliquotaEstImpMunicipai);      
      v_item_observacoes := FUNC_ADD_MONTA_OBSERVACAO_ITEM (
        p_uniqueMachineID,
        p_perfilUsuarioLogado,
        p_usuarioLogado,
        ' ',
        0,
        0,
        0,
        0,
        'O',
        p_cab_entradaSaida,
        0,
        p_cab_estabelecimento,
        0,
        comb.gradeProdutoFilho,
        0,
        0,
        0,
        v_item_controleQuantidade,
        v_item_loteMultiplo,
        v_item_altura,
        v_item_largura,
        v_item_comprimento,
        v_item_quantidade,
        p_item_observacoesDigitadas);
      ADD_CALCULA_TOTAIS_ITEM (
        p_uniqueMachineID,
        ' ',
        0,
        0,
        0,
        0,
        'O',
        p_cab_entradaSaida,
        0,
        p_cab_tipoPagamentoFrete,
        p_cab_tipoPagamentoFrete,
        0,
        p_modDoc_diminuiDescontoPrUnit,
        p_modDoc_somaAcrescimosPrUnit,
        p_modDoc_somaFreteSeguroPrUnit,
        0,
        v_item_quantidade,
        v_item_quantidadeConvertida,
        v_item_precoUnitarioBruto,
        v_item_precoUnitario,
        v_item_valorProdutoServicoBrut,
        v_item_valorProdutoServico,
        v_item_valorDescontoItem,
        v_item_valorAcrescimoItem,
        0,
        0,
        0,
        0,
        0,
        0,
        0,
        0,
        0,
        0,
        0,
        0,
        0,
        0,
        0,
        v_item_valorDescontoTotal,
        v_item_valorOutrasDespTotal,
        0,
        0,
        0,
        0,
        0,
        0,
        0,
        /* Retornos */
        v_auxNumber,
        v_auxNumber,
        v_item_precoUnitario,
        v_auxNumber,
        v_item_precoUnitarioConvertido,
        v_auxNumber,
        v_item_valorProdutoServico,
        v_auxNumber,
        v_auxNumber,
        v_auxNumber,
        v_auxNumber,
        v_item_valorDescontoTotal,
        v_item_valorOutrasDespTotal,
        v_auxNumber,
        v_auxNumber,
        v_auxNumber,
        v_auxNumber,
        v_auxNumber);
      ADD_CALCULA_IMPOSTOS_ITEM (
        p_config_64_casasDecSaidas,
        p_config_209_filtrarGrupoEcon,
        p_config_330_redIcmsBasePisCof,
        p_config_362_calcCustoPorGrade,
        p_cab_entradaSaida,
        0,
        p_cab_estabelecimento,
        0,
        p_cab_dataEmissao,
        p_cab_pessoa,
        p_cab_localDestinoOperacao,
        p_cab_indicadorConsumidorFinal,
        p_cab_tipoPagamentoFrete,
        p_pess_indicadorInscricaoEstad,
        0,
        v_item_quantidade,
        v_item_precoPautaTabelado,
        v_item_valorProdutoServico,
        0,
        0,
        v_item_valorDescontoTotal,
        v_item_valorOutrasDespTotal,
        0,
        0,
        v_item_cfop,
        1,
        v_item_indicadorISSQN,
        v_item_aliquotaISSQN,
        0,
        0,
        1,
        v_item_aliquotaIRRF,
        0,
        0,
        1,
        v_item_aliquotaINSS,
        0,
        0,
        1,
        v_item_retencaoPIS,
        0,
        0,
        1,
        v_item_retencaoCOFINS,
        0,
        0,
        1,
        v_item_retencaoCSLL,
        0,
        0,
        1,
        v_item_aliquotaII,
        0,
        0,
        1,
        v_item_aliquotaIOF,
        0,
        0,
        1,
        v_item_aliquotaIPI,
        v_item_valorAliquotaIPI,
        0,
        0,
        0,
        1,
        v_item_aliquotaPIS,
        v_item_valorAliquotaPIS,
        0,
        0,
        1,
        v_item_aliquotaPISST,
        v_item_valorAliquotaPISST,
        0,
        0,
        1,
        v_item_aliquotaCOFINS,
        v_item_valorAliquotaCOFINS,
        0,
        0,
        1,
        v_item_aliquotaCOFINSST,
        v_item_valorAliquotaCOFINSST,
        0,
        0,
        1,
        v_item_stSimplesNacional,
        v_item_creditoSimplesNacional,
        0,
        0,
        1,
        v_item_stICMS,
        v_item_modalBaseCalcICMS,
        v_item_reducaoBaseICMS,
        v_item_aliquotaICMS,
        v_item_diferimentoICMS,
        0,
        0,
        0,
        0,
        0,
        1,
        v_item_modalBaseCalcICMSST,
        v_item_margemValorAdicST,
        v_item_reducaoBaseST,
        v_item_aliquotaICMSST,
        0,
        0,
        1,
        0,
        0,
        0,
        v_item_reducaoBaseICMSEfetivo,
        v_item_aliquotaICMSEfetivo,
        0,
        0,
        0,
        '  ',
        0,
        0,
        0,
        0,
        0,
        0,
        0,
        0,
        0,
        0,
        0,
        1,
        v_item_aliquotaICMSUFDestinat,
        v_item_aliquotaICMSInterestad,
        v_item_partilhaICMSInterestad,
        0,
        0,
        0,
        0,
        1,
        v_item_aliquotaFCP,
        0,
        0,
        v_item_aliquotaFCPST,
        0,
        0,
        v_item_aliquotaFCPSTAnteriorm,
        0,
        0,
        v_item_aliquotaFCPUFDestinat,
        0,
        0,
        1,
        v_item_aliquotaEstImpFederais,
        v_item_aliquotaEstImpEstaduais,
        v_item_aliquotaEstImpMunicipai,
        0,
        0,
        0,
        0,
        comb.produto,
        comb.cor,
        comb.tamanho,
        comb.controleEstoque,
        comb.tipoProduto,
        /* Retornos */
        v_item_baseISSQN,
        v_item_valorISSQN,
        v_item_baseIRRF,
        v_item_valorIRRF,
        v_item_baseINSS,
        v_item_valorINSS,
        v_item_baseRetPIS,
        v_item_valorRetPIS,
        v_item_baseRetCOFINS,
        v_item_valorRetCOFINS,
        v_item_baseRetCSLL,
        v_item_valorRetCSLL,
        v_item_baseII,
        v_item_valorII,
        v_item_baseIOF,
        v_item_valorIOF,
        v_item_baseIPI,
        v_item_valorIPI,
        v_item_basePIS,
        v_item_valorPIS,
        v_item_basePISST,
        v_item_valorPISST,
        v_item_baseCOFINS,
        v_item_valorCOFINS,
        v_item_baseCOFINSST,
        v_item_valorCOFINSST,
        v_item_baseCreditoSimplesNac,
        v_item_valorCreditoSimplesNac,
        v_item_baseICMS,
        v_item_valorICMSOperacao,
        v_item_valorICMSDiferido,
        v_item_valorICMS,
        v_item_valorICMSDesoneracao,
        v_item_baseICMSST,
        v_item_valorICMSST,
        v_item_baseICMSSTAnteriormente,
        v_item_valorICMSSTAnteriorment,
        v_item_valorICMSProprioSubstit,
        v_item_baseICMSEfetivo,
        v_item_valorICMSEfetivo,
        v_auxNumber,
        v_auxNumber,
        v_auxNumber,
        v_auxNumber,
        v_auxNumber,
        v_item_baseICMSUFDestinatario,
        v_item_valorICMSUFDestinatario,
        v_item_baseICMSUFRemetente,
        v_item_valorICMSUFRemetente,
        v_item_baseFCP,
        v_item_valorFCP,
        v_item_baseFCPST,
        v_item_valorFCPST,
        v_item_baseFCPSTAnteriormente,
        v_item_valorFCPSTAnteriormente,
        v_item_baseFCPUFDestinatario,
        v_item_valorFCPUFDestinatario,
        v_item_baseEstimadaImpostos,
        v_item_valorEstImpFederais,
        v_item_valorEstImpEstaduais,
        v_item_valorEstImpMunicipais);
      ADD_CALCULA_VALOR_LIQUIDO (
        0,
        p_cab_tipoPagamentoFrete,
        p_item_geraFinanceiro,
        v_item_valorProdutoServico,
        0,
        0,
        0,
        0,
        0,
        v_item_valorDescontoTotal,
        v_item_valorOutrasDespTotal,
        v_item_valorIRRF,
        v_item_valorINSS,
        v_item_valorRetPIS,
        v_item_valorRetCOFINS,
        v_item_valorRetCSLL,
        v_item_valorII,
        v_item_valorIOF,
        v_item_valorIPI,
        0,
        v_item_valorICMSST,
        0,
        0,
        0,
        /* Retornos */
        v_item_valorBasePagamento,
        v_item_valorImpostosSomaPag,
        v_item_valorImpostosDiminuiPag,
        v_item_valorLiquidoItem);
      r_cab_quantidade               := r_cab_quantidade + v_item_quantidade;
      r_cab_quantidadeConvertida     := r_cab_quantidadeConvertida + v_item_quantidadeConvertida;
      r_cab_quantidadeSaldo          := r_cab_quantidadeSaldo + v_item_quantidade;
      r_cab_pesoLiquido              := r_cab_pesoLiquido + v_item_pesoLiquido;
      r_cab_pesoBruto                := r_cab_pesoBruto + v_item_pesoBruto;
      IF v_item_servico = 1 THEN
        r_cab_valorServicosBruto     := r_cab_valorServicosBruto + v_item_valorProdutoServicoBrut;
        r_cab_valorServicos          := r_cab_valorServicos + v_item_valorProdutoServico;
        r_cab_valorDescontoServicos  := r_cab_valorDescontoServicos + v_item_valorDescontoItem;
        r_cab_valorAcrescimoServicos := r_cab_valorAcrescimoServicos + v_item_valorAcrescimoItem;
      ELSE 
        r_cab_valorProdutosBruto     := r_cab_valorProdutosBruto + v_item_valorProdutoServicoBrut;
        r_cab_valorProdutos          := r_cab_valorProdutos + v_item_valorProdutoServico;
        r_cab_valorDescontoProdutos  := r_cab_valorDescontoProdutos + v_item_valorDescontoItem;
        r_cab_valorAcrescimoProdutos := r_cab_valorAcrescimoProdutos + v_item_valorAcrescimoItem;
      END IF;
      r_cab_valorBasePagamento       := r_cab_valorBasePagamento + v_item_valorBasePagamento;
      IF p_item_usarPrecoAVista = 1 AND p_item_geraFinanceiro = 1 THEN
        r_cab_valorAVistaMinimo      := r_cab_valorAVistaMinimo + v_item_valorProdutoServico - v_item_valorDescontoTotal + v_item_valorOutrasDespTotal;
      END IF;
      r_cab_valorDescontoTotal       := r_cab_valorDescontoTotal + v_item_valorDescontoTotal;
      r_cab_valorOutrasDespTotal     := r_cab_valorOutrasDespTotal + v_item_valorOutrasDespTotal;
      r_cab_valorImpostosSomaPag     := r_cab_valorImpostosSomaPag + v_item_valorImpostosSomaPag;
      r_cab_valorImpostosDiminuiPag  := r_cab_valorImpostosDiminuiPag + v_item_valorImpostosDiminuiPag;
      r_cab_valorLiquidoItem         := r_cab_valorLiquidoItem + v_item_valorLiquidoItem;
      SELECT COALESCE (MAX (sequencia),0) + 1
      INTO v_item_sequencia
      FROM MOORCAMENTOXITENS
      WHERE orcamento = p_cab_orcamento;
      ADD_ORCAMENTO_ITEM_GRAVA (
        p_estabelecimentoAtivo,
        r_obrigaFinalizar,
        p_cab_orcamento,
        p_cab_modeloDocumento,
        p_cab_entradaSaida,
        p_cab_estabelecimento,
        p_cab_dataEmissao,
        p_cab_dataEntrega,
        p_etOrc_situacaoOrcamento,
        0,
        v_item_sequencia,
        0,
        0,
        p_item_vendedor,
        0,
        comb.gradeProdutoFilho,
        v_item_servico,
        0,
        'A',
        0,
        0,
        0,
        0,
        0,
        999,
        v_item_operacaoFiscal,
        0,
        p_item_movimentaEstoque,
        p_item_geraFinanceiro,
        0,
        p_item_localEstoque,
        0,
        p_item_pessoaParticipante,
        p_item_dataEntrega,
        v_item_controleQuantidade,
        v_item_unidadeMedidaConversao,
        v_item_conversorQuantidade,
        v_item_loteMinimo,
        v_item_loteMultiplo,
        v_item_altura,
        v_item_largura,
        v_item_comprimento,
        v_item_pecas,
        v_item_quantidade,
        v_item_quantidadeConvertida,
        0,
        v_item_quantidade,
        p_item_controleEntrega,
        1,
        v_item_pesoLiquido,
        v_item_pesoBruto,
        v_item_tipoPreco,
        v_item_tabelaPreco,
        v_item_precoSugestaoAPrazo,
        v_item_precoSugestaoAVista,
        v_item_precoDesconto,
        v_item_precoMinimo,
        p_item_usarPrecoAVista,
        v_item_precoPautaTabelado,
        v_item_precoUnitarioBruto,
        0,
        v_item_precoUnitario,
        v_item_precoUnitarioConvertido,
        v_item_valorProdutoServicoBrut,
        v_item_valorProdutoServico,
        p_item_percDescontoItem,
        v_item_valorDescontoItem,
        p_item_percAcrescimoItem,
        v_item_valorAcrescimoItem,
        0,
        0,
        0,
        0,
        0,
        0,
        0,
        0,
        0,
        0,
        v_item_valorBasePagamento,
        0,
        0,
        0,
        0,
        0,
        v_item_valorDescontoTotal,
        v_item_valorOutrasDespTotal,
        0,
        0,
        v_item_cfop,
        v_item_indicadorISSQN,
        v_item_aliquotaISSQN,
        v_item_baseISSQN,
        v_item_valorISSQN,
        v_item_aliquotaIRRF,
        v_item_baseIRRF,
        v_item_valorIRRF,
        v_item_aliquotaINSS,
        v_item_baseINSS,
        v_item_valorINSS,
        v_item_retencaoPIS,
        v_item_baseRetPIS,
        v_item_valorRetPIS,
        v_item_retencaoCOFINS,
        v_item_baseRetCOFINS,
        v_item_valorRetCOFINS,
        v_item_retencaoCSLL,
        v_item_baseRetCSLL,
        v_item_valorRetCSLL,
        v_item_aliquotaII,
        v_item_baseII,
        v_item_valorII,
        v_item_aliquotaIOF,
        v_item_baseIOF,
        v_item_valorIOF,
        v_item_codigoEnquadramentoIPI,
        v_item_stIPI,
        v_item_aliquotaIPI,
        v_item_valorAliquotaIPI,
        v_item_baseIPI,
        v_item_valorIPI,
        v_item_stPIS,
        v_item_aliquotaPIS,
        v_item_valorAliquotaPIS,
        v_item_basePIS,
        v_item_valorPIS,
        v_item_aliquotaPISST,
        v_item_valorAliquotaPISST,
        v_item_basePISST,
        v_item_valorPISST,
        v_item_stCOFINS,
        v_item_aliquotaCOFINS,
        v_item_valorAliquotaCOFINS,
        v_item_baseCOFINS,
        v_item_valorCOFINS,
        v_item_aliquotaCOFINSST,
        v_item_valorAliquotaCOFINSST,
        v_item_baseCOFINSST,
        v_item_valorCOFINSST,
        v_item_stSimplesNacional,
        v_item_creditoSimplesNacional,
        v_item_baseCreditoSimplesNac,
        v_item_valorCreditoSimplesNac,
        v_item_stICMS,
        v_item_modalBaseCalcICMS,
        v_item_reducaoBaseICMS,
        v_item_aliquotaICMS,
        v_item_diferimentoICMS,
        v_item_motivoDesoneracaoICMS,
        v_item_baseICMS,
        v_item_valorICMSOperacao,
        v_item_valorICMSDiferido,
        v_item_valorICMS,
        v_item_valorICMSDesoneracao,
        v_item_modalBaseCalcICMSST,
        v_item_margemValorAdicST,
        v_item_reducaoBaseST,
        v_item_aliquotaICMSST,
        v_item_aliquotaSTSuportConsFin,
        v_item_baseICMSST,
        v_item_valorICMSST,
        v_item_baseICMSSTAnteriormente,
        v_item_valorICMSSTAnteriorment,
        v_item_valorICMSProprioSubstit,
        v_item_reducaoBaseICMSEfetivo,
        v_item_aliquotaICMSEfetivo,
        v_item_baseICMSEfetivo,
        v_item_valorICMSEfetivo,
        v_item_aliquotaICMSUFDestinat,
        v_item_aliquotaICMSInterestad,
        v_item_partilhaICMSInterestad,
        v_item_baseICMSUFDestinatario,
        v_item_valorICMSUFDestinatario,
        v_item_baseICMSUFRemetente,
        v_item_valorICMSUFRemetente,
        v_item_aliquotaFCP,
        v_item_baseFCP,
        v_item_valorFCP,
        v_item_aliquotaFCPST,
        v_item_baseFCPST,
        v_item_valorFCPST,
        v_item_aliquotaFCPSTAnteriorm,
        v_item_baseFCPSTAnteriormente,
        v_item_valorFCPSTAnteriormente,
        v_item_aliquotaFCPUFDestinat,
        v_item_baseFCPUFDestinatario,
        v_item_valorFCPUFDestinatario,
        v_item_aliquotaEstImpFederais,
        v_item_aliquotaEstImpEstaduais,
        v_item_aliquotaEstImpMunicipai,
        v_item_baseEstimadaImpostos,
        v_item_valorEstImpFederais,
        v_item_valorEstImpEstaduais,
        v_item_valorEstImpMunicipais,
        v_item_valorImpostosSomaPag,
        v_item_valorImpostosDiminuiPag,
        v_item_valorLiquidoItem,
        p_item_observacoesDigitadas,
        v_item_observacoes,
        /* Retornos */
        r_obrigaFinalizar,
        v_item_idItemOrcamento);
      IF p_modDoc_habilitaAmbiente = 1 THEN
        MERGE INTO MOORCAMENTOXAMBIENTES a
        USING (
          SELECT
            v_item_idItemOrcamento idItemOrcamento,
            p_item_ambiente        ambiente,
            p_item_amb_observacoes observacoes
          FROM DUAL
        ) b ON (a.idItemOrcamento = b.idItemOrcamento)
        WHEN MATCHED THEN
          UPDATE SET
            a.ambiente    = b.ambiente,
            a.observacoes = b.observacoes
        WHEN NOT MATCHED THEN
          INSERT (
            idItemOrcamento,
            ambiente,
            observacoes
          ) VALUES (
            b.idItemOrcamento,
            b.ambiente,
            b.observacoes
          );
      END IF;
      IF p_idItemOrcamentoReferenciado > 0 THEN
        ADD_ORCAMENTO_ITEM_ORC_GRAVA (
          p_estabelecimentoAtivo,
          v_item_idItemOrcamento,
          p_idItemOrcamentoReferenciado,
          v_item_quantidade
        );
      END IF;
      IF p_idItemDocTransferencia > 0 THEN
        ADD_ORCAMENTO_ITEM_TRANS_GRAVA (
          p_estabelecimentoAtivo,
          p_cab_entradaSaida,
          p_idItemDocTransferencia,
          v_item_idItemOrcamento,
          v_item_quantidade
        );
      END IF;
      IF p_idEnderecoEstoque > 0 THEN
        ADD_ORCAMENTO_ITEM_ENDER_GRAVA (
          p_estabelecimentoAtivo,
          0,
          v_item_idItemOrcamento,
          p_idEnderecoEstoque,
          v_item_quantidade,
          v_item_quantidade,
          v_item_observacoes,
          /* Retornos */
          v_auxNumber
        );
      END IF;
      IF p_atualizarTempMargem = 1 
        AND (
          p_regMarg_exibPercMargemCab = 1
          OR p_regMarg_exibImagemMargemCab = 1
          OR p_regMarg_exibPercMargemItem = 1
          OR p_regMarg_exibImagemMargemItem = 1
          OR p_regMarg_exibDetMargemItem = 1
        ) AND p_cab_tipoDocumento IN (101,102,301,501,503) THEN
        ADD_TEMP_MARGEM_ITEM_GRAVA (
          p_uniqueMachineID,
          p_config_65_casasDecEntrada,
          p_config_209_filtrarGrupoEcon,
          p_config_362_calcCustoPorGrade,
          p_regMarg_tipoPreco,
          p_regMarg_tabelaPreco,
          p_regMarg_fatorMultiplicador,
          p_regMarg_tipoPrecoB,
          p_regMarg_tabelaPrecoB,
          p_regMarg_fatorMultiplicadorB,
          p_regMarg_reduzirImpostos,
          p_regMarg_reduzirTarifaCartao,
          p_regMarg_taxaCapitacaoCustoFi,
          p_regMarg_exibImagemMargemCab,
          p_regMarg_regraImagemCab,
          p_regMarg_exibImagemMargemItem,
          p_regMarg_regraImagemItem,
          'O',
          p_cab_orcamento,
          p_cab_estabelecimento,
          p_cab_dataPreco,
          p_cab_prazoMedioPonderado,
          p_cab_valorFreteTotal,
          p_cab_valorSeguroTotal,
          p_cab_valorAdicFreteMarTotal,
          p_cab_valorDespesasAduanTotal,
          r_cab_valorLiquidoItem,
          p_cab_valorTarifaCartao,
          r_cab_valorMargem,
          p_munEndEst_uf,
          v_item_sequencia,
          0,
          0,
          0,
          0,
          p_item_localEstoque,
          p_item_pessoaParticipante,
          v_item_quantidade,
          0,
          0,
          0,
          0,
          v_item_valorII,
          v_item_valorIOF,
          v_item_valorIPI,
          0,
          v_item_valorPIS,
          v_item_valorPISST,
          v_item_valorCOFINS,
          v_item_valorCOFINSST,
          v_item_valorCreditoSimplesNac,
          v_item_valorICMSOperacao,
          v_item_valorICMSDiferido,
          v_item_valorICMS,
          v_item_valorICMSDesoneracao,
          v_item_valorICMSST,
          v_item_valorICMSSTAnteriorment,
          v_item_valorICMSUFDestinatario,
          v_item_valorICMSUFRemetente,
          v_item_valorFCP,
          v_item_valorFCPST,
          v_item_valorFCPSTAnteriormente,
          v_item_valorFCPUFDestinatario,
          v_item_valorLiquidoItem,
          comb.produto,
          comb.cor,
          comb.tamanho,
          comb.controleEstoque,
          v_locEst_indicadorPropPosseIt,
          /* Retornos */
          r_cab_valorMargem,
          r_cab_percentualMargem,
          r_cab_imagemMargem,
          v_auxNumber,
          v_auxNumber,
          v_auxNumber,
          v_auxNumber,
          v_auxNumber,
          v_auxNumber,
          v_auxNumber,
          v_auxNumber,
          v_auxVarchar
        );
      END IF;
    END IF;
  END LOOP;
END ADD_ORCAMENTO_ITEM_INSERE_COMB;

/

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

COMMIT;

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

/*
*/