create or replace PROCEDURE ADD_ESTOQUE_PRE_DOC_FIL_GRAVA (
  p_sys_estabelecimentoAtivo  IN NUMBER,
  p_config_354_estabProximoId IN NUMBER,
  p_id                        IN NUMBER,
  p_idItemPreDocumento        IN NUMBER,
  p_produto                   IN NUMBER,
  p_gradeProduto              IN NUMBER,
  p_personalizacao            IN NUMBER,
  p_idLoteEstoque             IN NUMBER,
  p_idNumeroSerie             IN NUMBER,
  p_quantidade                IN NUMBER,
  p_precoCustoOperacao        IN NUMBER,
  p_totalCustoOperacao        IN NUMBER,
  p_precoCMV                  IN NUMBER,
  p_valorCMV                  IN NUMBER,
  p_observacoes               IN VARCHAR2,
  p_bufferIdProdutoFilho      IN VARCHAR2,
  r_id                        OUT NUMBER,
  r_bufferIdProdutoFilho      OUT VARCHAR2)
IS
BEGIN
  IF p_id > 0 THEN
    r_id := p_id;
    r_bufferIdProdutoFilho := p_bufferIdProdutoFilho;
  ELSIF p_bufferIdProdutoFilho IS NOT NULL
    AND LENGTH (RTRIM (p_bufferIdProdutoFilho)) >= 14
  THEN
    r_id := TO_NUMBER (SUBSTR (p_bufferIdProdutoFilho, 1, 14));
    r_bufferIdProdutoFilho := RTRIM (SUBSTR (p_bufferIdProdutoFilho, 16, 32000));
  ELSE
    r_id := FUNC_ADD_PROXIMO_ID (
      p_sys_estabelecimentoAtivo,
      p_config_354_estabProximoId,
      'MOPREDOCUMXPRODUTOFILHO',
      'id',
      14);
    r_bufferIdProdutoFilho := '';
  END IF;
  MERGE INTO MOPREDOCUMXPRODUTOFILHO a 
  USING (
    SELECT
      r_id                 id,
      p_idItemPreDocumento idItemPreDocumento,
      p_produto            produto,
      p_gradeProduto       gradeProduto,
      p_personalizacao     personalizacao,
      p_idLoteEstoque      idLoteEstoque,
      p_idNumeroSerie      idNumeroSerie,
      p_quantidade         quantidade,
      p_precoCustoOperacao precoCustoOperacao,
      p_totalCustoOperacao totalCustoOperacao,
      p_precoCMV           precoCMV,
      p_valorCMV           valorCMV,
      p_observacoes        observacoes
    FROM DUAL) b
  ON (a.id = b.id)
  WHEN MATCHED THEN UPDATE SET
    a.idItemPreDocumento = b.idItemPreDocumento,
    a.produto            = b.produto,
    a.gradeProduto       = b.gradeProduto,
    a.personalizacao     = b.personalizacao,
    a.idLoteEstoque      = b.idLoteEstoque,
    a.idNumeroSerie      = b.idNumeroSerie,
    a.quantidade         = b.quantidade,
    a.precoCustoOperacao = b.precoCustoOperacao,
    a.totalCustoOperacao = b.totalCustoOperacao,
    a.precoCMV           = b.precoCMV,
    a.valorCMV           = b.valorCMV,
    a.observacoes        = b.observacoes
  WHEN NOT MATCHED THEN INSERT (
    id,
    idItemPreDocumento,
    produto,
    gradeProduto,
    personalizacao,
    idLoteEstoque,
    idNumeroSerie,
    quantidade,
    precoCustoOperacao,
    totalCustoOperacao,
    precoCMV,
    valorCMV,
    observacoes)
  VALUES (
    b.id,
    b.idItemPreDocumento,
    b.produto,
    b.gradeProduto,
    b.personalizacao,
    b.idLoteEstoque,
    b.idNumeroSerie,
    b.quantidade,
    b.precoCustoOperacao,
    b.totalCustoOperacao,
    b.precoCMV,
    b.valorCMV,
    b.observacoes);
END ADD_ESTOQUE_PRE_DOC_FIL_GRAVA;

/

create or replace PROCEDURE ADD_ESTOQUE_PRE_DOC_FIL_N_SER (
  p_sys_estabelecimentoAtivo  IN NUMBER,
  p_config_354_estabProximoId IN NUMBER,
  p_item_idItemPreDocumento   IN NUMBER,
  p_item_produto              IN NUMBER,
  p_item_gradeProduto         IN NUMBER,
  p_item_personalizacao       IN NUMBER,
  p_item_idLoteEstoque        IN NUMBER,
  p_item_precoCustoOperacao   IN NUMBER,
  p_item_precoCMV             IN NUMBER,
  p_item_observacoes          IN VARCHAR2,
  p_bufferIdProdutoFilho      IN VARCHAR2,
  r_bufferIdProdutoFilho      OUT VARCHAR2,
  r_quantidadeNumerosSerie    OUT NUMBER)
IS
  v_auxNumber NUMBER;
BEGIN
  r_bufferIdProdutoFilho   := p_bufferIdProdutoFilho;
  r_quantidadeNumerosSerie := 0;
  FOR a IN (
    SELECT idNumeroSerie
    FROM MOPREDOCUMXNUMEROSSERIE
    WHERE idItemPreDocumento = p_item_idItemPreDocumento
    AND gradeProduto = p_item_gradeProduto)
  LOOP
    r_quantidadeNumerosSerie := r_quantidadeNumerosSerie + 1;
    ADD_ESTOQUE_PRE_DOC_FIL_GRAVA (
      p_sys_estabelecimentoAtivo,
      p_config_354_estabProximoId,
      0, -- p_id
      p_item_idItemPreDocumento,
      p_item_produto,
      p_item_gradeProduto,
      p_item_personalizacao,
      p_item_idLoteEstoque,
      a.idNumeroSerie,
      1, -- p_quantidade
      p_item_precoCustoOperacao,
      ROUND (p_item_precoCustoOperacao, 2), -- p_totalCustoOperacao
      p_item_precoCMV,
      ROUND (p_item_precoCMV, 2), -- p_valorCMV
      p_item_observacoes,
      r_bufferIdProdutoFilho, 
      v_auxNumber,
      r_bufferIdProdutoFilho);
  END LOOP;
END ADD_ESTOQUE_PRE_DOC_FIL_N_SER;

/

create or replace PROCEDURE ADD_ESTOQUE_PRE_DOC_FIL_KIT (
  p_sys_estabelecimentoAtivo     IN NUMBER,
  p_config_209_filtrarGrupoEcon  IN NUMBER,
  p_config_354_estabProximoId    IN NUMBER,
  p_config_362_calcCustoPorGrade IN NUMBER,
  p_cab_atualizaCustoMedio       IN NUMBER,
  p_cab_estabelecimento          IN NUMBER,
  p_data                         IN DATE,
  p_item_idItemPreDocumento      IN NUMBER,
  p_item_gradeProduto            IN NUMBER,
  p_item_pessoaParticipante      IN NUMBER,
  p_item_quantidade              IN NUMBER,
  p_item_valorCustoOperacao      IN NUMBER,
  p_item_observacoes             IN VARCHAR2,
  p_locEst_indicProprPosseItem   IN CHAR,
  p_bufferIdProdutoFilho         IN VARCHAR2,
  r_bufferIdProdutoFilho         OUT VARCHAR2)
IS  
  v_quantidadeNumerosSerie NUMBER;
  v_quantidadeRateioTotal  NUMBER;
  v_quantSaldoRateioTotal  NUMBER;
  v_valorSaldoRateioTotal  NUMBER;
  v_valorCustoManter       NUMBER;
  v_precoCustoKit          NUMBER;
  v_valorCustoKit          NUMBER;
  v_auxNumber              NUMBER;
BEGIN
  r_bufferIdProdutoFilho := p_bufferIdProdutoFilho;
  IF p_cab_atualizaCustoMedio = 1 THEN
    SELECT COALESCE (SUM (ROUND (p_item_quantidade * a.quantidade, uniFilho.casasDecimaisUnidadeMedida)), 0)
    INTO v_quantidadeRateioTotal
    FROM CAGRADEPRODUTOXKITSCOMBOS a
    JOIN CAGRADESPRODUTO gradProdFilho
    ON gradProdFilho.gradeProduto = a.gradeProdutoFilho
    JOIN CAPRODUTOS prodFilho
    ON prodFilho.produto = gradProdFilho.produto
    JOIN SIUNIDADESMEDIDA uniFilho
    ON uniFilho.unidadeMedida = prodFilho.unidadeMedida
    WHERE a.gradeProduto = p_item_gradeProduto
    AND a.ativo = 1
    AND a.manterUltimoCusto = 0
    AND a.gradeProduto <> a.gradeProdutoFilho;
    SELECT ROUND ((COALESCE (SUM (ROUND (p_item_quantidade * a.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'),
          TRUNC (p_data) - 1,
          0,
          p_item_pessoaParticipante,
          gradProdFilho.produto,
          0,
          ' ',
          p_locEst_indicProprPosseItem,
          0)), 0)), 2)
    INTO v_valorCustoManter
    FROM CAGRADEPRODUTOXKITSCOMBOS a 
    JOIN CAGRADESPRODUTO gradProdFilho
    ON gradProdFilho.gradeProduto = a.gradeProdutoFilho
    JOIN CAPRODUTOS prodFilho
    ON prodFilho.produto = gradProdFilho.produto
    JOIN SIUNIDADESMEDIDA uniFilho
    ON uniFilho.unidadeMedida = prodFilho.unidadeMedida
    WHERE a.gradeProduto = p_item_gradeProduto
    AND a.ativo = 1
    AND a.manterUltimoCusto = 1
    AND a.gradeProduto <> a.gradeProdutoFilho;
  ELSE
    v_quantidadeRateioTotal := 0;
    v_valorCustoManter      := 0;
  END IF;
  v_quantSaldoRateioTotal := v_quantidadeRateioTotal;
  v_valorSaldoRateioTotal := p_item_valorCustoOperacao - v_valorCustoManter;
  FOR a IN (
    SELECT 
      a.gradeProdutoFilho,
      a.manterUltimoCusto,
      gradProdFilho.produto,
      prodFilho.controleEstoque,
      prodFilho.controlaNumeroSerie,
      ROUND (p_item_quantidade * a.quantidade, uniFilho.casasDecimaisUnidadeMedida) quantidade
    FROM CAGRADEPRODUTOXKITSCOMBOS a
    JOIN CAGRADESPRODUTO gradProdFilho
    ON gradProdFilho.gradeProduto = a.gradeProdutoFilho
    JOIN CAPRODUTOS prodFilho
    ON prodFilho.produto = gradProdFilho.produto
    JOIN SIUNIDADESMEDIDA uniFilho
    ON uniFilho.unidadeMedida = prodFilho.unidadeMedida
    WHERE a.gradeProduto = p_item_gradeProduto
    AND a.ativo = 1
    AND a.gradeProduto <> a.gradeProdutoFilho
    AND ROUND (p_item_quantidade * a.quantidade, uniFilho.casasDecimaisUnidadeMedida) > 0)
  LOOP  
    IF p_cab_atualizaCustoMedio = 1 AND a.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'),
          TRUNC (p_data) - 1,
          0,
          p_item_pessoaParticipante,
          a.produto,
          0,
          ' ',
          p_locEst_indicProprPosseItem,
          0);
      v_valorCustoKit := ROUND (a.quantidade * v_precoCustoKit, 2);
    ELSIF p_cab_atualizaCustoMedio = 1 AND p_item_valorCustoOperacao > v_valorCustoManter AND v_quantSaldoRateioTotal > a.quantidade THEN
      v_valorCustoKit := ROUND((p_item_valorCustoOperacao - v_valorCustoManter) * a.quantidade / v_quantidadeRateioTotal,2);
      v_precoCustoKit := ROUND(v_valorCustoKit / a.quantidade, 7);
      v_quantSaldoRateioTotal := v_quantSaldoRateioTotal - a.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 / a.quantidade, 7);
      v_quantSaldoRateioTotal := 0;
      v_valorSaldoRateioTotal := 0;
    ELSE
      v_precoCustoKit := 0;
      v_valorCustoKit := 0;
    END IF;
    IF a.controleEstoque IN (3,4) THEN
      ADD_ESTOQUE_PRE_DOC_FIL_KIT (
        p_sys_estabelecimentoAtivo,
        p_config_209_filtrarGrupoEcon,
        p_config_354_estabProximoId,
        p_config_362_calcCustoPorGrade,
        p_cab_atualizaCustoMedio,
        p_cab_estabelecimento,
        p_data,
        p_item_idItemPreDocumento,
        a.gradeProdutoFilho,
        p_item_pessoaParticipante,
        a.quantidade,
        v_valorCustoKit,
        p_item_observacoes,
        p_locEst_indicProprPosseItem,
        r_bufferIdProdutoFilho,
        r_bufferIdProdutoFilho);
    ELSIF a.controleEstoque IN(1,5,6,11,12) THEN
      v_quantidadeNumerosSerie := 0;
      IF a.controlaNumeroSerie > 0 THEN
        ADD_ESTOQUE_PRE_DOC_FIL_N_SER (
          p_sys_estabelecimentoAtivo,
          p_config_354_estabProximoId,
          p_item_idItemPreDocumento,
          a.produto,
          a.gradeProdutoFilho,
          0, -- p_item_personalizacao
          0, -- p_item_idLoteEstoque
          v_precoCustoKit, -- p_item_precoCustoOperacao,
          0, -- p_item_precoCMV,
          p_item_observacoes,
          r_bufferIdProdutoFilho,
          r_bufferIdProdutoFilho,
          v_quantidadeNumerosSerie);
      END IF;
      IF a.quantidade > v_quantidadeNumerosSerie THEN
        ADD_ESTOQUE_PRE_DOC_FIL_GRAVA (
          p_sys_estabelecimentoAtivo,
          p_config_354_estabProximoId,
          0, -- p_id
          p_item_idItemPreDocumento,
          a.produto,
          a.gradeProdutoFilho,
          0, -- p_personalizacao
          0, -- p_idLoteEstoque
          0, -- p_idNumeroSerie
          a.quantidade - v_quantidadeNumerosSerie, -- p_quantidade
          v_precoCustoKit, -- p_precoCustoOperacao
          CASE WHEN v_quantidadeNumerosSerie = 0 THEN v_valorCustoKit WHEN a.quantidade = 0 THEN 0 ELSE ROUND ((v_valorCustoKit * (a.quantidade - v_quantidadeNumerosSerie) / a.quantidade), 2) END, -- p_totalCustoOperacao
          0, -- p_precoCMV
          0, -- p_valorCMV
          p_item_observacoes,
          r_bufferIdProdutoFilho, 
          v_auxNumber,
          r_bufferIdProdutoFilho);
      END IF;
    END IF;
  END LOOP;
END ADD_ESTOQUE_PRE_DOC_FIL_KIT;

/

create or replace PROCEDURE ADD_ESTOQUE_PRE_DOC_FIL_PRTIN (
  p_sys_estabelecimentoAtivo     IN NUMBER,
  p_config_209_filtrarGrupoEcon  IN NUMBER,
  p_config_354_estabProximoId    IN NUMBER,
  p_config_362_calcCustoPorGrade IN NUMBER,
  p_cab_atualizaCustoMedio       IN NUMBER,
  p_cab_estabelecimento          IN NUMBER,
  p_data                         IN DATE,
  p_item_idItemPreDocumento      IN NUMBER,
  p_item_pessoaParticipante      IN NUMBER,
  p_item_quantidade              IN NUMBER,
  p_item_observacoes             IN VARCHAR2,
  p_locEst_indicProprPosseItem   IN CHAR,
  p_tinta_gradeProduto           IN NUMBER,
  p_tinta_quantidade             IN NUMBER,
  p_bufferIdProdutoFilho         IN VARCHAR2,
  r_bufferIdProdutoFilho         OUT VARCHAR2)
IS  
  v_auxNumber NUMBER;
BEGIN
  r_bufferIdProdutoFilho := p_bufferIdProdutoFilho;
  FOR a IN (
    SELECT
      gradProd.produto,
      prod.controleEstoque,
      ROUND (p_item_quantidade * p_tinta_quantidade / 900, uniMed.casasDecimaisUnidadeMedida) quantidade
    FROM CAGRADESPRODUTO gradProd 
    JOIN CAPRODUTOS prod
    ON prod.produto = gradProd.produto
    JOIN SIUNIDADESMEDIDA uniMed
    ON uniMed.unidadeMedida = prod.unidadeMedida
    WHERE gradProd.gradeProduto = p_tinta_gradeProduto
    AND ROUND (p_item_quantidade * p_tinta_quantidade / 900, uniMed.casasDecimaisUnidadeMedida) > 0)
  LOOP
    IF a.controleEstoque IN (3,4) THEN
      ADD_ESTOQUE_PRE_DOC_FIL_KIT (
        p_sys_estabelecimentoAtivo,
        p_config_209_filtrarGrupoEcon,
        p_config_354_estabProximoId,
        p_config_362_calcCustoPorGrade,
        p_cab_atualizaCustoMedio,
        p_cab_estabelecimento,
        p_data,
        p_item_idItemPreDocumento,
        p_tinta_gradeProduto,
        p_item_pessoaParticipante,
        a.quantidade,
        0, --p_item_valorCustoOperacao
        p_item_observacoes,
        p_locEst_indicProprPosseItem,
        r_bufferIdProdutoFilho,
        r_bufferIdProdutoFilho);
    ELSIF a.controleEstoque IN(1,5,6,11,12) THEN
      ADD_ESTOQUE_PRE_DOC_FIL_GRAVA (
        p_sys_estabelecimentoAtivo,
        p_config_354_estabProximoId,
        0, -- p_id
        p_item_idItemPreDocumento,
        a.produto,
        p_tinta_gradeProduto,
        0, -- p_personalizacao
        0, -- p_idLoteEstoque
        0, -- p_idNumeroSerie
        a.quantidade,
        0, -- p_precoCustoOperacao,
        0, -- p_totalCustoOperacao,
        0, -- p_precoCMV,
        0, -- p_valorCMV,
        p_item_observacoes,
        r_bufferIdProdutoFilho, 
        v_auxNumber,
        r_bufferIdProdutoFilho);
    END IF;
  END LOOP;
END ADD_ESTOQUE_PRE_DOC_FIL_PRTIN;

/

create or replace PROCEDURE ADD_ESTOQUE_PRE_DOC_FIL_FORM (
  p_sys_estabelecimentoAtivo     IN NUMBER,
  p_config_209_filtrarGrupoEcon  IN NUMBER,
  p_config_354_estabProximoId    IN NUMBER,
  p_config_362_calcCustoPorGrade IN NUMBER,
  p_cab_atualizaCustoMedio       IN NUMBER,
  p_cab_estabelecimento          IN NUMBER,
  p_data                         IN DATE,
  p_idItemPreDocumento           IN NUMBER,
  p_item_idFormulaTinta          IN NUMBER,
  p_item_pessoaParticipante      IN NUMBER,
  p_item_quantidade              IN NUMBER,
  p_item_observacoes             IN VARCHAR2,
  p_locEst_indicProprPosseItem   IN CHAR,
  p_bufferIdProdutoFilho         IN VARCHAR2,
  r_bufferIdProdutoFilho         OUT VARCHAR2)
IS
BEGIN
  r_bufferIdProdutoFilho := p_bufferIdProdutoFilho;
  FOR a IN (
    SELECT 
      a.idBaseTinta,
      baseTinta.gradeProduto,
      a.idColoranteTintaA,
      a.quantidadeA,
      COALESCE (colTintaA.gradeProduto, 0) gradeProdutoA,
      a.idColoranteTintaB,
      a.quantidadeB,
      COALESCE (colTintaB.gradeProduto, 0) gradeProdutoB,
      a.idColoranteTintaC,
      a.quantidadeC,
      COALESCE (colTintaC.gradeProduto, 0) gradeProdutoC,
      a.idColoranteTintaD,
      a.quantidadeD,
      COALESCE (colTintaD.gradeProduto, 0) gradeProdutoD,
      a.idColoranteTintaE,
      a.quantidadeE,
      COALESCE (colTintaE.gradeProduto, 0) gradeProdutoE,
      a.idColoranteTintaF,
      a.quantidadeF,
      COALESCE (colTintaF.gradeProduto, 0) gradeProdutoF,
      a.idColoranteTintaG,
      a.quantidadeG,
      COALESCE (colTintaG.gradeProduto, 0) gradeProdutoG,
      a.idColoranteTintaH,
      a.quantidadeH,
      COALESCE (colTintaH.gradeProduto, 0) gradeProdutoH,
      a.idColoranteTintaI,
      a.quantidadeI,
      COALESCE (colTintaI.gradeProduto, 0) gradeProdutoI,
      a.idColoranteTintaJ,
      a.quantidadeJ,
      COALESCE (colTintaJ.gradeProduto, 0) gradeProdutoJ,
      a.idColoranteTintaK,
      a.quantidadeK,
      COALESCE (colTintaK.gradeProduto, 0) gradeProdutoK,
      a.idColoranteTintaL,
      a.quantidadeL,
      COALESCE (colTintaL.gradeProduto, 0) gradeProdutoL,
      a.idColoranteTintaM,
      a.quantidadeM,
      COALESCE (colTintaM.gradeProduto, 0) gradeProdutoM,
      a.idColoranteTintaN,
      a.quantidadeN,
      COALESCE (colTintaN.gradeProduto, 0) gradeProdutoN,
      a.idColoranteTintaO,
      a.quantidadeO,
      COALESCE (colTintaO.gradeProduto, 0) gradeProdutoO
    FROM CAFORMULASTINTAS a
    JOIN CABASESTINTAS baseTinta
    ON baseTinta.idBaseTinta = a.idBaseTinta
    JOIN CACOLORANTESTINTAS colTintaA
    ON colTintaA.idColoranteTinta = a.idColoranteTintaA
    JOIN CACOLORANTESTINTAS colTintaB
    ON colTintaB.idColoranteTinta = a.idColoranteTintaB
    JOIN CACOLORANTESTINTAS colTintaC
    ON colTintaC.idColoranteTinta = a.idColoranteTintaC
    JOIN CACOLORANTESTINTAS colTintaD
    ON colTintaD.idColoranteTinta = a.idColoranteTintaD
    JOIN CACOLORANTESTINTAS colTintaE
    ON colTintaE.idColoranteTinta = a.idColoranteTintaE
    JOIN CACOLORANTESTINTAS colTintaF
    ON colTintaF.idColoranteTinta = a.idColoranteTintaF
    JOIN CACOLORANTESTINTAS colTintaG
    ON colTintaG.idColoranteTinta = a.idColoranteTintaG
    JOIN CACOLORANTESTINTAS colTintaH
    ON colTintaH.idColoranteTinta = a.idColoranteTintaH
    JOIN CACOLORANTESTINTAS colTintaI
    ON colTintaI.idColoranteTinta = a.idColoranteTintaI
    JOIN CACOLORANTESTINTAS colTintaJ
    ON colTintaJ.idColoranteTinta = a.idColoranteTintaJ
    JOIN CACOLORANTESTINTAS colTintaK
    ON colTintaK.idColoranteTinta = a.idColoranteTintaK
    JOIN CACOLORANTESTINTAS colTintaL
    ON colTintaL.idColoranteTinta = a.idColoranteTintaL
    JOIN CACOLORANTESTINTAS colTintaM
    ON colTintaM.idColoranteTinta = a.idColoranteTintaM
    JOIN CACOLORANTESTINTAS colTintaN
    ON colTintaN.idColoranteTinta = a.idColoranteTintaN
    JOIN CACOLORANTESTINTAS colTintaO
    ON colTintaO.idColoranteTinta = a.idColoranteTintaO
    WHERE a.idFormulaTinta = p_item_idFormulaTinta
    AND a.idBaseTinta > 0
    AND baseTinta.gradeProduto > 0)
  LOOP
    ADD_ESTOQUE_PRE_DOC_FIL_PRTIN (
      p_sys_estabelecimentoAtivo,
      p_config_209_filtrarGrupoEcon,
      p_config_354_estabProximoId,
      p_config_362_calcCustoPorGrade,
      p_cab_atualizaCustoMedio,
      p_cab_estabelecimento,
      p_data,
      p_idItemPreDocumento,
      p_item_pessoaParticipante,
      p_item_quantidade,
      p_item_observacoes,
      p_locEst_indicProprPosseItem,
      a.gradeProduto,
      900, -- p_tinta_quantidade,
      r_bufferIdProdutoFilho,
      r_bufferIdProdutoFilho);    
    IF a.idColoranteTintaA > 0
      AND a.gradeProdutoA > 0
      AND a.quantidadeA > 0
    THEN
      ADD_ESTOQUE_PRE_DOC_FIL_PRTIN (
        p_sys_estabelecimentoAtivo,
        p_config_209_filtrarGrupoEcon,
        p_config_354_estabProximoId,
        p_config_362_calcCustoPorGrade,
        p_cab_atualizaCustoMedio,
        p_cab_estabelecimento,
        p_data,
        p_idItemPreDocumento,
        p_item_pessoaParticipante,
        p_item_quantidade,
        p_item_observacoes,
        p_locEst_indicProprPosseItem,
        a.gradeProdutoA,
        a.quantidadeA,
        r_bufferIdProdutoFilho,
        r_bufferIdProdutoFilho);
    END IF;
    IF a.idColoranteTintaB > 0
      AND a.gradeProdutoB > 0
      AND a.quantidadeB > 0
    THEN
      ADD_ESTOQUE_PRE_DOC_FIL_PRTIN (
        p_sys_estabelecimentoAtivo,
        p_config_209_filtrarGrupoEcon,
        p_config_354_estabProximoId,
        p_config_362_calcCustoPorGrade,
        p_cab_atualizaCustoMedio,
        p_cab_estabelecimento,
        p_data,
        p_idItemPreDocumento,
        p_item_pessoaParticipante,
        p_item_quantidade,
        p_item_observacoes,
        p_locEst_indicProprPosseItem,
        a.gradeProdutoB,
        a.quantidadeB,
        r_bufferIdProdutoFilho,
        r_bufferIdProdutoFilho);
    END IF;
    IF a.idColoranteTintaC > 0
      AND a.gradeProdutoC > 0
      AND a.quantidadeC > 0
    THEN
      ADD_ESTOQUE_PRE_DOC_FIL_PRTIN (
        p_sys_estabelecimentoAtivo,
        p_config_209_filtrarGrupoEcon,
        p_config_354_estabProximoId,
        p_config_362_calcCustoPorGrade,
        p_cab_atualizaCustoMedio,
        p_cab_estabelecimento,
        p_data,
        p_idItemPreDocumento,
        p_item_pessoaParticipante,
        p_item_quantidade,
        p_item_observacoes,
        p_locEst_indicProprPosseItem,
        a.gradeProdutoC,
        a.quantidadeC,
        r_bufferIdProdutoFilho,
        r_bufferIdProdutoFilho);
    END IF;
    IF a.idColoranteTintaD > 0
      AND a.gradeProdutoD > 0
      AND a.quantidadeD > 0
    THEN
      ADD_ESTOQUE_PRE_DOC_FIL_PRTIN (
        p_sys_estabelecimentoAtivo,
        p_config_209_filtrarGrupoEcon,
        p_config_354_estabProximoId,
        p_config_362_calcCustoPorGrade,
        p_cab_atualizaCustoMedio,
        p_cab_estabelecimento,
        p_data,
        p_idItemPreDocumento,
        p_item_pessoaParticipante,
        p_item_quantidade,
        p_item_observacoes,
        p_locEst_indicProprPosseItem,
        a.gradeProdutoD,
        a.quantidadeD,
        r_bufferIdProdutoFilho,
        r_bufferIdProdutoFilho);
    END IF;
    IF a.idColoranteTintaE > 0
      AND a.gradeProdutoE > 0
      AND a.quantidadeE > 0
    THEN
      ADD_ESTOQUE_PRE_DOC_FIL_PRTIN (
        p_sys_estabelecimentoAtivo,
        p_config_209_filtrarGrupoEcon,
        p_config_354_estabProximoId,
        p_config_362_calcCustoPorGrade,
        p_cab_atualizaCustoMedio,
        p_cab_estabelecimento,
        p_data,
        p_idItemPreDocumento,
        p_item_pessoaParticipante,
        p_item_quantidade,
        p_item_observacoes,
        p_locEst_indicProprPosseItem,
        a.gradeProdutoE,
        a.quantidadeE,
        r_bufferIdProdutoFilho,
        r_bufferIdProdutoFilho);
    END IF;
    IF a.idColoranteTintaF > 0
      AND a.gradeProdutoF > 0
      AND a.quantidadeF > 0
    THEN
      ADD_ESTOQUE_PRE_DOC_FIL_PRTIN (
        p_sys_estabelecimentoAtivo,
        p_config_209_filtrarGrupoEcon,
        p_config_354_estabProximoId,
        p_config_362_calcCustoPorGrade,
        p_cab_atualizaCustoMedio,
        p_cab_estabelecimento,
        p_data,
        p_idItemPreDocumento,
        p_item_pessoaParticipante,
        p_item_quantidade,
        p_item_observacoes,
        p_locEst_indicProprPosseItem,
        a.gradeProdutoF,
        a.quantidadeF,
        r_bufferIdProdutoFilho,
        r_bufferIdProdutoFilho);
    END IF;
    IF a.idColoranteTintaG > 0
      AND a.gradeProdutoG > 0
      AND a.quantidadeG > 0
    THEN
      ADD_ESTOQUE_PRE_DOC_FIL_PRTIN (
        p_sys_estabelecimentoAtivo,
        p_config_209_filtrarGrupoEcon,
        p_config_354_estabProximoId,
        p_config_362_calcCustoPorGrade,
        p_cab_atualizaCustoMedio,
        p_cab_estabelecimento,
        p_data,
        p_idItemPreDocumento,
        p_item_pessoaParticipante,
        p_item_quantidade,
        p_item_observacoes,
        p_locEst_indicProprPosseItem,
        a.gradeProdutoG,
        a.quantidadeG,
        r_bufferIdProdutoFilho,
        r_bufferIdProdutoFilho);
    END IF;
    IF a.idColoranteTintaH > 0
      AND a.gradeProdutoH > 0
      AND a.quantidadeH > 0
    THEN
      ADD_ESTOQUE_PRE_DOC_FIL_PRTIN (
        p_sys_estabelecimentoAtivo,
        p_config_209_filtrarGrupoEcon,
        p_config_354_estabProximoId,
        p_config_362_calcCustoPorGrade,
        p_cab_atualizaCustoMedio,
        p_cab_estabelecimento,
        p_data,
        p_idItemPreDocumento,
        p_item_pessoaParticipante,
        p_item_quantidade,
        p_item_observacoes,
        p_locEst_indicProprPosseItem,
        a.gradeProdutoH,
        a.quantidadeH,
        r_bufferIdProdutoFilho,
        r_bufferIdProdutoFilho);
    END IF;
    IF a.idColoranteTintaI > 0
      AND a.gradeProdutoI > 0
      AND a.quantidadeI > 0
    THEN
      ADD_ESTOQUE_PRE_DOC_FIL_PRTIN (
        p_sys_estabelecimentoAtivo,
        p_config_209_filtrarGrupoEcon,
        p_config_354_estabProximoId,
        p_config_362_calcCustoPorGrade,
        p_cab_atualizaCustoMedio,
        p_cab_estabelecimento,
        p_data,
        p_idItemPreDocumento,
        p_item_pessoaParticipante,
        p_item_quantidade,
        p_item_observacoes,
        p_locEst_indicProprPosseItem,
        a.gradeProdutoI,
        a.quantidadeI,
        r_bufferIdProdutoFilho,
        r_bufferIdProdutoFilho);
    END IF;
    IF a.idColoranteTintaJ > 0
      AND a.gradeProdutoJ > 0
      AND a.quantidadeJ > 0
    THEN
      ADD_ESTOQUE_PRE_DOC_FIL_PRTIN (
        p_sys_estabelecimentoAtivo,
        p_config_209_filtrarGrupoEcon,
        p_config_354_estabProximoId,
        p_config_362_calcCustoPorGrade,
        p_cab_atualizaCustoMedio,
        p_cab_estabelecimento,
        p_data,
        p_idItemPreDocumento,
        p_item_pessoaParticipante,
        p_item_quantidade,
        p_item_observacoes,
        p_locEst_indicProprPosseItem,
        a.gradeProdutoJ,
        a.quantidadeJ,
        r_bufferIdProdutoFilho,
        r_bufferIdProdutoFilho);
    END IF;
    IF a.idColoranteTintaK > 0
      AND a.gradeProdutoK > 0
      AND a.quantidadeK > 0
    THEN
      ADD_ESTOQUE_PRE_DOC_FIL_PRTIN (
        p_sys_estabelecimentoAtivo,
        p_config_209_filtrarGrupoEcon,
        p_config_354_estabProximoId,
        p_config_362_calcCustoPorGrade,
        p_cab_atualizaCustoMedio,
        p_cab_estabelecimento,
        p_data,
        p_idItemPreDocumento,
        p_item_pessoaParticipante,
        p_item_quantidade,
        p_item_observacoes,
        p_locEst_indicProprPosseItem,
        a.gradeProdutoK,
        a.quantidadeK,
        r_bufferIdProdutoFilho,
        r_bufferIdProdutoFilho);
    END IF;
    IF a.idColoranteTintaL > 0
      AND a.gradeProdutoL > 0
      AND a.quantidadeL > 0
    THEN
      ADD_ESTOQUE_PRE_DOC_FIL_PRTIN (
        p_sys_estabelecimentoAtivo,
        p_config_209_filtrarGrupoEcon,
        p_config_354_estabProximoId,
        p_config_362_calcCustoPorGrade,
        p_cab_atualizaCustoMedio,
        p_cab_estabelecimento,
        p_data,
        p_idItemPreDocumento,
        p_item_pessoaParticipante,
        p_item_quantidade,
        p_item_observacoes,
        p_locEst_indicProprPosseItem,
        a.gradeProdutoL,
        a.quantidadeL,
        r_bufferIdProdutoFilho,
        r_bufferIdProdutoFilho);
    END IF;
    IF a.idColoranteTintaM > 0
      AND a.gradeProdutoM > 0
      AND a.quantidadeM > 0
    THEN
      ADD_ESTOQUE_PRE_DOC_FIL_PRTIN (
        p_sys_estabelecimentoAtivo,
        p_config_209_filtrarGrupoEcon,
        p_config_354_estabProximoId,
        p_config_362_calcCustoPorGrade,
        p_cab_atualizaCustoMedio,
        p_cab_estabelecimento,
        p_data,
        p_idItemPreDocumento,
        p_item_pessoaParticipante,
        p_item_quantidade,
        p_item_observacoes,
        p_locEst_indicProprPosseItem,
        a.gradeProdutoM,
        a.quantidadeM,
        r_bufferIdProdutoFilho,
        r_bufferIdProdutoFilho);
    END IF;
    IF a.idColoranteTintaN > 0
      AND a.gradeProdutoN > 0
      AND a.quantidadeN > 0
    THEN
      ADD_ESTOQUE_PRE_DOC_FIL_PRTIN (
        p_sys_estabelecimentoAtivo,
        p_config_209_filtrarGrupoEcon,
        p_config_354_estabProximoId,
        p_config_362_calcCustoPorGrade,
        p_cab_atualizaCustoMedio,
        p_cab_estabelecimento,
        p_data,
        p_idItemPreDocumento,
        p_item_pessoaParticipante,
        p_item_quantidade,
        p_item_observacoes,
        p_locEst_indicProprPosseItem,
        a.gradeProdutoN,
        a.quantidadeN,
        r_bufferIdProdutoFilho,
        r_bufferIdProdutoFilho);
    END IF;
    IF a.idColoranteTintaO > 0
      AND a.gradeProdutoO > 0
      AND a.quantidadeO > 0
    THEN
      ADD_ESTOQUE_PRE_DOC_FIL_PRTIN (
        p_sys_estabelecimentoAtivo,
        p_config_209_filtrarGrupoEcon,
        p_config_354_estabProximoId,
        p_config_362_calcCustoPorGrade,
        p_cab_atualizaCustoMedio,
        p_cab_estabelecimento,
        p_data,
        p_idItemPreDocumento,
        p_item_pessoaParticipante,
        p_item_quantidade,
        p_item_observacoes,
        p_locEst_indicProprPosseItem,
        a.gradeProdutoO,
        a.quantidadeO,
        r_bufferIdProdutoFilho,
        r_bufferIdProdutoFilho);
    END IF;
  END LOOP;
END ADD_ESTOQUE_PRE_DOC_FIL_FORM;

/

create or replace PROCEDURE ADD_ESTOQUE_DOC_FISC_N_SERIE (
  p_sys_estabelecimentoAtivo     IN NUMBER,
  p_config_354_estabProximoId    IN NUMBER,
  p_cab_atualizaCustoMedio       IN NUMBER,
  p_cab_atualizaUltimaCompra     IN NUMBER,
  p_cab_entradaSaida             IN CHAR,
  p_cab_estabelecimento          IN NUMBER,
  p_data                         IN DATE,
  p_item_idItemDocFiscal         IN NUMBER,
  p_item_modeloDocumento         IN NUMBER,
  p_item_gradeProduto            IN NUMBER,
  p_item_personalizacao          IN NUMBER,
  p_item_idLoteEstoque           IN NUMBER,
  p_item_localEstoque            IN NUMBER,
  p_item_pessoaParticipante      IN NUMBER,
  p_item_precoCustoOperacao      IN NUMBER,
  p_item_precoCMV                IN NUMBER,
  p_item_observacoes             IN VARCHAR2,
  p_modDoc_geraTransferencia     IN NUMBER,
  p_modDoc_geraOperacaoEmTransit IN NUMBER,
  p_modDoc_transitoLocalEstoque  IN NUMBER,
  p_locEstTransito_indicProprPos IN CHAR,
  p_graProd_produto              IN NUMBER,
  p_locEst_indicProprPosseItem   IN CHAR,
  p_docTransf_estabelecEntrada   IN NUMBER,
  p_docTransf_estabelecSaida     IN NUMBER,
  p_bufferIdEstoque              IN VARCHAR2,
  r_bufferIdEstoque              OUT VARCHAR2,
  r_quantidadeNumerosSerie       OUT NUMBER)
IS
  v_auxNumber NUMBER;
BEGIN
  r_bufferIdEstoque        := p_bufferIdEstoque;
  r_quantidadeNumerosSerie := 0;
  FOR a IN (
    SELECT idNumeroSerie
    FROM MODOCFISCALXNUMEROSSERIE
    WHERE idItemDocFiscal = p_item_idItemDocFiscal
    AND gradeProduto = p_item_gradeProduto)
  LOOP
    r_quantidadeNumerosSerie := r_quantidadeNumerosSerie + 1;
    ADD_ESTOQUE_GRAVA (
      p_sys_estabelecimentoAtivo,
      p_config_354_estabProximoId,
      0, -- p_idEstoque
      p_cab_estabelecimento,
      p_data,
      p_graProd_produto,
      p_item_gradeProduto,
      p_item_modeloDocumento,
      0, -- p_item_motivoEstoque
      100, -- p_operacaoInternaEstoque
      p_cab_atualizaCustoMedio,
      p_cab_atualizaUltimaCompra,
      p_cab_entradaSaida,
      p_locEst_indicProprPosseItem,
      p_item_pessoaParticipante,
      p_item_localEstoque,
      p_item_personalizacao,
      p_item_idLoteEstoque,
      a.idNumeroSerie,
      1, -- p_quantidade
      p_item_precoCustoOperacao,
      ROUND (p_item_precoCustoOperacao, 2),
      p_item_precoCMV,
      ROUND (p_item_precoCMV, 2),
      p_item_observacoes,
      0, -- p_idFichaProdutoRealOrcamento
      0, -- p_idItemPreDocumento
      p_item_idItemDocFiscal,
      0, -- p_divergenciaBalanco
      0, -- p_idItemDocTransferencia
      r_bufferIdEstoque,
      v_auxNumber,
      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_GRAVA (
        p_sys_estabelecimentoAtivo,
        p_config_354_estabProximoId,
        0, -- p_idEstoque
        p_docTransf_estabelecSaida,
        p_data,
        p_graProd_produto,
        p_item_gradeProduto,
        p_item_modeloDocumento,
        0, -- p_item_motivoEstoque
        900, -- p_operacaoInternaEstoque
        0, -- p_atualizaCustoMedio
        0, -- p_atualizaUltimaCompra
        CASE WHEN p_cab_entradaSaida = 'S' THEN 'E' ELSE 'S' END, -- p_entradaSaida
        p_locEstTransito_indicProprPos,
        p_item_pessoaParticipante,
        p_modDoc_transitoLocalEstoque,
        p_item_personalizacao,
        p_item_idLoteEstoque,
        a.idNumeroSerie,
        1, -- p_quantidade
        p_item_precoCustoOperacao,
        ROUND (p_item_precoCustoOperacao, 2), -- p_totalCustoOperacao
        p_item_precoCMV,
        ROUND (p_item_precoCMV, 2), -- p_valorCMV
        p_item_observacoes,
        0, -- p_idFichaProdutoRealOrcamento
        0, -- p_idItemPreDocumento
        p_item_idItemDocFiscal,
        0, -- p_divergenciaBalanco
        0, -- p_idItemDocTransferencia
        r_bufferIdEstoque,
        v_auxNumber,
        r_bufferIdEstoque);
    END IF;
  END LOOP;
END ADD_ESTOQUE_DOC_FISC_N_SERIE;

/

create or replace PROCEDURE ADD_ESTOQUE_PRE_DOC_N_SERIE (
  p_sys_estabelecimentoAtivo     IN NUMBER,
  p_config_354_estabProximoId    IN NUMBER,
  p_cab_atualizaCustoMedio       IN NUMBER,
  p_cab_atualizaUltimaCompra     IN NUMBER,
  p_cab_entradaSaida             IN CHAR,
  p_cab_estabelecimento          IN NUMBER,
  p_data                         IN DATE,
  p_item_idItemPreDocumento      IN NUMBER,
  p_item_modeloDocumento         IN NUMBER,
  p_item_gradeProduto            IN NUMBER,
  p_item_personalizacao          IN NUMBER,
  p_item_idLoteEstoque           IN NUMBER,
  p_item_localEstoque            IN NUMBER,
  p_item_pessoaParticipante      IN NUMBER,
  p_item_precoCustoOperacao      IN NUMBER,
  p_item_precoCMV                IN NUMBER,
  p_item_observacoes             IN VARCHAR2,
  p_modDoc_geraTransferencia     IN NUMBER,
  p_modDoc_geraOperacaoEmTransit IN NUMBER,
  p_modDoc_transitoLocalEstoque  IN NUMBER,
  p_locEstTransito_indicProprPos IN CHAR,
  p_graProd_produto              IN NUMBER,
  p_locEst_indicProprPosseItem   IN CHAR,
  p_docTransf_estabelecEntrada   IN NUMBER,
  p_docTransf_estabelecSaida     IN NUMBER,
  p_bufferIdEstoque              IN VARCHAR2,
  r_bufferIdEstoque              OUT VARCHAR2,
  r_quantidadeNumerosSerie       OUT NUMBER)
IS
  v_auxNumber NUMBER;
BEGIN
  r_bufferIdEstoque        := p_bufferIdEstoque;
  r_quantidadeNumerosSerie := 0;
  FOR a IN (
    SELECT idNumeroSerie
    FROM MOPREDOCUMXNUMEROSSERIE
    WHERE idItemPreDocumento = p_item_idItemPreDocumento
    AND gradeProduto = p_item_gradeProduto)
  LOOP
    r_quantidadeNumerosSerie := r_quantidadeNumerosSerie + 1;
    ADD_ESTOQUE_GRAVA (
      p_sys_estabelecimentoAtivo,
      p_config_354_estabProximoId,
      0, -- p_idEstoque
      p_cab_estabelecimento,
      p_data,
      p_graProd_produto,
      p_item_gradeProduto,
      p_item_modeloDocumento,
      0, -- p_item_motivoEstoque
      101, -- p_operacaoInternaEstoque
      p_cab_atualizaCustoMedio,
      p_cab_atualizaUltimaCompra,
      p_cab_entradaSaida,
      p_locEst_indicProprPosseItem,
      p_item_pessoaParticipante,
      p_item_localEstoque,
      p_item_personalizacao,
      p_item_idLoteEstoque,
      a.idNumeroSerie,
      1, -- p_quantidade
      p_item_precoCustoOperacao,
      ROUND (p_item_precoCustoOperacao, 2),
      p_item_precoCMV,
      ROUND (p_item_precoCMV, 2),
      p_item_observacoes,
      0, -- p_idFichaProdutoRealOrcamento
      p_item_idItemPreDocumento,
      0, -- p_idItemDocFiscal,
      0, -- p_divergenciaBalanco
      0, -- p_idItemDocTransferencia
      r_bufferIdEstoque,
      v_auxNumber,
      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_GRAVA (
        p_sys_estabelecimentoAtivo,
        p_config_354_estabProximoId,
        0, -- p_idEstoque
        p_docTransf_estabelecSaida,
        p_data,
        p_graProd_produto,
        p_item_gradeProduto,
        p_item_modeloDocumento,
        0, -- p_item_motivoEstoque
        900, -- p_operacaoInternaEstoque
        0, -- p_atualizaCustoMedio
        0, -- p_atualizaUltimaCompra
        CASE WHEN p_cab_entradaSaida = 'S' THEN 'E' ELSE 'S' END, -- p_entradaSaida
        p_locEstTransito_indicProprPos,
        p_item_pessoaParticipante,
        p_modDoc_transitoLocalEstoque,
        p_item_personalizacao,
        p_item_idLoteEstoque,
        a.idNumeroSerie,
        1, -- p_quantidade
        p_item_precoCustoOperacao,
        ROUND (p_item_precoCustoOperacao, 2), -- p_totalCustoOperacao
        p_item_precoCMV,
        ROUND (p_item_precoCMV, 2), -- p_valorCMV
        p_item_observacoes,
        0, -- p_idFichaProdutoRealOrcamento
        p_item_idItemPreDocumento,
        0, -- p_idItemDocFiscal,
        0, -- p_divergenciaBalanco
        0, -- p_idItemDocTransferencia
        r_bufferIdEstoque,
        v_auxNumber,
        r_bufferIdEstoque);
    END IF;
  END LOOP;
END ADD_ESTOQUE_PRE_DOC_N_SERIE;

/

create or replace PROCEDURE ADD_ESTOQUE_KIT (
  p_sys_estabelecimentoAtivo     IN NUMBER,
  p_config_209_filtrarGrupoEcon  IN NUMBER,
  p_config_354_estabProximoId    IN NUMBER,
  p_config_362_calcCustoPorGrade 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_data                         IN DATE,
  p_item_modeloDocumento         IN NUMBER,
  p_item_motivoEstoque           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_idFichaProdutoRealOrcamento  IN NUMBER,
  p_idItemPreDocumento           IN NUMBER,
  p_idItemDocFiscal              IN NUMBER,
  p_divergenciaBalanco           IN NUMBER,
  p_idItemDocTransferencia       IN NUMBER,
  p_modDoc_geraTransferencia     IN NUMBER,
  p_modDoc_geraOperacaoEmTransit IN NUMBER,
  p_modDoc_transitoLocalEstoque  IN NUMBER,
  p_locEstTransito_indicProprPos IN CHAR,
  p_locEst_indicProprPosseItem   IN CHAR,
  p_docTransf_estabelecEntrada   IN NUMBER,
  p_docTransf_estabelecSaida     IN NUMBER,
  p_bufferIdEstoque              IN VARCHAR2,
  r_bufferIdEstoque              OUT VARCHAR2)
IS
  v_quantidadeRateioTotal  NUMBER;
  v_quantSaldoRateioTotal  NUMBER;
  v_valorSaldoRateioTotal  NUMBER;
  v_valorCustoManter       NUMBER;
  v_precoCustoKit          NUMBER;
  v_valorCustoKit          NUMBER;
  v_quantidadeNumerosSerie NUMBER;
  v_auxNumber              NUMBER;
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'), -- p_cab_dataPrecoInicial
          TRUNC (p_data) - 1, -- p_cab_dataPrecoFinal
          0, -- p_item_personalizacao
          p_item_pessoaParticipante,
          gradProdFilho.produto,
          gradProdFilho.cor,
          gradProdFilho.tamanho,
          p_locEst_indicProprPosseItem,
          0) -- p_gerandoInventario
          ), 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 a IN (
    SELECT 
      kit.gradeProdutoFilho,
      kit.manterUltimoCusto,
      gradProdFilho.produto,
      gradProdFilho.cor,
      gradProdFilho.tamanho,
      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)
  LOOP
    IF p_cab_atualizaCustoMedio = 1
      AND a.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'), -- p_cab_dataPrecoInicial
          TRUNC (p_data) - 1, -- p_cab_dataPrecoFinal
          0, -- p_item_personalizacao
          p_item_pessoaParticipante,
          a.produto,
          a.cor,
          a.tamanho,
          p_locEst_indicProprPosseItem,
          0); -- p_gerandoInventario
      v_valorCustoKit := ROUND (a.quantidade * v_precoCustoKit, 2);
    ELSIF p_cab_atualizaCustoMedio = 1
      AND p_item_valorCustoOperacao > v_valorCustoManter
      AND v_quantSaldoRateioTotal > a.quantidade
    THEN
      v_valorCustoKit := ROUND ((p_item_valorCustoOperacao - v_valorCustoManter) * a.quantidade / v_quantidadeRateioTotal, 2);
      v_precoCustoKit := ROUND (v_valorCustoKit / a.quantidade, 7);
      v_quantSaldoRateioTotal := v_quantSaldoRateioTotal - a.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 / a.quantidade,7);
      v_quantSaldoRateioTotal := 0;
      v_valorSaldoRateioTotal := 0;
    ELSE
      v_precoCustoKit := 0;
      v_valorCustoKit := 0;
    END IF;
    IF a.controleEstoque IN (3,4) THEN
      ADD_ESTOQUE_KIT (
        p_sys_estabelecimentoAtivo,
        p_config_209_filtrarGrupoEcon,
        p_config_354_estabProximoId,
        p_config_362_calcCustoPorGrade,
        p_cab_operacaoInternaEstoque,
        p_cab_atualizaCustoMedio,
        p_cab_atualizaUltimaCompra,
        p_cab_entradaSaida,
        p_cab_estabelecimento,
        p_data,
        p_item_modeloDocumento,
        p_item_motivoEstoque,
        a.gradeProdutoFilho,
        p_item_localEstoque,
        p_item_pessoaParticipante,
        a.quantidade,
        v_valorCustoKit,
        p_item_observacoes,
        p_idFichaProdutoRealOrcamento,
        p_idItemPreDocumento,
        p_idItemDocFiscal,
        p_divergenciaBalanco,
        p_idItemDocTransferencia,
        p_modDoc_geraTransferencia,
        p_modDoc_geraOperacaoEmTransit,
        p_modDoc_transitoLocalEstoque,
        p_locEstTransito_indicProprPos,
        p_locEst_indicProprPosseItem,
        p_docTransf_estabelecEntrada,
        p_docTransf_estabelecSaida,
        r_bufferIdEstoque,
        r_bufferIdEstoque);
    ELSIF a.controleEstoque IN(1,5,6,11,12) THEN
      v_quantidadeNumerosSerie := 0;
      IF a.controlaNumeroSerie > 0
        AND p_idItemPreDocumento > 0
      THEN
        ADD_ESTOQUE_PRE_DOC_N_SERIE (
          p_sys_estabelecimentoAtivo,
          p_config_354_estabProximoId,
          p_cab_atualizaCustoMedio,
          p_cab_atualizaUltimaCompra,
          p_cab_entradaSaida,
          p_cab_estabelecimento,
          p_data,
          p_idItemPreDocumento,
          p_item_modeloDocumento,
          a.gradeProdutoFilho,
          0, -- p_personalizacao
          0, -- p_idLoteEstoque
          p_item_localEstoque,
          p_item_pessoaParticipante,
          v_valorCustoKit, -- p_totalCustoOperacao
          0, -- p_precoCMV
          p_item_observacoes,
          p_modDoc_geraTransferencia,
          p_modDoc_geraOperacaoEmTransit,
          p_modDoc_transitoLocalEstoque,
          p_locEstTransito_indicProprPos,
          a.produto,
          p_locEst_indicProprPosseItem,
          p_docTransf_estabelecEntrada,
          p_docTransf_estabelecSaida,
          r_bufferIdEstoque,
          r_bufferIdEstoque,
          v_quantidadeNumerosSerie);
      ELSIF a.controlaNumeroSerie > 0
        AND p_idItemDocFiscal > 0
      THEN
        ADD_ESTOQUE_DOC_FISC_N_SERIE (
          p_sys_estabelecimentoAtivo,
          p_config_354_estabProximoId,
          p_cab_atualizaCustoMedio,
          p_cab_atualizaUltimaCompra,
          p_cab_entradaSaida,
          p_cab_estabelecimento,
          p_data,
          p_idItemDocFiscal,
          p_item_modeloDocumento,
          a.gradeProdutoFilho,
          0, -- p_personalizacao
          0, -- p_idLoteEstoque
          p_item_localEstoque,
          p_item_pessoaParticipante,
          v_valorCustoKit, -- p_totalCustoOperacao
          0, -- p_precoCMV
          p_item_observacoes,
          p_modDoc_geraTransferencia,
          p_modDoc_geraOperacaoEmTransit,
          p_modDoc_transitoLocalEstoque,
          p_locEstTransito_indicProprPos,
          a.produto,
          p_locEst_indicProprPosseItem,
          p_docTransf_estabelecEntrada,
          p_docTransf_estabelecSaida,
          r_bufferIdEstoque,
          r_bufferIdEstoque,
          v_quantidadeNumerosSerie);
      END IF;
      IF a.quantidade > v_quantidadeNumerosSerie THEN
        ADD_ESTOQUE_GRAVA (
          p_sys_estabelecimentoAtivo, 
          p_config_354_estabProximoId,
          0, -- p_idEstoque
          p_cab_estabelecimento,
          p_data,
          a.produto,
          a.gradeProdutoFilho,
          p_item_modeloDocumento,
          p_item_motivoEstoque,
          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
          0, -- p_idNumeroSerie
          a.quantidade - v_quantidadeNumerosSerie, -- p_quantidade
          v_precoCustoKit, -- p_precoCustoOperacao
          CASE WHEN a.quantidade = 0 THEN v_valorCustoKit ELSE ROUND ((v_valorCustoKit * (a.quantidade - v_quantidadeNumerosSerie) / a.quantidade), 2) END, -- p_totalCustoOperacao
          0, -- p_precoCMV
          0, -- p_valorCMV
          p_item_observacoes,
          p_idFichaProdutoRealOrcamento,
          p_idItemPreDocumento,
          p_idItemDocFiscal,
          p_divergenciaBalanco,
          p_idItemDocTransferencia,
          r_bufferIdEstoque,
          v_auxNumber,
          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_GRAVA (
            p_sys_estabelecimentoAtivo,
            p_config_354_estabProximoId,
            0, -- p_idEstoque
            p_docTransf_estabelecSaida,
            p_data,
            a.produto,
            a.gradeProdutoFilho,
            p_item_modeloDocumento,
            p_item_motivoEstoque,
            900, -- p__operacaoInternaEstoque
            0, -- p_atualizaCustoMedio
            0, -- p_atualizaUltimaCompra
            CASE
              WHEN p_cab_entradaSaida = 'S'
              THEN 'E'
              ELSE 'S'
            END, -- p_entradaSaida
            p_locEstTransito_indicProprPos,
            CASE WHEN p_locEstTransito_indicProprPos = '0' THEN 0 ELSE p_item_pessoaParticipante END,
            p_modDoc_transitoLocalEstoque,
            0, -- p_personalizacao
            0, -- p_idLoteEstoque
            0, -- p_idNumeroSerie
            a.quantidade - v_quantidadeNumerosSerie, -- p_quantidade
            v_precoCustoKit, -- p_precoCustoOperacao
            CASE WHEN a.quantidade = 0 THEN v_valorCustoKit ELSE ROUND ((v_valorCustoKit * (a.quantidade - v_quantidadeNumerosSerie) / a.quantidade), 2) END, -- p_totalCustoOperacao
            0, -- p_precoCMV
            0, -- p_valorCMV
            p_item_observacoes,
            p_idFichaProdutoRealOrcamento,
            p_idItemPreDocumento,
            p_idItemDocFiscal,
            p_divergenciaBalanco,
            p_idItemDocTransferencia,
            r_bufferIdEstoque,
            v_auxNumber,
            r_bufferIdEstoque);
        END IF;    
      END IF;
    END IF;
  END LOOP;
END ADD_ESTOQUE_KIT;

/

create or replace PROCEDURE ADD_ESTOQUE_PRODUTO_TINTA (
  p_sys_estabelecimentoAtivo     IN NUMBER,
  p_config_209_filtrarGrupoEcon  IN NUMBER,
  p_config_354_estabProximoId    IN NUMBER,
  p_config_362_calcCustoPorGrade 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_data                         IN DATE,
  p_item_modeloDocumento         IN NUMBER,
  p_item_motivoEstoque           IN NUMBER,
  p_item_localEstoque            IN NUMBER,
  p_item_pessoaParticipante      IN NUMBER,
  p_item_quantidade              IN NUMBER,
  p_item_observacoes             IN VARCHAR2,
  p_idFichaProdutoRealOrcamento  IN NUMBER,
  p_idItemPreDocumento           IN NUMBER,
  p_idItemDocFiscal              IN NUMBER,
  p_divergenciaBalanco           IN NUMBER,
  p_idItemDocTransferencia       IN NUMBER,
  p_modDoc_geraTransferencia     IN NUMBER,
  p_modDoc_geraOperacaoEmTransit IN NUMBER,
  p_modDoc_transitoLocalEstoque  IN NUMBER,
  p_locEstTransito_indicProprPos IN CHAR,
  p_locEst_indicProprPosseItem   IN CHAR,
  p_docTransf_estabelecEntrada   IN NUMBER,
  p_docTransf_estabelecSaida     IN NUMBER,
  p_tinta_gradeProduto           IN NUMBER,
  p_tinta_quantidade             IN NUMBER,
  p_bufferIdEstoque              IN VARCHAR2,
  r_bufferIdEstoque              OUT VARCHAR2)
IS
  v_auxNumber NUMBER;
BEGIN
  r_bufferIdEstoque := p_bufferIdEstoque;
  FOR a IN (
    SELECT 
      gradProd.produto,
      prod.controleEstoque,
      ROUND(p_item_quantidade * p_tinta_quantidade / 900, uniMed.casasDecimaisUnidadeMedida) quantidade
    FROM CAGRADESPRODUTO gradProd 
    JOIN CAPRODUTOS prod
    ON prod.produto = gradProd.produto
    JOIN SIUNIDADESMEDIDA uniMed
    ON uniMed.unidadeMedida = prod.unidadeMedida
    WHERE gradProd.gradeProduto = p_tinta_gradeProduto
    AND ROUND(p_item_quantidade * p_tinta_quantidade / 900, uniMed.casasDecimaisUnidadeMedida) > 0)
  LOOP
    IF a.controleEstoque IN (3,4) THEN
      ADD_ESTOQUE_KIT (
        p_sys_estabelecimentoAtivo,
        p_config_209_filtrarGrupoEcon,
        p_config_354_estabProximoId,
        p_config_362_calcCustoPorGrade,
        p_cab_operacaoInternaEstoque,
        p_cab_atualizaCustoMedio,
        p_cab_atualizaUltimaCompra,
        p_cab_entradaSaida,
        p_cab_estabelecimento,
        p_data,
        p_item_modeloDocumento,
        p_item_motivoEstoque,
        p_tinta_gradeProduto,
        p_item_localEstoque,
        p_item_pessoaParticipante,
        a.quantidade,
        0, --p_item_valorCustoOperacao
        p_item_observacoes,
        p_idFichaProdutoRealOrcamento,
        p_idItemPreDocumento,
        p_idItemDocFiscal,
        p_divergenciaBalanco,
        p_idItemDocTransferencia,
        p_modDoc_geraTransferencia,
        p_modDoc_geraOperacaoEmTransit,
        p_modDoc_transitoLocalEstoque,
        p_locEstTransito_indicProprPos,
        p_locEst_indicProprPosseItem,
        p_docTransf_estabelecEntrada,
        p_docTransf_estabelecSaida,
        r_bufferIdEstoque,
        r_bufferIdEstoque);
    ELSIF a.controleEstoque IN(1,5,6,11,12) THEN
      ADD_ESTOQUE_GRAVA (
        p_sys_estabelecimentoAtivo,
        p_config_354_estabProximoId,
        0, -- p_idEstoque
        p_cab_estabelecimento,
        p_data,
        a.produto,
        p_tinta_gradeProduto,
        p_item_modeloDocumento,
        p_item_motivoEstoque,
        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
        0, -- p_idNumeroSerie
        a.quantidade,
        0, -- p_precoCustoOperacao,
        0, -- p_totalCustoOperacao,
        0, -- p_precoCMV,
        0, -- p_valorCMV,
        p_item_observacoes,
        p_idFichaProdutoRealOrcamento,
        p_idItemPreDocumento,
        p_idItemDocFiscal,
        p_divergenciaBalanco,
        p_idItemDocTransferencia,
        r_bufferIdEstoque,
        v_auxNumber,
        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_GRAVA (
          p_sys_estabelecimentoAtivo,
          p_config_354_estabProximoId,
          0, -- p_idEstoque
          p_docTransf_estabelecSaida,
          p_data,
          a.produto,
          p_tinta_gradeProduto,
          p_item_modeloDocumento,
          p_item_motivoEstoque,
          900, --p_operacaoInternaEstoque
          0, --p_atualizaCustoMedio
          0, --p_atualizaUltimaCompra
          CASE
            WHEN p_cab_entradaSaida = 'S'
            THEN 'E'
            ELSE 'S'
          END, --p_entradaSaida
          p_locEstTransito_indicProprPos,
          p_item_pessoaParticipante,
          p_modDoc_transitoLocalEstoque,
          0, -- p_personalizacao
          0, -- p_idLoteEstoque
          0, -- p_idNumeroSerie
          a.quantidade,
          0, -- p_precoCustoOperacao,
          0, -- p_totalCustoOperacao,
          0, -- p_precoCMV,
          0, -- p_valorCMV,
          p_item_observacoes,
          p_idFichaProdutoRealOrcamento,
          p_idItemPreDocumento,
          p_idItemDocFiscal,
          p_divergenciaBalanco,
          p_idItemDocTransferencia,
          v_auxNumber,
          r_bufferIdEstoque,
          r_bufferIdEstoque);
      END IF;
    END IF;    
  END LOOP;
END ADD_ESTOQUE_PRODUTO_TINTA;

/

create or replace PROCEDURE ADD_ESTOQUE_FORMULA_TINTA (
  p_sys_estabelecimentoAtivo     IN NUMBER,
  p_config_209_filtrarGrupoEcon  IN NUMBER,
  p_config_354_estabProximoId    IN NUMBER,
  p_config_362_calcCustoPorGrade 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_data                         IN DATE,
  p_item_modeloDocumento         IN NUMBER,
  p_item_motivoEstoque           IN NUMBER,
  p_item_idFormulaTinta          IN NUMBER,
  p_item_localEstoque            IN NUMBER,
  p_item_pessoaParticipante      IN NUMBER,
  p_item_quantidade              IN NUMBER,
  p_item_observacoes             IN VARCHAR2,
  p_idFichaProdutoRealOrcamento  IN NUMBER,
  p_idItemPreDocumento           IN NUMBER,
  p_idItemDocFiscal              IN NUMBER,
  p_divergenciaBalanco           IN NUMBER,
  p_idItemDocTransferencia       IN NUMBER,
  p_modDoc_geraTransferencia     IN NUMBER,
  p_modDoc_geraOperacaoEmTransit IN NUMBER,
  p_modDoc_transitoLocalEstoque  IN NUMBER,
  p_locEstTransito_indicProprPos IN CHAR,
  p_locEst_indicProprPosseItem   IN CHAR,
  p_docTransf_estabelecEntrada   IN NUMBER,
  p_docTransf_estabelecSaida     IN NUMBER,
  p_bufferIdEstoque              IN VARCHAR2,
  r_bufferIdEstoque              OUT VARCHAR2)
IS
BEGIN
  r_bufferIdEstoque := p_bufferIdEstoque;
  FOR a IN (
    SELECT 
      a.idBaseTinta,
      baseTinta.gradeProduto,
      a.idColoranteTintaA,
      a.quantidadeA,
      COALESCE (colTintaA.gradeProduto, 0) gradeProdutoA,
      a.idColoranteTintaB,
      a.quantidadeB,
      COALESCE (colTintaB.gradeProduto, 0) gradeProdutoB,
      a.idColoranteTintaC,
      a.quantidadeC,
      COALESCE (colTintaC.gradeProduto, 0) gradeProdutoC,
      a.idColoranteTintaD,
      a.quantidadeD,
      COALESCE (colTintaD.gradeProduto, 0) gradeProdutoD,
      a.idColoranteTintaE,
      a.quantidadeE,
      COALESCE (colTintaE.gradeProduto, 0) gradeProdutoE,
      a.idColoranteTintaF,
      a.quantidadeF,
      COALESCE (colTintaF.gradeProduto, 0) gradeProdutoF,
      a.idColoranteTintaG,
      a.quantidadeG,
      COALESCE (colTintaG.gradeProduto, 0) gradeProdutoG,
      a.idColoranteTintaH,
      a.quantidadeH,
      COALESCE (colTintaH.gradeProduto, 0) gradeProdutoH,
      a.idColoranteTintaI,
      a.quantidadeI,
      COALESCE (colTintaI.gradeProduto, 0) gradeProdutoI,
      a.idColoranteTintaJ,
      a.quantidadeJ,
      COALESCE (colTintaJ.gradeProduto, 0) gradeProdutoJ,
      a.idColoranteTintaK,
      a.quantidadeK,
      COALESCE (colTintaK.gradeProduto, 0) gradeProdutoK,
      a.idColoranteTintaL,
      a.quantidadeL,
      COALESCE (colTintaL.gradeProduto, 0) gradeProdutoL,
      a.idColoranteTintaM,
      a.quantidadeM,
      COALESCE (colTintaM.gradeProduto, 0) gradeProdutoM,
      a.idColoranteTintaN,
      a.quantidadeN,
      COALESCE (colTintaN.gradeProduto, 0) gradeProdutoN,
      a.idColoranteTintaO,
      a.quantidadeO,
      COALESCE (colTintaO.gradeProduto, 0) gradeProdutoO
    FROM CAFORMULASTINTAS a
    JOIN CABASESTINTAS baseTinta
    ON baseTinta.idBaseTinta = a.idBaseTinta
    JOIN CACOLORANTESTINTAS colTintaA
    ON colTintaA.idColoranteTinta = a.idColoranteTintaA
    JOIN CACOLORANTESTINTAS colTintaB
    ON colTintaB.idColoranteTinta = a.idColoranteTintaB
    JOIN CACOLORANTESTINTAS colTintaC
    ON colTintaC.idColoranteTinta = a.idColoranteTintaC
    JOIN CACOLORANTESTINTAS colTintaD
    ON colTintaD.idColoranteTinta = a.idColoranteTintaD
    JOIN CACOLORANTESTINTAS colTintaE
    ON colTintaE.idColoranteTinta = a.idColoranteTintaE
    JOIN CACOLORANTESTINTAS colTintaF
    ON colTintaF.idColoranteTinta = a.idColoranteTintaF
    JOIN CACOLORANTESTINTAS colTintaG
    ON colTintaG.idColoranteTinta = a.idColoranteTintaG
    JOIN CACOLORANTESTINTAS colTintaH
    ON colTintaH.idColoranteTinta = a.idColoranteTintaH
    JOIN CACOLORANTESTINTAS colTintaI
    ON colTintaI.idColoranteTinta = a.idColoranteTintaI
    JOIN CACOLORANTESTINTAS colTintaJ
    ON colTintaJ.idColoranteTinta = a.idColoranteTintaJ
    JOIN CACOLORANTESTINTAS colTintaK
    ON colTintaK.idColoranteTinta = a.idColoranteTintaK
    JOIN CACOLORANTESTINTAS colTintaL
    ON colTintaL.idColoranteTinta = a.idColoranteTintaL
    JOIN CACOLORANTESTINTAS colTintaM
    ON colTintaM.idColoranteTinta = a.idColoranteTintaM
    JOIN CACOLORANTESTINTAS colTintaN
    ON colTintaN.idColoranteTinta = a.idColoranteTintaN
    JOIN CACOLORANTESTINTAS colTintaO
    ON colTintaO.idColoranteTinta = a.idColoranteTintaO
    WHERE a.idFormulaTinta = p_item_idFormulaTinta
    AND a.idBaseTinta > 0
    AND baseTinta.gradeProduto > 0)
  LOOP
    ADD_ESTOQUE_PRODUTO_TINTA (
      p_sys_estabelecimentoAtivo,
      p_config_209_filtrarGrupoEcon,
      p_config_354_estabProximoId,
      p_config_362_calcCustoPorGrade,
      p_cab_operacaoInternaEstoque,
      p_cab_atualizaCustoMedio,
      p_cab_atualizaUltimaCompra,
      p_cab_entradaSaida,
      p_cab_estabelecimento,
      p_data,
      p_item_modeloDocumento,
      p_item_motivoEstoque,
      p_item_localEstoque,
      p_item_pessoaParticipante,
      p_item_quantidade,
      p_item_observacoes,
      p_idFichaProdutoRealOrcamento,
      p_idItemPreDocumento,
      p_idItemDocFiscal,
      p_divergenciaBalanco,
      p_idItemDocTransferencia,
      p_modDoc_geraTransferencia,
      p_modDoc_geraOperacaoEmTransit,
      p_modDoc_transitoLocalEstoque,
      p_locEstTransito_indicProprPos,
      p_locEst_indicProprPosseItem,
      p_docTransf_estabelecEntrada,
      p_docTransf_estabelecSaida,
      a.gradeProduto,
      900, -- p_quantidade,
      r_bufferIdEstoque,
      r_bufferIdEstoque);    
    IF a.idColoranteTintaA > 0
      AND a.gradeProdutoA > 0
      AND a.quantidadeA > 0
    THEN
      ADD_ESTOQUE_PRODUTO_TINTA (
        p_sys_estabelecimentoAtivo,
        p_config_209_filtrarGrupoEcon,
        p_config_354_estabProximoId,
        p_config_362_calcCustoPorGrade,
        p_cab_operacaoInternaEstoque,
        p_cab_atualizaCustoMedio,
        p_cab_atualizaUltimaCompra,
        p_cab_entradaSaida,
        p_cab_estabelecimento,
        p_data,
        p_item_modeloDocumento,
        p_item_motivoEstoque,
        p_item_localEstoque,
        p_item_pessoaParticipante,
        p_item_quantidade,
        p_item_observacoes,
        p_idFichaProdutoRealOrcamento,
        p_idItemPreDocumento,
        p_idItemDocFiscal,
        p_divergenciaBalanco,
        p_idItemDocTransferencia,
        p_modDoc_geraTransferencia,
        p_modDoc_geraOperacaoEmTransit,
        p_modDoc_transitoLocalEstoque,
        p_locEstTransito_indicProprPos,
        p_locEst_indicProprPosseItem,
        p_docTransf_estabelecEntrada,
        p_docTransf_estabelecSaida,
        a.gradeProdutoA,
        a.quantidadeA,
        r_bufferIdEstoque,
        r_bufferIdEstoque);
    END IF;
    IF a.idColoranteTintaB > 0
      AND a.gradeProdutoB > 0
      AND a.quantidadeB > 0
    THEN
      ADD_ESTOQUE_PRODUTO_TINTA (
        p_sys_estabelecimentoAtivo,
        p_config_209_filtrarGrupoEcon,
        p_config_354_estabProximoId,
        p_config_362_calcCustoPorGrade,
        p_cab_operacaoInternaEstoque,
        p_cab_atualizaCustoMedio,
        p_cab_atualizaUltimaCompra,
        p_cab_entradaSaida,
        p_cab_estabelecimento,
        p_data,
        p_item_modeloDocumento,
        p_item_motivoEstoque,
        p_item_localEstoque,
        p_item_pessoaParticipante,
        p_item_quantidade,
        p_item_observacoes,
        p_idFichaProdutoRealOrcamento,
        p_idItemPreDocumento,
        p_idItemDocFiscal,
        p_divergenciaBalanco,
        p_idItemDocTransferencia,
        p_modDoc_geraTransferencia,
        p_modDoc_geraOperacaoEmTransit,
        p_modDoc_transitoLocalEstoque,
        p_locEstTransito_indicProprPos,
        p_locEst_indicProprPosseItem,
        p_docTransf_estabelecEntrada,
        p_docTransf_estabelecSaida,
        a.gradeProdutoB,
        a.quantidadeB,
        r_bufferIdEstoque,
        r_bufferIdEstoque);
    END IF;
    IF a.idColoranteTintaC > 0
      AND a.gradeProdutoC > 0
      AND a.quantidadeC > 0
    THEN
      ADD_ESTOQUE_PRODUTO_TINTA (
        p_sys_estabelecimentoAtivo,
        p_config_209_filtrarGrupoEcon,
        p_config_354_estabProximoId,
        p_config_362_calcCustoPorGrade,
        p_cab_operacaoInternaEstoque,
        p_cab_atualizaCustoMedio,
        p_cab_atualizaUltimaCompra,
        p_cab_entradaSaida,
        p_cab_estabelecimento,
        p_data,
        p_item_modeloDocumento,
        p_item_motivoEstoque,
        p_item_localEstoque,
        p_item_pessoaParticipante,
        p_item_quantidade,
        p_item_observacoes,
        p_idFichaProdutoRealOrcamento,
        p_idItemPreDocumento,
        p_idItemDocFiscal,
        p_divergenciaBalanco,
        p_idItemDocTransferencia,
        p_modDoc_geraTransferencia,
        p_modDoc_geraOperacaoEmTransit,
        p_modDoc_transitoLocalEstoque,
        p_locEstTransito_indicProprPos,
        p_locEst_indicProprPosseItem,
        p_docTransf_estabelecEntrada,
        p_docTransf_estabelecSaida,
        a.gradeProdutoC,
        a.quantidadeC,
        r_bufferIdEstoque,
        r_bufferIdEstoque);
    END IF;
    IF a.idColoranteTintaD > 0
      AND a.gradeProdutoD > 0
      AND a.quantidadeD > 0
    THEN
      ADD_ESTOQUE_PRODUTO_TINTA (
        p_sys_estabelecimentoAtivo,
        p_config_209_filtrarGrupoEcon,
        p_config_354_estabProximoId,
        p_config_362_calcCustoPorGrade,
        p_cab_operacaoInternaEstoque,
        p_cab_atualizaCustoMedio,
        p_cab_atualizaUltimaCompra,
        p_cab_entradaSaida,
        p_cab_estabelecimento,
        p_data,
        p_item_modeloDocumento,
        p_item_motivoEstoque,
        p_item_localEstoque,
        p_item_pessoaParticipante,
        p_item_quantidade,
        p_item_observacoes,
        p_idFichaProdutoRealOrcamento,
        p_idItemPreDocumento,
        p_idItemDocFiscal,
        p_divergenciaBalanco,
        p_idItemDocTransferencia,
        p_modDoc_geraTransferencia,
        p_modDoc_geraOperacaoEmTransit,
        p_modDoc_transitoLocalEstoque,
        p_locEstTransito_indicProprPos,
        p_locEst_indicProprPosseItem,
        p_docTransf_estabelecEntrada,
        p_docTransf_estabelecSaida,
        a.gradeProdutoD,
        a.quantidadeD,
        r_bufferIdEstoque,
        r_bufferIdEstoque);
    END IF;
    IF a.idColoranteTintaE > 0
      AND a.gradeProdutoE > 0
      AND a.quantidadeE > 0
    THEN
      ADD_ESTOQUE_PRODUTO_TINTA (
        p_sys_estabelecimentoAtivo,
        p_config_209_filtrarGrupoEcon,
        p_config_354_estabProximoId,
        p_config_362_calcCustoPorGrade,
        p_cab_operacaoInternaEstoque,
        p_cab_atualizaCustoMedio,
        p_cab_atualizaUltimaCompra,
        p_cab_entradaSaida,
        p_cab_estabelecimento,
        p_data,
        p_item_modeloDocumento,
        p_item_motivoEstoque,
        p_item_localEstoque,
        p_item_pessoaParticipante,
        p_item_quantidade,
        p_item_observacoes,
        p_idFichaProdutoRealOrcamento,
        p_idItemPreDocumento,
        p_idItemDocFiscal,
        p_divergenciaBalanco,
        p_idItemDocTransferencia,
        p_modDoc_geraTransferencia,
        p_modDoc_geraOperacaoEmTransit,
        p_modDoc_transitoLocalEstoque,
        p_locEstTransito_indicProprPos,
        p_locEst_indicProprPosseItem,
        p_docTransf_estabelecEntrada,
        p_docTransf_estabelecSaida,
        a.gradeProdutoE,
        a.quantidadeE,
        r_bufferIdEstoque,
        r_bufferIdEstoque);
    END IF;
    IF a.idColoranteTintaF > 0
      AND a.gradeProdutoF > 0
      AND a.quantidadeF > 0
    THEN
      ADD_ESTOQUE_PRODUTO_TINTA (
        p_sys_estabelecimentoAtivo,
        p_config_209_filtrarGrupoEcon,
        p_config_354_estabProximoId,
        p_config_362_calcCustoPorGrade,
        p_cab_operacaoInternaEstoque,
        p_cab_atualizaCustoMedio,
        p_cab_atualizaUltimaCompra,
        p_cab_entradaSaida,
        p_cab_estabelecimento,
        p_data,
        p_item_modeloDocumento,
        p_item_motivoEstoque,
        p_item_localEstoque,
        p_item_pessoaParticipante,
        p_item_quantidade,
        p_item_observacoes,
        p_idFichaProdutoRealOrcamento,
        p_idItemPreDocumento,
        p_idItemDocFiscal,
        p_divergenciaBalanco,
        p_idItemDocTransferencia,
        p_modDoc_geraTransferencia,
        p_modDoc_geraOperacaoEmTransit,
        p_modDoc_transitoLocalEstoque,
        p_locEstTransito_indicProprPos,
        p_locEst_indicProprPosseItem,
        p_docTransf_estabelecEntrada,
        p_docTransf_estabelecSaida,
        a.gradeProdutoF,
        a.quantidadeF,
        r_bufferIdEstoque,
        r_bufferIdEstoque);
    END IF;
    IF a.idColoranteTintaG > 0
      AND a.gradeProdutoG > 0
      AND a.quantidadeG > 0
    THEN
      ADD_ESTOQUE_PRODUTO_TINTA (
        p_sys_estabelecimentoAtivo,
        p_config_209_filtrarGrupoEcon,
        p_config_354_estabProximoId,
        p_config_362_calcCustoPorGrade,
        p_cab_operacaoInternaEstoque,
        p_cab_atualizaCustoMedio,
        p_cab_atualizaUltimaCompra,
        p_cab_entradaSaida,
        p_cab_estabelecimento,
        p_data,
        p_item_modeloDocumento,
        p_item_motivoEstoque,
        p_item_localEstoque,
        p_item_pessoaParticipante,
        p_item_quantidade,
        p_item_observacoes,
        p_idFichaProdutoRealOrcamento,
        p_idItemPreDocumento,
        p_idItemDocFiscal,
        p_divergenciaBalanco,
        p_idItemDocTransferencia,
        p_modDoc_geraTransferencia,
        p_modDoc_geraOperacaoEmTransit,
        p_modDoc_transitoLocalEstoque,
        p_locEstTransito_indicProprPos,
        p_locEst_indicProprPosseItem,
        p_docTransf_estabelecEntrada,
        p_docTransf_estabelecSaida,
        a.gradeProdutoG,
        a.quantidadeG,
        r_bufferIdEstoque,
        r_bufferIdEstoque);
    END IF;
    IF a.idColoranteTintaH > 0
      AND a.gradeProdutoH > 0
      AND a.quantidadeH > 0
    THEN
      ADD_ESTOQUE_PRODUTO_TINTA (
        p_sys_estabelecimentoAtivo,
        p_config_209_filtrarGrupoEcon,
        p_config_354_estabProximoId,
        p_config_362_calcCustoPorGrade,
        p_cab_operacaoInternaEstoque,
        p_cab_atualizaCustoMedio,
        p_cab_atualizaUltimaCompra,
        p_cab_entradaSaida,
        p_cab_estabelecimento,
        p_data,
        p_item_modeloDocumento,
        p_item_motivoEstoque,
        p_item_localEstoque,
        p_item_pessoaParticipante,
        p_item_quantidade,
        p_item_observacoes,
        p_idFichaProdutoRealOrcamento,
        p_idItemPreDocumento,
        p_idItemDocFiscal,
        p_divergenciaBalanco,
        p_idItemDocTransferencia,
        p_modDoc_geraTransferencia,
        p_modDoc_geraOperacaoEmTransit,
        p_modDoc_transitoLocalEstoque,
        p_locEstTransito_indicProprPos,
        p_locEst_indicProprPosseItem,
        p_docTransf_estabelecEntrada,
        p_docTransf_estabelecSaida,
        a.gradeProdutoH,
        a.quantidadeH,
        r_bufferIdEstoque,
        r_bufferIdEstoque);
    END IF;
    IF a.idColoranteTintaI > 0
      AND a.gradeProdutoI > 0
      AND a.quantidadeI > 0
    THEN
      ADD_ESTOQUE_PRODUTO_TINTA (
        p_sys_estabelecimentoAtivo,
        p_config_209_filtrarGrupoEcon,
        p_config_354_estabProximoId,
        p_config_362_calcCustoPorGrade,
        p_cab_operacaoInternaEstoque,
        p_cab_atualizaCustoMedio,
        p_cab_atualizaUltimaCompra,
        p_cab_entradaSaida,
        p_cab_estabelecimento,
        p_data,
        p_item_modeloDocumento,
        p_item_motivoEstoque,
        p_item_localEstoque,
        p_item_pessoaParticipante,
        p_item_quantidade,
        p_item_observacoes,
        p_idFichaProdutoRealOrcamento,
        p_idItemPreDocumento,
        p_idItemDocFiscal,
        p_divergenciaBalanco,
        p_idItemDocTransferencia,
        p_modDoc_geraTransferencia,
        p_modDoc_geraOperacaoEmTransit,
        p_modDoc_transitoLocalEstoque,
        p_locEstTransito_indicProprPos,
        p_locEst_indicProprPosseItem,
        p_docTransf_estabelecEntrada,
        p_docTransf_estabelecSaida,
        a.gradeProdutoI,
        a.quantidadeI,
        r_bufferIdEstoque,
        r_bufferIdEstoque);
    END IF;
    IF a.idColoranteTintaJ > 0
      AND a.gradeProdutoJ > 0
      AND a.quantidadeJ > 0
    THEN
      ADD_ESTOQUE_PRODUTO_TINTA (
        p_sys_estabelecimentoAtivo,
        p_config_209_filtrarGrupoEcon,
        p_config_354_estabProximoId,
        p_config_362_calcCustoPorGrade,
        p_cab_operacaoInternaEstoque,
        p_cab_atualizaCustoMedio,
        p_cab_atualizaUltimaCompra,
        p_cab_entradaSaida,
        p_cab_estabelecimento,
        p_data,
        p_item_modeloDocumento,
        p_item_motivoEstoque,
        p_item_localEstoque,
        p_item_pessoaParticipante,
        p_item_quantidade,
        p_item_observacoes,
        p_idFichaProdutoRealOrcamento,
        p_idItemPreDocumento,
        p_idItemDocFiscal,
        p_divergenciaBalanco,
        p_idItemDocTransferencia,
        p_modDoc_geraTransferencia,
        p_modDoc_geraOperacaoEmTransit,
        p_modDoc_transitoLocalEstoque,
        p_locEstTransito_indicProprPos,
        p_locEst_indicProprPosseItem,
        p_docTransf_estabelecEntrada,
        p_docTransf_estabelecSaida,
        a.gradeProdutoJ,
        a.quantidadeJ,
        r_bufferIdEstoque,
        r_bufferIdEstoque);
    END IF;
    IF a.idColoranteTintaK > 0
      AND a.gradeProdutoK > 0
      AND a.quantidadeK > 0
    THEN
      ADD_ESTOQUE_PRODUTO_TINTA (
        p_sys_estabelecimentoAtivo,
        p_config_209_filtrarGrupoEcon,
        p_config_354_estabProximoId,
        p_config_362_calcCustoPorGrade,
        p_cab_operacaoInternaEstoque,
        p_cab_atualizaCustoMedio,
        p_cab_atualizaUltimaCompra,
        p_cab_entradaSaida,
        p_cab_estabelecimento,
        p_data,
        p_item_modeloDocumento,
        p_item_motivoEstoque,
        p_item_localEstoque,
        p_item_pessoaParticipante,
        p_item_quantidade,
        p_item_observacoes,
        p_idFichaProdutoRealOrcamento,
        p_idItemPreDocumento,
        p_idItemDocFiscal,
        p_divergenciaBalanco,
        p_idItemDocTransferencia,
        p_modDoc_geraTransferencia,
        p_modDoc_geraOperacaoEmTransit,
        p_modDoc_transitoLocalEstoque,
        p_locEstTransito_indicProprPos,
        p_locEst_indicProprPosseItem,
        p_docTransf_estabelecEntrada,
        p_docTransf_estabelecSaida,
        a.gradeProdutoK,
        a.quantidadeK,
        r_bufferIdEstoque,
        r_bufferIdEstoque);
    END IF;
    IF a.idColoranteTintaL > 0
      AND a.gradeProdutoL > 0
      AND a.quantidadeL > 0
    THEN
      ADD_ESTOQUE_PRODUTO_TINTA (
        p_sys_estabelecimentoAtivo,
        p_config_209_filtrarGrupoEcon,
        p_config_354_estabProximoId,
        p_config_362_calcCustoPorGrade,
        p_cab_operacaoInternaEstoque,
        p_cab_atualizaCustoMedio,
        p_cab_atualizaUltimaCompra,
        p_cab_entradaSaida,
        p_cab_estabelecimento,
        p_data,
        p_item_modeloDocumento,
        p_item_motivoEstoque,
        p_item_localEstoque,
        p_item_pessoaParticipante,
        p_item_quantidade,
        p_item_observacoes,
        p_idFichaProdutoRealOrcamento,
        p_idItemPreDocumento,
        p_idItemDocFiscal,
        p_divergenciaBalanco,
        p_idItemDocTransferencia,
        p_modDoc_geraTransferencia,
        p_modDoc_geraOperacaoEmTransit,
        p_modDoc_transitoLocalEstoque,
        p_locEstTransito_indicProprPos,
        p_locEst_indicProprPosseItem,
        p_docTransf_estabelecEntrada,
        p_docTransf_estabelecSaida,
        a.gradeProdutoL,
        a.quantidadeL,
        r_bufferIdEstoque,
        r_bufferIdEstoque);
    END IF;
    IF a.idColoranteTintaM > 0
      AND a.gradeProdutoM > 0
      AND a.quantidadeM > 0
    THEN
      ADD_ESTOQUE_PRODUTO_TINTA (
        p_sys_estabelecimentoAtivo,
        p_config_209_filtrarGrupoEcon,
        p_config_354_estabProximoId,
        p_config_362_calcCustoPorGrade,
        p_cab_operacaoInternaEstoque,
        p_cab_atualizaCustoMedio,
        p_cab_atualizaUltimaCompra,
        p_cab_entradaSaida,
        p_cab_estabelecimento,
        p_data,
        p_item_modeloDocumento,
        p_item_motivoEstoque,
        p_item_localEstoque,
        p_item_pessoaParticipante,
        p_item_quantidade,
        p_item_observacoes,
        p_idFichaProdutoRealOrcamento,
        p_idItemPreDocumento,
        p_idItemDocFiscal,
        p_divergenciaBalanco,
        p_idItemDocTransferencia,
        p_modDoc_geraTransferencia,
        p_modDoc_geraOperacaoEmTransit,
        p_modDoc_transitoLocalEstoque,
        p_locEstTransito_indicProprPos,
        p_locEst_indicProprPosseItem,
        p_docTransf_estabelecEntrada,
        p_docTransf_estabelecSaida,
        a.gradeProdutoM,
        a.quantidadeM,
        r_bufferIdEstoque,
        r_bufferIdEstoque);
    END IF;
    IF a.idColoranteTintaN > 0
      AND a.gradeProdutoN > 0
      AND a.quantidadeN > 0
    THEN
      ADD_ESTOQUE_PRODUTO_TINTA (
        p_sys_estabelecimentoAtivo,
        p_config_209_filtrarGrupoEcon,
        p_config_354_estabProximoId,
        p_config_362_calcCustoPorGrade,
        p_cab_operacaoInternaEstoque,
        p_cab_atualizaCustoMedio,
        p_cab_atualizaUltimaCompra,
        p_cab_entradaSaida,
        p_cab_estabelecimento,
        p_data,
        p_item_modeloDocumento,
        p_item_motivoEstoque,
        p_item_localEstoque,
        p_item_pessoaParticipante,
        p_item_quantidade,
        p_item_observacoes,
        p_idFichaProdutoRealOrcamento,
        p_idItemPreDocumento,
        p_idItemDocFiscal,
        p_divergenciaBalanco,
        p_idItemDocTransferencia,
        p_modDoc_geraTransferencia,
        p_modDoc_geraOperacaoEmTransit,
        p_modDoc_transitoLocalEstoque,
        p_locEstTransito_indicProprPos,
        p_locEst_indicProprPosseItem,
        p_docTransf_estabelecEntrada,
        p_docTransf_estabelecSaida,
        a.gradeProdutoN,
        a.quantidadeN,
        r_bufferIdEstoque,
        r_bufferIdEstoque);
    END IF;
    IF a.idColoranteTintaO > 0
      AND a.gradeProdutoO > 0
      AND a.quantidadeO > 0
    THEN
      ADD_ESTOQUE_PRODUTO_TINTA (
        p_sys_estabelecimentoAtivo,
        p_config_209_filtrarGrupoEcon,
        p_config_354_estabProximoId,
        p_config_362_calcCustoPorGrade,
        p_cab_operacaoInternaEstoque,
        p_cab_atualizaCustoMedio,
        p_cab_atualizaUltimaCompra,
        p_cab_entradaSaida,
        p_cab_estabelecimento,
        p_data,
        p_item_modeloDocumento,
        p_item_motivoEstoque,
        p_item_localEstoque,
        p_item_pessoaParticipante,
        p_item_quantidade,
        p_item_observacoes,
        p_idFichaProdutoRealOrcamento,
        p_idItemPreDocumento,
        p_idItemDocFiscal,
        p_divergenciaBalanco,
        p_idItemDocTransferencia,
        p_modDoc_geraTransferencia,
        p_modDoc_geraOperacaoEmTransit,
        p_modDoc_transitoLocalEstoque,
        p_locEstTransito_indicProprPos,
        p_locEst_indicProprPosseItem,
        p_docTransf_estabelecEntrada,
        p_docTransf_estabelecSaida,
        a.gradeProdutoO,
        a.quantidadeO,
        r_bufferIdEstoque,
        r_bufferIdEstoque);
    END IF;
  END LOOP;
END ADD_ESTOQUE_FORMULA_TINTA;

/

create or replace PROCEDURE ADD_ESTOQUE_DOC_FISC_ITEM (
  p_sys_estabelecimentoAtivo     IN NUMBER,
  p_config_209_filtrarGrupoEcon  IN NUMBER,
  p_config_354_estabProximoId    IN NUMBER,
  p_config_362_calcCustoPorGrade IN NUMBER,
  p_idItemDocFiscal              IN NUMBER,
  p_bufferIdEstoque              IN VARCHAR2,
  p_bufferIdProdutoFilho         IN VARCHAR2,
  r_bufferIdEstoque              OUT VARCHAR2,
  r_bufferIdProdutoFilho         OUT VARCHAR2)
IS
  v_quantidadeNumerosSerie NUMBER;
  v_auxNumber              NUMBER;
BEGIN
  r_bufferIdEstoque := p_bufferIdEstoque;
  r_bufferIdProdutoFilho := p_bufferIdProdutoFilho;
  ADD_ESTOQUE_DOC_FISC_EXCLUI (
    p_idItemDocFiscal,
    r_bufferIdEstoque,
    r_bufferIdEstoque);
  ADD_ESTOQUE_DOC_FISC_FIL_EXCL (
    p_idItemDocFiscal,
    r_bufferIdProdutoFilho,
    r_bufferIdProdutoFilho);
  FOR a IN (
    SELECT
      cab.entradaSaida,
      cab.atualizaCustoMedio,
      cab.atualizaUltimaCompra,
      cab.estabelecimento,
      cab.dataEmissao,
      cab.dataEntradaSaida,
      item.idItemDocFiscal,
      item.modeloDocumento,
      item.gradeProduto,
      item.idFormulaTinta,
      item.personalizacao,
      item.idLoteEstoque,
      item.localEstoque,
      item.pessoaParticipante,
      item.quantidade,
      item.precoCustoOperacao,
      item.valorCustoOperacao,
      item.precoCMV,
      item.valorCMV,
      item.quantidadeExtemporanea,
      item.valorAcrescimoExtempTotal,
      item.observacoes,
      modDoc.geraTransferencia,
      modDoc.geraOperacaoEmTransito,
      modDoc.transitoLocalEstoque,
      locEstTransito.indicadorPropriedadePosseItem locEstTransito_indicProprPos,
      gradProd.produto,
      prod.controlaNumeroSerie,
      prod.controleEstoque,
      prod.tipoProduto,
      uniMed.casasDecimaisUnidadeMedida,
      locEst.indicadorPropriedadePosseItem locEst_indicProprPosseItem,
      COALESCE (cabTransf.estabelecimentoEntrada, 0) docTransf_estabelecEntrada,
      COALESCE (cabTransf.estabelecimentoSaida, 0) docTransf_estabelecSaida
    FROM MODOCFISCALXITENS item
    JOIN PAMODELOSDOCUMENTO modDoc
    ON modDoc.modeloDocumento = item.modeloDocumento
    JOIN PALOCAISESTOQUE locEstTransito
    ON locEstTransito.localEstoque = modDoc.transitoLocalEstoque 
    JOIN MODOCUMENTOSFISCAIS cab
    ON cab.idDocumentoFiscal = item.idDocumentoFiscal
    JOIN CAGRADESPRODUTO gradProd
    ON gradProd.gradeProduto = item.gradeProduto
    JOIN CAPRODUTOS prod
    ON prod.produto = gradProd.produto
    JOIN SIUNIDADESMEDIDA uniMed
    ON uniMed.unidadeMedida = prod.unidadeMedida
    JOIN PALOCAISESTOQUE locEst
    ON locEst.localEstoque = item.localEstoque
    LEFT JOIN MODOCTRANSFXDOCFISCAL transfXDoc
    ON transfXDoc.idItemDocFiscal = item.idItemDocFiscal
    AND transfXDoc.entradaSaidaOriginal IN ('E','S')
    LEFT JOIN MODOCUMENTOTRANSFXITENS itemTransf
    ON itemTransf.idItemDocTransferencia = transfXDoc.idItemDocTransferencia
    LEFT JOIN MODOCUMENTOSTRANSFERENCIA cabTransf
    ON cabTransf.documentoTransferencia = itemTransf.documentoTransferencia
    WHERE item.idItemDocFiscal = p_idItemDocFiscal
    AND item.cancelado = 0
    AND item.quantidade+item.quantidadeExtemporanea > 0
    AND item.movimentaEstoque = 1
    AND cab.situacaoDocumentoFiscal BETWEEN 21 AND 23)
  LOOP
    IF a.controleEstoque = 12 AND a.idFormulaTinta > 0 THEN
      ADD_ESTOQUE_FORMULA_TINTA (
        p_sys_estabelecimentoAtivo, 
        p_config_209_filtrarGrupoEcon,
        p_config_354_estabProximoId,
        p_config_362_calcCustoPorGrade,
        100, -- p_cab_operacaoInternaEstoque
        a.atualizaCustoMedio,
        a.atualizaUltimaCompra,
        a.entradaSaida,
        a.estabelecimento,
        CASE WHEN a.dataEntradaSaida IS NULL OR a.dataEntradaSaida < a.dataEmissao THEN a.dataEmissao ELSE a.dataEntradaSaida END, -- p_data
        a.modeloDocumento,
        0, -- p_item_motivoEstoque
        a.idFormulaTinta,
        a.localEstoque,
        a.pessoaParticipante,
        a.quantidade + a.quantidadeExtemporanea, -- a.quantidade
        a.observacoes,
        0, -- p_idFichaProdutoRealOrcamento
        0, -- p_idItemPreDocumento
        a.idItemDocFiscal,
        0, -- p_divergenciaBalanco
        0, -- p_idItemDocTransferencia
        a.geraTransferencia,
        a.geraOperacaoEmTransito,
        a.transitoLocalEstoque,
        a.locEstTransito_indicProprPos,
        a.locEst_indicProprPosseItem,
        a.docTransf_estabelecEntrada,
        a.docTransf_estabelecSaida,
        r_bufferIdEstoque, 
        r_bufferIdEstoque);
    ELSIF a.controleEstoque IN (3,4) THEN
      ADD_ESTOQUE_KIT (
        p_sys_estabelecimentoAtivo, 
        p_config_209_filtrarGrupoEcon,
        p_config_354_estabProximoId,
        p_config_362_calcCustoPorGrade,
        100, -- p_cab_operacaoInternaEstoque
        a.atualizaCustoMedio,
        a.atualizaUltimaCompra,
        a.entradaSaida,
        a.estabelecimento,
        CASE WHEN a.dataEntradaSaida IS NULL OR a.dataEntradaSaida < a.dataEmissao THEN a.dataEmissao ELSE a.dataEntradaSaida END, -- p_data
        a.modeloDocumento,
        0, -- p_item_motivoEstoque
        a.gradeProduto,
        a.localEstoque,
        a.pessoaParticipante,
        a.quantidade + a.quantidadeExtemporanea, -- a.quantidade
        a.valorCustoOperacao + a.valorAcrescimoExtempTotal, -- a.valorCustoOperacao
        a.observacoes,
        0, -- p_idFichaProdutoRealOrcamento
        0, -- p_idItemPreDocumento
        a.idItemDocFiscal,
        0, -- p_divergenciaBalanco
        0, -- p_idItemDocTransferencia
        a.geraTransferencia,
        a.geraOperacaoEmTransito,
        a.transitoLocalEstoque,
        a.locEstTransito_indicProprPos,
        a.locEst_indicProprPosseItem,
        a.docTransf_estabelecEntrada,
        a.docTransf_estabelecSaida,
        r_bufferIdEstoque,
        r_bufferIdEstoque);
    ELSIF a.controleEstoque IN (1,5,6,11,12) THEN
      v_quantidadeNumerosSerie := 0;
      IF a.controlaNumeroSerie > 0 THEN
        ADD_ESTOQUE_DOC_FISC_N_SERIE (
          p_sys_estabelecimentoAtivo,
          p_config_354_estabProximoId,
          a.atualizaCustoMedio,
          a.atualizaUltimaCompra,
          a.entradaSaida,
          a.estabelecimento,
          CASE WHEN a.dataEntradaSaida IS NULL OR a.dataEntradaSaida < a.dataEmissao THEN a.dataEmissao ELSE a.dataEntradaSaida END, -- p_data
          a.idItemDocFiscal,
          a.modeloDocumento,
          a.gradeProduto,
          a.personalizacao,
          a.idLoteEstoque,
          a.localEstoque,
          a.pessoaParticipante,
          CASE
            WHEN a.valorCustoOperacao = 0
              OR a.valorAcrescimoExtempTotal = 0
              OR a.valorCustoOperacao + a.valorAcrescimoExtempTotal = 0
            THEN a.precoCustoOperacao
            ELSE ROUND(a.precoCustoOperacao * (a.valorCustoOperacao + a.valorAcrescimoExtempTotal) / a.valorCustoOperacao, 7)
          END, -- a.precoCustoOperacao
          a.precoCMV,
          a.observacoes,
          a.geraTransferencia,
          a.geraOperacaoEmTransito,
          a.transitoLocalEstoque,
          a.locEstTransito_indicProprPos,
          a.produto,
          a.locEst_indicProprPosseItem,
          a.docTransf_estabelecEntrada,
          a.docTransf_estabelecSaida,
          r_bufferIdEstoque,
          r_bufferIdEstoque,
          v_quantidadeNumerosSerie);
      END IF;
      IF a.quantidade + a.quantidadeExtemporanea > v_quantidadeNumerosSerie THEN
        ADD_ESTOQUE_GRAVA (
          p_sys_estabelecimentoAtivo,
          p_config_354_estabProximoId,
          0, -- p_idEstoque
          a.estabelecimento,
          CASE WHEN a.dataEntradaSaida IS NULL OR a.dataEntradaSaida < a.dataEmissao THEN a.dataEmissao ELSE a.dataEntradaSaida END, -- p_data
          a.produto,
          a.gradeProduto,
          a.modeloDocumento,
          0, -- p_item_motivoEstoque
          100, -- p_operacaoInternaEstoque
          a.atualizaCustoMedio,
          a.atualizaUltimaCompra,
          a.entradaSaida,
          a.locEst_indicProprPosseItem,
          a.pessoaParticipante,
          a.localEstoque,
          a.personalizacao,
          a.idLoteEstoque,
          0, -- p_idNumeroSerie
          a.quantidade + a.quantidadeExtemporanea - v_quantidadeNumerosSerie, -- p_quantidade
          CASE
            WHEN a.valorCustoOperacao = 0
              OR a.valorAcrescimoExtempTotal = 0
              OR a.valorCustoOperacao + a.valorAcrescimoExtempTotal = 0
            THEN a.precoCustoOperacao
            ELSE ROUND(a.precoCustoOperacao * (a.valorCustoOperacao + a.valorAcrescimoExtempTotal) / a.valorCustoOperacao,7)
          END, -- p_precoCustoOperacao
          CASE WHEN a.quantidade = 0 THEN 0 ELSE ROUND (((a.valorCustoOperacao + a.valorAcrescimoExtempTotal) * (a.quantidade + a.quantidadeExtemporanea - v_quantidadeNumerosSerie) / a.quantidade), 2) END, -- p_totalCustoOperacao
          a.precoCMV,
          CASE WHEN a.quantidade = 0 THEN 0 ELSE ROUND ((a.valorCMV * (a.quantidade + a.quantidadeExtemporanea - v_quantidadeNumerosSerie) / a.quantidade), 2) END, -- p_valorCMV
          a.observacoes,
          0, -- p_idFichaProdutoRealOrcamento
          0, -- p_idItemPreDocumento
          a.idItemDocFiscal,
          0, -- p_divergenciaBalanco
          0, -- p_idItemDocTransferencia
          r_bufferIdEstoque,
          v_auxNumber,
          r_bufferIdEstoque);
        IF a.geraTransferencia = 1 AND a.geraOperacaoEmTransito = 1 AND a.transitoLocalEstoque > 0 AND a.docTransf_estabelecEntrada > 0 AND a.docTransf_estabelecSaida > 0 THEN
          ADD_ESTOQUE_GRAVA (
            p_sys_estabelecimentoAtivo,
            p_config_354_estabProximoId,
            0, -- p_idEstoque
            a.docTransf_estabelecSaida,
            CASE WHEN a.dataEntradaSaida IS NULL OR a.dataEntradaSaida < a.dataEmissao THEN a.dataEmissao ELSE a.dataEntradaSaida END, -- p_data
            a.produto,
            a.gradeProduto,
            a.modeloDocumento,
            0, -- p_item_motivoEstoque
            900, -- p_operacaoInternaEstoque
            0, -- p_atualizaCustoMedio
            0, -- p_atualizaUltimaCompra
            CASE WHEN a.entradaSaida='S' THEN 'E' ELSE 'S' END, -- p_entradaSaida
            a.locEstTransito_indicProprPos,
            a.pessoaParticipante,
            a.transitoLocalEstoque,
            a.personalizacao,
            a.idLoteEstoque,
            0, -- p_idNumeroSerie
            a.quantidade + a.quantidadeExtemporanea - v_quantidadeNumerosSerie, -- p_quantidade
            CASE
              WHEN a.valorCustoOperacao = 0
                OR a.valorAcrescimoExtempTotal = 0
                OR a.valorCustoOperacao + a.valorAcrescimoExtempTotal = 0
              THEN a.precoCustoOperacao
              ELSE ROUND(a.precoCustoOperacao * (a.valorCustoOperacao + a.valorAcrescimoExtempTotal) / a.valorCustoOperacao,7)
            END, -- p_precoCustoOperacao
            CASE WHEN a.quantidade = 0 THEN 0 ELSE ROUND (((a.valorCustoOperacao + a.valorAcrescimoExtempTotal) * (a.quantidade + a.quantidadeExtemporanea - v_quantidadeNumerosSerie) / a.quantidade), 2) END, -- p_totalCustoOperacao
            a.precoCMV,
            CASE WHEN a.quantidade = 0 THEN 0 ELSE ROUND ((a.valorCMV * (a.quantidade + a.quantidadeExtemporanea - v_quantidadeNumerosSerie) / a.quantidade), 2) END, -- p_valorCMV
            a.observacoes,
            0, -- p_idFichaProdutoRealOrcamento
            0, -- p_idItemPreDocumento
            a.idItemDocFiscal,
            0, -- p_divergenciaBalanco
            0, -- p_idItemDocTransferencia
            r_bufferIdEstoque, 
            v_auxNumber,
            r_bufferIdEstoque);
        END IF;
      END IF;
    ELSIF a.controleEstoque IN (2,21,99)
      AND a.tipoProduto = '09'
    THEN
      FOR b IN (
        SELECT
          itemOrc.gradeProduto,
          itemOrc.idFormulaTinta,
          itemOrc.personalizacao,
          itemOrc.idLoteEstoque,
          gradProd.produto,
          prod.controleEstoque,
          prod.controlaNumeroSerie
        FROM MODOCFISCALXORCAMENTOITEM docXDoc
        JOIN MOORCAMENTOXITENS itemOrc
        ON itemOrc.idItemOrcamento = docXDoc.idItemOrcamento
        JOIN CAGRADESPRODUTO gradProd
        ON gradProd.gradeProduto = itemOrc.gradeProduto
        JOIN CAPRODUTOS prod
        ON prod.produto = gradProd.produto
        WHERE docXDoc.idItemDocFiscal = a.idItemDocFiscal
        AND docXDoc.quantidade <> 0
        AND itemOrc.cancelado = 0)
      LOOP
        IF b.controleEstoque = 12 AND b.idFormulaTinta > 0 THEN
          ADD_ESTOQUE_FORMULA_TINTA (
            p_sys_estabelecimentoAtivo, 
            p_config_209_filtrarGrupoEcon,
            p_config_354_estabProximoId,
            p_config_362_calcCustoPorGrade,
            100, -- p_cab_operacaoInternaEstoque
            a.atualizaCustoMedio,
            a.atualizaUltimaCompra,
            a.entradaSaida,
            a.estabelecimento,
            CASE WHEN a.dataEntradaSaida IS NULL OR a.dataEntradaSaida < a.dataEmissao THEN a.dataEmissao ELSE a.dataEntradaSaida END, -- p_data
            a.modeloDocumento,
            0, -- p_item_motivoEstoque
            b.idFormulaTinta,
            a.localEstoque,
            a.pessoaParticipante,
            a.quantidade + a.quantidadeExtemporanea, -- a.quantidade
            a.observacoes,
            0, -- p_idFichaProdutoRealOrcamento
            0, -- p_idItemPreDocumento
            a.idItemDocFiscal,
            0, -- p_divergenciaBalanco
            0, -- p_idItemDocTransferencia
            a.geraTransferencia,
            a.geraOperacaoEmTransito,
            a.transitoLocalEstoque,
            a.locEstTransito_indicProprPos,
            a.locEst_indicProprPosseItem,
            a.docTransf_estabelecEntrada,
            a.docTransf_estabelecSaida,
            r_bufferIdEstoque, 
            r_bufferIdEstoque);
        ELSIF b.controleEstoque IN (3,4) THEN
          ADD_ESTOQUE_KIT (
            p_sys_estabelecimentoAtivo, 
            p_config_209_filtrarGrupoEcon,
            p_config_354_estabProximoId,
            p_config_362_calcCustoPorGrade,
            100, -- p_cab_operacaoInternaEstoque
            a.atualizaCustoMedio,
            a.atualizaUltimaCompra,
            a.entradaSaida,
            a.estabelecimento,
            CASE WHEN a.dataEntradaSaida IS NULL OR a.dataEntradaSaida < a.dataEmissao THEN a.dataEmissao ELSE a.dataEntradaSaida END, -- p_data
            a.modeloDocumento,
            0, -- p_item_motivoEstoque
            b.gradeProduto,
            a.localEstoque,
            a.pessoaParticipante,
            a.quantidade + a.quantidadeExtemporanea, -- a.quantidade
            a.valorCustoOperacao + a.valorAcrescimoExtempTotal, -- a.valorCustoOperacao
            a.observacoes,
            0, -- p_idFichaProdutoRealOrcamento
            0, -- p_idItemPreDocumento
            a.idItemDocFiscal,
            0, -- p_divergenciaBalanco
            0, -- p_idItemDocTransferencia
            a.geraTransferencia,
            a.geraOperacaoEmTransito,
            a.transitoLocalEstoque,
            a.locEstTransito_indicProprPos,
            a.locEst_indicProprPosseItem,
            a.docTransf_estabelecEntrada,
            a.docTransf_estabelecSaida,
            r_bufferIdEstoque,
            r_bufferIdEstoque);
        ELSIF a.controleEstoque IN (1,5,6,11,12) THEN
          v_quantidadeNumerosSerie := 0;
          IF b.controlaNumeroSerie > 0 THEN
            ADD_ESTOQUE_DOC_FISC_N_SERIE (
              p_sys_estabelecimentoAtivo,
              p_config_354_estabProximoId,
              a.atualizaCustoMedio,
              a.atualizaUltimaCompra,
              a.entradaSaida,
              a.estabelecimento,
              CASE WHEN a.dataEntradaSaida IS NULL OR a.dataEntradaSaida < a.dataEmissao THEN a.dataEmissao ELSE a.dataEntradaSaida END, -- p_data
              a.idItemDocFiscal,
              a.modeloDocumento,
              b.gradeProduto,
              b.personalizacao,
              b.idLoteEstoque,
              a.localEstoque,
              a.pessoaParticipante,
              CASE
                WHEN a.valorCustoOperacao = 0
                  OR a.valorAcrescimoExtempTotal = 0
                  OR a.valorCustoOperacao + a.valorAcrescimoExtempTotal = 0
                THEN a.precoCustoOperacao
                ELSE ROUND(a.precoCustoOperacao * (a.valorCustoOperacao + a.valorAcrescimoExtempTotal) / a.valorCustoOperacao, 7)
              END, -- a.precoCustoOperacao
              a.precoCMV,
              a.observacoes,
              a.geraTransferencia,
              a.geraOperacaoEmTransito,
              a.transitoLocalEstoque,
              a.locEstTransito_indicProprPos,
              b.produto,
              a.locEst_indicProprPosseItem,
              a.docTransf_estabelecEntrada,
              a.docTransf_estabelecSaida,
              r_bufferIdEstoque,
              r_bufferIdEstoque,
              v_quantidadeNumerosSerie);
          END IF;
          IF a.quantidade + a.quantidadeExtemporanea > v_quantidadeNumerosSerie THEN
            ADD_ESTOQUE_GRAVA (
              p_sys_estabelecimentoAtivo,
              p_config_354_estabProximoId,
              0, -- p_idEstoque
              a.estabelecimento,
              CASE WHEN a.dataEntradaSaida IS NULL OR a.dataEntradaSaida < a.dataEmissao THEN a.dataEmissao ELSE a.dataEntradaSaida END, -- p_data
              b.produto,
              b.gradeProduto,
              a.modeloDocumento,
              0, -- p_item_motivoEstoque
              100, -- p_operacaoInternaEstoque
              a.atualizaCustoMedio,
              a.atualizaUltimaCompra,
              a.entradaSaida,
              a.locEst_indicProprPosseItem,
              a.pessoaParticipante,
              a.localEstoque,
              b.personalizacao,
              b.idLoteEstoque,
              0, -- p_idNumeroSerie
              a.quantidade + a.quantidadeExtemporanea - v_quantidadeNumerosSerie, -- p_quantidade
              CASE
                WHEN a.valorCustoOperacao = 0
                  OR a.valorAcrescimoExtempTotal = 0
                  OR a.valorCustoOperacao + a.valorAcrescimoExtempTotal = 0
                THEN a.precoCustoOperacao
                ELSE ROUND(a.precoCustoOperacao * (a.valorCustoOperacao + a.valorAcrescimoExtempTotal) / a.valorCustoOperacao,7)
              END, -- p_precoCustoOperacao
              CASE WHEN a.quantidade = 0 THEN 0 ELSE ROUND (((a.valorCustoOperacao + a.valorAcrescimoExtempTotal) * (a.quantidade + a.quantidadeExtemporanea - v_quantidadeNumerosSerie) / a.quantidade), 2) END, -- p_totalCustoOperacao
              a.precoCMV,
              CASE WHEN a.quantidade = 0 THEN 0 ELSE ROUND ((a.valorCMV * (a.quantidade + a.quantidadeExtemporanea - v_quantidadeNumerosSerie) / a.quantidade), 2) END, -- p_valorCMV
              a.observacoes,
              0, -- p_idFichaProdutoRealOrcamento
              0, -- p_idItemPreDocumento
              a.idItemDocFiscal,
              0, -- p_divergenciaBalanco
              0, -- p_idItemDocTransferencia
              r_bufferIdEstoque,
              v_auxNumber,
              r_bufferIdEstoque);
            IF a.geraTransferencia = 1 AND a.geraOperacaoEmTransito = 1 AND a.transitoLocalEstoque > 0 AND a.docTransf_estabelecEntrada > 0 AND a.docTransf_estabelecSaida > 0 THEN
              ADD_ESTOQUE_GRAVA (
                p_sys_estabelecimentoAtivo,
                p_config_354_estabProximoId,
                0, -- p_idEstoque
                a.docTransf_estabelecSaida,
                CASE WHEN a.dataEntradaSaida IS NULL OR a.dataEntradaSaida < a.dataEmissao THEN a.dataEmissao ELSE a.dataEntradaSaida END, -- p_data
                b.produto,
                b.gradeProduto,
                a.modeloDocumento,
                0, -- p_item_motivoEstoque
                900, -- p_operacaoInternaEstoque
                0, -- p_atualizaCustoMedio
                0, -- p_atualizaUltimaCompra
                CASE WHEN a.entradaSaida='S' THEN 'E' ELSE 'S' END, -- p_entradaSaida
                a.locEstTransito_indicProprPos,
                a.pessoaParticipante,
                a.transitoLocalEstoque,
                b.personalizacao,
                b.idLoteEstoque,
                0, -- p_idNumeroSerie
                a.quantidade + a.quantidadeExtemporanea - v_quantidadeNumerosSerie, -- p_quantidade
                CASE
                  WHEN a.valorCustoOperacao = 0
                    OR a.valorAcrescimoExtempTotal = 0
                    OR a.valorCustoOperacao + a.valorAcrescimoExtempTotal = 0
                  THEN a.precoCustoOperacao
                  ELSE ROUND(a.precoCustoOperacao * (a.valorCustoOperacao + a.valorAcrescimoExtempTotal) / a.valorCustoOperacao,7)
                END, -- p_precoCustoOperacao
                CASE WHEN a.quantidade = 0 THEN 0 ELSE ROUND (((a.valorCustoOperacao + a.valorAcrescimoExtempTotal) * (a.quantidade + a.quantidadeExtemporanea - v_quantidadeNumerosSerie) / a.quantidade), 2) END, -- p_totalCustoOperacao
                a.precoCMV,
                CASE WHEN a.quantidade = 0 THEN 0 ELSE ROUND ((a.valorCMV * (a.quantidade + a.quantidadeExtemporanea - v_quantidadeNumerosSerie) / a.quantidade), 2) END, -- p_valorCMV
                a.observacoes,
                0, -- p_idFichaProdutoRealOrcamento
                0, -- p_idItemPreDocumento
                a.idItemDocFiscal,
                0, -- p_divergenciaBalanco
                0, -- p_idItemDocTransferencia
                r_bufferIdEstoque, 
                v_auxNumber,
                r_bufferIdEstoque);
            END IF;
          END IF;
        END IF;
      END LOOP;
    END IF;
    FOR b IN (
      SELECT
        b.observacoes,
        comp.gradeProdutoEstoque gradeProduto,
        gradprod.produto,
        prod.controleEstoque,
        ROUND ((a.quantidade + a.quantidadeExtemporanea) * b.quantidade, uniFilho.casasDecimaisUnidadeMedida) quantidade
      FROM MODOCFISCALXCOMPOSICOESPR b
      JOIN CAPRODUTOXCOMPOSICOESPREC comp
      ON comp.composicaoPreco = b.composicaoPreco
      JOIN CAGRADESPRODUTO gradProd
      ON gradProd.gradeProduto = comp.gradeProdutoEstoque
      JOIN CAPRODUTOS prod
      ON prod.produto = gradprod.produto
      JOIN SIUNIDADESMEDIDA uniFilho
      ON uniFilho.unidadeMedida = prod.unidadeMedida
      WHERE b.idItemDocFiscal = a.idItemDocFiscal
      AND b.selecionado = 1
      AND comp.gradeProdutoEstoque > 0
      AND ROUND ((a.quantidade + a.quantidadeExtemporanea) * b.quantidade, uniFilho.casasDecimaisUnidadeMedida) > 0)
    LOOP
      IF b.controleEstoque IN (3,4) THEN
        ADD_ESTOQUE_KIT (
          p_sys_estabelecimentoAtivo,
          p_config_209_filtrarGrupoEcon,
          p_config_354_estabProximoId,
          p_config_362_calcCustoPorGrade,
          100, -- p_cab_operacaoInternaEstoque
          a.atualizaCustoMedio,
          a.atualizaUltimaCompra,
          a.entradaSaida,
          a.estabelecimento,
          CASE WHEN a.dataEntradaSaida IS NULL OR a.dataEntradaSaida < a.dataEmissao THEN a.dataEmissao ELSE a.dataEntradaSaida END, -- p_data
          a.modeloDocumento,
          0, -- p_item_motivoEstoque
          a.gradeProduto,
          a.localEstoque,
          a.pessoaParticipante,
          b.quantidade,
          0,
          b.observacoes,
          0, -- p_idFichaProdutoRealOrcamento
          0, -- p_item_idItemPreDocumento,
          a.idItemDocFiscal,
          0, -- p_divergenciaBalanco,
          0, -- p_idItemDocTransferencia,
          a.geraTransferencia,
          a.geraOperacaoEmTransito,
          a.transitoLocalEstoque,
          a.locEstTransito_indicProprPos,
          a.locEst_indicProprPosseItem,
          a.docTransf_estabelecEntrada,
          a.docTransf_estabelecSaida,
          r_bufferIdEstoque,
          r_bufferIdEstoque);
      ELSIF a.controleEstoque IN(1,5,6,11,12) THEN
        ADD_ESTOQUE_GRAVA (
          p_sys_estabelecimentoAtivo,
          p_config_354_estabProximoId,
          0, -- p_idEstoque
          a.estabelecimento,
          CASE WHEN a.dataEntradaSaida IS NULL OR a.dataEntradaSaida < a.dataEmissao THEN a.dataEmissao ELSE a.dataEntradaSaida END, -- p_data
          b.produto,
          b.gradeProduto,
          a.modeloDocumento,
          0, -- p_item_motivoEstoque
          100, -- p_cab_operacaoInternaEstoque
          a.atualizaCustoMedio,
          a.atualizaUltimaCompra,
          a.entradaSaida,
          a.locEst_indicProprPosseItem,
          a.pessoaParticipante,
          a.localEstoque,
          0, -- p_personalizacao
          0, -- p_idLoteEstoque
          0, -- p_idNumeroSerie
          b.quantidade,
          0, -- p_precoCustoOperacao
          0, -- p_totalCustoOperacao
          0, -- p_precoCMV
          0, -- p_valorCMV
          b.observacoes,
          0, -- p_idFichaProdutoRealOrcamento
          0, -- p_item_idItemPreDocumento,
          a.idItemDocFiscal,
          0, -- p_divergenciaBalanco,
          0, -- p_idItemDocTransferencia,
          r_bufferIdEstoque,
          v_auxNumber,
          r_bufferIdEstoque);
        IF a.geraTransferencia = 1
          AND a.geraOperacaoEmTransito = 1
          AND a.transitoLocalEstoque > 0
          AND a.docTransf_estabelecEntrada > 0
          AND a.docTransf_estabelecSaida > 0
        THEN
          ADD_ESTOQUE_GRAVA (
            p_sys_estabelecimentoAtivo,
            p_config_354_estabProximoId,
            0, -- p_idEstoque
            a.docTransf_estabelecSaida,
            CASE WHEN a.dataEntradaSaida IS NULL OR a.dataEntradaSaida < a.dataEmissao THEN a.dataEmissao ELSE a.dataEntradaSaida END, -- p_data
            b.produto,
            b.gradeProduto,
            a.modeloDocumento,
            0, -- p_item_motivoEstoque
            900, -- p_operacaoInternaEstoque
            0, -- p_atualizaCustoMedio
            0, -- p_atualizaUltimaCompra
            CASE
              WHEN a.entradaSaida = 'S'
              THEN 'E'
              ELSE 'S'
            END, -- p_entradaSaida
            a.locEstTransito_indicProprPos,
            a.pessoaParticipante,
            a.transitoLocalEstoque,
            0, -- p_personalizacao
            0, -- p_idLoteEstoque
            0, -- p_idNumeroSerie
            b.quantidade,
            0, -- p_precoCustoOperacao
            0, -- p_totalCustoOperacao
            0, -- p_precoCMV
            0, -- p_valorCMV
            b.observacoes,
            0, -- p_idFichaProdutoRealOrcamento
            0, -- p_item_idItemPreDocumento,
            a.idItemDocFiscal,
            0, -- p_divergenciaBalanco,
            0, -- p_idItemDocTransferencia,
            r_bufferIdEstoque, 
            v_auxNumber,
            r_bufferIdEstoque);
        END IF;    
      END IF;
    END LOOP;
  END LOOP;
  FOR a IN (
    SELECT id
    FROM MODOCFISCALXPRODUTOFILHO
    WHERE idItemDocFiscal = p_idItemDocFiscal
    ORDER BY id)
  LOOP
    r_bufferIdProdutoFilho :=
      CASE
        WHEN r_bufferIdProdutoFilho IS NULL
          OR r_bufferIdProdutoFilho = ''
          OR r_bufferIdProdutoFilho = ' '
        THEN ''
        ELSE RTRIM (r_bufferIdProdutoFilho) || ';'
      END
      || TO_CHAR (LPAD(a.id,14,'0'));
    DELETE MODOCFISCALXPRODUTOFILHO b
    WHERE a.id = a.id;
  END LOOP;
  FOR a IN (
    SELECT 
      cab.atualizaCustoMedio,
      cab.estabelecimento,
      cab.dataEmissao,
      cab.dataEntradaSaida,
      item.idItemDocFiscal,
      item.gradeProduto,
      item.idFormulaTinta,
      item.personalizacao,
      item.pessoaParticipante,
      item.quantidade,
      item.precoCustoOperacao,
      item.valorCustoOperacao,
      item.precoCMV,
      item.valorCMV,
      item.observacoes,
      prod.controlaNumeroSerie,
      prod.controleEstoque,
      locEst.indicadorPropriedadePosseItem locEst_indicProprPosseItem
    FROM MODOCFISCALXITENS item
    JOIN MODOCUMENTOSFISCAIS cab
    ON cab.idDocumentoFiscal = item.idDocumentoFiscal
    JOIN CAGRADESPRODUTO gradProd
    ON gradProd.gradeProduto = item.gradeProduto
    JOIN CAPRODUTOS prod
    ON prod.produto = gradProd.produto
    JOIN PALOCAISESTOQUE locEst
    ON locEst.localEstoque = item.localEstoque
    WHERE item.idItemDocFiscal = p_idItemDocFiscal
    AND item.cancelado = 0
    AND item.quantidade > 0
    AND cab.situacaoDocumentoFiscal BETWEEN 21 AND 23)
  LOOP
    IF a.controleEstoque = 12
      AND a.idFormulaTinta > 0
    THEN
      ADD_ESTOQUE_DOC_FISC_FIL_FORM (
        p_sys_estabelecimentoAtivo, 
        p_config_209_filtrarGrupoEcon,
        p_config_354_estabProximoId,
        p_config_362_calcCustoPorGrade,
        a.atualizaCustoMedio,
        a.estabelecimento,
        CASE WHEN a.dataEntradaSaida IS NULL OR a.dataEntradaSaida < a.dataEmissao THEN a.dataEmissao ELSE a.dataEntradaSaida END, -- p_data
        a.idItemDocFiscal,
        a.idFormulaTinta,
        a.pessoaParticipante,
        a.quantidade,
        a.observacoes,
        a.locEst_indicProprPosseItem,
        r_bufferIdProdutoFilho, 
        r_bufferIdProdutoFilho);
    ELSIF a.controleEstoque IN (3,4) THEN
      ADD_ESTOQUE_DOC_FISC_FIL_KIT (
        p_sys_estabelecimentoAtivo, 
        p_config_209_filtrarGrupoEcon,
        p_config_354_estabProximoId,
        p_config_362_calcCustoPorGrade,
        a.atualizaCustoMedio,
        a.estabelecimento,
        CASE WHEN a.dataEntradaSaida IS NULL OR a.dataEntradaSaida < a.dataEmissao THEN a.dataEmissao ELSE a.dataEntradaSaida END, -- p_data
        a.idItemDocFiscal,
        a.gradeProduto,
        a.pessoaParticipante,
        a.quantidade,
        a.valorCustoOperacao,
        a.observacoes,
        a.locEst_indicProprPosseItem,
        r_bufferIdProdutoFilho,
        r_bufferIdProdutoFilho);
    END IF;
    FOR b IN (
      SELECT 
        b.observacoes,
        comp.gradeProdutoEstoque gradeProduto,
        gradprod.produto,
        prod.controleEstoque,
        ROUND (a.quantidade * b.quantidade, uniFilho.casasDecimaisUnidadeMedida) quantidade
      FROM MODOCFISCALXCOMPOSICOESPR b
      JOIN CAPRODUTOXCOMPOSICOESPREC comp
      ON comp.composicaoPreco = b.composicaoPreco
      JOIN CAGRADESPRODUTO gradProd
      ON gradProd.gradeProduto = comp.gradeProdutoEstoque
      JOIN CAPRODUTOS prod
      ON prod.produto = gradprod.produto
      JOIN SIUNIDADESMEDIDA uniFilho
      ON uniFilho.unidadeMedida = prod.unidadeMedida
      WHERE b.idItemDocFiscal = a.idItemDocFiscal
      AND b.selecionado = 1
      AND comp.gradeProdutoEstoque > 0
      AND ROUND (a.quantidade * b.quantidade, uniFilho.casasDecimaisUnidadeMedida) > 0)
    LOOP
      IF b.controleEstoque IN (3,4) THEN
        ADD_ESTOQUE_DOC_FISC_FIL_KIT (
          p_sys_estabelecimentoAtivo,
          p_config_209_filtrarGrupoEcon,
          p_config_354_estabProximoId,
          p_config_362_calcCustoPorGrade,
          a.atualizaCustoMedio,
          a.estabelecimento,
          CASE WHEN a.dataEntradaSaida IS NULL OR a.dataEntradaSaida < a.dataEmissao THEN a.dataEmissao ELSE a.dataEntradaSaida END, -- p_data
          a.idItemDocFiscal,
          b.gradeProduto,
          a.pessoaParticipante,
          b.quantidade,
          0, -- a.valorCustoOperacao
          b.observacoes,
          a.locEst_indicProprPosseItem,
          r_bufferIdProdutoFilho,
          r_bufferIdProdutoFilho);
      ELSIF b.controleEstoque IN (1,5,6,11,12) THEN
        ADD_ESTOQUE_DOC_FISC_FIL_GRAVA (
          p_sys_estabelecimentoAtivo,
          p_config_354_estabProximoId,
          0, -- p_id
          a.idItemDocFiscal,
          b.produto,
          b.gradeProduto,
          0, -- p_personalizacao
          0, -- p_idLoteEstoque
          0, -- p_idNumeroSerie
          b.quantidade,
          0, -- p_precoCustoOperacao,
          0, -- p_totalCustoOperacao,
          0, -- p_precoCMV,
          0, -- p_valorCMV,
          b.observacoes,
          r_bufferIdProdutoFilho, 
          v_auxNumber,
          r_bufferIdProdutoFilho);
      END IF;
    END LOOP;
  END LOOP;
END ADD_ESTOQUE_DOC_FISC_ITEM;

/

create or replace PROCEDURE ADD_ESTOQUE_DOC_FISC_CABECALHO (
  p_sys_estabelecimentoAtivo     IN NUMBER,
  p_config_209_filtrarGrupoEcon  IN NUMBER,
  p_config_354_estabProximoId    IN NUMBER,
  p_config_362_calcCustoPorGrade IN NUMBER,
  p_idDocumentoFiscal            IN NUMBER)
IS
  v_bufferIdEstoque      VARCHAR2 (32000);
  v_bufferIdProdutoFilho VARCHAR2 (32000);
BEGIN
  v_bufferIdEstoque := '';
  v_bufferIdProdutoFilho := '';
  FOR a IN (
    SELECT idItemDocFiscal
    FROM MODOCFISCALXITENS
    WHERE idDocumentoFiscal = p_idDocumentoFiscal)
  LOOP
    ADD_ESTOQUE_DOC_FISC_EXCLUI (
      a.idItemDocFiscal,
      v_bufferIdEstoque,
      v_bufferIdEstoque);
    ADD_ESTOQUE_DOC_FISC_FIL_EXCL (
      a.idItemDocFiscal,
      v_bufferIdProdutoFilho,
      v_bufferIdProdutoFilho);
  END LOOP;
  FOR a IN (
    SELECT item.idItemDocFiscal
    FROM MODOCFISCALXITENS item
    JOIN MODOCUMENTOSFISCAIS cab
    ON cab.idDocumentoFiscal = item.idDocumentoFiscal
    WHERE item.idDocumentoFiscal = p_idDocumentoFiscal
    AND item.cancelado = 0
    AND cab.situacaoDocumentoFiscal BETWEEN 21 AND 23)
  LOOP
    ADD_ESTOQUE_DOC_FISC_ITEM (
      p_sys_estabelecimentoAtivo,
      p_config_209_filtrarGrupoEcon,
      p_config_354_estabProximoId,
      p_config_362_calcCustoPorGrade,
      a.idItemDocFiscal,
      v_bufferIdEstoque,
      v_bufferIdProdutoFilho,
      v_bufferIdEstoque,
      v_bufferIdProdutoFilho);
  END LOOP;
END ADD_ESTOQUE_DOC_FISC_CABECALHO;

/

create or replace PROCEDURE ADD_ESTOQUE_PRE_DOC_ITEM (
  p_sys_estabelecimentoAtivo     IN NUMBER,
  p_config_209_filtrarGrupoEcon  IN NUMBER,
  p_config_354_estabProximoId    IN NUMBER,
  p_config_362_calcCustoPorGrade IN NUMBER,
  p_idItemPreDocumento           IN NUMBER,
  p_bufferIdEstoque              IN VARCHAR2,
  p_bufferIdProdutoFilho         IN VARCHAR2,
  r_bufferIdEstoque              OUT VARCHAR2,
  r_bufferIdProdutoFilho         OUT VARCHAR2)
IS
  v_quantidadeNumerosSerie NUMBER;
  v_auxNumber              NUMBER;
BEGIN
  r_bufferIdEstoque := p_bufferIdEstoque;
  r_bufferIdProdutoFilho := p_bufferIdProdutoFilho;
  ADD_ESTOQUE_PRE_DOC_EXCLUI (
    p_idItemPreDocumento,
    r_bufferIdEstoque,
    r_bufferIdEstoque);
  ADD_ESTOQUE_PRE_DOC_FIL_EXCL (
    p_idItemPreDocumento,
    r_bufferIdProdutoFilho,
    r_bufferIdProdutoFilho);
  FOR a IN (
    SELECT
      cab.entradaSaida,
      cab.atualizaCustoMedio,
      cab.atualizaUltimaCompra,
      cab.estabelecimento,
      cab.dataEmissao,
      cab.dataEntradaSaida,
      item.idItemPreDocumento,
      item.modeloDocumento,
      item.gradeProduto,
      item.idFormulaTinta,
      item.personalizacao,
      item.idLoteEstoque,
      item.localEstoque,
      item.pessoaParticipante,
      item.quantidade,
      item.precoCustoOperacao,
      item.valorCustoOperacao,
      item.precoCMV,
      item.valorCMV,
      item.quantidadeExtemporanea,
      item.valorAcrescimoExtempTotal,
      item.observacoes,
      modDoc.geraTransferencia,
      modDoc.geraOperacaoEmTransito,
      modDoc.transitoLocalEstoque,
      locEstTransito.indicadorPropriedadePosseItem locEstTransito_indicProprPos,
      gradProd.produto,
      prod.controlaNumeroSerie,
      prod.controleEstoque,
      prod.tipoProduto,
      uniMed.casasDecimaisUnidadeMedida,
      locEst.indicadorPropriedadePosseItem locEst_indicProprPosseItem,
      COALESCE (cabTransf.estabelecimentoEntrada, 0) docTransf_estabelecEntrada,
      COALESCE (cabTransf.estabelecimentoSaida, 0) docTransf_estabelecSaida
    FROM MOPREDOCUMXITENS item
    JOIN PAMODELOSDOCUMENTO modDoc
    ON modDoc.modeloDocumento = item.modeloDocumento
    JOIN PALOCAISESTOQUE locEstTransito
    ON locEstTransito.localEstoque = modDoc.transitoLocalEstoque 
    JOIN MOPREDOCUMENTOS cab
    ON cab.preDocumento = item.preDocumento
    JOIN CAGRADESPRODUTO gradProd
    ON gradProd.gradeProduto = item.gradeProduto
    JOIN CAPRODUTOS prod
    ON prod.produto = gradProd.produto
    JOIN SIUNIDADESMEDIDA uniMed
    ON uniMed.unidadeMedida = prod.unidadeMedida
    JOIN PALOCAISESTOQUE locEst
    ON locEst.localEstoque = item.localEstoque
    LEFT JOIN MODOCTRANSFXPREDOCUM transfXDoc
    ON transfXDoc.idItemPreDocumento = item.idItemPreDocumento
    AND transfXDoc.entradaSaidaOriginal IN ('E','S')
    LEFT JOIN MODOCUMENTOTRANSFXITENS itemTransf
    ON itemTransf.idItemDocTransferencia = transfXDoc.idItemDocTransferencia
    LEFT JOIN MODOCUMENTOSTRANSFERENCIA cabTransf
    ON cabTransf.documentoTransferencia = itemTransf.documentoTransferencia
    WHERE item.idItemPreDocumento = p_idItemPreDocumento
    AND item.cancelado = 0
    AND item.quantidade+item.quantidadeExtemporanea > 0
    AND item.movimentaEstoque = 1
    AND cab.statusPreDocumento IN ('A','F'))
  LOOP
    IF a.controleEstoque = 12 AND a.idFormulaTinta > 0 THEN
      ADD_ESTOQUE_FORMULA_TINTA (
        p_sys_estabelecimentoAtivo, 
        p_config_209_filtrarGrupoEcon,
        p_config_354_estabProximoId,
        p_config_362_calcCustoPorGrade,
        100, -- p_cab_operacaoInternaEstoque
        a.atualizaCustoMedio,
        a.atualizaUltimaCompra,
        a.entradaSaida,
        a.estabelecimento,
        CASE WHEN a.dataEntradaSaida IS NULL OR a.dataEntradaSaida < a.dataEmissao THEN a.dataEmissao ELSE a.dataEntradaSaida END, -- p_data
        a.modeloDocumento,
        0, -- p_item_motivoEstoque
        a.idFormulaTinta,
        a.localEstoque,
        a.pessoaParticipante,
        a.quantidade + a.quantidadeExtemporanea, -- a.quantidade
        a.observacoes,
        0, -- p_idFichaProdutoRealOrcamento
        a.idItemPreDocumento,
        0, -- p_idItemDocFiscal
        0, -- p_divergenciaBalanco
        0, -- p_idItemDocTransferencia
        a.geraTransferencia,
        a.geraOperacaoEmTransito,
        a.transitoLocalEstoque,
        a.locEstTransito_indicProprPos,
        a.locEst_indicProprPosseItem,
        a.docTransf_estabelecEntrada,
        a.docTransf_estabelecSaida,
        r_bufferIdEstoque, 
        r_bufferIdEstoque);
    ELSIF a.controleEstoque IN (3,4) THEN
      ADD_ESTOQUE_KIT (
        p_sys_estabelecimentoAtivo, 
        p_config_209_filtrarGrupoEcon,
        p_config_354_estabProximoId,
        p_config_362_calcCustoPorGrade,
        100, -- p_cab_operacaoInternaEstoque
        a.atualizaCustoMedio,
        a.atualizaUltimaCompra,
        a.entradaSaida,
        a.estabelecimento,
        CASE WHEN a.dataEntradaSaida IS NULL OR a.dataEntradaSaida < a.dataEmissao THEN a.dataEmissao ELSE a.dataEntradaSaida END, -- p_data
        a.modeloDocumento,
        0, -- p_item_motivoEstoque
        a.gradeProduto,
        a.localEstoque,
        a.pessoaParticipante,
        a.quantidade + a.quantidadeExtemporanea, -- a.quantidade
        a.valorCustoOperacao + a.valorAcrescimoExtempTotal, -- a.valorCustoOperacao
        a.observacoes,
        0, -- p_idFichaProdutoRealOrcamento
        a.idItemPreDocumento,
        0, -- p_idItemDocFiscal
        0, -- p_divergenciaBalanco
        0, -- p_idItemDocTransferencia
        a.geraTransferencia,
        a.geraOperacaoEmTransito,
        a.transitoLocalEstoque,
        a.locEstTransito_indicProprPos,
        a.locEst_indicProprPosseItem,
        a.docTransf_estabelecEntrada,
        a.docTransf_estabelecSaida,
        r_bufferIdEstoque,
        r_bufferIdEstoque);
    ELSIF a.controleEstoque IN (1,5,6,11,12) THEN
      v_quantidadeNumerosSerie := 0;
      IF a.controlaNumeroSerie > 0 THEN
        ADD_ESTOQUE_PRE_DOC_N_SERIE (
          p_sys_estabelecimentoAtivo,
          p_config_354_estabProximoId,
          a.atualizaCustoMedio,
          a.atualizaUltimaCompra,
          a.entradaSaida,
          a.estabelecimento,
          CASE WHEN a.dataEntradaSaida IS NULL OR a.dataEntradaSaida < a.dataEmissao THEN a.dataEmissao ELSE a.dataEntradaSaida END, -- p_data
          a.idItemPreDocumento,
          a.modeloDocumento,
          a.gradeProduto,
          a.personalizacao,
          a.idLoteEstoque,
          a.localEstoque,
          a.pessoaParticipante,
          CASE
            WHEN a.valorCustoOperacao = 0
              OR a.valorAcrescimoExtempTotal = 0
              OR a.valorCustoOperacao + a.valorAcrescimoExtempTotal = 0
            THEN a.precoCustoOperacao
            ELSE ROUND(a.precoCustoOperacao * (a.valorCustoOperacao + a.valorAcrescimoExtempTotal) / a.valorCustoOperacao, 7)
          END, -- a.precoCustoOperacao
          a.precoCMV,
          a.observacoes,
          a.geraTransferencia,
          a.geraOperacaoEmTransito,
          a.transitoLocalEstoque,
          a.locEstTransito_indicProprPos,
          a.produto,
          a.locEst_indicProprPosseItem,
          a.docTransf_estabelecEntrada,
          a.docTransf_estabelecSaida,
          r_bufferIdEstoque,
          r_bufferIdEstoque,
          v_quantidadeNumerosSerie);
      END IF;
      IF a.quantidade + a.quantidadeExtemporanea > v_quantidadeNumerosSerie THEN
        ADD_ESTOQUE_GRAVA (
          p_sys_estabelecimentoAtivo,
          p_config_354_estabProximoId,
          0, -- p_idEstoque
          a.estabelecimento,
          CASE WHEN a.dataEntradaSaida IS NULL OR a.dataEntradaSaida < a.dataEmissao THEN a.dataEmissao ELSE a.dataEntradaSaida END, -- p_data
          a.produto,
          a.gradeProduto,
          a.modeloDocumento,
          0, -- p_item_motivoEstoque
          100, -- p_operacaoInternaEstoque
          a.atualizaCustoMedio,
          a.atualizaUltimaCompra,
          a.entradaSaida,
          a.locEst_indicProprPosseItem,
          a.pessoaParticipante,
          a.localEstoque,
          a.personalizacao,
          a.idLoteEstoque,
          0, -- p_idNumeroSerie
          a.quantidade + a.quantidadeExtemporanea - v_quantidadeNumerosSerie, -- p_quantidade
          CASE
            WHEN a.valorCustoOperacao = 0
              OR a.valorAcrescimoExtempTotal = 0
              OR a.valorCustoOperacao + a.valorAcrescimoExtempTotal = 0
            THEN a.precoCustoOperacao
            ELSE ROUND(a.precoCustoOperacao * (a.valorCustoOperacao + a.valorAcrescimoExtempTotal) / a.valorCustoOperacao,7)
          END, -- p_precoCustoOperacao
          CASE WHEN a.quantidade = 0 THEN 0 ELSE ROUND (((a.valorCustoOperacao + a.valorAcrescimoExtempTotal) * (a.quantidade + a.quantidadeExtemporanea - v_quantidadeNumerosSerie) / a.quantidade), 2) END, -- p_totalCustoOperacao
          a.precoCMV,
          CASE WHEN a.quantidade = 0 THEN 0 ELSE ROUND ((a.valorCMV * (a.quantidade + a.quantidadeExtemporanea - v_quantidadeNumerosSerie) / a.quantidade), 2) END, -- p_valorCMV
          a.observacoes,
          0, -- p_idFichaProdutoRealOrcamento
          a.idItemPreDocumento,
          0, -- p_idItemDocFiscal
          0, -- p_divergenciaBalanco
          0, -- p_idItemDocTransferencia
          r_bufferIdEstoque,
          v_auxNumber,
          r_bufferIdEstoque);
        IF a.geraTransferencia = 1 AND a.geraOperacaoEmTransito = 1 AND a.transitoLocalEstoque > 0 AND a.docTransf_estabelecEntrada > 0 AND a.docTransf_estabelecSaida > 0 THEN
          ADD_ESTOQUE_GRAVA (
            p_sys_estabelecimentoAtivo,
            p_config_354_estabProximoId,
            0, -- p_idEstoque
            a.docTransf_estabelecSaida,
            CASE WHEN a.dataEntradaSaida IS NULL OR a.dataEntradaSaida < a.dataEmissao THEN a.dataEmissao ELSE a.dataEntradaSaida END, -- p_data
            a.produto,
            a.gradeProduto,
            a.modeloDocumento,
            0, -- p_item_motivoEstoque
            900, -- p_operacaoInternaEstoque
            0, -- p_atualizaCustoMedio
            0, -- p_atualizaUltimaCompra
            CASE WHEN a.entradaSaida='S' THEN 'E' ELSE 'S' END, -- p_entradaSaida
            a.locEstTransito_indicProprPos,
            a.pessoaParticipante,
            a.transitoLocalEstoque,
            a.personalizacao,
            a.idLoteEstoque,
            0, -- p_idNumeroSerie
            a.quantidade + a.quantidadeExtemporanea - v_quantidadeNumerosSerie, -- p_quantidade
            CASE
              WHEN a.valorCustoOperacao = 0
                OR a.valorAcrescimoExtempTotal = 0
                OR a.valorCustoOperacao + a.valorAcrescimoExtempTotal = 0
              THEN a.precoCustoOperacao
              ELSE ROUND(a.precoCustoOperacao * (a.valorCustoOperacao + a.valorAcrescimoExtempTotal) / a.valorCustoOperacao,7)
            END, -- p_precoCustoOperacao
            CASE WHEN a.quantidade = 0 THEN 0 ELSE ROUND (((a.valorCustoOperacao + a.valorAcrescimoExtempTotal) * (a.quantidade + a.quantidadeExtemporanea - v_quantidadeNumerosSerie) / a.quantidade), 2) END, -- p_totalCustoOperacao
            a.precoCMV,
            CASE WHEN a.quantidade = 0 THEN 0 ELSE ROUND ((a.valorCMV * (a.quantidade + a.quantidadeExtemporanea - v_quantidadeNumerosSerie) / a.quantidade), 2) END, -- p_valorCMV
            a.observacoes,
            0, -- p_idFichaProdutoRealOrcamento
            a.idItemPreDocumento,
            0, -- p_idItemDocFiscal
            0, -- p_divergenciaBalanco
            0, -- p_idItemDocTransferencia
            r_bufferIdEstoque, 
            v_auxNumber,
            r_bufferIdEstoque);
        END IF;
      END IF;
    ELSIF a.controleEstoque IN (2,21,99)
      AND a.tipoProduto = '09'
    THEN
      FOR b IN (
        SELECT
          itemOrc.gradeProduto,
          itemOrc.idFormulaTinta,
          itemOrc.personalizacao,
          itemOrc.idLoteEstoque,
          gradProd.produto,
          prod.controleEstoque,
          prod.controlaNumeroSerie
        FROM MOPREDOCUMXORCAMENTOITEM docXDoc
        JOIN MOORCAMENTOXITENS itemOrc
        ON itemOrc.idItemOrcamento = docXDoc.idItemOrcamento
        JOIN CAGRADESPRODUTO gradProd
        ON gradProd.gradeProduto = itemOrc.gradeProduto
        JOIN CAPRODUTOS prod
        ON prod.produto = gradProd.produto
        WHERE docXDoc.idItemPreDocumento = a.idItemPreDocumento
        AND docXDoc.quantidade <> 0
        AND itemOrc.cancelado = 0)
      LOOP
        IF b.controleEstoque = 12 AND b.idFormulaTinta > 0 THEN
          ADD_ESTOQUE_FORMULA_TINTA (
            p_sys_estabelecimentoAtivo, 
            p_config_209_filtrarGrupoEcon,
            p_config_354_estabProximoId,
            p_config_362_calcCustoPorGrade,
            100, -- p_cab_operacaoInternaEstoque
            a.atualizaCustoMedio,
            a.atualizaUltimaCompra,
            a.entradaSaida,
            a.estabelecimento,
            CASE WHEN a.dataEntradaSaida IS NULL OR a.dataEntradaSaida < a.dataEmissao THEN a.dataEmissao ELSE a.dataEntradaSaida END, -- p_data
            a.modeloDocumento,
            0, -- p_item_motivoEstoque
            b.idFormulaTinta,
            a.localEstoque,
            a.pessoaParticipante,
            a.quantidade + a.quantidadeExtemporanea, -- a.quantidade
            a.observacoes,
            0, -- p_idFichaProdutoRealOrcamento
            a.idItemPreDocumento,
            0, -- p_idItemDocFiscal
            0, -- p_divergenciaBalanco
            0, -- p_idItemDocTransferencia
            a.geraTransferencia,
            a.geraOperacaoEmTransito,
            a.transitoLocalEstoque,
            a.locEstTransito_indicProprPos,
            a.locEst_indicProprPosseItem,
            a.docTransf_estabelecEntrada,
            a.docTransf_estabelecSaida,
            r_bufferIdEstoque, 
            r_bufferIdEstoque);
        ELSIF b.controleEstoque IN (3,4) THEN
          ADD_ESTOQUE_KIT (
            p_sys_estabelecimentoAtivo, 
            p_config_209_filtrarGrupoEcon,
            p_config_354_estabProximoId,
            p_config_362_calcCustoPorGrade,
            100, -- p_cab_operacaoInternaEstoque
            a.atualizaCustoMedio,
            a.atualizaUltimaCompra,
            a.entradaSaida,
            a.estabelecimento,
            CASE WHEN a.dataEntradaSaida IS NULL OR a.dataEntradaSaida < a.dataEmissao THEN a.dataEmissao ELSE a.dataEntradaSaida END, -- p_data
            a.modeloDocumento,
            0, -- p_item_motivoEstoque
            b.gradeProduto,
            a.localEstoque,
            a.pessoaParticipante,
            a.quantidade + a.quantidadeExtemporanea, -- a.quantidade
            a.valorCustoOperacao + a.valorAcrescimoExtempTotal, -- a.valorCustoOperacao
            a.observacoes,
            0, -- p_idFichaProdutoRealOrcamento
            a.idItemPreDocumento,
            0, -- p_idItemDocFiscal
            0, -- p_divergenciaBalanco
            0, -- p_idItemDocTransferencia
            a.geraTransferencia,
            a.geraOperacaoEmTransito,
            a.transitoLocalEstoque,
            a.locEstTransito_indicProprPos,
            a.locEst_indicProprPosseItem,
            a.docTransf_estabelecEntrada,
            a.docTransf_estabelecSaida,
            r_bufferIdEstoque,
            r_bufferIdEstoque);
        ELSIF a.controleEstoque IN (1,5,6,11,12) THEN
          v_quantidadeNumerosSerie := 0;
          IF b.controlaNumeroSerie > 0 THEN
            ADD_ESTOQUE_PRE_DOC_N_SERIE (
              p_sys_estabelecimentoAtivo,
              p_config_354_estabProximoId,
              a.atualizaCustoMedio,
              a.atualizaUltimaCompra,
              a.entradaSaida,
              a.estabelecimento,
              CASE WHEN a.dataEntradaSaida IS NULL OR a.dataEntradaSaida < a.dataEmissao THEN a.dataEmissao ELSE a.dataEntradaSaida END, -- p_data
              a.idItemPreDocumento,
              a.modeloDocumento,
              b.gradeProduto,
              b.personalizacao,
              b.idLoteEstoque,
              a.localEstoque,
              a.pessoaParticipante,
              CASE
                WHEN a.valorCustoOperacao = 0
                  OR a.valorAcrescimoExtempTotal = 0
                  OR a.valorCustoOperacao + a.valorAcrescimoExtempTotal = 0
                THEN a.precoCustoOperacao
                ELSE ROUND(a.precoCustoOperacao * (a.valorCustoOperacao + a.valorAcrescimoExtempTotal) / a.valorCustoOperacao, 7)
              END, -- a.precoCustoOperacao
              a.precoCMV,
              a.observacoes,
              a.geraTransferencia,
              a.geraOperacaoEmTransito,
              a.transitoLocalEstoque,
              a.locEstTransito_indicProprPos,
              b.produto,
              a.locEst_indicProprPosseItem,
              a.docTransf_estabelecEntrada,
              a.docTransf_estabelecSaida,
              r_bufferIdEstoque,
              r_bufferIdEstoque,
              v_quantidadeNumerosSerie);
          END IF;
          IF a.quantidade + a.quantidadeExtemporanea > v_quantidadeNumerosSerie THEN
            ADD_ESTOQUE_GRAVA (
              p_sys_estabelecimentoAtivo,
              p_config_354_estabProximoId,
              0, -- p_idEstoque
              a.estabelecimento,
              CASE WHEN a.dataEntradaSaida IS NULL OR a.dataEntradaSaida < a.dataEmissao THEN a.dataEmissao ELSE a.dataEntradaSaida END, -- p_data
              b.produto,
              b.gradeProduto,
              a.modeloDocumento,
              0, -- p_item_motivoEstoque
              100, -- p_operacaoInternaEstoque
              a.atualizaCustoMedio,
              a.atualizaUltimaCompra,
              a.entradaSaida,
              a.locEst_indicProprPosseItem,
              a.pessoaParticipante,
              a.localEstoque,
              b.personalizacao,
              b.idLoteEstoque,
              0, -- p_idNumeroSerie
              a.quantidade + a.quantidadeExtemporanea - v_quantidadeNumerosSerie, -- p_quantidade
              CASE
                WHEN a.valorCustoOperacao = 0
                  OR a.valorAcrescimoExtempTotal = 0
                  OR a.valorCustoOperacao + a.valorAcrescimoExtempTotal = 0
                THEN a.precoCustoOperacao
                ELSE ROUND(a.precoCustoOperacao * (a.valorCustoOperacao + a.valorAcrescimoExtempTotal) / a.valorCustoOperacao,7)
              END, -- p_precoCustoOperacao
              CASE WHEN a.quantidade = 0 THEN 0 ELSE ROUND (((a.valorCustoOperacao + a.valorAcrescimoExtempTotal) * (a.quantidade + a.quantidadeExtemporanea - v_quantidadeNumerosSerie) / a.quantidade), 2) END, -- p_totalCustoOperacao
              a.precoCMV,
              CASE WHEN a.quantidade = 0 THEN 0 ELSE ROUND ((a.valorCMV * (a.quantidade + a.quantidadeExtemporanea - v_quantidadeNumerosSerie) / a.quantidade), 2) END, -- p_valorCMV
              a.observacoes,
              0, -- p_idFichaProdutoRealOrcamento
              a.idItemPreDocumento,
              0, -- p_idItemDocFiscal
              0, -- p_divergenciaBalanco
              0, -- p_idItemDocTransferencia
              r_bufferIdEstoque,
              v_auxNumber,
              r_bufferIdEstoque);
            IF a.geraTransferencia = 1 AND a.geraOperacaoEmTransito = 1 AND a.transitoLocalEstoque > 0 AND a.docTransf_estabelecEntrada > 0 AND a.docTransf_estabelecSaida > 0 THEN
              ADD_ESTOQUE_GRAVA (
                p_sys_estabelecimentoAtivo,
                p_config_354_estabProximoId,
                0, -- p_idEstoque
                a.docTransf_estabelecSaida,
                CASE WHEN a.dataEntradaSaida IS NULL OR a.dataEntradaSaida < a.dataEmissao THEN a.dataEmissao ELSE a.dataEntradaSaida END, -- p_data
                b.produto,
                b.gradeProduto,
                a.modeloDocumento,
                0, -- p_item_motivoEstoque
                900, -- p_operacaoInternaEstoque
                0, -- p_atualizaCustoMedio
                0, -- p_atualizaUltimaCompra
                CASE WHEN a.entradaSaida='S' THEN 'E' ELSE 'S' END, -- p_entradaSaida
                a.locEstTransito_indicProprPos,
                a.pessoaParticipante,
                a.transitoLocalEstoque,
                b.personalizacao,
                b.idLoteEstoque,
                0, -- p_idNumeroSerie
                a.quantidade + a.quantidadeExtemporanea - v_quantidadeNumerosSerie, -- p_quantidade
                CASE
                  WHEN a.valorCustoOperacao = 0
                    OR a.valorAcrescimoExtempTotal = 0
                    OR a.valorCustoOperacao + a.valorAcrescimoExtempTotal = 0
                  THEN a.precoCustoOperacao
                  ELSE ROUND(a.precoCustoOperacao * (a.valorCustoOperacao + a.valorAcrescimoExtempTotal) / a.valorCustoOperacao,7)
                END, -- p_precoCustoOperacao
                CASE WHEN a.quantidade = 0 THEN 0 ELSE ROUND (((a.valorCustoOperacao + a.valorAcrescimoExtempTotal) * (a.quantidade + a.quantidadeExtemporanea - v_quantidadeNumerosSerie) / a.quantidade), 2) END, -- p_totalCustoOperacao
                a.precoCMV,
                CASE WHEN a.quantidade = 0 THEN 0 ELSE ROUND ((a.valorCMV * (a.quantidade + a.quantidadeExtemporanea - v_quantidadeNumerosSerie) / a.quantidade), 2) END, -- p_valorCMV
                a.observacoes,
                0, -- p_idFichaProdutoRealOrcamento
                a.idItemPreDocumento,
                0, -- p_idItemDocFiscal
                0, -- p_divergenciaBalanco
                0, -- p_idItemDocTransferencia
                r_bufferIdEstoque, 
                v_auxNumber,
                r_bufferIdEstoque);
            END IF;
          END IF;
        END IF;
      END LOOP;
    END IF;
    FOR b IN (
      SELECT
        b.observacoes,
        comp.gradeProdutoEstoque gradeProduto,
        gradprod.produto,
        prod.controleEstoque,
        ROUND ((a.quantidade + a.quantidadeExtemporanea) * b.quantidade, uniFilho.casasDecimaisUnidadeMedida) quantidade
      FROM MOPREDOCUMXCOMPOSICOESPR b
      JOIN CAPRODUTOXCOMPOSICOESPREC comp
      ON comp.composicaoPreco = b.composicaoPreco
      JOIN CAGRADESPRODUTO gradProd
      ON gradProd.gradeProduto = comp.gradeProdutoEstoque
      JOIN CAPRODUTOS prod
      ON prod.produto = gradprod.produto
      JOIN SIUNIDADESMEDIDA uniFilho
      ON uniFilho.unidadeMedida = prod.unidadeMedida
      WHERE b.idItemPreDocumento = a.idItemPreDocumento
      AND b.selecionado = 1
      AND comp.gradeProdutoEstoque > 0
      AND ROUND ((a.quantidade + a.quantidadeExtemporanea) * b.quantidade, uniFilho.casasDecimaisUnidadeMedida) > 0)
    LOOP
      IF b.controleEstoque IN (3,4) THEN
        ADD_ESTOQUE_KIT (
          p_sys_estabelecimentoAtivo,
          p_config_209_filtrarGrupoEcon,
          p_config_354_estabProximoId,
          p_config_362_calcCustoPorGrade,
          100, -- p_cab_operacaoInternaEstoque
          a.atualizaCustoMedio,
          a.atualizaUltimaCompra,
          a.entradaSaida,
          a.estabelecimento,
          CASE WHEN a.dataEntradaSaida IS NULL OR a.dataEntradaSaida < a.dataEmissao THEN a.dataEmissao ELSE a.dataEntradaSaida END, -- p_data
          a.modeloDocumento,
          0, -- p_item_motivoEstoque
          a.gradeProduto,
          a.localEstoque,
          a.pessoaParticipante,
          b.quantidade,
          0,
          b.observacoes,
          0, -- p_idFichaProdutoRealOrcamento
          a.idItemPreDocumento,
          0, -- p_idItemDocFiscal
          0, -- p_divergenciaBalanco,
          0, -- p_idItemDocTransferencia,
          a.geraTransferencia,
          a.geraOperacaoEmTransito,
          a.transitoLocalEstoque,
          a.locEstTransito_indicProprPos,
          a.locEst_indicProprPosseItem,
          a.docTransf_estabelecEntrada,
          a.docTransf_estabelecSaida,
          r_bufferIdEstoque,
          r_bufferIdEstoque);
      ELSIF a.controleEstoque IN(1,5,6,11,12) THEN
        ADD_ESTOQUE_GRAVA (
          p_sys_estabelecimentoAtivo,
          p_config_354_estabProximoId,
          0, -- p_idEstoque
          a.estabelecimento,
          CASE WHEN a.dataEntradaSaida IS NULL OR a.dataEntradaSaida < a.dataEmissao THEN a.dataEmissao ELSE a.dataEntradaSaida END, -- p_data
          b.produto,
          b.gradeProduto,
          a.modeloDocumento,
          0, -- p_item_motivoEstoque
          100, -- p_cab_operacaoInternaEstoque
          a.atualizaCustoMedio,
          a.atualizaUltimaCompra,
          a.entradaSaida,
          a.locEst_indicProprPosseItem,
          a.pessoaParticipante,
          a.localEstoque,
          0, -- p_personalizacao
          0, -- p_idLoteEstoque
          0, -- p_idNumeroSerie
          b.quantidade,
          0, -- p_precoCustoOperacao
          0, -- p_totalCustoOperacao
          0, -- p_precoCMV
          0, -- p_valorCMV
          b.observacoes,
          0, -- p_idFichaProdutoRealOrcamento
          a.idItemPreDocumento,
          0, -- p_idItemDocFiscal
          0, -- p_divergenciaBalanco,
          0, -- p_idItemDocTransferencia,
          r_bufferIdEstoque,
          v_auxNumber,
          r_bufferIdEstoque);
        IF a.geraTransferencia = 1
          AND a.geraOperacaoEmTransito = 1
          AND a.transitoLocalEstoque > 0
          AND a.docTransf_estabelecEntrada > 0
          AND a.docTransf_estabelecSaida > 0
        THEN
          ADD_ESTOQUE_GRAVA (
            p_sys_estabelecimentoAtivo,
            p_config_354_estabProximoId,
            0, -- p_idEstoque
            a.docTransf_estabelecSaida,
            CASE WHEN a.dataEntradaSaida IS NULL OR a.dataEntradaSaida < a.dataEmissao THEN a.dataEmissao ELSE a.dataEntradaSaida END, -- p_data
            b.produto,
            b.gradeProduto,
            a.modeloDocumento,
            0, -- p_item_motivoEstoque
            900, -- p_operacaoInternaEstoque
            0, -- p_atualizaCustoMedio
            0, -- p_atualizaUltimaCompra
            CASE
              WHEN a.entradaSaida = 'S'
              THEN 'E'
              ELSE 'S'
            END, -- p_entradaSaida
            a.locEstTransito_indicProprPos,
            a.pessoaParticipante,
            a.transitoLocalEstoque,
            0, -- p_personalizacao
            0, -- p_idLoteEstoque
            0, -- p_idNumeroSerie
            b.quantidade,
            0, -- p_precoCustoOperacao
            0, -- p_totalCustoOperacao
            0, -- p_precoCMV
            0, -- p_valorCMV
            b.observacoes,
            0, -- p_idFichaProdutoRealOrcamento
            a.idItemPreDocumento,
            0, -- p_idItemDocFiscal
            0, -- p_divergenciaBalanco,
            0, -- p_idItemDocTransferencia,
            r_bufferIdEstoque, 
            v_auxNumber,
            r_bufferIdEstoque);
        END IF;    
      END IF;
    END LOOP;
  END LOOP;
  FOR a IN (
    SELECT id
    FROM MOPREDOCUMXPRODUTOFILHO
    WHERE idItemPreDocumento = p_idItemPreDocumento
    ORDER BY id)
  LOOP
    r_bufferIdProdutoFilho :=
      CASE
        WHEN r_bufferIdProdutoFilho IS NULL
          OR r_bufferIdProdutoFilho = ''
          OR r_bufferIdProdutoFilho = ' '
        THEN ''
        ELSE RTRIM (r_bufferIdProdutoFilho) || ';'
      END
      || TO_CHAR (LPAD(a.id,14,'0'));
    DELETE MOPREDOCUMXPRODUTOFILHO b
    WHERE a.id = a.id;
  END LOOP;
  FOR a IN (
    SELECT 
      cab.atualizaCustoMedio,
      cab.estabelecimento,
      cab.dataEmissao,
      cab.dataEntradaSaida,
      item.idItemPreDocumento,
      item.gradeProduto,
      item.idFormulaTinta,
      item.personalizacao,
      item.pessoaParticipante,
      item.quantidade,
      item.precoCustoOperacao,
      item.valorCustoOperacao,
      item.precoCMV,
      item.valorCMV,
      item.observacoes,
      prod.controlaNumeroSerie,
      prod.controleEstoque,
      locEst.indicadorPropriedadePosseItem locEst_indicProprPosseItem
    FROM MOPREDOCUMXITENS item
    JOIN MOPREDOCUMENTOS cab
    ON cab.preDocumento = item.preDocumento
    JOIN CAGRADESPRODUTO gradProd
    ON gradProd.gradeProduto = item.gradeProduto
    JOIN CAPRODUTOS prod
    ON prod.produto = gradProd.produto
    JOIN PALOCAISESTOQUE locEst
    ON locEst.localEstoque = item.localEstoque
    WHERE item.idItemPreDocumento = p_idItemPreDocumento
    AND item.cancelado = 0
    AND item.quantidade > 0
    AND cab.statusPreDocumento IN ('A','F'))
  LOOP
    IF a.controleEstoque = 12
      AND a.idFormulaTinta > 0
    THEN
      ADD_ESTOQUE_PRE_DOC_FIL_FORM (
        p_sys_estabelecimentoAtivo, 
        p_config_209_filtrarGrupoEcon,
        p_config_354_estabProximoId,
        p_config_362_calcCustoPorGrade,
        a.atualizaCustoMedio,
        a.estabelecimento,
        CASE WHEN a.dataEntradaSaida IS NULL OR a.dataEntradaSaida < a.dataEmissao THEN a.dataEmissao ELSE a.dataEntradaSaida END, -- p_data
        a.idItemPreDocumento,
        a.idFormulaTinta,
        a.pessoaParticipante,
        a.quantidade,
        a.observacoes,
        a.locEst_indicProprPosseItem,
        r_bufferIdProdutoFilho, 
        r_bufferIdProdutoFilho);
    ELSIF a.controleEstoque IN (3,4) THEN
      ADD_ESTOQUE_PRE_DOC_FIL_KIT (
        p_sys_estabelecimentoAtivo, 
        p_config_209_filtrarGrupoEcon,
        p_config_354_estabProximoId,
        p_config_362_calcCustoPorGrade,
        a.atualizaCustoMedio,
        a.estabelecimento,
        CASE WHEN a.dataEntradaSaida IS NULL OR a.dataEntradaSaida < a.dataEmissao THEN a.dataEmissao ELSE a.dataEntradaSaida END, -- p_data
        a.idItemPreDocumento,
        a.gradeProduto,
        a.pessoaParticipante,
        a.quantidade,
        a.valorCustoOperacao,
        a.observacoes,
        a.locEst_indicProprPosseItem,
        r_bufferIdProdutoFilho,
        r_bufferIdProdutoFilho);
    END IF;
    FOR b IN (
      SELECT 
        b.observacoes,
        comp.gradeProdutoEstoque gradeProduto,
        gradprod.produto,
        prod.controleEstoque,
        ROUND (a.quantidade * b.quantidade, uniFilho.casasDecimaisUnidadeMedida) quantidade
      FROM MOPREDOCUMXCOMPOSICOESPR b
      JOIN CAPRODUTOXCOMPOSICOESPREC comp
      ON comp.composicaoPreco = b.composicaoPreco
      JOIN CAGRADESPRODUTO gradProd
      ON gradProd.gradeProduto = comp.gradeProdutoEstoque
      JOIN CAPRODUTOS prod
      ON prod.produto = gradprod.produto
      JOIN SIUNIDADESMEDIDA uniFilho
      ON uniFilho.unidadeMedida = prod.unidadeMedida
      WHERE b.idItemPreDocumento = a.idItemPreDocumento
      AND b.selecionado = 1
      AND comp.gradeProdutoEstoque > 0
      AND ROUND (a.quantidade * b.quantidade, uniFilho.casasDecimaisUnidadeMedida) > 0)
    LOOP
      IF b.controleEstoque IN (3,4) THEN
        ADD_ESTOQUE_PRE_DOC_FIL_KIT (
          p_sys_estabelecimentoAtivo,
          p_config_209_filtrarGrupoEcon,
          p_config_354_estabProximoId,
          p_config_362_calcCustoPorGrade,
          a.atualizaCustoMedio,
          a.estabelecimento,
          CASE WHEN a.dataEntradaSaida IS NULL OR a.dataEntradaSaida < a.dataEmissao THEN a.dataEmissao ELSE a.dataEntradaSaida END, -- p_data
          a.idItemPreDocumento,
          b.gradeProduto,
          a.pessoaParticipante,
          b.quantidade,
          0, -- a.valorCustoOperacao
          b.observacoes,
          a.locEst_indicProprPosseItem,
          r_bufferIdProdutoFilho,
          r_bufferIdProdutoFilho);
      ELSIF b.controleEstoque IN (1,5,6,11,12) THEN
        ADD_ESTOQUE_PRE_DOC_FIL_GRAVA (
          p_sys_estabelecimentoAtivo,
          p_config_354_estabProximoId,
          0, -- p_id
          a.idItemPreDocumento,
          b.produto,
          b.gradeProduto,
          0, -- p_personalizacao
          0, -- p_idLoteEstoque
          0, -- p_idNumeroSerie
          b.quantidade,
          0, -- p_precoCustoOperacao,
          0, -- p_totalCustoOperacao,
          0, -- p_precoCMV,
          0, -- p_valorCMV,
          b.observacoes,
          r_bufferIdProdutoFilho, 
          v_auxNumber,
          r_bufferIdProdutoFilho);
      END IF;
    END LOOP;
  END LOOP;
END ADD_ESTOQUE_PRE_DOC_ITEM;

/

create or replace PROCEDURE ADD_ESTOQUE_PRE_DOC_CABECALHO (
  p_sys_estabelecimentoAtivo     IN NUMBER,
  p_config_209_filtrarGrupoEcon  IN NUMBER,
  p_config_354_estabProximoId    IN NUMBER,
  p_config_362_calcCustoPorGrade IN NUMBER,
  p_preDocumento            IN NUMBER)
IS
  v_bufferIdEstoque      VARCHAR2 (32000);
  v_bufferIdProdutoFilho VARCHAR2 (32000);
BEGIN
  v_bufferIdEstoque := '';
  v_bufferIdProdutoFilho := '';
  FOR a IN (
    SELECT idItemPreDocumento
    FROM MOPREDOCUMXITENS
    WHERE preDocumento = p_preDocumento)
  LOOP
    ADD_ESTOQUE_PRE_DOC_EXCLUI (
      a.idItemPreDocumento,
      v_bufferIdEstoque,
      v_bufferIdEstoque);
    ADD_ESTOQUE_PRE_DOC_FIL_EXCL (
      a.idItemPreDocumento,
      v_bufferIdProdutoFilho,
      v_bufferIdProdutoFilho);
  END LOOP;
  FOR a IN (
    SELECT item.idItemPreDocumento
    FROM MOPREDOCUMXITENS item
    JOIN MOPREDOCUMENTOS cab
    ON cab.preDocumento = item.preDocumento
    WHERE item.preDocumento = p_preDocumento
    AND item.cancelado = 0
    AND cab.statusPreDocumento IN ('A','F'))
  LOOP
    ADD_ESTOQUE_PRE_DOC_ITEM (
      p_sys_estabelecimentoAtivo,
      p_config_209_filtrarGrupoEcon,
      p_config_354_estabProximoId,
      p_config_362_calcCustoPorGrade,
      a.idItemPreDocumento,
      v_bufferIdEstoque,
      v_bufferIdProdutoFilho,
      v_bufferIdEstoque,
      v_bufferIdProdutoFilho);
  END LOOP;
END ADD_ESTOQUE_PRE_DOC_CABECALHO;

/

create or replace PROCEDURE ADD_ESTOQUE_ORCAMENTO_FIC_PROD (
  p_sys_estabelecimentoAtivo     IN NUMBER,
  p_config_209_filtrarGrupoEcon  IN NUMBER,
  p_config_354_estabProximoId    IN NUMBER,
  p_config_362_calcCustoPorGrade IN NUMBER,
  p_cab_estabelecimento          IN NUMBER,
  p_ativ_idAtividadeRealOrcament IN NUMBER,
  p_ativ_dataTermino             IN DATE,
  p_ativ_modeloDocumento         IN NUMBER,
  p_ativ_motivoEstoque           IN NUMBER,
  p_fich_idFichaProdutoRealOrcam IN NUMBER,
  p_fich_gradeProduto            IN NUMBER,
  p_fich_atualizaCustoMedio      IN NUMBER,
  p_fich_atualizaUltimaCompra    IN NUMBER,
  p_fich_entradaSaida            IN CHAR,
  p_fich_localEstoque            IN NUMBER,
  p_fich_personalizacao          IN NUMBER,
  p_fich_idLoteEstoque           IN NUMBER,
  p_fich_quantidade              IN NUMBER,
  p_fich_precoCustoOperacao      IN NUMBER,
  p_fich_totalCustoOperacao      IN NUMBER,
  p_fich_precoCMV                IN NUMBER,
  p_fich_valorCMV                IN NUMBER,
  p_fich_observacoes             IN VARCHAR2,
  p_locEst_indicProprPosseItem   IN CHAR,
  p_gradProd_produto             IN NUMBER,
  p_prod_controleEstoque         IN CHAR,
  p_bufferIdEstoque              IN VARCHAR2,
  r_bufferIdEstoque              OUT VARCHAR2)
IS
  v_auxNumber NUMBER;
BEGIN
  r_bufferIdEstoque := p_bufferIdEstoque;
  ADD_ESTOQUE_FIC_TEC_EXCLUI (
    p_fich_idFichaProdutoRealOrcam,
    r_bufferIdEstoque,
    r_bufferIdEstoque);
  IF p_fich_quantidade > 0 THEN
    IF p_prod_controleEstoque IN (3,4) THEN
      ADD_ESTOQUE_KIT (
        p_sys_estabelecimentoAtivo,
        p_config_209_filtrarGrupoEcon,
        p_config_354_estabProximoId,
        p_config_362_calcCustoPorGrade,
        105, -- p_cab_operacaoInternaEstoque
        p_fich_atualizaCustoMedio,
        p_fich_atualizaUltimaCompra,
        p_fich_entradaSaida,
        p_cab_estabelecimento,
        p_ativ_dataTermino,
        p_ativ_modeloDocumento,
        p_ativ_motivoEstoque,
        p_fich_gradeProduto,
        p_fich_localEstoque,
        0, -- p_item_pessoaParticipante,
        p_fich_quantidade,
        p_fich_totalCustoOperacao,
        p_fich_observacoes,
        p_fich_idFichaProdutoRealOrcam,
        0, -- p_idItemPreDocumento,
        0, -- p_idItemDocFiscal,
        0, -- p_divergenciaBalanco,
        0, -- p_idItemDocTransferencia,
        0, -- p_modDoc_geraTransferencia
        0, -- p_modDoc_geraOperacaoEmTransit
        0, -- p_modDoc_transitoLocalEstoque
        ' ', -- p_locEstTransito_indicProprPos
        p_locEst_indicProprPosseItem,
        0, -- p_docTransf_estabelecEntrada,
        0, -- p_docTransf_estabelecSaida,
        r_bufferIdEstoque,
        r_bufferIdEstoque);
    ELSIF p_prod_controleEstoque IN (1,5,6,11,12) THEN
      ADD_ESTOQUE_GRAVA (
        p_sys_estabelecimentoAtivo,
        p_config_354_estabProximoId,
        0, -- p_idEstoque
        p_cab_estabelecimento,
        p_ativ_dataTermino, -- p_data
        p_gradProd_produto,
        p_fich_gradeProduto,
        p_ativ_modeloDocumento,
        p_ativ_motivoEstoque,
        105, -- p_operacaoInternaEstoque
        p_fich_atualizaCustoMedio,
        p_fich_atualizaUltimaCompra,
        p_fich_entradaSaida,
        p_locEst_indicProprPosseItem,
        0, -- p_item_pessoaParticipante,
        p_fich_localEstoque,
        p_fich_personalizacao,
        p_fich_idLoteEstoque,
        0, -- p_idNumeroSerie
        p_fich_quantidade,
        p_fich_precoCustoOperacao,
        p_fich_totalCustoOperacao,
        p_fich_precoCMV,
        p_fich_valorCMV,
        p_fich_observacoes,
        p_fich_idFichaProdutoRealOrcam,
        0, -- p_idItemPreDocumento,
        0, -- p_item_idItemDocFiscal,
        0, -- p_divergenciaBalanco,
        0, -- p_idItemDocTransferencia,
        r_bufferIdEstoque, 
        v_auxNumber,
        r_bufferIdEstoque);
    END IF;
  END IF;
END ADD_ESTOQUE_ORCAMENTO_FIC_PROD;

/

create or replace PROCEDURE ADD_ESTOQUE_ORCAMENTO_FIC_TEC (
  p_sys_estabelecimentoAtivo     IN NUMBER,
  p_config_209_filtrarGrupoEcon  IN NUMBER,
  p_config_354_estabProximoId    IN NUMBER,
  p_config_362_calcCustoPorGrade IN NUMBER,
  p_cab_estabelecimento          IN NUMBER,
  p_ativ_idAtividadeRealOrcament IN NUMBER,
  p_ativ_dataTermino             IN DATE,
  p_ativ_modeloDocumento         IN NUMBER,
  p_ativ_motivoEstoque           IN NUMBER,
  p_bufferIdEstoque              IN VARCHAR2,
  r_bufferIdEstoque              OUT VARCHAR2)
IS
  v_auxNumber NUMBER;
BEGIN
  r_bufferIdEstoque := p_bufferIdEstoque;
  FOR a IN (
    SELECT
      a.idFichaProdutoRealOrcamento,
      a.gradeProduto,
      a.atualizaCustoMedio,
      a.atualizaUltimaCompra,
      a.entradaSaida,
      a.localEstoque,
      a.personalizacao,
      a.idLoteEstoque,
      a.quantidade,
      a.precoCustoOperacao,
      a.totalCustoOperacao,
      a.precoCMV,
      a.valorCMV,
      a.observacoes,
      locEst.indicadorPropriedadePosseItem,
      gradProd.produto,
      prod.controleEstoque
    FROM MOORCAMENTOXFICHAPRODREAL a
    JOIN PALOCAISESTOQUE locEst
    ON locEst.localEstoque = a.localEstoque
    JOIN CAGRADESPRODUTO gradProd
    ON gradProd.gradeProduto = a.gradeProduto
    JOIN CAPRODUTOS prod
    ON prod.produto = gradProd.produto
    WHERE a.idAtividadeRealOrcamento = p_ativ_idAtividadeRealOrcament
    AND a.quantidade > 0
    ORDER BY a.ordenacao)
  LOOP
    ADD_ESTOQUE_ORCAMENTO_FIC_PROD (
      p_sys_estabelecimentoAtivo,
      p_config_209_filtrarGrupoEcon,
      p_config_354_estabProximoId,
      p_config_362_calcCustoPorGrade,
      p_cab_estabelecimento,
      p_ativ_idAtividadeRealOrcament,
      p_ativ_dataTermino,
      p_ativ_modeloDocumento,
      p_ativ_motivoEstoque,
      a.idFichaProdutoRealOrcamento,
      a.gradeProduto,
      a.atualizaCustoMedio,
      a.atualizaUltimaCompra,
      a.entradaSaida,
      a.localEstoque,
      a.personalizacao,
      a.idLoteEstoque,
      a.quantidade,
      a.precoCustoOperacao,
      a.totalCustoOperacao,
      a.precoCMV,
      a.valorCMV,
      a.observacoes,
      a.indicadorPropriedadePosseItem,
      a.produto,
      a.controleEstoque,
      r_bufferIdEstoque,
      r_bufferIdEstoque);
  END LOOP;
END ADD_ESTOQUE_ORCAMENTO_FIC_TEC;

/

create or replace PROCEDURE ADD_ESTOQUE_ORCAMENTO_AT_REAL (
  p_sys_estabelecimentoAtivo     IN NUMBER,
  p_config_209_filtrarGrupoEcon  IN NUMBER,
  p_config_354_estabProximoId    IN NUMBER,
  p_config_362_calcCustoPorGrade IN NUMBER,
  p_cab_estabelecimento          IN NUMBER,
  p_ativ_idAtividadePrevOrcament IN NUMBER,
  p_bufferIdEstoque              IN VARCHAR2,
  r_bufferIdEstoque              OUT VARCHAR2)
IS
BEGIN
  r_bufferIdEstoque := p_bufferIdEstoque;
  FOR a IN (
    SELECT
      idAtividadeRealOrcamento,
      dataTermino,
      modeloDocumento,
      motivoEstoque
    FROM MOORCAMENTOXATIVIDADEREAL
    WHERE idAtividadePrevOrcamento = p_ativ_idAtividadePrevOrcament
    AND statusAtividadeServico = 'E'
    ORDER BY sequencia)
  LOOP
    ADD_ESTOQUE_ORCAMENTO_FIC_TEC (
      p_sys_estabelecimentoAtivo,
      p_config_209_filtrarGrupoEcon,
      p_config_354_estabProximoId,
      p_config_362_calcCustoPorGrade,
      p_cab_estabelecimento,
      a.idAtividadeRealOrcamento,
      a.dataTermino,
      a.modeloDocumento,
      a.motivoEstoque,
      r_bufferIdEstoque,
      r_bufferIdEstoque);
  END LOOP;
END ADD_ESTOQUE_ORCAMENTO_AT_REAL;

/

create or replace PROCEDURE ADD_ESTOQUE_ORCAMENTO_AT_PREV (
  p_sys_estabelecimentoAtivo     IN NUMBER,
  p_config_209_filtrarGrupoEcon  IN NUMBER,
  p_config_354_estabProximoId    IN NUMBER,
  p_config_362_calcCustoPorGrade IN NUMBER,
  p_cab_estabelecimento          IN NUMBER,
  p_item_idItemOrcamento         IN NUMBER,
  p_bufferIdEstoque              IN VARCHAR2,
  r_bufferIdEstoque              OUT VARCHAR2)
IS
BEGIN
  r_bufferIdEstoque := p_bufferIdEstoque;
  FOR a IN (
    SELECT idAtividadePrevOrcamento
    FROM MOORCAMENTOXATIVIDADEPREV
    WHERE idItemOrcamento = p_item_idItemOrcamento
    ORDER BY sequencia)
  LOOP
    ADD_ESTOQUE_ORCAMENTO_AT_REAL (
      p_sys_estabelecimentoAtivo,
      p_config_209_filtrarGrupoEcon,
      p_config_354_estabProximoId,
      p_config_362_calcCustoPorGrade,
      p_cab_estabelecimento,
      a.idAtividadePrevOrcamento,
      r_bufferIdEstoque,
      r_bufferIdEstoque);
  END LOOP;
END ADD_ESTOQUE_ORCAMENTO_AT_PREV;

/

create or replace PROCEDURE ADD_ESTOQUE_INSERE (
  p_sys_estabelecimentoAtivo     IN NUMBER,
  p_config_209_filtrarGrupoEcon  IN NUMBER,
  p_config_354_estabProximoId    IN NUMBER,
  p_config_362_calcCustoPorGrade IN NUMBER,
  p_estabelecimento              IN NUMBER,
  p_data                         IN DATE,
  p_produto                      IN NUMBER,
  p_gradeProduto                 IN NUMBER,
  p_modeloDocumento              IN NUMBER,
  p_motivoEstoque                IN NUMBER,
  p_operacaoInternaEstoque       IN NUMBER,
  p_atualizaCustoMedio           IN NUMBER,
  p_atualizaUltimaCompra         IN NUMBER,
  p_entradaSaida                 IN CHAR,
  p_indicadorPropPosseItem       IN CHAR,
  p_pessoaParticipante           IN NUMBER,
  p_localEstoque                 IN NUMBER,
  p_idFormulaTinta               IN NUMBER,
  p_personalizacao               IN NUMBER,
  p_idLoteEstoque                IN NUMBER,
  p_idNumeroSerie                IN NUMBER,
  p_quantidade                   IN NUMBER,
  p_precoCustoOperacao           IN NUMBER,
  p_totalCustoOperacao           IN NUMBER,
  p_precoCMV                     IN NUMBER,
  p_valorCMV                     IN NUMBER,
  p_observacoes                  IN VARCHAR2,
  p_idFichaProdutoRealOrcamento  IN NUMBER,
  p_idItemPreDocumento           IN NUMBER,
  p_idItemDocFiscal              IN NUMBER,
  p_divergenciaBalanco           IN NUMBER,
  p_idItemDocTransferencia       IN NUMBER,
  p_prod_controleEstoque         IN NUMBER)
IS
  v_bufferIdEstoque VARCHAR2 (32000);
  v_auxNumber       NUMBER;
BEGIN
  v_bufferIdEstoque := '';
  IF p_prod_controleEstoque = 12 AND p_idFormulaTinta > 0 THEN
    ADD_ESTOQUE_FORMULA_TINTA (
      p_sys_estabelecimentoAtivo, 
      p_config_209_filtrarGrupoEcon,
      p_config_354_estabProximoId,
      p_config_362_calcCustoPorGrade,
      p_operacaoInternaEstoque,
      p_atualizaCustoMedio,
      p_atualizaUltimaCompra,
      p_entradaSaida,
      p_estabelecimento,
      p_data,
      p_modeloDocumento,
      p_motivoEstoque,
      p_idFormulaTinta,
      p_localEstoque,
      p_pessoaParticipante,
      p_quantidade,
      p_observacoes,
      p_idFichaProdutoRealOrcamento,
      p_idItemPreDocumento,
      p_idItemDocFiscal,
      p_divergenciaBalanco,
      p_idItemDocTransferencia,
      0, -- p_modDoc_geraTransferencia
      0, -- p_modDoc_geraOperacaoEmTransit
      0, -- p_modDoc_transitoLocalEstoque
      ' ', -- p_locEstTransito_indicProprPos
      p_indicadorPropPosseItem,
      0, -- p_docTransf_estabelecEntrada
      0, -- p_docTransf_estabelecSaida
      v_bufferIdEstoque, 
      v_bufferIdEstoque);
    ELSIF p_prod_controleEstoque IN (3,4) THEN
    ADD_ESTOQUE_KIT (
      p_sys_estabelecimentoAtivo,
      p_config_209_filtrarGrupoEcon,
      p_config_354_estabProximoId,
      p_config_362_calcCustoPorGrade,
      p_operacaoInternaEstoque,
      p_atualizaCustoMedio,
      p_atualizaUltimaCompra,
      p_entradaSaida,
      p_estabelecimento,
      p_data,
      p_modeloDocumento,
      p_motivoEstoque,
      p_gradeProduto,
      p_localEstoque,
      p_pessoaParticipante,
      p_quantidade,
      p_totalCustoOperacao,
      p_observacoes,
      p_idFichaProdutoRealOrcamento,
      p_idItemPreDocumento,
      p_idItemDocFiscal,
      p_divergenciaBalanco,
      p_idItemDocTransferencia,
      0, -- p_modDoc_geraTransferencia
      0, -- p_modDoc_geraOperacaoEmTransit
      0, -- p_modDoc_transitoLocalEstoque
      ' ', -- p_locEstTransito_indicProprPos
      p_indicadorPropPosseItem,
      0, -- p_docTransf_estabelecEntrada
      0, -- p_docTransf_estabelecSaida
      v_bufferIdEstoque,
      v_bufferIdEstoque);
  ELSIF p_prod_controleEstoque IN(1,5,6,11,12) THEN
    ADD_ESTOQUE_GRAVA (
      p_sys_estabelecimentoAtivo, 
      p_config_354_estabProximoId,
      0, -- p_idEstoque
      p_estabelecimento,
      p_data,
      p_produto,
      p_gradeProduto,
      p_modeloDocumento,
      p_motivoEstoque,
      p_operacaoInternaEstoque,
      p_atualizaCustoMedio,
      p_atualizaUltimaCompra,
      p_entradaSaida,
      p_indicadorPropPosseItem,
      p_pessoaParticipante,
      p_localEstoque,
      p_personalizacao,
      p_idLoteEstoque,
      p_idNumeroSerie,
      p_quantidade,
      p_precoCustoOperacao,
      p_totalCustoOperacao,
      p_precoCMV,
      p_valorCMV,
      p_observacoes,
      p_idFichaProdutoRealOrcamento,
      p_idItemPreDocumento,
      p_idItemDocFiscal,
      p_divergenciaBalanco,
      p_idItemDocTransferencia,
      v_bufferIdEstoque,
      v_auxNumber,
      v_bufferIdEstoque);
  END IF;
END ADD_ESTOQUE_INSERE;

/

create or replace PROCEDURE ADD_RESERVA_ESTOQUE_EXCLUI (
  p_idReservaEstoque IN NUMBER)
IS
BEGIN
  DELETE MODOCTRANSFXRESERVAESTOQ
  WHERE idReservaEstoque = p_idReservaEstoque;
  DELETE MOORCAMENTOXFICHAXRESERVA
  WHERE idReservaEstoque = p_idReservaEstoque;
  DELETE MOORCAMENTOXRESERVAESTOQ
  WHERE idReservaEstoque = p_idReservaEstoque;
  DELETE MORESERVASESTOQUE
  WHERE idReservaEstoque = p_idReservaEstoque;
END ADD_RESERVA_ESTOQUE_EXCLUI;

/

create or replace PROCEDURE ADD_RESERVA_ESTOQUE_FIC_EXCLUI (
  p_idFichaProdutoPrevOrcamento IN NUMBER,
  p_bufferIdReservaEstoque      IN VARCHAR,
  /* Retornos */
  r_bufferIdReservaEstoque      OUT VARCHAR)
IS
BEGIN
  r_bufferIdReservaEstoque := p_bufferIdReservaEstoque;
  FOR a IN (
    SELECT idReservaEstoque
    FROM MOORCAMENTOXFICHAXRESERVA
    WHERE idFichaProdutoPrevOrcamento = p_idFichaProdutoPrevOrcamento)
  LOOP
    r_bufferIdReservaEstoque :=
      CASE
        WHEN r_bufferIdReservaEstoque IS NULL
          OR r_bufferIdReservaEstoque = ''
          OR r_bufferIdReservaEstoque = ' '
        THEN ''
        ELSE TRIM (r_bufferIdReservaEstoque) || ';'
      END
      || LPAD(a.idReservaEstoque,14,'0');
    ADD_RESERVA_ESTOQUE_EXCLUI (a.idReservaEstoque);
  END LOOP;
END ADD_RESERVA_ESTOQUE_FIC_EXCLUI;

/

create or replace PROCEDURE ADD_RESERVA_ESTOQUE_TRA_EXCLUI (
  p_idItemDocTransferencia IN NUMBER,
  p_bufferIdReservaEstoque IN VARCHAR,
  /* Retornos */
  r_bufferIdReservaEstoque OUT VARCHAR)
IS
BEGIN
  r_bufferIdReservaEstoque := p_bufferIdReservaEstoque;
  FOR a IN (
    SELECT idReservaEstoque
    FROM MODOCTRANSFXRESERVAESTOQ
    WHERE idItemDocTransferencia = p_idItemDocTransferencia)
  LOOP
    r_bufferIdReservaEstoque :=
      CASE
        WHEN r_bufferIdReservaEstoque IS NULL
          OR r_bufferIdReservaEstoque = ''
          OR r_bufferIdReservaEstoque = ' '
        THEN ''
        ELSE TRIM (r_bufferIdReservaEstoque) || ';'
      END
      || LPAD(a.idReservaEstoque,14,'0');
    ADD_RESERVA_ESTOQUE_EXCLUI (a.idReservaEstoque);
  END LOOP;
END ADD_RESERVA_ESTOQUE_TRA_EXCLUI;

/

create or replace PROCEDURE ADD_RESERVA_ESTOQUE_ORC_EXCLUI (
  p_idItemOrcamento        IN NUMBER,
  p_bufferIdReservaEstoque IN VARCHAR,
  /* Retornos */
  r_bufferIdReservaEstoque OUT VARCHAR)
IS
BEGIN
  r_bufferIdReservaEstoque := p_bufferIdReservaEstoque;
  FOR a IN (
    SELECT idReservaEstoque
    FROM MOORCAMENTOXRESERVAESTOQ
    WHERE idItemOrcamento = p_idItemOrcamento)
  LOOP
    r_bufferIdReservaEstoque :=
      CASE
        WHEN r_bufferIdReservaEstoque IS NULL
          OR r_bufferIdReservaEstoque = ''
          OR r_bufferIdReservaEstoque = ' '
        THEN ''
        ELSE TRIM (r_bufferIdReservaEstoque) || ';'
      END
      || LPAD(a.idReservaEstoque,14,'0');
    ADD_RESERVA_ESTOQUE_EXCLUI (a.idReservaEstoque);
  END LOOP;
  FOR a IN (
    SELECT idAtividadePrevOrcamento
    FROM MOORCAMENTOXATIVIDADEPREV
    WHERE idItemOrcamento = p_idItemOrcamento
	AND idAtividadePrevOrcamento > 0)
  LOOP
    FOR b IN (
      SELECT b.idFichaProdutoPrevOrcamento
      FROM MOORCAMENTOXFICHAPRODPREV b
      WHERE b.idAtividadePrevOrcamento = idAtividadePrevOrcamento
      AND b.idFichaProdutoPrevOrcamento > 0)
    LOOP
      ADD_RESERVA_ESTOQUE_FIC_EXCLUI (
        b.idFichaProdutoPrevOrcamento,
        r_bufferIdReservaEstoque,
        r_bufferIdReservaEstoque);
    END LOOP;
  END LOOP;
END ADD_RESERVA_ESTOQUE_ORC_EXCLUI;

/

create or replace PROCEDURE ADD_RESERVA_ESTOQUE_GRAVA (
  p_sys_estabelecimentoAtivo    IN NUMBER,
  p_config_354_estabProximoId   IN NUMBER,
  p_idReservaEstoque            IN NUMBER,
  p_estabelecimento             IN NUMBER,
  p_dataEntrega                 IN DATE,
  p_produto                     IN NUMBER,
  p_gradeProduto                IN NUMBER,
  p_modeloDocumento             IN NUMBER,
  p_entradaSaida                IN CHAR,
  p_indicadorPropPosseItem      IN CHAR,
  p_pessoaParticipante          IN NUMBER,
  p_localEstoque                IN NUMBER,
  p_personalizacao              IN NUMBER,
  p_idLoteEstoque               IN NUMBER,
  p_idNumeroSerie               IN NUMBER,
  p_quantidadeSaldo             IN NUMBER,
  p_observacoes                 IN VARCHAR2,
  p_idItemOrcamento             IN NUMBER,
  p_idFichaProdutoPrevOrcamento IN NUMBER,
  p_idItemDocTransferencia      IN NUMBER,
  p_bufferIdReservaEstoque      IN VARCHAR2,
  r_idReservaEstoque            OUT NUMBER,
  r_bufferIdReservaEstoque      OUT VARCHAR2)
IS
  v_existeRegistro NUMBER;
BEGIN
  IF p_idReservaEstoque > 0 THEN
    r_idReservaEstoque       := p_idReservaEstoque;
    r_bufferIdReservaEstoque := p_bufferIdReservaEstoque;
  ELSIF p_bufferIdReservaEstoque IS NOT NULL AND LENGTH (RTRIM (p_bufferIdReservaEstoque)) >= 14 THEN
    r_idReservaEstoque       := TO_NUMBER (SUBSTR (p_bufferIdReservaEstoque, 1, 14));
    r_bufferIdReservaEstoque := RTRIM (SUBSTR (p_bufferIdReservaEstoque, 16, 31984));
  ELSE
    r_idReservaEstoque       := FUNC_ADD_PROXIMO_ID (
      p_sys_estabelecimentoAtivo,
      p_config_354_estabProximoId,
      'MORESERVASESTOQUE',
      'idReservaEstoque',
      14);
    r_bufferIdReservaEstoque := '';
  END IF;
  MERGE INTO MORESERVASESTOQUE a USING (
    SELECT
      r_idReservaEstoque       idReservaEstoque,
      p_estabelecimento        estabelecimento,
      p_dataEntrega            dataEntrega,
      p_produto                produto,
      p_gradeProduto           gradeProduto,
      p_modeloDocumento        modeloDocumento,
      p_entradaSaida           entradaSaida,
      p_indicadorPropPosseItem indicadorPropriedadePosseItem,
      p_pessoaParticipante     pessoaParticipante,
      p_localEstoque           localEstoque,
      p_personalizacao         personalizacao,
      p_idLoteEstoque          idLoteEstoque,
      p_idNumeroSerie          idNumeroSerie,
      p_quantidadeSaldo        quantidadeSaldo,
      p_observacoes            observacoes
    FROM DUAL) b
  ON (a.idReservaEstoque = b.idReservaEstoque)
  WHEN MATCHED THEN UPDATE SET 
    a.estabelecimento               = b.estabelecimento,
    a.dataEntrega                   = b.dataEntrega,
    a.produto                       = b.produto,
    a.gradeProduto                  = b.gradeProduto,
    a.modeloDocumento               = b.modeloDocumento,
    a.entradaSaida                  = b.entradaSaida,
    a.indicadorPropriedadePosseItem = b.indicadorPropriedadePosseItem,
    a.pessoaParticipante            = b.pessoaParticipante,
    a.localEstoque                  = b.localEstoque,
    a.personalizacao                = b.personalizacao,
    a.idLoteEstoque                 = b.idLoteEstoque,
    a.idNumeroSerie                 = b.idNumeroSerie,
    a.quantidadeSaldo               = b.quantidadeSaldo,
    a.observacoes                   = b.observacoes
  WHEN NOT MATCHED THEN INSERT (
    idReservaEstoque,
    estabelecimento,
    dataEntrega,
    produto,
    gradeProduto,
    modeloDocumento,
    entradaSaida,
    indicadorPropriedadePosseItem,
    pessoaParticipante,
    localEstoque,
    personalizacao,
    idLoteEstoque,
    idNumeroSerie,
    quantidadeSaldo,
    observacoes)
  VALUES (
    b.idReservaEstoque,
    b.estabelecimento,
    b.dataEntrega,
    b.produto,
    b.gradeProduto,
    b.modeloDocumento,
    b.entradaSaida,
    b.indicadorPropriedadePosseItem,
    b.pessoaParticipante,
    b.localEstoque,
    b.personalizacao,
    b.idLoteEstoque,
    b.idNumeroSerie,
    b.quantidadeSaldo,
    b.observacoes);
  IF p_idItemOrcamento > 0 THEN
    SELECT COALESCE (MAX (1), 0)
    INTO v_existeRegistro
    FROM MOORCAMENTOXRESERVAESTOQ
    WHERE idItemOrcamento = p_idItemOrcamento
    AND idReservaEstoque = r_idReservaEstoque;
    IF v_existeRegistro = 0 THEN
      INSERT INTO MOORCAMENTOXRESERVAESTOQ (
        id,
        idReservaEstoque,
        idItemOrcamento)
      VALUES (
        FUNC_ADD_PROXIMO_ID (
          p_sys_estabelecimentoAtivo,
          p_config_354_estabProximoId,
          'MOORCAMENTOXRESERVAESTOQ',
          'id',
          14),
        r_idReservaEstoque,
        p_idItemOrcamento);
    END IF;
  END IF;
  IF p_idFichaProdutoPrevOrcamento > 0 THEN
    SELECT COALESCE (MAX (1), 0)
    INTO v_existeRegistro
    FROM MOORCAMENTOXFICHAXRESERVA
    WHERE idFichaProdutoPrevOrcamento = p_idFichaProdutoPrevOrcamento
    AND idReservaEstoque = r_idReservaEstoque;
    IF v_existeRegistro = 0 THEN
      INSERT INTO MOORCAMENTOXFICHAXRESERVA (
        id,
        idReservaEstoque,
        idFichaProdutoPrevOrcamento)
      VALUES (
        FUNC_ADD_PROXIMO_ID (
          p_sys_estabelecimentoAtivo,
          p_config_354_estabProximoId,
          'MOORCAMENTOXFICHAXRESERVA',
          'id',
          14),
        r_idReservaEstoque,
        p_idFichaProdutoPrevOrcamento);
    END IF;
  END IF;
  IF p_idItemDocTransferencia > 0 THEN
    SELECT COALESCE (MAX (1), 0)
    INTO v_existeRegistro
    FROM MODOCTRANSFXRESERVAESTOQ
    WHERE idItemDocTransferencia = p_idItemDocTransferencia
    AND idReservaEstoque = r_idReservaEstoque;
    IF v_existeRegistro = 0 THEN
      INSERT INTO MODOCTRANSFXRESERVAESTOQ (
        id,
        idReservaEstoque,
        idItemDocTransferencia)
      VALUES (
        FUNC_ADD_PROXIMO_ID (
          p_sys_estabelecimentoAtivo,
          p_config_354_estabProximoId,
          'MODOCTRANSFXRESERVAESTOQ',
          'id',
          14),
        r_idReservaEstoque,
        p_idItemDocTransferencia);
    END IF;
  END IF;
END ADD_RESERVA_ESTOQUE_GRAVA;

/

create or replace PROCEDURE ADD_RESERVA_ESTOQUE_ORC_N_SER (
  p_sys_estabelecimentoAtivo   IN NUMBER,
  p_config_354_estabProximoId  IN NUMBER,
  p_cab_entradaSaida           IN CHAR,
  p_cab_estabelecimento        IN NUMBER,
  p_dataEntrega                IN DATE,
  p_item_idItemOrcamento       IN NUMBER,
  p_item_modeloDocumento       IN NUMBER,
  p_item_gradeProduto          IN NUMBER,
  p_item_personalizacao        IN NUMBER,
  p_item_idLoteEstoque         IN NUMBER,
  p_item_localEstoque          IN NUMBER,
  p_item_pessoaParticipante    IN NUMBER,
  p_item_observacoes           IN VARCHAR2,
  p_graProd_produto            IN NUMBER,
  p_locEst_indicProprPosseItem IN CHAR,
  p_bufferIdReservaEstoque     IN VARCHAR2,
  r_bufferIdReservaEstoque     OUT VARCHAR2,
  r_quantidadeNumerosSerie     OUT NUMBER)
IS
  v_auxNumber NUMBER;  
BEGIN
  r_bufferIdReservaEstoque := p_bufferIdReservaEstoque;
  r_quantidadeNumerosSerie := 0;
  FOR a IN (
    SELECT idNumeroSerie
    FROM MOORCAMENTOXNUMEROSSERIE 
    WHERE idItemOrcamento = p_item_idItemOrcamento
    AND gradeProduto = p_item_gradeProduto)
  LOOP
    r_quantidadeNumerosSerie := r_quantidadeNumerosSerie + 1;
    ADD_RESERVA_ESTOQUE_GRAVA (
      p_sys_estabelecimentoAtivo,
      p_config_354_estabProximoId,
      0, -- p_idReservaEstoque
      p_cab_estabelecimento,
      p_dataEntrega,
      p_graProd_produto,
      p_item_gradeProduto,
      p_item_modeloDocumento,
      p_cab_entradaSaida,
      p_locEst_indicProprPosseItem,
      p_item_pessoaParticipante,
      p_item_localEstoque,
      p_item_personalizacao,
      p_item_idLoteEstoque,
      a.idNumeroSerie,
      1, -- p_quantidadeSaldo
      p_item_observacoes,
      p_item_idItemOrcamento,
      0, -- p_idFichaProdutoPrevOrcamento
      0, -- p_idItemDocTransferencia
      r_bufferIdReservaEstoque, 
      v_auxNumber,
      r_bufferIdReservaEstoque);
  END LOOP;
END ADD_RESERVA_ESTOQUE_ORC_N_SER;

/

create or replace PROCEDURE ADD_RESERVA_ESTOQUE_TRA_N_SER (
  p_sys_estabelecimentoAtivo     IN NUMBER,
  p_config_354_estabProximoId    IN NUMBER,
  p_cab_modeloDocumento          IN NUMBER,
  p_cab_entradaSaida             IN CHAR,
  p_cab_estabelecimento          IN NUMBER,
  p_cab_dataEmissao              IN DATE,
  p_item_idItemDocTransferencia  IN NUMBER,
  p_item_gradeProduto            IN NUMBER,
  p_item_personalizacao          IN NUMBER,
  p_item_idLoteEstoque           IN NUMBER,
  p_item_localEstoque            IN NUMBER,
  p_item_pessoaParticipante      IN NUMBER,
  p_item_observacoes             IN VARCHAR2,
  p_graProd_produto              IN NUMBER,
  p_locEst_indicProprPosseItem   IN CHAR,
  p_bufferIdReservaEstoque       IN VARCHAR2,
  r_bufferIdReservaEstoque       OUT VARCHAR2,
  r_quantidadeNumerosSerie       OUT NUMBER)
IS
  v_auxNumber NUMBER;  
BEGIN
  r_bufferIdReservaEstoque := p_bufferIdReservaEstoque;
  r_quantidadeNumerosSerie := 0;
  FOR a IN (
    SELECT idNumeroSerie
    FROM MODOCTRANSFXNUMEROSSERIE 
    WHERE idItemDocTransferencia = p_item_idItemDocTransferencia
    AND gradeProduto = p_item_gradeProduto)
  LOOP
    r_quantidadeNumerosSerie := r_quantidadeNumerosSerie + 1;
    ADD_RESERVA_ESTOQUE_GRAVA (
      p_sys_estabelecimentoAtivo,
      p_config_354_estabProximoId,
      0, -- p_idReservaEstoque
      p_cab_estabelecimento,
      p_cab_dataEmissao,
      p_graProd_produto,
      p_item_gradeProduto,
      p_cab_modeloDocumento,
      p_cab_entradaSaida,
      p_locEst_indicProprPosseItem,
      p_item_pessoaParticipante,
      p_item_localEstoque,
      p_item_personalizacao,
      p_item_idLoteEstoque,
      a.idNumeroSerie,
      1, -- p_quantidadeSaldo
      p_item_observacoes,
      0, --p_idItemOrcamento
      0, -- p_idFichaProdutoPrevOrcamento
      p_item_idItemDocTransferencia,
      r_bufferIdReservaEstoque, 
      v_auxNumber,
      r_bufferIdReservaEstoque);
  END LOOP;
END ADD_RESERVA_ESTOQUE_TRA_N_SER;

/

create or replace PROCEDURE ADD_RESERVA_ESTOQUE_KIT (
  p_sys_estabelecimentoAtivo    IN NUMBER,
  p_config_354_estabProximoId   IN NUMBER,
  p_cab_entradaSaida            IN CHAR,
  p_cab_estabelecimento         IN NUMBER,
  p_dataEntrega                 IN DATE,
  p_item_modeloDocumento        IN NUMBER,
  p_item_gradeProduto           IN NUMBER,
  p_item_localEstoque           IN NUMBER,
  p_item_pessoaParticipante     IN NUMBER,
  p_item_quantidadeSaldo        IN NUMBER,
  p_item_observacoes            IN VARCHAR2,
  p_idItemOrcamento             IN NUMBER,
  p_idFichaProdutoPrevOrcamento IN NUMBER,
  p_idItemDocTransferencia      IN NUMBER,
  p_locEst_indicProprPosseItem  IN CHAR,
  p_bufferIdReservaEstoque      IN VARCHAR2,
  r_bufferIdReservaEstoque      OUT VARCHAR2)
IS
  v_quantidadeNumerosSerie     NUMBER;
  v_auxNumber                  NUMBER;
BEGIN
  r_bufferIdReservaEstoque := p_bufferIdReservaEstoque;
  FOR a IN (
    SELECT 
      a.gradeProdutoFilho gradeProduto,
      gradProdFilho.produto,
      prodFilho.controleEstoque,
      prodFilho.controlaNumeroSerie,
      ROUND (p_item_quantidadeSaldo * a.quantidade, uniFilho.casasDecimaisUnidadeMedida) quantidadeSaldo
    FROM CAGRADEPRODUTOXKITSCOMBOS a 
    JOIN CAGRADESPRODUTO gradProdFilho
    ON gradProdFilho.gradeProduto = a.gradeProdutoFilho
    JOIN CAPRODUTOS prodFilho
    ON prodFilho.produto = gradProdFilho.produto
    JOIN SIUNIDADESMEDIDA uniFilho
    ON uniFilho.unidadeMedida = prodFilho.unidadeMedida
    WHERE a.gradeProduto = p_item_gradeProduto
    AND a.ativo = 1
    AND ROUND (p_item_quantidadeSaldo * a.quantidade, uniFilho.casasDecimaisUnidadeMedida) > 0)
  LOOP
    IF a.controleEstoque IN (3,4) THEN
      ADD_RESERVA_ESTOQUE_KIT (
        p_sys_estabelecimentoAtivo,
        p_config_354_estabProximoId,
        p_cab_entradaSaida,
        p_cab_estabelecimento,
        p_dataEntrega,
        p_item_modeloDocumento,
        a.gradeProduto,
        p_item_localEstoque,
        p_item_pessoaParticipante,
        a.quantidadeSaldo,
        p_item_observacoes,
        p_idItemOrcamento,
        p_idFichaProdutoPrevOrcamento,
        p_idItemDocTransferencia,
        p_locEst_indicProprPosseItem,
        r_bufferIdReservaEstoque,
        r_bufferIdReservaEstoque);
    ELSIF a.controleEstoque IN (1,5,6,11,12) THEN
      v_quantidadeNumerosSerie := 0;
      IF a.controlaNumeroSerie > 0
        AND p_idItemOrcamento > 0
      THEN
        ADD_RESERVA_ESTOQUE_ORC_N_SER (
          p_sys_estabelecimentoAtivo,
          p_config_354_estabProximoId,
          p_cab_entradaSaida,
          p_cab_estabelecimento,
          p_dataEntrega,
          p_idItemOrcamento,
          p_item_modeloDocumento,
          a.gradeProduto,
          0, -- p_personalizacao,
          0, -- p_idLoteEstoque,
          p_item_localEstoque,
          p_item_pessoaParticipante,
          p_item_observacoes,
          a.produto,
          p_locEst_indicProprPosseItem,
          r_bufferIdReservaEstoque, 
          r_bufferIdReservaEstoque,
          v_quantidadeNumerosSerie);
      ELSIF a.controlaNumeroSerie > 0
        AND p_idItemDocTransferencia > 0
      THEN
        ADD_RESERVA_ESTOQUE_TRA_N_SER (
          p_sys_estabelecimentoAtivo,
          p_config_354_estabProximoId,
          p_item_modeloDocumento,
          p_cab_entradaSaida,
          p_cab_estabelecimento,
          p_dataEntrega,
          p_idItemDocTransferencia,
          a.gradeProduto,
          0, -- p_personalizacao,
          0, -- p_idLoteEstoque,
          p_item_localEstoque,
          p_item_pessoaParticipante,
          p_item_observacoes,
          a.produto,
          p_locEst_indicProprPosseItem,
          r_bufferIdReservaEstoque, 
          r_bufferIdReservaEstoque,
          v_quantidadeNumerosSerie);
      END IF;
      IF a.quantidadeSaldo > v_quantidadeNumerosSerie THEN
        ADD_RESERVA_ESTOQUE_GRAVA (
          p_sys_estabelecimentoAtivo,
          p_config_354_estabProximoId,
          0, -- p_idReservaEstoque
          p_cab_estabelecimento,
          p_dataEntrega,
          a.produto,
          a.gradeProduto,
          p_item_modeloDocumento,
          p_cab_entradaSaida,
          p_locEst_indicProprPosseItem,
          p_item_pessoaParticipante,
          p_item_localEstoque,
          0, -- p_item_personalizacao
          0, -- p_idLoteEstoque
          0, -- p_idNumeroSerie
          a.quantidadeSaldo,
          p_item_observacoes,
          p_idItemOrcamento,
          p_idFichaProdutoPrevOrcamento,
          p_idItemDocTransferencia,
          r_bufferIdReservaEstoque, 
          v_auxNumber,
          r_bufferIdReservaEstoque);
      END IF;
    END IF;
  END LOOP; 
END ADD_RESERVA_ESTOQUE_KIT;

/

create or replace PROCEDURE ADD_RESERVA_ESTOQUE_PROD_TINTA (
  p_sys_estabelecimentoAtivo    IN NUMBER,
  p_config_354_estabProximoId   IN NUMBER,
  p_cab_entradaSaida            IN CHAR,
  p_cab_estabelecimento         IN NUMBER,
  p_dataEntrega                 IN DATE,
  p_item_modeloDocumento        IN NUMBER,
  p_item_localEstoque           IN NUMBER,
  p_item_pessoaParticipante     IN NUMBER,
  p_item_quantidadeSaldo        IN NUMBER,
  p_item_observacoes            IN VARCHAR2,
  p_tinta_gradeProduto          IN NUMBER,
  p_tinta_quantidade            IN NUMBER,
  p_idItemOrcamento             IN NUMBER,
  p_idFichaProdutoPrevOrcamento IN NUMBER,
  p_idItemDocTransferencia      IN NUMBER,
  p_locEst_indicProprPosseItem  IN CHAR,
  p_bufferIdReservaEstoque      IN VARCHAR2,
  r_bufferIdReservaEstoque      OUT VARCHAR2)
IS
  v_auxNumber                   NUMBER;
BEGIN
  r_bufferIdReservaEstoque := p_bufferIdReservaEstoque;
  FOR a IN (
    SELECT 
      gradProd.produto,
      prod.controleEstoque,
      ROUND(p_item_quantidadeSaldo * p_tinta_quantidade / 900, uniMed.casasDecimaisUnidadeMedida) quantidadeSaldo
    FROM CAGRADESPRODUTO gradProd 
    JOIN CAPRODUTOS prod
    ON prod.produto = gradProd.produto
    JOIN SIUNIDADESMEDIDA uniMed
    ON uniMed.unidadeMedida = prod.unidadeMedida
    WHERE gradProd.gradeProduto = p_tinta_gradeProduto
    AND ROUND(p_item_quantidadeSaldo * p_tinta_quantidade / 900, uniMed.casasDecimaisUnidadeMedida) > 0)
  LOOP
    IF a.controleEstoque IN (3,4) THEN
      ADD_RESERVA_ESTOQUE_KIT (
        p_sys_estabelecimentoAtivo,
        p_config_354_estabProximoId,
        p_cab_entradaSaida,
        p_cab_estabelecimento,
        p_dataEntrega,
        p_item_modeloDocumento,
        p_tinta_gradeProduto,
        p_item_localEstoque,
        p_item_pessoaParticipante,
        a.quantidadeSaldo,
        p_item_observacoes,
        p_idItemOrcamento,
        p_idFichaProdutoPrevOrcamento,
        p_idItemDocTransferencia,
        p_locEst_indicProprPosseItem,
        r_bufferIdReservaEstoque,
        r_bufferIdReservaEstoque);
    ELSIF a.controleEstoque IN (1,5,6,11,12) THEN
      ADD_RESERVA_ESTOQUE_GRAVA (
        p_sys_estabelecimentoAtivo, 
        p_config_354_estabProximoId,
        0, -- p_idReservaEstoque
        p_cab_estabelecimento,
        p_dataEntrega,
        a.produto,
        p_tinta_gradeProduto,
        p_item_modeloDocumento,
        p_cab_entradaSaida,
        p_locEst_indicProprPosseItem,
        p_item_pessoaParticipante,
        p_item_localEstoque,
        0, -- p_item_personalizacao
        0, --p_idLoteEstoque
        0, --p_idNumeroSerie
        a.quantidadeSaldo,
        p_item_observacoes,
        p_idItemOrcamento,
        p_idFichaProdutoPrevOrcamento,
        p_idItemDocTransferencia,
        r_bufferIdReservaEstoque,
        v_auxNumber,
        r_bufferIdReservaEstoque);
    END IF;
  END LOOP;
END ADD_RESERVA_ESTOQUE_PROD_TINTA;

/

create or replace PROCEDURE ADD_RESERVA_ESTOQUE_FORM_TINTA ( 
  p_sys_estabelecimentoAtivo    IN NUMBER,
  p_config_354_estabProximoId   IN NUMBER,
  p_cab_entradaSaida            IN CHAR,
  p_cab_estabelecimento         IN NUMBER,
  p_dataEntrega                 IN DATE,
  p_item_modeloDocumento        IN NUMBER,
  p_item_idFormulaTinta         IN NUMBER,
  p_item_localEstoque           IN NUMBER,
  p_item_pessoaParticipante     IN NUMBER,
  p_item_quantidadeSaldo        IN NUMBER,
  p_item_observacoes            IN VARCHAR2,
  p_idItemOrcamento             IN NUMBER,
  p_idFichaProdutoPrevOrcamento IN NUMBER,
  p_idItemDocTransferencia      IN NUMBER,
  p_locEst_indicProprPosseItem  IN CHAR,
  p_bufferIdReservaEstoque      IN VARCHAR2,
  r_bufferIdReservaEstoque      OUT VARCHAR2)
IS
BEGIN
  r_bufferIdReservaEstoque := p_bufferIdReservaEstoque;
  FOR a IN (
    SELECT 
      formTinta.idBaseTinta,
      baseTinta.gradeProduto,
      formTinta.idColoranteTintaA,
      formTinta.quantidadeA,
      COALESCE(colTintaA.gradeProduto, 0) gradeProdutoA,
      formTinta.idColoranteTintaB,
      formTinta.quantidadeB,
      COALESCE(colTintaB.gradeProduto, 0) gradeProdutoB,
      formTinta.idColoranteTintaC,
      formTinta.quantidadeC,
      COALESCE(colTintaC.gradeProduto, 0) gradeProdutoC,
      formTinta.idColoranteTintaD,
      formTinta.quantidadeD,
      COALESCE(colTintaD.gradeProduto, 0) gradeProdutoD,
      formTinta.idColoranteTintaE,
      formTinta.quantidadeE,
      COALESCE(colTintaE.gradeProduto, 0) gradeProdutoE,
      formTinta.idColoranteTintaF,
      formTinta.quantidadeF,
      COALESCE(colTintaF.gradeProduto, 0) gradeProdutoF,
      formTinta.idColoranteTintaG,
      formTinta.quantidadeG,
      COALESCE(colTintaG.gradeProduto, 0) gradeProdutoG,
      formTinta.idColoranteTintaH,
      formTinta.quantidadeH,
      COALESCE(colTintaH.gradeProduto, 0) gradeProdutoH,
      formTinta.idColoranteTintaI,
      formTinta.quantidadeI,
      COALESCE(colTintaI.gradeProduto, 0) gradeProdutoI,
      formTinta.idColoranteTintaJ,
      formTinta.quantidadeJ,
      COALESCE(colTintaJ.gradeProduto, 0) gradeProdutoJ,
      formTinta.idColoranteTintaK,
      formTinta.quantidadeK,
      COALESCE(colTintaK.gradeProduto, 0) gradeProdutoK,
      formTinta.idColoranteTintaL,
      formTinta.quantidadeL,
      COALESCE(colTintaL.gradeProduto, 0) gradeProdutoL,
      formTinta.idColoranteTintaM,
      formTinta.quantidadeM,
      COALESCE(colTintaM.gradeProduto, 0) gradeProdutoM,
      formTinta.idColoranteTintaN,
      formTinta.quantidadeN,
      COALESCE(colTintaN.gradeProduto, 0) gradeProdutoN,
      formTinta.idColoranteTintaO,
      formTinta.quantidadeO,
      COALESCE(colTintaO.gradeProduto, 0) gradeProdutoO
    FROM CAFORMULASTINTAS formTinta 
    JOIN CABASESTINTAS baseTinta
    ON baseTinta.idBaseTinta = formTinta.idBaseTinta
    LEFT JOIN CACOLORANTESTINTAS colTintaA
    ON colTintaA.idColoranteTinta = formTinta.idColoranteTintaA
    LEFT JOIN CACOLORANTESTINTAS colTintaB
    ON colTintaB.idColoranteTinta = formTinta.idColoranteTintaB
    LEFT JOIN CACOLORANTESTINTAS colTintaC
    ON colTintaC.idColoranteTinta = formTinta.idColoranteTintaC
    LEFT JOIN CACOLORANTESTINTAS colTintaD
    ON colTintaD.idColoranteTinta = formTinta.idColoranteTintaD
    LEFT JOIN CACOLORANTESTINTAS colTintaE
    ON colTintaE.idColoranteTinta = formTinta.idColoranteTintaE
    LEFT JOIN CACOLORANTESTINTAS colTintaF
    ON colTintaF.idColoranteTinta = formTinta.idColoranteTintaF
    LEFT JOIN CACOLORANTESTINTAS colTintaG
    ON colTintaG.idColoranteTinta = formTinta.idColoranteTintaG
    LEFT JOIN CACOLORANTESTINTAS colTintaH
    ON colTintaH.idColoranteTinta = formTinta.idColoranteTintaH
    LEFT JOIN CACOLORANTESTINTAS colTintaI
    ON colTintaI.idColoranteTinta = formTinta.idColoranteTintaI
    LEFT JOIN CACOLORANTESTINTAS colTintaJ
    ON colTintaJ.idColoranteTinta = formTinta.idColoranteTintaJ
    LEFT JOIN CACOLORANTESTINTAS colTintaK
    ON colTintaK.idColoranteTinta = formTinta.idColoranteTintaK
    LEFT JOIN CACOLORANTESTINTAS colTintaL
    ON colTintaL.idColoranteTinta = formTinta.idColoranteTintaL
    LEFT JOIN CACOLORANTESTINTAS colTintaM
    ON colTintaM.idColoranteTinta = formTinta.idColoranteTintaM
    LEFT JOIN CACOLORANTESTINTAS colTintaN
    ON colTintaN.idColoranteTinta = formTinta.idColoranteTintaN
    LEFT JOIN CACOLORANTESTINTAS colTintaO
    ON colTintaO.idColoranteTinta = formTinta.idColoranteTintaO
    WHERE formTinta.idFormulaTinta = p_item_idFormulaTinta
    AND formTinta.idBaseTinta > 0
    AND baseTinta.gradeProduto > 0)
  LOOP
    ADD_RESERVA_ESTOQUE_PROD_TINTA (
      p_sys_estabelecimentoAtivo,
      p_config_354_estabProximoId,
      p_cab_entradaSaida,
      p_cab_estabelecimento,
      p_dataEntrega,
      p_item_modeloDocumento,
      p_item_localEstoque,
      p_item_pessoaParticipante,
      p_item_quantidadeSaldo,
      p_item_observacoes,
      a.gradeProduto, -- p_tinta_gradeProduto
      900, -- p_tinta_quantidade
      p_idItemOrcamento,
      p_idFichaProdutoPrevOrcamento,
      p_idItemDocTransferencia,
      p_locEst_indicProprPosseItem,
      r_bufferIdReservaEstoque,
      r_bufferIdReservaEstoque);
    IF a.idColoranteTintaA > 0
      AND a.quantidadeA > 0
      AND a.gradeProdutoA > 0
    THEN
       ADD_RESERVA_ESTOQUE_PROD_TINTA (
        p_sys_estabelecimentoAtivo,
        p_config_354_estabProximoId,
        p_cab_entradaSaida,
        p_cab_estabelecimento,
        p_dataEntrega,
        p_item_modeloDocumento,
        p_item_localEstoque,
        p_item_pessoaParticipante,
        p_item_quantidadeSaldo,
        p_item_observacoes,
        a.gradeProdutoA, -- p_tinta_gradeProduto
        a.quantidadeA, -- p_tinta_quantidade
        p_idItemOrcamento,
        p_idFichaProdutoPrevOrcamento,
        p_idItemDocTransferencia,
        p_locEst_indicProprPosseItem,
        r_bufferIdReservaEstoque,
        r_bufferIdReservaEstoque);
   END IF;
    IF a.idColoranteTintaB > 0
      AND a.quantidadeB > 0
      AND a.gradeProdutoB > 0
    THEN
       ADD_RESERVA_ESTOQUE_PROD_TINTA (
        p_sys_estabelecimentoAtivo,
        p_config_354_estabProximoId,
        p_cab_entradaSaida,
        p_cab_estabelecimento,
        p_dataEntrega,
        p_item_modeloDocumento,
        p_item_localEstoque,
        p_item_pessoaParticipante,
        p_item_quantidadeSaldo,
        p_item_observacoes,
        a.gradeProdutoB, -- p_tinta_gradeProduto
        a.quantidadeB, -- p_tinta_quantidade
        p_idItemOrcamento,
        p_idFichaProdutoPrevOrcamento,
        p_idItemDocTransferencia,
        p_locEst_indicProprPosseItem,
        r_bufferIdReservaEstoque,
        r_bufferIdReservaEstoque);
    END IF;
    IF a.idColoranteTintaC > 0
      AND a.quantidadeC > 0
      AND a.gradeProdutoC > 0
    THEN
       ADD_RESERVA_ESTOQUE_PROD_TINTA (
        p_sys_estabelecimentoAtivo,
        p_config_354_estabProximoId,
        p_cab_entradaSaida,
        p_cab_estabelecimento,
        p_dataEntrega,
        p_item_modeloDocumento,
        p_item_localEstoque,
        p_item_pessoaParticipante,
        p_item_quantidadeSaldo,
        p_item_observacoes,
        a.gradeProdutoC, -- p_tinta_gradeProduto
        a.quantidadeC, -- p_tinta_quantidade
        p_idItemOrcamento,
        p_idFichaProdutoPrevOrcamento,
        p_idItemDocTransferencia,
        p_locEst_indicProprPosseItem,
        r_bufferIdReservaEstoque,
        r_bufferIdReservaEstoque);
    END IF;
    IF a.idColoranteTintaD > 0
      AND a.quantidadeD > 0
      AND a.gradeProdutoD > 0
    THEN
       ADD_RESERVA_ESTOQUE_PROD_TINTA (
        p_sys_estabelecimentoAtivo,
        p_config_354_estabProximoId,
        p_cab_entradaSaida,
        p_cab_estabelecimento,
        p_dataEntrega,
        p_item_modeloDocumento,
        p_item_localEstoque,
        p_item_pessoaParticipante,
        p_item_quantidadeSaldo,
        p_item_observacoes,
        a.gradeProdutoD, -- p_tinta_gradeProduto
        a.quantidadeD, -- p_tinta_quantidade
        p_idItemOrcamento,
        p_idFichaProdutoPrevOrcamento,
        p_idItemDocTransferencia,
        p_locEst_indicProprPosseItem,
        r_bufferIdReservaEstoque,
        r_bufferIdReservaEstoque);
    END IF;
    IF a.idColoranteTintaE > 0
      AND a.quantidadeE > 0
      AND a.gradeProdutoE > 0
    THEN
       ADD_RESERVA_ESTOQUE_PROD_TINTA (
        p_sys_estabelecimentoAtivo,
        p_config_354_estabProximoId,
        p_cab_entradaSaida,
        p_cab_estabelecimento,
        p_dataEntrega,
        p_item_modeloDocumento,
        p_item_localEstoque,
        p_item_pessoaParticipante,
        p_item_quantidadeSaldo,
        p_item_observacoes,
        a.gradeProdutoE, -- p_tinta_gradeProduto
        a.quantidadeE, -- p_tinta_quantidade
        p_idItemOrcamento,
        p_idFichaProdutoPrevOrcamento,
        p_idItemDocTransferencia,
        p_locEst_indicProprPosseItem,
        r_bufferIdReservaEstoque,
        r_bufferIdReservaEstoque);
    END IF;
    IF a.idColoranteTintaF > 0
      AND a.quantidadeF > 0
      AND a.gradeProdutoF > 0
    THEN
       ADD_RESERVA_ESTOQUE_PROD_TINTA (
        p_sys_estabelecimentoAtivo,
        p_config_354_estabProximoId,
        p_cab_entradaSaida,
        p_cab_estabelecimento,
        p_dataEntrega,
        p_item_modeloDocumento,
        p_item_localEstoque,
        p_item_pessoaParticipante,
        p_item_quantidadeSaldo,
        p_item_observacoes,
        a.gradeProdutoF, -- p_tinta_gradeProduto
        a.quantidadeF, -- p_tinta_quantidade
        p_idItemOrcamento,
        p_idFichaProdutoPrevOrcamento,
        p_idItemDocTransferencia,
        p_locEst_indicProprPosseItem,
        r_bufferIdReservaEstoque,
        r_bufferIdReservaEstoque);
    END IF;
    IF a.idColoranteTintaG > 0
      AND a.quantidadeG > 0
      AND a.gradeProdutoG > 0
    THEN
       ADD_RESERVA_ESTOQUE_PROD_TINTA (
        p_sys_estabelecimentoAtivo,
        p_config_354_estabProximoId,
        p_cab_entradaSaida,
        p_cab_estabelecimento,
        p_dataEntrega,
        p_item_modeloDocumento,
        p_item_localEstoque,
        p_item_pessoaParticipante,
        p_item_quantidadeSaldo,
        p_item_observacoes,
        a.gradeProdutoG, -- p_tinta_gradeProduto
        a.quantidadeG, -- p_tinta_quantidade
        p_idItemOrcamento,
        p_idFichaProdutoPrevOrcamento,
        p_idItemDocTransferencia,
        p_locEst_indicProprPosseItem,
        r_bufferIdReservaEstoque,
        r_bufferIdReservaEstoque);
    END IF;
    IF a.idColoranteTintaH > 0
      AND a.quantidadeH > 0
      AND a.gradeProdutoH > 0
    THEN
       ADD_RESERVA_ESTOQUE_PROD_TINTA (
        p_sys_estabelecimentoAtivo,
        p_config_354_estabProximoId,
        p_cab_entradaSaida,
        p_cab_estabelecimento,
        p_dataEntrega,
        p_item_modeloDocumento,
        p_item_localEstoque,
        p_item_pessoaParticipante,
        p_item_quantidadeSaldo,
        p_item_observacoes,
        a.gradeProdutoH, -- p_tinta_gradeProduto
        a.quantidadeH, -- p_tinta_quantidade
        p_idItemOrcamento,
        p_idFichaProdutoPrevOrcamento,
        p_idItemDocTransferencia,
        p_locEst_indicProprPosseItem,
        r_bufferIdReservaEstoque,
        r_bufferIdReservaEstoque);
    END IF;
    IF a.idColoranteTintaI > 0
      AND a.quantidadeI > 0
      AND a.gradeProdutoI > 0
    THEN
       ADD_RESERVA_ESTOQUE_PROD_TINTA (
        p_sys_estabelecimentoAtivo,
        p_config_354_estabProximoId,
        p_cab_entradaSaida,
        p_cab_estabelecimento,
        p_dataEntrega,
        p_item_modeloDocumento,
        p_item_localEstoque,
        p_item_pessoaParticipante,
        p_item_quantidadeSaldo,
        p_item_observacoes,
        a.gradeProdutoI, -- p_tinta_gradeProduto
        a.quantidadeI, -- p_tinta_quantidade
        p_idItemOrcamento,
        p_idFichaProdutoPrevOrcamento,
        p_idItemDocTransferencia,
        p_locEst_indicProprPosseItem,
        r_bufferIdReservaEstoque,
        r_bufferIdReservaEstoque);
    END IF;
    IF a.idColoranteTintaJ > 0
      AND a.quantidadeJ > 0
      AND a.gradeProdutoJ > 0
    THEN
       ADD_RESERVA_ESTOQUE_PROD_TINTA (
        p_sys_estabelecimentoAtivo,
        p_config_354_estabProximoId,
        p_cab_entradaSaida,
        p_cab_estabelecimento,
        p_dataEntrega,
        p_item_modeloDocumento,
        p_item_localEstoque,
        p_item_pessoaParticipante,
        p_item_quantidadeSaldo,
        p_item_observacoes,
        a.gradeProdutoJ, -- p_tinta_gradeProduto
        a.quantidadeJ, -- p_tinta_quantidade
        p_idItemOrcamento,
        p_idFichaProdutoPrevOrcamento,
        p_idItemDocTransferencia,
        p_locEst_indicProprPosseItem,
        r_bufferIdReservaEstoque,
        r_bufferIdReservaEstoque);
    END IF;
    IF a.idColoranteTintaK > 0
      AND a.quantidadeK > 0
      AND a.gradeProdutoK > 0
    THEN
       ADD_RESERVA_ESTOQUE_PROD_TINTA (
        p_sys_estabelecimentoAtivo,
        p_config_354_estabProximoId,
        p_cab_entradaSaida,
        p_cab_estabelecimento,
        p_dataEntrega,
        p_item_modeloDocumento,
        p_item_localEstoque,
        p_item_pessoaParticipante,
        p_item_quantidadeSaldo,
        p_item_observacoes,
        a.gradeProdutoK, -- p_tinta_gradeProduto
        a.quantidadeK, -- p_tinta_quantidade
        p_idItemOrcamento,
        p_idFichaProdutoPrevOrcamento,
        p_idItemDocTransferencia,
        p_locEst_indicProprPosseItem,
        r_bufferIdReservaEstoque,
        r_bufferIdReservaEstoque);
    END IF;
    IF a.idColoranteTintaL > 0
      AND a.quantidadeL > 0
      AND a.gradeProdutoL > 0
    THEN
       ADD_RESERVA_ESTOQUE_PROD_TINTA (
        p_sys_estabelecimentoAtivo,
        p_config_354_estabProximoId,
        p_cab_entradaSaida,
        p_cab_estabelecimento,
        p_dataEntrega,
        p_item_modeloDocumento,
        p_item_localEstoque,
        p_item_pessoaParticipante,
        p_item_quantidadeSaldo,
        p_item_observacoes,
        a.gradeProdutoL, -- p_tinta_gradeProduto
        a.quantidadeL, -- p_tinta_quantidade
        p_idItemOrcamento,
        p_idFichaProdutoPrevOrcamento,
        p_idItemDocTransferencia,
        p_locEst_indicProprPosseItem,
        r_bufferIdReservaEstoque,
        r_bufferIdReservaEstoque);
    END IF;
    IF a.idColoranteTintaM > 0
      AND a.quantidadeM > 0
      AND a.gradeProdutoM > 0
    THEN
       ADD_RESERVA_ESTOQUE_PROD_TINTA (
        p_sys_estabelecimentoAtivo,
        p_config_354_estabProximoId,
        p_cab_entradaSaida,
        p_cab_estabelecimento,
        p_dataEntrega,
        p_item_modeloDocumento,
        p_item_localEstoque,
        p_item_pessoaParticipante,
        p_item_quantidadeSaldo,
        p_item_observacoes,
        a.gradeProdutoM, -- p_tinta_gradeProduto
        a.quantidadeM, -- p_tinta_quantidade
        p_idItemOrcamento,
        p_idFichaProdutoPrevOrcamento,
        p_idItemDocTransferencia,
        p_locEst_indicProprPosseItem,
        r_bufferIdReservaEstoque,
        r_bufferIdReservaEstoque);
    END IF;
    IF a.idColoranteTintaN > 0
      AND a.quantidadeN > 0
      AND a.gradeProdutoN > 0
    THEN
       ADD_RESERVA_ESTOQUE_PROD_TINTA (
        p_sys_estabelecimentoAtivo,
        p_config_354_estabProximoId,
        p_cab_entradaSaida,
        p_cab_estabelecimento,
        p_dataEntrega,
        p_item_modeloDocumento,
        p_item_localEstoque,
        p_item_pessoaParticipante,
        p_item_quantidadeSaldo,
        p_item_observacoes,
        a.gradeProdutoN, -- p_tinta_gradeProduto
        a.quantidadeN, -- p_tinta_quantidade
        p_idItemOrcamento,
        p_idFichaProdutoPrevOrcamento,
        p_idItemDocTransferencia,
        p_locEst_indicProprPosseItem,
        r_bufferIdReservaEstoque,
        r_bufferIdReservaEstoque);
    END IF;
    IF a.idColoranteTintaO > 0
      AND a.quantidadeO > 0
      AND a.gradeProdutoO > 0
    THEN
       ADD_RESERVA_ESTOQUE_PROD_TINTA (
        p_sys_estabelecimentoAtivo,
        p_config_354_estabProximoId,
        p_cab_entradaSaida,
        p_cab_estabelecimento,
        p_dataEntrega,
        p_item_modeloDocumento,
        p_item_localEstoque,
        p_item_pessoaParticipante,
        p_item_quantidadeSaldo,
        p_item_observacoes,
        a.gradeProdutoO, -- p_tinta_gradeProduto
        a.quantidadeO, -- p_tinta_quantidade
        p_idItemOrcamento,
        p_idFichaProdutoPrevOrcamento,
        p_idItemDocTransferencia,
        p_locEst_indicProprPosseItem,
        r_bufferIdReservaEstoque,
        r_bufferIdReservaEstoque);
    END IF;
  END LOOP;
END ADD_RESERVA_ESTOQUE_FORM_TINTA;

/

create or replace PROCEDURE ADD_RESERVA_ESTOQUE_ORC_FIC_PR (
  p_sys_estabelecimentoAtivo     IN NUMBER,
  p_config_354_estabProximoId    IN NUMBER,
  p_cab_estabelecimento          IN NUMBER,
  p_cab_dataEmissao              IN DATE,
  p_cab_dataEntrega              IN DATE,
  p_item_modeloDocumento         IN NUMBER,
  p_ativ_dataInicio              IN DATE,
  p_ativ_dataTermino             IN DATE,
  p_fich_idFichaProdutoPrevOrcam IN NUMBER,
  p_fich_entradaSaida            IN CHAR,
  p_fich_localEstoque            IN NUMBER,
  p_fich_gradeProduto            IN NUMBER,
  p_fich_personalizacao          IN NUMBER,
  p_fich_idLoteEstoque           IN NUMBER,
  p_fich_quantidadeSaldo         IN NUMBER,
  p_fich_observacoes             IN VARCHAR2,
  p_locEst_indicProprPosseItem   IN CHAR,
  p_gradProd_produto             IN NUMBER,
  p_prod_controleEstoque         IN CHAR,
  p_bufferIdReservaEstoque       IN VARCHAR2,
  r_bufferIdReservaEstoque       OUT VARCHAR2)
IS
  v_auxNumber NUMBER;
BEGIN
  r_bufferIdReservaEstoque := p_bufferIdReservaEstoque;
  ADD_RESERVA_ESTOQUE_FIC_EXCLUI (
    p_fich_idFichaProdutoPrevOrcam,
    r_bufferIdReservaEstoque,
    r_bufferIdReservaEstoque);
  IF p_fich_quantidadeSaldo > 0 THEN
    IF p_prod_controleEstoque IN (3,4) THEN
      ADD_RESERVA_ESTOQUE_KIT (
        p_sys_estabelecimentoAtivo,
        p_config_354_estabProximoId,
        p_fich_entradaSaida,
        p_cab_estabelecimento,
        CASE
          WHEN p_fich_entradaSaida = 'E'
            AND p_ativ_dataTermino IS NOT NULL
            AND (p_ativ_dataInicio IS NULL
              OR p_ativ_dataTermino >= p_ativ_dataInicio)
          THEN p_ativ_dataTermino
          WHEN p_ativ_dataInicio IS NOT NULL
          THEN p_ativ_dataInicio
          WHEN p_cab_dataEntrega IS NOT NULL
            AND p_cab_dataEntrega >= p_cab_dataEmissao
          THEN p_cab_dataEntrega
          ELSE p_cab_dataEmissao
        END, -- p_dataEntrega
        p_item_modeloDocumento,
        p_fich_gradeProduto,
        p_fich_localEstoque,
        0, -- p_item_pessoaParticipante,
        p_fich_quantidadeSaldo,
        p_fich_observacoes,
        0, -- p_idItemOrcamento,
        p_fich_idFichaProdutoPrevOrcam,
        0, -- p_idItemDocTransferencia
        p_locEst_indicProprPosseItem,
        r_bufferIdReservaEstoque, 
        r_bufferIdReservaEstoque);
    ELSIF p_prod_controleEstoque IN (1,5,6,11,12) THEN
      ADD_RESERVA_ESTOQUE_GRAVA (
        p_sys_estabelecimentoAtivo, 
        p_config_354_estabProximoId,
        0, -- p_idReservaEstoque
        p_cab_estabelecimento,
        CASE
          WHEN p_fich_entradaSaida = 'E'
            AND p_ativ_dataTermino IS NOT NULL
            AND (p_ativ_dataInicio IS NULL
              OR p_ativ_dataTermino >= p_ativ_dataInicio)
          THEN p_ativ_dataTermino
          WHEN p_ativ_dataInicio IS NOT NULL
          THEN p_ativ_dataInicio
          WHEN p_cab_dataEntrega IS NOT NULL
            AND p_cab_dataEntrega >= p_cab_dataEmissao
          THEN p_cab_dataEntrega
          ELSE p_cab_dataEmissao
        END, -- p_dataEntrega
        p_gradProd_produto,
        p_fich_gradeProduto,
        p_item_modeloDocumento,
        p_fich_entradaSaida,
        p_locEst_indicProprPosseItem,
        0, -- p_item_pessoaParticipante,
        p_fich_localEstoque,
        p_fich_personalizacao,
        p_fich_idLoteEstoque,
        0, -- p_idNumeroSerie
        p_fich_quantidadeSaldo,
        p_fich_observacoes,
        0, -- p_idItemOrcamento,
        p_fich_idFichaProdutoPrevOrcam,
        0, -- p_idItemDocTransferencia
        r_bufferIdReservaEstoque, 
        v_auxNumber,
        r_bufferIdReservaEstoque);
    END IF;
  END IF;
END ADD_RESERVA_ESTOQUE_ORC_FIC_PR;

/

create or replace PROCEDURE ADD_RESERVA_ESTOQUE_ORC_FICHA (
  p_sys_estabelecimentoAtivo     IN NUMBER,
  p_config_354_estabProximoId    IN NUMBER,
  p_cab_estabelecimento          IN NUMBER,
  p_cab_dataEmissao              IN DATE,
  p_cab_dataEntrega              IN DATE,
  p_item_modeloDocumento         IN NUMBER,
  p_ativ_idAtividadePrevOrcament IN NUMBER,
  p_ativ_dataInicio              IN DATE,
  p_ativ_dataTermino             IN DATE,
  p_bufferIdReservaEstoque       IN VARCHAR2,
  r_bufferIdReservaEstoque       OUT VARCHAR2)
IS
  v_auxNumber NUMBER;
BEGIN
  r_bufferIdReservaEstoque := p_bufferIdReservaEstoque;
  FOR a IN (
    SELECT
      a.idFichaProdutoPrevOrcamento,
      a.entradaSaida,
      a.localEstoque,
      a.gradeProduto,
      a.personalizacao,
      a.idLoteEstoque,
      a.quantidadeSaldo,
      a.observacoes,
      locEst.indicadorPropriedadePosseItem,
      gradProd.produto,
      prod.controleEstoque
    FROM MOORCAMENTOXFICHAPRODPREV a
    JOIN PALOCAISESTOQUE locEst
    ON locEst.localEstoque = a.localEstoque
    JOIN CAGRADESPRODUTO gradProd
    ON gradProd.gradeProduto = a.gradeProduto
    JOIN CAPRODUTOS prod
    ON prod.produto = gradProd.produto
    WHERE a.idAtividadePrevOrcamento = p_ativ_idAtividadePrevOrcament
    AND a.quantidadeSaldo > 0
    ORDER BY a.ordenacao)
  LOOP
    ADD_RESERVA_ESTOQUE_ORC_FIC_PR (
      p_sys_estabelecimentoAtivo,
      p_config_354_estabProximoId,
      p_cab_estabelecimento,
      p_cab_dataEmissao,
      p_cab_dataEntrega,
      p_item_modeloDocumento,
      p_ativ_dataInicio,
      p_ativ_dataTermino,
      a.idFichaProdutoPrevOrcamento,
      a.entradaSaida,
      a.localEstoque,
      a.gradeProduto,
      a.personalizacao,
      a.idLoteEstoque,
      a.quantidadeSaldo,
      a.observacoes,
      a.indicadorPropriedadePosseItem,
      a.produto,
      a.controleEstoque,
      r_bufferIdReservaEstoque,
      r_bufferIdReservaEstoque);
  END LOOP;
END ADD_RESERVA_ESTOQUE_ORC_FICHA;

/

create or replace PROCEDURE ADD_RESERVA_ESTOQUE_ORC_ATIV (
  p_sys_estabelecimentoAtivo  IN NUMBER,
  p_config_354_estabProximoId IN NUMBER,
  p_cab_estabelecimento       IN NUMBER,
  p_cab_dataEmissao           IN DATE,
  p_cab_dataEntrega           IN DATE,
  p_item_idItemOrcamento      IN NUMBER,
  p_item_modeloDocumento      IN NUMBER,
  p_bufferIdReservaEstoque    IN VARCHAR2,
  r_bufferIdReservaEstoque    OUT VARCHAR2)
IS
BEGIN
  r_bufferIdReservaEstoque := p_bufferIdReservaEstoque;
  FOR a IN (
    SELECT
      idAtividadePrevOrcamento,
      dataInicio,
      dataTermino
    FROM MOORCAMENTOXATIVIDADEPREV
    WHERE idItemOrcamento = p_item_idItemOrcamento
    AND statusAtividadeServico IN ('A', 'I', 'P')
    ORDER BY sequencia)
  LOOP
    ADD_RESERVA_ESTOQUE_ORC_FICHA (
      p_sys_estabelecimentoAtivo,
      p_config_354_estabProximoId,
      p_cab_estabelecimento,
      p_cab_dataEmissao,
      p_cab_dataEntrega,
      p_item_modeloDocumento,
      a.idAtividadePrevOrcamento,
      a.dataInicio,
      a.dataTermino,
      r_bufferIdReservaEstoque,
      r_bufferIdReservaEstoque);
  END LOOP;
END ADD_RESERVA_ESTOQUE_ORC_ATIV;

/

create or replace PROCEDURE ADD_RESERVA_ESTOQUE_ORC_ITEM (
  p_sys_estabelecimentoAtivo     IN NUMBER,
  p_config_209_filtrarGrupoEcon  IN NUMBER,
  p_config_354_estabProximoId    IN NUMBER,
  p_config_362_calcCustoPorGrade IN NUMBER,
  p_item_idItemOrcamento         IN NUMBER,
  p_bufferIdReservaEstoque       IN VARCHAR2,
  p_bufferIdEstoque              IN VARCHAR2,
  r_bufferIdReservaEstoque       OUT VARCHAR2,
  r_bufferIdEstoque              OUT VARCHAR2)
IS
  v_quantidadeNumerosSerie NUMBER;
  v_auxNumber              NUMBER;
BEGIN
  r_bufferIdReservaEstoque := p_bufferIdReservaEstoque;
  r_bufferIdEstoque := p_bufferIdEstoque;
  ADD_RESERVA_ESTOQUE_ORC_EXCLUI (
    p_item_idItemOrcamento,
    r_bufferIdReservaEstoque,
    r_bufferIdReservaEstoque);
  ADD_ESTOQUE_ORCAMENTO_EXCLUI (
    p_item_idItemOrcamento,
    r_bufferIdEstoque,
    r_bufferIdEstoque);
  FOR a IN (
    SELECT
      cabOrc.tipoDocumento,
      cabOrc.entradaSaida,
      CASE
        WHEN itemOrc.controleEntrega > 0
          AND contrEntr.estabelecimentoRemessa > 0
        THEN contrEntr.estabelecimentoRemessa
        WHEN prod.estabelecimentoFaturamento > 0
        THEN prod.estabelecimentoFaturamento
        WHEN itemOrc.controleEntrega > 0
          AND contrEntr.estabelecimentoSaida > 0
        THEN contrEntr.estabelecimentoSaida
        ELSE cabOrc.estabelecimento
      END estabelecimento,
      cabOrc.dataEmissao,
      itemOrc.dataEntrega,
      itemOrc.idItemOrcamento,
      itemOrc.modeloDocumento,
      itemOrc.gradeProduto,
      itemOrc.personalizacao,
      itemOrc.idFormulaTinta,
      itemOrc.idLoteEstoque,
      CASE
        WHEN itemOrc.controleEntrega > 0
          AND contrEntr.localEstoqueSaida > 0
        THEN contrEntr.localEstoqueSaida
        ELSE itemOrc.localEstoque
      END localEstoque,
      itemOrc.pessoaParticipante,
      itemOrc.quantidadeSaldo,
      itemOrc.observacoes,
      gradProd.produto,
      prod.controlaNumeroSerie,
      prod.controleEstoque,
      locEst.indicadorPropriedadePosseItem
    FROM MOORCAMENTOXITENS itemOrc
    JOIN CAGRADESPRODUTO gradProd
    ON gradProd.gradeProduto = itemOrc.gradeProduto
    JOIN CAPRODUTOS prod
    ON prod.produto = gradProd.produto
    JOIN PACONTROLESENTREGA contrEntr
    ON contrEntr.controleEntrega = itemOrc.controleEntrega
    JOIN MOORCAMENTOS cabOrc
    ON cabOrc.orcamento = itemOrc.orcamento
    JOIN PAETAPASORCAMENTO etapOrc
    ON etapOrc.etapaOrcamento = cabOrc.etapaOrcamento
    JOIN PALOCAISESTOQUE locEst
    ON locEst.localEstoque =
      CASE
        WHEN itemOrc.controleEntrega > 0
          AND contrEntr.localEstoqueSaida > 0
        THEN contrEntr.localEstoqueSaida
        ELSE itemOrc.localEstoque
      END 
   WHERE itemOrc.idItemOrcamento = p_item_idItemOrcamento
    AND itemOrc.cancelado = 0
    AND itemOrc.movimentaEstoque = 1
    AND (cabOrc.tipoDocumento = 202
      OR itemOrc.quantidadeSaldo > 0)
    AND etapOrc.situacaoOrcamento BETWEEN 41 AND 89
    UNION ALL
    SELECT
      cabOrc.tipoDocumento,
      cabOrc.entradaSaida,
      CASE
        WHEN contrEntr.estabelecimentoRemessa > 0
        THEN contrEntr.estabelecimentoRemessa
        ELSE doc.estabelecimento
      END estabelecimento,
      doc.dataEmissao,
      itemOrc.dataEntrega,
      itemOrc.idItemOrcamento,
      itemOrc.modeloDocumento,
      itemDoc.gradeProduto,
      itemDoc.personalizacao,
      itemDoc.idFormulaTinta,
      itemDoc.idLoteEstoque,
      itemDoc.localEstoque,
      itemDoc.pessoaParticipante,
      ( itemDoc.quantidade
        - itemDoc.quantidadeDevolvidaRetornada
        - COALESCE ((
            SELECT SUM (entr.quantidade *
              CASE
                WHEN itemDoc.quantidadeConvertida = 0
                THEN 1
                ELSE itemDoc.quantidade / itemDoc.quantidadeConvertida
              END)
            FROM MOENTREGAS entr
            WHERE entr.idItemOrcamento = itemOrc.idItemOrcamento
            AND entr.situacaoEntrega IN (5,6)),0)) quantidadeSaldo,
      itemDoc.observacoes,
      gradProd.produto,
      prod.controlaNumeroSerie,
      prod.controleEstoque,
      locEst.indicadorPropriedadePosseItem
    FROM MOORCAMENTOXITENS itemOrc
    JOIN MOPREDOCUMXORCAMENTOITEM docXOrc
    ON docXOrc.idItemOrcamento = itemOrc.idItemOrcamento
    JOIN MOPREDOCUMXITENS itemDoc
    ON itemDoc.idItemPreDocumento = docXOrc.idItemPreDocumento
    JOIN MOPREDOCUMENTOS doc
    ON doc.preDocumento = itemDoc.preDocumento
    JOIN CAGRADESPRODUTO gradProd
    ON gradProd.gradeProduto = itemDoc.gradeProduto
    JOIN CAPRODUTOS prod
    ON prod.produto = gradProd.produto
    JOIN PACONTROLESENTREGA contrEntr
    ON contrEntr.controleEntrega = itemOrc.controleEntrega
    JOIN MOORCAMENTOS cabOrc
    ON cabOrc.orcamento = itemOrc.orcamento
    JOIN PAETAPASORCAMENTO etapOrc
    ON etapOrc.etapaOrcamento = cabOrc.etapaOrcamento
    JOIN PALOCAISESTOQUE locEst
    ON locEst.localEstoque = itemDoc.localEstoque 
    WHERE itemOrc.idItemOrcamento = p_item_idItemOrcamento
    AND itemOrc.cancelado = 0
    AND itemOrc.movimentaEstoque = 1
    AND itemOrc.quantidadeSaldo = 0
    AND itemOrc.controleEntrega > 0
    AND cabOrc.tipoDocumento <> 202
    AND etapOrc.situacaoOrcamento BETWEEN 64 AND 89
    AND contrEntr.reservaEstoque = 1
    AND docXOrc.quantidade > 0
    AND itemDoc.cancelado = 0
    AND itemDoc.movimentaEstoque = 0
    AND doc.entradaSaida = 'S'
    AND doc.devolucaoAnulacaoRetorno = 0
    AND doc.statusPreDocumento <> 'C'
    AND ( itemDoc.quantidade
      - itemDoc.quantidadeDevolvidaRetornada
      - COALESCE ((
          SELECT SUM (entr.quantidade *
            CASE
              WHEN itemDoc.quantidadeConvertida = 0
              THEN 1
              ELSE itemDoc.quantidade / itemDoc.quantidadeConvertida
            END)
          FROM MOENTREGAS entr
          WHERE entr.idItemOrcamento = itemOrc.idItemOrcamento
          AND entr.situacaoEntrega IN (5,6)),0)) > 0
    UNION ALL
    SELECT
      cabOrc.tipoDocumento,
      cabOrc.entradaSaida,
      CASE
        WHEN contrEntr.estabelecimentoRemessa > 0
        THEN contrEntr.estabelecimentoRemessa
        ELSE doc.estabelecimento
      END estabelecimento,
      doc.dataEmissao,
      doc.dataEntradaSaida dataEntrega,
      itemOrc.idItemOrcamento,
      itemOrc.modeloDocumento,
      itemDoc.gradeProduto,
      itemDoc.personalizacao,
      itemDoc.idFormulaTinta,
      itemDoc.idLoteEstoque,
      itemDoc.localEstoque,
      itemDoc.pessoaParticipante,
      ( itemDoc.quantidade
        - itemDoc.quantidadeDevolvidaRetornada
        - COALESCE ((
            SELECT SUM (entr.quantidade *
              CASE
                WHEN itemDoc.quantidadeConvertida = 0
                THEN 1
                ELSE itemDoc.quantidade / itemDoc.quantidadeConvertida
              END)
            FROM MOENTREGAS entr
            WHERE entr.idItemOrcamento = itemOrc.idItemOrcamento
            AND entr.situacaoEntrega IN (5,6)),0)) quantidadeSaldo,
      itemDoc.observacoes,
      gradProd.produto,
      prod.controlaNumeroSerie,
      prod.controleEstoque,
      locEst.indicadorPropriedadePosseItem
    FROM MOORCAMENTOXITENS itemOrc
    JOIN MODOCFISCALXORCAMENTOITEM docXOrc
    ON docXOrc.idItemOrcamento = itemOrc.idItemOrcamento
    JOIN MODOCFISCALXITENS itemDoc
    ON itemDoc.idItemDocFiscal = docXOrc.idItemDocFiscal
    JOIN MODOCUMENTOSFISCAIS doc
    ON doc.idDocumentoFiscal = itemDoc.idDocumentoFiscal
    JOIN CAGRADESPRODUTO gradProd
    ON gradProd.gradeProduto = itemDoc.gradeProduto
    JOIN CAPRODUTOS prod
    ON prod.produto = gradProd.produto
    JOIN PACONTROLESENTREGA contrEntr
    ON contrEntr.controleEntrega = itemOrc.controleEntrega
    JOIN MOORCAMENTOS cabOrc
    ON cabOrc.orcamento = itemOrc.orcamento
    JOIN PAETAPASORCAMENTO etapOrc
    ON etapOrc.etapaOrcamento = cabOrc.etapaOrcamento
    JOIN PALOCAISESTOQUE locEst
    ON locEst.localEstoque = itemDoc.localEstoque 
    WHERE itemOrc.idItemOrcamento = p_item_idItemOrcamento
    AND itemOrc.cancelado = 0
    AND itemOrc.movimentaEstoque = 1
    AND itemOrc.quantidadeSaldo = 0
    AND itemOrc.controleEntrega > 0
    AND cabOrc.tipoDocumento <> 202
    AND etapOrc.situacaoOrcamento BETWEEN 64 AND 89
    AND contrEntr.reservaEstoque = 1
    AND docXOrc.quantidade > 0
    AND itemDoc.cancelado = 0
    AND itemDoc.movimentaEstoque = 0
    AND doc.entradaSaida = 'S'
    AND doc.devolucaoAnulacaoRetorno = 0
    AND doc.situacaoDocumentoFiscal <= 23
    AND ( itemDoc.quantidade
      - itemDoc.quantidadeDevolvidaRetornada
      - COALESCE ((
          SELECT SUM (entr.quantidade *
            CASE
              WHEN itemDoc.quantidadeConvertida = 0
              THEN 1
              ELSE itemDoc.quantidade / itemDoc.quantidadeConvertida
            END)
          FROM MOENTREGAS entr
          WHERE entr.idItemOrcamento = itemOrc.idItemOrcamento
          AND entr.situacaoEntrega IN (5,6)),0)) > 0)
  LOOP
    IF a.tipoDocumento = 202 THEN
      ADD_RESERVA_ESTOQUE_ORC_ATIV (
        p_sys_estabelecimentoAtivo,
        p_config_354_estabProximoId,
        a.estabelecimento,
        a.dataEmissao,
        a.dataEntrega,
        a.idItemOrcamento,
        a.modeloDocumento,
        r_bufferIdReservaEstoque,
        r_bufferIdReservaEstoque);
      ADD_ESTOQUE_ORCAMENTO_AT_PREV (
        p_sys_estabelecimentoAtivo,
        p_config_209_filtrarGrupoEcon,
        p_config_354_estabProximoId,
        p_config_362_calcCustoPorGrade,
        a.estabelecimento,
        a.idItemOrcamento,
        r_bufferIdEstoque,
        r_bufferIdEstoque);
    ELSE
      IF a.controleEstoque = 12 AND a.idFormulaTinta > 0 THEN
        ADD_RESERVA_ESTOQUE_FORM_TINTA (
          p_sys_estabelecimentoAtivo, 
          p_config_354_estabProximoId,
          a.entradaSaida,
          a.estabelecimento,
          CASE WHEN a.dataEntrega IS NULL OR a.dataEntrega < a.dataEmissao THEN a.dataEmissao ELSE a.dataEntrega END, -- p_dataEntrega
          a.modeloDocumento,
          a.idFormulaTinta,
          a.localEstoque,
          a.pessoaParticipante,
          a.quantidadeSaldo,
          a.observacoes,
          a.idItemOrcamento,
          0, -- p_idFichaProdutoPrevOrcamento
          0, -- p_idItemDocTransferencia
          a.indicadorPropriedadePosseItem,
          r_bufferIdReservaEstoque, 
          r_bufferIdReservaEstoque);
      ELSIF a.controleEstoque IN (3,4) THEN
        ADD_RESERVA_ESTOQUE_KIT (
          p_sys_estabelecimentoAtivo,
          p_config_354_estabProximoId,
          a.entradaSaida,
          a.estabelecimento,
          CASE WHEN a.dataEntrega IS NULL OR a.dataEntrega < a.dataEmissao THEN a.dataEmissao ELSE a.dataEntrega END, -- p_dataEntrega
          a.modeloDocumento,
          a.gradeProduto,
          a.localEstoque,
          a.pessoaParticipante,
          a.quantidadeSaldo,
          a.observacoes,
          a.idItemOrcamento,
          0, -- p_idFichaProdutoPrevOrcamento
          0, -- p_idItemDocTransferencia
          a.indicadorPropriedadePosseItem,
          r_bufferIdReservaEstoque,
          r_bufferIdReservaEstoque);
      ELSIF a.controleEstoque IN (1,5,6,11,12) THEN
        v_quantidadeNumerosSerie := 0;
        IF a.controlaNumeroSerie > 0 THEN
          ADD_RESERVA_ESTOQUE_ORC_N_SER (
            p_sys_estabelecimentoAtivo,
            p_config_354_estabProximoId,
            a.entradaSaida,
            a.estabelecimento,
            CASE WHEN a.dataEntrega IS NULL OR a.dataEntrega < a.dataEmissao THEN a.dataEmissao ELSE a.dataEntrega END, -- p_dataEntrega
            a.idItemOrcamento,
            a.modeloDocumento,
            a.gradeProduto,
            a.personalizacao,
            a.idLoteEstoque,
            a.localEstoque,
            a.pessoaParticipante,
            a.observacoes,
            a.produto,
            a.indicadorPropriedadePosseItem,
            r_bufferIdReservaEstoque, 
            r_bufferIdReservaEstoque,
            v_quantidadeNumerosSerie);
        END IF;
        IF a.quantidadeSaldo > v_quantidadeNumerosSerie THEN
          ADD_RESERVA_ESTOQUE_GRAVA (
            p_sys_estabelecimentoAtivo,
            p_config_354_estabProximoId,
            0, --p_idReservaEstoque
            a.estabelecimento,
            CASE WHEN a.dataEntrega IS NULL OR a.dataEntrega < a.dataEmissao THEN a.dataEmissao ELSE a.dataEntrega END, -- p_dataEntrega
            a.produto,
            a.gradeProduto,
            a.modeloDocumento,
            a.entradaSaida,
            a.indicadorPropriedadePosseItem,
            a.pessoaParticipante,
            a.localEstoque,
            a.personalizacao,
            a.idLoteEstoque,
            0, -- p_idNumeroSerie
            a.quantidadeSaldo - v_quantidadeNumerosSerie, -- p_quantidadeSaldo
            a.observacoes,
            a.idItemOrcamento,
            0, -- p_idFichaProdutoPrevOrcamento
            0, -- p_idItemDocTransferencia
            r_bufferIdReservaEstoque,
            v_auxNumber,
            r_bufferIdReservaEstoque);
        END IF;
      END IF;
      FOR b IN (
        SELECT
          comp.gradeProdutoEstoque gradeProduto,
          gradProd.produto,
          b.observacoes,
          prod.controleEstoque,
          ROUND (a.quantidadeSaldo * b.quantidade, uniMed.casasDecimaisUnidadeMedida) quantidadeSaldo
        FROM MOORCAMENTOXCOMPOSICOESPR b
        JOIN CAPRODUTOXCOMPOSICOESPREC comp
        ON comp.composicaoPreco = b.composicaoPreco
        JOIN CAGRADESPRODUTO gradProd
        ON gradProd.gradeProduto = comp.gradeProdutoEstoque
        JOIN CAPRODUTOS prod
        ON prod.produto = gradProd.produto
        JOIN SIUNIDADESMEDIDA uniMed
        ON uniMed.unidadeMedida = prod.unidadeMedida
        WHERE b.idItemOrcamento = a.idItemOrcamento
        AND b.selecionado = 1
        AND comp.gradeProdutoEstoque > 0
        AND ROUND (a.quantidadeSaldo * b.quantidade, uniMed.casasDecimaisUnidadeMedida) > 0)
      LOOP
        IF b.controleEstoque IN (3,4) THEN
          ADD_RESERVA_ESTOQUE_KIT (
            p_sys_estabelecimentoAtivo,
            p_config_354_estabProximoId,
            a.entradaSaida,
            a.estabelecimento,
            CASE WHEN a.dataEntrega IS NULL OR a.dataEntrega < a.dataEmissao THEN a.dataEmissao ELSE a.dataEntrega END, -- a.dataEntrega
            a.modeloDocumento,
            b.gradeProduto,
            a.localEstoque,
            a.pessoaParticipante,
            b.quantidadeSaldo,
            b.observacoes,
            a.idItemOrcamento,
            0, -- p_idFichaProdutoPrevOrcamento
            0, -- p_idItemDocTransferencia
            a.indicadorPropriedadePosseItem,
            r_bufferIdReservaEstoque,
            r_bufferIdReservaEstoque);
        ELSIF b.controleEstoque IN (1,5,6,11,12) THEN
          ADD_RESERVA_ESTOQUE_GRAVA (
            p_sys_estabelecimentoAtivo,
            p_config_354_estabProximoId,
            0, -- p_idReservaEstoque
            a.estabelecimento,
            CASE WHEN a.dataEntrega IS NULL OR a.dataEntrega < a.dataEmissao THEN a.dataEmissao ELSE a.dataEntrega END, -- a.dataEntrega
            b.produto,
            b.gradeProduto,
            a.modeloDocumento,
            a.entradaSaida,
            a.indicadorPropriedadePosseItem,
            a.pessoaParticipante,
            a.localEstoque,
            0, -- p_personalizacao,
            0, -- p_idLoteEstoque,
            0, -- p_idNumeroSerie
            b.quantidadeSaldo,
            b.observacoes,
            a.idItemOrcamento,
            0, -- p_idFichaProdutoPrevOrcamento
            0, -- p_idItemDocTransferencia
            r_bufferIdReservaEstoque, 
            v_auxNumber,
            r_bufferIdReservaEstoque);
        END IF;
      END LOOP; 
    END IF;
  END LOOP;
END ADD_RESERVA_ESTOQUE_ORC_ITEM;

/

create or replace PROCEDURE ADD_RESERVA_ESTOQUE_ORC_CAB (
  p_sys_estabelecimentoAtivo     IN NUMBER,
  p_config_209_filtrarGrupoEcon  IN NUMBER,
  p_config_354_estabProximoId    IN NUMBER,
  p_config_362_calcCustoPorGrade IN NUMBER,
  p_orcamento                    IN NUMBER)
IS
  v_bufferIdReservaEstoque VARCHAR2 (32000);
  v_bufferIdEstoque VARCHAR2 (32000);
BEGIN
  v_bufferIdReservaEstoque := '';
  v_bufferIdEstoque := '';
  FOR a IN (
    SELECT idItemOrcamento
    FROM MOORCAMENTOXITENS
    WHERE orcamento = p_orcamento
    ORDER BY sequencia)
  LOOP
    ADD_RESERVA_ESTOQUE_ORC_ITEM (
      p_sys_estabelecimentoAtivo, 
      p_config_209_filtrarGrupoEcon,
      p_config_354_estabProximoId,
      p_config_362_calcCustoPorGrade,
      a.idItemOrcamento,
      v_bufferIdReservaEstoque,
      v_bufferIdEstoque,
      v_bufferIdReservaEstoque,
      v_bufferIdEstoque);
  END LOOP;
END ADD_RESERVA_ESTOQUE_ORC_CAB;

/

create or replace PROCEDURE ADD_RESERVA_ESTOQUE_TRA_ITEM (
  p_sys_estabelecimentoAtivo  IN NUMBER,
  p_config_354_estabProximoId IN NUMBER,
  p_idItemDocTransferencia    IN NUMBER,
  /* Retornos */
  p_bufferIdReservaEstoque    IN VARCHAR2,
  r_bufferIdReservaEstoque    OUT VARCHAR2)
IS
  v_quantidadeNumerosSerie NUMBER;
  v_auxNumber              NUMBER;  
BEGIN
  r_bufferIdReservaEstoque := p_bufferIdReservaEstoque;
  ADD_RESERVA_ESTOQUE_TRA_EXCLUI (
    p_idItemDocTransferencia,
    r_bufferIdReservaEstoque,
    r_bufferIdReservaEstoque);
  FOR a IN (
    SELECT 
      cab.modeloDocumento,
      cab.estabelecimentoSaida,
      cab.estabelecimentoEntrada,
      cab.dataEmissao,
      cab.tipoDocumentoSaida,
      cab.tipoDocumentoEntrada,
      cab.situacaoDocTransferencia,
      modDoc.movimentaEstoque,
      item.idItemDocTransferencia,
      item.cancelado,
      item.validoSaida,
      item.validoEntrada,
      item.gradeProduto,
      item.idFormulaTinta,
      item.personalizacao,
      item.idLoteEstoque,
      item.localEstoqueSaida,
      item.pessoaParticipanteSaida,
      item.localEstoqueEntrada,
      item.pessoaParticipanteEntrada,
      item.quantidadeSaldo,
      item.observacoes,
      gradProd.produto,
      prod.controleEstoque,
      prod.controlaNumeroSerie,
      locEstSaida.indicadorPropriedadePosseItem locEstSaida_indicProprPosseI,
      locEstEntrada.indicadorPropriedadePosseItem locEstEntr_indicProprPosseI
    FROM MODOCUMENTOTRANSFXITENS item
    JOIN MODOCUMENTOSTRANSFERENCIA cab
    ON cab.documentoTransferencia = item.documentoTransferencia
    JOIN PAMODELOSDOCUMENTO modDoc
    ON modDoc.modeloDocumento = cab.modeloDocumento
    JOIN CAGRADESPRODUTO gradProd
    ON gradProd.gradeProduto = item.gradeProduto
    JOIN CAPRODUTOS prod
    ON prod.produto = gradProd.produto
    JOIN PALOCAISESTOQUE locEstSaida
    ON locEstSaida.localEstoque = item.localEstoqueSaida
    JOIN PALOCAISESTOQUE locEstEntrada
    ON locEstEntrada.localEstoque = item.localEstoqueEntrada
    WHERE item.idItemDocTransferencia = p_idItemDocTransferencia
    AND item.cancelado = 0
    AND item.quantidadeSaldo <> 0
    AND cab.situacaoDocTransferencia = 'A'
    AND modDoc.movimentaEstoque = 1)
  LOOP
    IF a.tipoDocumentoSaida > 100
      AND a.validoSaida = 1
    THEN 
      IF a.controleEstoque = 12 AND a.idFormulaTinta > 0 THEN
        ADD_RESERVA_ESTOQUE_FORM_TINTA (
          p_sys_estabelecimentoAtivo,
          p_config_354_estabProximoId,
          'S', -- p_cab_entradaSaida,
          a.estabelecimentoSaida,
          a.dataEmissao, -- p_dataEntrega
          a.modeloDocumento,
          a.idFormulaTinta,
          a.localEstoqueSaida,
          a.pessoaParticipanteSaida,
          a.quantidadeSaldo,
          a.observacoes,
          0, -- p_item_idItemOrcamento
          0, -- p_item_idFichaProdutoPrevOrcam
          p_idItemDocTransferencia,
          a.locEstSaida_indicProprPosseI,
          r_bufferIdReservaEstoque,
          r_bufferIdReservaEstoque);
      ELSIF a.controleEstoque IN (3,4) THEN
        ADD_RESERVA_ESTOQUE_KIT (
          p_sys_estabelecimentoAtivo,
          p_config_354_estabProximoId,
          'S', -- p_cab_entradaSaida,
          a.estabelecimentoSaida,
          a.dataEmissao, -- p_dataEntrega
          a.modeloDocumento,
          a.gradeProduto,
          a.localEstoqueSaida,
          a.pessoaParticipanteSaida,
          a.quantidadeSaldo,
          a.observacoes,
          0, -- p_item_idItemOrcamento
          0, -- p_item_idFichaProdutoPrevOrcam
          p_idItemDocTransferencia,
          a.locEstSaida_indicProprPosseI,
          r_bufferIdReservaEstoque, 
          r_bufferIdReservaEstoque);
      ELSIF a.controleEstoque IN (1,5,6,11,12) THEN
        v_quantidadeNumerosSerie := 0;
        IF a.controlaNumeroSerie > 0 THEN
          ADD_RESERVA_ESTOQUE_TRA_N_SER (
            p_sys_estabelecimentoAtivo,
            p_config_354_estabProximoId,
            a.modeloDocumento,
            'S', -- p_cab_entradaSaida,
            a.estabelecimentoSaida,
            a.dataEmissao,
            p_idItemDocTransferencia,
            a.gradeProduto,
            a.personalizacao,
            a.idLoteEstoque,
            a.localEstoqueSaida,
            a.pessoaParticipanteSaida,
            a.observacoes,
            a.produto,
            a.locEstSaida_indicProprPosseI,
            r_bufferIdReservaEstoque, 
            r_bufferIdReservaEstoque,
            v_quantidadeNumerosSerie);
           END IF;
        IF a.quantidadeSaldo > v_quantidadeNumerosSerie THEN
          ADD_RESERVA_ESTOQUE_GRAVA (
            p_sys_estabelecimentoAtivo,
            p_config_354_estabProximoId,
            0, -- p_idReservaEstoque
            a.estabelecimentoSaida,
            a.dataEmissao, -- p_dataEntrega
            a.produto,
            a.gradeProduto,
            a.modeloDocumento,
            'S', -- p_cab_entradaSaida,
            a.locEstSaida_indicProprPosseI,
            a.pessoaParticipanteSaida,
            a.localEstoqueSaida,
            a.personalizacao,
            a.idLoteEstoque,
            0, -- p_idNumeroSerie
            a.quantidadeSaldo - v_quantidadeNumerosSerie,
            a.observacoes,
            0, -- p_item_idItemOrcamento
            0, -- p_item_idFichaProdutoPrevOrcam
            p_idItemDocTransferencia,
            r_bufferIdReservaEstoque, 
            v_auxNumber,
            r_bufferIdReservaEstoque);
        END IF;
      END IF;
    END IF;
    IF a.tipoDocumentoEntrada > 100
      AND a.validoEntrada = 1
    THEN 
      IF a.controleEstoque = 12 AND a.idFormulaTinta > 0 THEN
        ADD_RESERVA_ESTOQUE_FORM_TINTA (
          p_sys_estabelecimentoAtivo,
          p_config_354_estabProximoId,
          'E', -- p_cab_entradaSaida,
          a.estabelecimentoEntrada,
          a.dataEmissao, -- p_dataEntrega
          a.modeloDocumento,
          a.idFormulaTinta,
          a.localEstoqueEntrada,
          a.pessoaParticipanteEntrada,
          a.quantidadeSaldo,
          a.observacoes,
          0, -- p_item_idItemOrcamento
          0, -- p_item_idFichaProdutoPrevOrcam
          p_idItemDocTransferencia,
          a.locEstEntr_indicProprPosseI,
          r_bufferIdReservaEstoque,
          r_bufferIdReservaEstoque);
      ELSIF a.controleEstoque IN (3,4) THEN
        ADD_RESERVA_ESTOQUE_KIT (
          p_sys_estabelecimentoAtivo,
          p_config_354_estabProximoId,
          'E', -- p_cab_entradaSaida,
          a.estabelecimentoEntrada,
          a.dataEmissao, -- p_dataEntrega
          a.modeloDocumento,
          a.gradeProduto,
          a.localEstoqueEntrada,
          a.pessoaParticipanteEntrada,
          a.quantidadeSaldo,
          a.observacoes,
          0, -- p_item_idItemOrcamento
          0, -- p_item_idFichaProdutoPrevOrcam
          p_idItemDocTransferencia,
          a.locEstEntr_indicProprPosseI,
          r_bufferIdReservaEstoque, 
          r_bufferIdReservaEstoque);
      ELSIF a.controleEstoque IN (1,5,6,11,12) THEN
        v_quantidadeNumerosSerie := 0;
        IF a.controlaNumeroSerie > 0 THEN
          ADD_RESERVA_ESTOQUE_TRA_N_SER (
            p_sys_estabelecimentoAtivo,
            p_config_354_estabProximoId,
            a.modeloDocumento,
            'E', -- p_cab_entradaSaida,
            a.estabelecimentoEntrada,
            a.dataEmissao,
            p_idItemDocTransferencia,
            a.gradeProduto,
            a.personalizacao,
            a.idLoteEstoque,
            a.localEstoqueEntrada,
            a.pessoaParticipanteEntrada,
            a.observacoes,
            a.produto,
            a.locEstEntr_indicProprPosseI,
            r_bufferIdReservaEstoque, 
            r_bufferIdReservaEstoque,
            v_quantidadeNumerosSerie);
           END IF;
        IF a.quantidadeSaldo > v_quantidadeNumerosSerie THEN
          ADD_RESERVA_ESTOQUE_GRAVA (
            p_sys_estabelecimentoAtivo,
            p_config_354_estabProximoId,
            0, -- p_idReservaEstoque
            a.estabelecimentoEntrada,
            a.dataEmissao, -- p_dataEntrega
            a.produto,
            a.gradeProduto,
            a.modeloDocumento,
            'E', -- p_cab_entradaSaida,
            a.locEstEntr_indicProprPosseI,
            a.pessoaParticipanteEntrada,
            a.localEstoqueEntrada,
            a.personalizacao,
            a.idLoteEstoque,
            0, -- p_idNumeroSerie
            a.quantidadeSaldo - v_quantidadeNumerosSerie,
            a.observacoes,
            0, -- p_item_idItemOrcamento
            0, -- p_item_idFichaProdutoPrevOrcam
            p_idItemDocTransferencia,
            r_bufferIdReservaEstoque, 
            v_auxNumber,
            r_bufferIdReservaEstoque);
        END IF;
      END IF;
    END IF;
  END LOOP;  
END ADD_RESERVA_ESTOQUE_TRA_ITEM;

/

create or replace PROCEDURE ADD_RESERVA_ESTOQUE_TRA_CAB (
  p_sys_estabelecimentoAtivo  IN NUMBER,
  p_config_354_estabProximoId IN NUMBER,
  p_documentoTransferencia    IN NUMBER)
IS
  v_bufferIdReservaEstoque VARCHAR2 (32000);
BEGIN
  v_bufferIdReservaEstoque := '';
  FOR a IN (
    SELECT idItemDocTransferencia
    FROM MODOCUMENTOTRANSFXITENS
    WHERE documentoTransferencia = p_documentoTransferencia)
  LOOP
    ADD_RESERVA_ESTOQUE_TRA_EXCLUI (
      a.idItemDocTransferencia,
      v_bufferIdReservaEstoque,
      v_bufferIdReservaEstoque);
  END LOOP;
  FOR a IN (
    SELECT item.idItemDocTransferencia
    FROM MODOCUMENTOTRANSFXITENS item
    JOIN MODOCUMENTOSTRANSFERENCIA cab
    ON cab.documentoTransferencia = item.documentoTransferencia
    JOIN PAMODELOSDOCUMENTO modDoc
    ON modDoc.modeloDocumento = cab.modeloDocumento
    WHERE item.documentoTransferencia = p_documentoTransferencia
    AND cab.situacaoDocTransferencia = 'A'
    AND modDoc.movimentaEstoque = 1
    AND item.cancelado = 0
    AND item.quantidadeSaldo <> 0)
  LOOP
    ADD_RESERVA_ESTOQUE_TRA_ITEM (
      p_sys_estabelecimentoAtivo,
      p_config_354_estabProximoId,
      a.idItemDocTransferencia,
      v_bufferIdReservaEstoque, 
      v_bufferIdReservaEstoque);
  END LOOP;
END ADD_RESERVA_ESTOQUE_TRA_CAB;

/

create or replace PROCEDURE ADD_EFETIVA_TEMP_INVENTARIO (
  p_sessaoClient            IN VARCHAR2,
  p_estabelecimentoAtivo    IN NUMBER,
  p_contadorSessaoFiscal    IN NUMBER,
  p_contadorSessaoGerencial IN NUMBER,
  p_invEst_data             IN DATE,
  p_invEst_motivoInventario IN CHAR,
  p_invEst_observacoes      IN VARCHAR2,
  p_inEstabelecimentos      IN VARCHAR2)
IS
  v_idInventarioEstoque NUMBER;
BEGIN
  FOR estab IN (
    SELECT estabelecimento
    FROM PAESTABELECIMENTOS
    WHERE estabelecimento > 0
    AND ((p_inEstabelecimentos IS NULL
        OR p_inEstabelecimentos = ' '
        OR p_inEstabelecimentos = '0')
      AND ativo = 1
      OR NOT(p_inEstabelecimentos IS NULL)
      AND p_inEstabelecimentos <> ' '
      AND p_inEstabelecimentos <> '0'
      AND INSTR(',' || RTRIM(p_inEstabelecimentos) || ',', ',' || TRIM(TO_CHAR(estabelecimento)) || ',') > 0)
    ORDER BY estabelecimento)
  LOOP
    v_idInventarioEstoque := FUNC_ADD_BUSCA_PROXIMO_ID('MOINVENTARIOSESTOQUE', 'inventarioEstoque', 0, p_estabelecimentoAtivo, NULL);
    INSERT INTO MOINVENTARIOSESTOQUE (
      inventarioEstoque,
      estabelecimento,
      data,
      motivoInventarioEstoque,
      observacoes)
    VALUES (
      v_idInventarioEstoque,
      estab.estabelecimento,
      p_invEst_data,
      COALESCE(p_invEst_motivoInventario,'01'),
      COALESCE(p_invEst_observacoes,' '));
    INSERT INTO MOINVENTARIOESTOQUEXFISC (
      id,
      inventarioEstoque,
      produto,
      gradeProduto,
      indicadorPropriedadePosseItem,
      pessoaParticipante,
      quantidade,
      precoUnitarioCMV,
      stICMS,
      baseICMS,
      valorICMS)
    SELECT
      FUNC_ADD_BUSCA_PROXIMO_ID('MOINVENTARIOESTOQUEXFISC', 'id', 0, p_estabelecimentoAtivo, NULL),
      v_idInventarioEstoque,
      temp.produto,
      temp.gradeProduto,
      temp.indicadorPropriedadePosseItem,
      temp.pessoaParticipante,
      CASE WHEN temp.quantidade < 0 THEN 0 ELSE temp.quantidade END,
      temp.precoUnitarioCMV,
      temp.stICMS,
      temp.baseICMS,
      temp.valorICMS
    FROM TEMPINVENTARIOESTXFISCAL temp
    WHERE temp.sessaoClient = p_sessaoClient
    AND temp.contadorSessao = p_contadorSessaoFiscal
    AND temp.estabelecimento = estab.estabelecimento;
    INSERT INTO MOINVENTARIOESTOQUEXITENS (
      idItemInventarioEstoque,
      inventarioEstoque,
      produto,
      gradeProduto,
      indicadorPropriedadePosseItem,
      pessoaParticipante,
      localEstoque,
      personalizacao,
      idLoteEstoque,
      idNumeroSerie,
      quantidade,
      precoUnitarioCMV,
      precoUnitarioUltimaCompra,
      precoCustoUltimaCompra,
      precoCustoUltimaFormacao)
    SELECT
      FUNC_ADD_BUSCA_PROXIMO_ID('MOINVENTARIOESTOQUEXITENS', 'idItemInventarioEstoque', 0, p_estabelecimentoAtivo, NULL),
      v_idInventarioEstoque,
      temp.produto,
      temp.gradeProduto,
      temp.indicadorPropriedadePosseItem,
      temp.pessoaParticipante,
      temp.localEstoque,
      temp.personalizacao,
      temp.idLoteEstoque,
      temp.idNumeroSerie,
      CASE WHEN temp.quantidade < 0 THEN 0 ELSE temp.quantidade END,
      temp.precoUnitarioCMV,
      temp.precoUnitarioUltimaCompra,
      temp.precoCustoUltimaCompra,
      temp.precoCustoUltimaFormacao
    FROM TEMPINVENTARIOESTXGERENC temp
    WHERE temp.sessaoClient = p_sessaoClient
    AND temp.contadorSessao = p_contadorSessaoGerencial
    AND temp.estabelecimento = estab.estabelecimento;
  END LOOP;
END ADD_EFETIVA_TEMP_INVENTARIO;

/

create or replace PROCEDURE ADD_TEMPCONTABIL_GERA_TEMP (
  p_sessaoClient           IN VARCHAR,
  p_contadorSessao         IN NUMERIC,
  p_dataInicial            IN DATE,
  p_dataFinal              IN DATE,
  p_estabelecimento        IN NUMERIC,
  p_situacaoContabilizacao IN CHAR)
IS
  v_idRegraContabilizacao   NUMBER;
  v_idPlanoContaContabil    NUMBER;
  v_tipoAglutinacaoContabil NUMBER;
  v_valor                   NUMBER;
  v_residuo                 NUMBER;
  v_saldo                   NUMBER;
  v_idCriar                 NUMBER;
  v_idAtualizar             NUMBER;
  v_quebra                  VARCHAR (15);
  v_fato                    NUMBER;
  v_sequencia               NUMBER;
BEGIN
  DELETE TEMPCONTABILSINTETICO
  WHERE sessaoClient = p_sessaoClient
  AND contadorSessao = p_contadorSessao;
  DELETE TEMPCONTABILANALITICO
  WHERE sessaoClient = p_sessaoClient
  AND contadorSessao = p_contadorSessao;
  IF p_situacaoContabilizacao = 'C' THEN
    -- Início Gera TEMPCONTABILSINTETICO
    v_idCriar := 0;
    FOR a IN (
      SELECT
        idContabil,
        estabelecimento,
        data,
        pessoa,
        documento,
        fatoContabil,
        ordenacao,
        debitoCredito,
        idContaContabil,
        valor,
        historicoContabil,
        complemento,
        historicoMontado,
        origemContabil
      FROM MOCONTABEIS
      WHERE idContabil > 0
      AND data BETWEEN TO_DATE (
        CASE
          WHEN p_dataInicial IS NULL
          THEN '00/00/0000'
          ELSE TO_CHAR (p_dataInicial, 'DD/MM/YYYY')
        END || ' 00:00:00', 'DD/MM/YYYY HH24:MI:SS')
      AND TO_DATE (
        CASE
          WHEN p_dataFinal IS NULL
            OR TO_CHAR (p_dataFinal, 'DD/MM/YYYY') = '00/00/0000'
          THEN '31/12/2500'
          ELSE TO_CHAR (p_dataFinal, 'DD/MM/YYYY')
        END || ' 23:59:59', 'DD/MM/YYYY HH24:MI:SS')
      AND estabelecimento = p_estabelecimento
      ORDER BY
        fatoContabil,
        ordenacao)
    LOOP
      IF a.debitoCredito = 'D' THEN
        SELECT COALESCE (MIN (b.id), 0)
        INTO v_idAtualizar
        FROM TEMPCONTABILSINTETICO b
        WHERE b.sessaoClient = p_sessaoClient
        AND b.contadorSessao = p_contadorSessao
        AND b.quebra = '1' || LPAD (a.fatoContabil, 14, '0')
        AND b.valor = a.valor
        AND b.estabelecimento = a.estabelecimento
        AND b.historicoContabil = a.historicoContabil
        AND b.debitar = 0;
      ELSE
        SELECT COALESCE (MIN (b.id), 0)
        INTO v_idAtualizar
        FROM TEMPCONTABILSINTETICO b
        WHERE b.sessaoClient = p_sessaoClient
        AND b.contadorSessao = p_contadorSessao
        AND b.quebra = '1' || LPAD (a.fatoContabil, 14, '0')
        AND b.valor = a.valor
        AND b.historicoContabil = a.historicoContabil
        AND b.creditar = 0;
      END IF;
      IF v_idAtualizar = 0 THEN
        v_idCriar := v_idCriar + 1;
        INSERT INTO TEMPCONTABILSINTETICO (
          sessaoClient,
          contadorSessao,
          id,
          quebra,
          fato,
          sequencia,
          selecionado,
          estabelecimento,
          estabelecimentoCodigoDescricao,
          idPlanoContaContabil,
          data,
          pessoa,
          pessoaCodigoDescricao,
          documento,
          fatoContabil,
          debitar,
          debitoIdContabil,
          debitoIdContaContabil,
          debitoReduzido,
          debitoCodigoDescricao,
          creditar,
          creditoIdContabil,
          creditoIdContaContabil,
          creditoReduzido,
          creditoCodigoDescricao,
          valor,
          historicoContabil,
          complemento,
          historicoMontado,
          origemContabil,
          idDocumento,
          documentoAberto,
          erroDebito,
          erroCredito,
          erroHistorico,
          erroValor,
          erroGeral)
        VALUES (
          p_sessaoClient,
          p_contadorSessao,
          v_idCriar, -- id
          '1' || LPAD (a.fatoContabil, 14, '0'),
          0, -- fato
          0, -- sequencia
          0, -- selecionado
          a.estabelecimento,
          ' ', -- estabelecimentoCodigoDescricao
          0, -- idPlanoContaContabil
          a.data,
          a.pessoa,
          ' ', -- pessoaCodigoDescricao
          a.documento,
          a.fatoContabil,
          CASE
            WHEN a.debitoCredito = 'D'
            THEN 1
            ELSE 0
          END, -- debitar
          CASE
            WHEN a.debitoCredito = 'D'
            THEN a.idContabil
            ELSE 0
          END, -- debitoIdContabil
          CASE
            WHEN a.debitoCredito = 'D'
            THEN a.idContaContabil
            ELSE 0
          END, -- debitoIdContaContabil
          0, -- debitoReduzido
          ' ', -- debitoCodigoDescricao
          CASE
            WHEN a.debitoCredito = 'C'
            THEN 1
            ELSE 0
          END, -- creditar,
          CASE
            WHEN a.debitoCredito = 'C'
            THEN a.idContabil
            ELSE 0
          END, -- creditoIdContabil
          CASE
            WHEN a.debitoCredito = 'C'
            THEN a.idContaContabil
            ELSE 0
          END, -- creditoIdContaContabil
          0, -- creditoReduzido
          ' ', -- creditoCodigoDescricao
          a.valor,
          a.historicoContabil,
          a.complemento,
          a.historicoMontado,
          a.origemContabil,
          0, -- idDocumento
          0, -- documentoAberto
          ' ',
          ' ',
          ' ',
          ' ',
          ' ');
      ELSIF a.debitoCredito = 'D' THEN
        UPDATE TEMPCONTABILSINTETICO b SET
          b.debitoIdContabil = a.idContabil,
          b.debitar = 1,
          b.debitoIdContaContabil = a.idContaContabil
        WHERE b.sessaoClient = p_sessaoClient
        AND b.contadorSessao = p_contadorSessao
        AND b.id = v_idAtualizar;
      ELSE
        UPDATE TEMPCONTABILSINTETICO b SET
          b.creditoIdContabil = a.idContabil,
          b.creditar = 1,
          b.creditoIdContaContabil = a.idContaContabil
        WHERE b.sessaoClient = p_sessaoClient
        AND b.contadorSessao = p_contadorSessao
        AND b.id = v_idAtualizar;
      END IF;
    END LOOP;
    -- Fim Gera TEMPCONTABILSINTETICO
  ELSE 
    v_idCriar := 0;
    -- Início Gera TEMPCONTABILANALITICO
    FOR a IN (
      SELECT fatoContabil
      FROM MOFATOSCONTABEIS
      WHERE fatoContabil > 0
      AND data BETWEEN TO_DATE (
        CASE
          WHEN p_dataInicial IS NULL
          THEN '00/00/0000'
          ELSE TO_CHAR (p_dataInicial, 'DD/MM/YYYY')
        END || ' 00:00:00', 'DD/MM/YYYY HH24:MI:SS')
      AND TO_DATE (
        CASE
          WHEN p_dataFinal IS NULL
            OR TO_CHAR (p_dataFinal, 'DD/MM/YYYY') = '00/00/0000'
          THEN '31/12/2500'
          ELSE TO_CHAR (p_dataFinal, 'DD/MM/YYYY')
        END || ' 23:59:59', 'DD/MM/YYYY HH24:MI:SS')
      AND estabelecimento = p_estabelecimento
      AND situacaoContabilizacao = p_situacaoContabilizacao)
    LOOP
      FOR b IN (
        SELECT
          'MODOCFISCALXITENS' tabelaSistema,
          b.idItemDocFiscal idTabelaSistema,
          100 origemContabil,
          b.idDocumentoFiscal idDocumento,
          cab.dataEmissao data,
          cab.fatoContabil,
          cab.estabelecimento,
          cab.pessoa,
          TO_CHAR (cab.documentoFiscal) documento,
          COALESCE (SUBSTR (RTRIM (
            COALESCE ((SELECT LISTAGG (UPPER (infCompl.descInformacaoComplementar), ' ')
            WITHIN GROUP (ORDER BY infCompl.sequencia)
            FROM MODOCFISCALXINFOCOMPLEMEN infCompl
            WHERE infCompl.idDocumentoFiscal = b.idDocumentoFiscal
            AND infCompl.geradoPeloSistema = 0
            AND infCompl.descInformacaoComplementar <> ' '), ' ')), 1, 120),' ') complemento,
          CASE
            WHEN cab.situacaoDocumentoFiscal < 23
            THEN 1
            ELSE 0
          END documentoAberto,
          gradProd.produto,
          cab.contaFinanceira,
          0 carteiraFinanceira,
          b.valorLiquidoItem valorContabil,
          b.valorFreteTotal,
          b.valorSeguroTotal,
          b.valorDescontoTotal,
          b.valorOutrasDespesasTotal,
          b.valorAdicFreteMarinhaMerTotal,
          b.valorDespesasAduaneirasTotal,
          b.valorDescontoCustoOpTotal,
          b.valorAcrescimoCustoOpTotal,
          b.valorAcrescimoExtempTotal,
          b.retidoISSQN,
          b.valorISSQN,
          b.valorRetIRRF,
          b.valorRetINSS,
          b.valorRetPIS,
          b.valorRetCOFINS,
          b.valorRetCSLL,
          b.valorRetOutros,
          b.valorII,
          b.valorIOF,
          b.valorIPI,
          b.valorIPIDevolucao,
          b.valorPIS,
          b.valorPISST,
          b.valorCOFINS,
          b.valorCOFINSST,
          b.valorCreditoSimplesNacional,
          b.valorICMSOperacao,
          b.valorICMSDiferido,
          b.valorICMS,
          b.valorICMSDesoneracao,
          b.valorICMSST,
          b.valorICMSSTAnteriormente,
          b.valorICMSProprioSubstituto,
          b.valorICMSEfetivo,
          b.valorICMSUFDestinatario,
          b.valorICMSUFRemetente,
          b.valorFCP,
          b.valorFCPST,
          b.valorFCPSTAnteriormente,
          b.valorFCPUFDestinatario,
          b.valorEstimadoImpFederais,
          b.valorEstimadoImpEstaduais,
          b.valorEstimadoImpMunicipais,
          b.valorCustoOperacao,
          b.valorCMV,
          0 baixa_valorVariacaoIndexador,
          0 baixa_valorJurosDeMora,
          0 baixa_valorMulta,
          0 baixa_valorTarifaCartao,
          0 baixa_valorDescontos,
          0 baixa_valorOutrosAcrescimos
        FROM MODOCFISCALXITENS b
        JOIN MODOCUMENTOSFISCAIS cab
        ON cab.idDocumentoFiscal = b.idDocumentoFiscal
        JOIN PAMODELOSDOCUMENTO modDoc
        ON modDoc.modeloDocumento = cab.modeloDocumento
        JOIN CAGRADESPRODUTO gradProd
        ON gradProd.gradeProduto = b.gradeProduto
        WHERE cab.fatoContabil = a.fatoContabil
        AND b.cancelado = 0
        AND cab.situacaoDocumentoFiscal < 24
        UNION ALL
        SELECT
          'MOPREDOCUMXITENS' tabelaSistema,
          b.idItemPreDocumento idTabelaSistema,
          101 origemContabil,
          b.preDocumento idDocumento,
          cab.dataEmissao data,
          cab.fatoContabil,
          cab.estabelecimento,
          cab.pessoa,
          TO_CHAR (CASE WHEN cab.documentoFiscal = 0 THEN cab.preDocumento ELSE cab.documentoFiscal END) documento,
          COALESCE (SUBSTR (RTRIM (
            COALESCE ((SELECT LISTAGG (UPPER (infCompl.descInformacaoComplementar), ' ')
            WITHIN GROUP (ORDER BY infCompl.sequencia)
            FROM MOPREDOCUMXINFOCOMPLENT infCompl
            WHERE infCompl.preDocumento = b.preDocumento
            AND infCompl.geradoPeloSistema = 0
            AND infCompl.descInformacaoComplementar <> ' '), ' ')), 1, 120),' ') complemento,
          CASE
            WHEN cab.statusPreDocumento = 'E'
            THEN 1
            ELSE 0
          END documentoAberto,
          gradProd.produto,
          cab.contaFinanceira,
          0 carteiraFinanceira,
          b.valorLiquidoItem valorContabil,
          b.valorFreteTotal,
          b.valorSeguroTotal,
          b.valorDescontoTotal,
          b.valorOutrasDespesasTotal,
          b.valorAdicFreteMarinhaMerTotal,
          b.valorDespesasAduaneirasTotal,
          b.valorDescontoCustoOpTotal,
          b.valorAcrescimoCustoOpTotal,
          b.valorAcrescimoExtempTotal,
          b.retidoISSQN,
          b.valorISSQN,
          b.valorRetIRRF,
          b.valorRetINSS,
          b.valorRetPIS,
          b.valorRetCOFINS,
          b.valorRetCSLL,
          b.valorRetOutros,
          b.valorII,
          b.valorIOF,
          b.valorIPI,
          b.valorIPIDevolucao,
          b.valorPIS,
          b.valorPISST,
          b.valorCOFINS,
          b.valorCOFINSST,
          b.valorCreditoSimplesNacional,
          b.valorICMSOperacao,
          b.valorICMSDiferido,
          b.valorICMS,
          b.valorICMSDesoneracao,
          b.valorICMSST,
          b.valorICMSSTAnteriormente,
          b.valorICMSProprioSubstituto,
          b.valorICMSEfetivo,
          b.valorICMSUFDestinatario,
          b.valorICMSUFRemetente,
          b.valorFCP,
          b.valorFCPST,
          b.valorFCPSTAnteriormente,
          b.valorFCPUFDestinatario,
          b.valorEstimadoImpFederais,
          b.valorEstimadoImpEstaduais,
          b.valorEstimadoImpMunicipais,
          b.valorCustoOperacao,
          b.valorCMV,
          0 baixa_valorVariacaoIndexador,
          0 baixa_valorJurosDeMora,
          0 baixa_valorMulta,
          0 baixa_valorTarifaCartao,
          0 baixa_valorDescontos,
          0 baixa_valorOutrosAcrescimos
        FROM MOPREDOCUMXITENS b
        JOIN MOPREDOCUMENTOS cab
        ON cab.preDocumento = b.preDocumento
        JOIN PAMODELOSDOCUMENTO modDoc
        ON modDoc.modeloDocumento = cab.modeloDocumento
        JOIN CAGRADESPRODUTO gradProd
        ON gradProd.gradeProduto = b.gradeProduto
        WHERE cab.fatoContabil = a.fatoContabil
        AND b.cancelado = 0
        AND cab.statusPreDocumento <> 'C'
        UNION ALL
        SELECT
          'MOFINANCEIROS' tabelaSistema,
          b.idFinanceiro idTabelaSistema,
          200 origemContabil,
          b.idFinanceiro idDocumento,
          b.dataEmissao data,
          b.fatoContabil,
          b.estabelecimento,
          b.pessoa,
          b.documento,
          COALESCE (RTRIM (SUBSTR (b.complemento, 1, 120)), ' ') complemento,
          0 documentoAberto,
          0 produto,
          b.contaFinanceira,
          b.carteiraFinanceira,
          b.valor valorContabil,
          0 valorFreteTotal,
          0 valorSeguroTotal,
          0 valorDescontoTotal,
          0 valorOutrasDespesasTotal,
          0 valorAdicFreteMarinhaMerTotal,
          0 valorDespesasAduaneirasTotal,
          0 valorDescontoCustoOpTotal,
          0 valorAcrescimoCustoOpTotal,
          0 valorAcrescimoExtempTotal,
          0 retidoISSQN,
          0 valorISSQN,
          0 valorRetIRRF,
          0 valorRetINSS,
          0 valorRetPIS,
          0 valorRetCOFINS,
          0 valorRetCSLL,
          0 valorRetOutros,
          0 valorII,
          0 valorIOF,
          0 valorIPI,
          0 valorIPIDevolucao,
          0 valorPIS,
          0 valorPISST,
          0 valorCOFINS,
          0 valorCOFINSST,
          0 valorCreditoSimplesNacional,
          0 valorICMSOperacao,
          0 valorICMSDiferido,
          0 valorICMS,
          0 valorICMSDesoneracao,
          0 valorICMSST,
          0 valorICMSSTAnteriormente,
          0 valorICMSProprioSubstituto,
          0 valorICMSEfetivo,
          0 valorICMSUFDestinatario,
          0 valorICMSUFRemetente,
          0 valorFCP,
          0 valorFCPST,
          0 valorFCPSTAnteriormente,
          0 valorFCPUFDestinatario,
          0 valorEstimadoImpFederais,
          0 valorEstimadoImpEstaduais,
          0 valorEstimadoImpMunicipais,
          0 valorCustoOperacao,
          0 valorCMV,
          0 baixa_valorVariacaoIndexador,
          0 baixa_valorJurosDeMora,
          0 baixa_valorMulta,
          0 baixa_valorTarifaCartao,
          0 baixa_valorDescontos,
          0 baixa_valorOutrosAcrescimos
        FROM MOFINANCEIROS b
        WHERE b.fatoContabil = a.fatoContabil
        AND b.idPagamentoPreDocumento = 0
        AND b.idPagamentoDocFiscal = 0
        UNION ALL
        SELECT
          'MOFINANCEIROXBAIXAS' tabelaSistema,
          b.idBaixaFinanceiro idTabelaSistema,
          300 origemContabil,
          b.idBaixaFinanceiro idDocumento,
          b.data,
          b.fatoContabil,
          b.estabelecimento,
          financ.pessoa,
          financ.documento,
          COALESCE (RTRIM (SUBSTR (b.observacoes, 1, 120)), ' ') complemento,
          0 documentoAberto,
          0 produto,
          b.contaFinanceira,
          b.carteiraFinanceira,
          b.valorLiquido valorContabil,
          0 valorFreteTotal,
          0 valorSeguroTotal,
          0 valorDescontoTotal,
          0 valorOutrasDespesasTotal,
          0 valorAdicFreteMarinhaMerTotal,
          0 valorDespesasAduaneirasTotal,
          0 valorDescontoCustoOpTotal,
          0 valorAcrescimoCustoOpTotal,
          0 valorAcrescimoExtempTotal,
          0 retidoISSQN,
          0 valorISSQN,
          0 valorRetIRRF,
          0 valorRetINSS,
          0 valorRetPIS,
          0 valorRetCOFINS,
          0 valorRetCSLL,
          0 valorRetOutros,
          0 valorII,
          0 valorIOF,
          0 valorIPI,
          0 valorIPIDevolucao,
          0 valorPIS,
          0 valorPISST,
          0 valorCOFINS,
          0 valorCOFINSST,
          0 valorCreditoSimplesNacional,
          0 valorICMSOperacao,
          0 valorICMSDiferido,
          0 valorICMS,
          0 valorICMSDesoneracao,
          0 valorICMSST,
          0 valorICMSSTAnteriormente,
          0 valorICMSProprioSubstituto,
          0 valorICMSEfetivo,
          0 valorICMSUFDestinatario,
          0 valorICMSUFRemetente,
          0 valorFCP,
          0 valorFCPST,
          0 valorFCPSTAnteriormente,
          0 valorFCPUFDestinatario,
          0 valorEstimadoImpFederais,
          0 valorEstimadoImpEstaduais,
          0 valorEstimadoImpMunicipais,
          0 valorCustoOperacao,
          0 valorCMV,
          b.valorVariacaoIndexador baixa_valorVariacaoIndexador,
          b.valorJurosDeMora baixa_valorJurosDeMora,
          b.valorMulta baixa_valorMulta,
          b.valorTarifaCartao baixa_valorTarifaCartao,
          b.valorDescontos baixa_valorDescontos,
          b.valorOutrosAcrescimos baixa_valorOutrosAcrescimos
        FROM MOFINANCEIROXBAIXAS b
        JOIN MOFINANCEIROS financ
        ON financ.idFinanceiro = b.idFinanceiro
        WHERE b.fatoContabil = a.fatoContabil
        AND b.baixaAutomatica = 0)
      LOOP
        SELECT COALESCE (MAX (c.idRegraContabilizacao), 0)
        INTO v_idRegraContabilizacao
        FROM (
          SELECT
            c.idRegraContabilizacao,
            ROW_NUMBER() OVER (
              ORDER BY
                c.ordenacao,
                c.idRegraContabilizacao) ordenacao
          FROM (
            SELECT
              c.idRegraContabilizacao,
              c.ordenacao,
              c.id,
              MIN (c.valido) valido
            FROM (
              SELECT
                c.idRegraContabilizacao,
                c.ordenacao,
                c.id,
                c.filtroContabil,
                MAX (c.valido) valido
              FROM (
                SELECT
                  regra.idRegraContabilizacao,
                  regra.ordenacao,
                  COALESCE (regraXFiltro.id, 0) id,
                  COALESCE (regraXFiltro.filtroContabil, 0) filtroContabil,
                  CASE
                    WHEN regraXFiltro.filtroContabil IS NULL
                    THEN 1
                    WHEN filtro.campoSelect IS NULL
                      OR filtro.campoSelect = ' '
                    THEN 0
                    ELSE FUNC_ADD_EXECUTE_IMMEDIATE_N ('SELECT
    CASE
      WHEN EXISTS (
        SELECT 1
        FROM PAREGRACONTABXFILTROS regraXFiltro
        LEFT JOIN SIFILTROSCONTABEIS filtro
        ON filtro.filtroContabil = regraXFiltro.filtroContabil
        LEFT JOIN SITABELASSISTEMA tabelaSistema
        ON tabelaSistema.tabelaSistema = filtro.tabelaSistema'
  || CASE b.tabelaSistema
       WHEN 'MODOCFISCALXITENS'
       THEN '
        JOIN MODOCFISCALXITENS itemDoc
        ON itemDoc.idItemDocFiscal = ' || TO_CHAR (b.idTabelaSistema) || CASE WHEN filtro.cabecalhoItemPagamento = 'C' THEN '
        JOIN MODOCUMENTOSFISCAIS cabDoc
        ON cabDoc.idDocumentoFiscal = itemDoc.idDocumentoFiscal' ELSE '' END
       WHEN 'MOPREDOCUMXITENS'
       THEN '
        JOIN MOPREDOCUMXITENS itemDoc
        ON itemDoc.idItemPreDocumento = ' || TO_CHAR (b.idTabelaSistema) || CASE WHEN filtro.cabecalhoItemPagamento = 'C' THEN '
        JOIN MOPREDOCUMENTOS cabDoc
        ON cabDoc.preDocumento = itemDoc.preDocumento' ELSE '' END
       WHEN 'MOFINANCEIROS'
       THEN '
        JOIN MOFINANCEIROS financ
        ON financ.idFinanceiro = ' || TO_CHAR (b.idTabelaSistema)
       WHEN 'MOFINANCEIROXBAIXAS'
       THEN '
        JOIN MOFINANCEIROXBAIXAS baixa
        ON baixa.idBaixaFinanceiro = ' || TO_CHAR (b.idTabelaSistema)
       ELSE ''
     END
  || CASE
       WHEN filtro.campoJoin IS NULL OR filtro.campoJoin = ' '
       THEN ''
       ELSE '
       ' || filtro.campoJoin
     END
  || '
        WHERE regraXFiltro.id = ' || TO_CHAR (regraXFiltro.id) || '
        AND (' || filtro.campoSelect || ') '
                      || CASE
                           WHEN filtro.tabelaSistema <> ' '
                           THEN 'IN ('
                             || CAST (regraXFiltro.campoIn AS VARCHAR2 (4000))
                             || ')'
                           WHEN filtro.tipoCampo = 'L'
                           THEN '= '
                             || CASE
                                  WHEN regraXFiltro.faixaDe IN ('S','1')
                                  THEN '1'
                                  ELSE '0'
                                END
                           WHEN filtro.tipoCampo = 'N'
                           THEN 'BETWEEN '
                             || CASE
                                  WHEN regraXFiltro.faixaDe = ' '
                                  THEN '0'
                                  ELSE REPLACE (regraXFiltro.faixaDe,',','.')
                                END
                             || ' AND '
                             || CASE
                                  WHEN regraXFiltro.faixaAte = ' '
                                  THEN '0'
                                  ELSE REPLACE (regraXFiltro.faixaAte,',','.')
                                END
                           ELSE 'BETWEEN '
                             || regraXFiltro.faixaDe
                             || ' AND '
                             || regraXFiltro.faixaAte
                         END || ')
      THEN 1
      ELSE 0
    END
  FROM DUAL')
                  END valido
                FROM PAREGRASCONTABILIZACAO regra
                JOIN PAESTABELECIMENTOS estab
                ON estab.estabelecimento = b.estabelecimento
                LEFT JOIN PAREGRACONTABXFILTROS regraXFiltro
                ON regraXFiltro.idRegraContabilizacao = regra.idRegraContabilizacao
                LEFT JOIN SIFILTROSCONTABEIS filtro
                ON filtro.filtroContabil = regraXFiltro.filtroContabil
                LEFT JOIN SITABELASSISTEMA tabelaSistema
                ON tabelaSistema.tabelaSistema = filtro.tabelaSistema
                WHERE regra.idRegraContabilizacao > 0
                AND regra.idPlanoContaContabil = estab.idPlanoContaContabil
                AND regra.origemContabil = CASE WHEN b.origemContabil = 101 THEN 100 ELSE b.origemContabil END
                AND regra.ativo = 1
                AND TRUNC (regra.dataValidadeInicial) <= TRUNC (SYSDATE)
                AND TRUNC (regra.dataValidadeFinal) >= TRUNC (SYSDATE)) c
              GROUP BY
                c.idRegraContabilizacao,
                c.ordenacao,
                c.id,
                c.filtroContabil) c
            GROUP BY
              c.idRegraContabilizacao,
              c.ordenacao,
              c.id) c
          WHERE c.valido = 1) c
        WHERE c.ordenacao = 1;
        SELECT
          idPlanoContaContabil,
          tipoAglutinacaoContabil
        INTO
          v_idPlanoContaContabil,
          v_tipoAglutinacaoContabil
        FROM PAREGRASCONTABILIZACAO
        WHERE idRegraContabilizacao = v_idRegraContabilizacao;
        FOR c IN (
          SELECT
            c.linhaContabil,
            c.debitoCredito,
            c.tipoContabilizacao,
            c.categoriaContabil,
            c.idContaContabil,
            c.valor,
            c.historicoContabil
          FROM (
            SELECT
              c.linhaContabil,
              c.debitoCredito,
              c.tipoContabilizacao,
              c.categoriaContabil,
              c.idContaContabil,
              CASE c.linhaContabil
                -- 110 Valor Frete
                WHEN 110 THEN b.valorFreteTotal
                -- 111 Valor Seguro
                WHEN 111 THEN b.valorSeguroTotal
                -- 112 Valor Desconto
                WHEN 112 THEN b.valorDescontoTotal
                -- 113 Valor Outras Despesas
                WHEN 113 THEN b.valorOutrasDespesasTotal
                -- 114 Valor Adicional Frete Marinha Mercantil
                WHEN 114 THEN b.valorAdicFreteMarinhaMerTotal
                -- 115 Valor Despesas Aduaneiras
                WHEN 115 THEN b.valorDespesasAduaneirasTotal
                -- 116 Valor Outros Descontos Custo
                WHEN 116 THEN b.valorDescontoCustoOpTotal
                -- 117 Valor Outros Acréscimos Custo
                WHEN 117 THEN b.valorAcrescimoCustoOpTotal
                -- 118 Valor Acréscimo Extemporâneo
                WHEN 118 THEN b.valorAcrescimoExtempTotal
                -- 130 Valor ISSQN
                WHEN 130 THEN
                  CASE
                    WHEN b.retidoISSQN = 1
                    THEN 0
                    ELSE b.valorISSQN
                  END
                -- 131 Valor ISSQN Retido
                WHEN 131 THEN
                  CASE
                    WHEN b.retidoISSQN = 1
                    THEN b.valorISSQN
                    ELSE 0
                  END
                -- 132 Valor Retenção IRRF
                WHEN 132 THEN b.valorRetIRRF
                -- 133 Valor Retenção INSS
                WHEN 133 THEN b.valorRetINSS
                -- 134 Valor Retenção PIS
                WHEN 134 THEN b.valorRetPIS
                -- 135 Valor Retenção COFINS
                WHEN 135 THEN b.valorRetCOFINS
                -- 136 Valor Retenção CSLL
                WHEN 136 THEN b.valorRetCSLL
                -- 137 Valor Retenção Outros
                WHEN 137 THEN b.valorRetOutros
                -- 140 Valor Imposto Importação
                WHEN 140 THEN b.valorII
                -- 141 Valor IOF
                WHEN 141 THEN b.valorIOF
                -- 142 Valor IPI
                WHEN 142 THEN b.valorIPI
                -- 143 Valor IPI Devolução
                WHEN 143 THEN b.valorIPIDevolucao
                -- 144 Valor PIS
                WHEN 144 THEN b.valorPIS
                -- 145 Valor PIS ST
                WHEN 145 THEN b.valorPISST
                -- 146 Valor COFINS
                WHEN 146 THEN b.valorCOFINS
                -- 147 Valor COFINS ST
                WHEN 147 THEN b.valorCOFINSST
                -- 148 Valor Crédito Simples Nacional
                WHEN 148 THEN b.valorCreditoSimplesNacional
                -- 160 Valor ICMS Operação
                WHEN 160 THEN b.valorICMSOperacao
                -- 161 Valor ICMS Diferido
                WHEN 161 THEN b.valorICMSDiferido
                -- 162 Valor ICMS
                WHEN 162 THEN b.valorICMS
                -- 163 Valor ICMS Desoneração
                WHEN 163 THEN b.valorICMSDesoneracao
                -- 164 Valor ICMS ST
                WHEN 164 THEN b.valorICMSST
                -- 165 Valor ICMS ST Anteriormente
                WHEN 165 THEN b.valorICMSSTAnteriormente
                -- 166 Valor ICMS Próprio Substituto
                WHEN 166 THEN b.valorICMSProprioSubstituto
                -- 167 Valor ICMS Efetivo
                WHEN 167 THEN b.valorICMSEfetivo
                -- 168 Valor ICMS UF Destinatario
                WHEN 168 THEN b.valorICMSUFDestinatario
                -- 169 Valor ICMS UF Remetente
                WHEN 169 THEN b.valorICMSUFRemetente
                -- 180 Valor FCP
                WHEN 180 THEN b.valorFCP
                -- 181 Valor FCP ST
                WHEN 181 THEN b.valorFCPST
                -- 182 Valor FCP ST Anteriormente
                WHEN 182 THEN b.valorFCPSTAnteriormente
                -- 183 Valor FCP UF Destinatario
                WHEN 183 THEN b.valorFCPUFDestinatario
                -- 187 Valor Estimado Impostos Federais
                WHEN 187 THEN b.valorEstimadoImpFederais
                -- 188 Valor Estimado Impostos Estaduais
                WHEN 188 THEN b.valorEstimadoImpEstaduais
                -- 189 Valor Estimado Impostos Municipais
                WHEN 189 THEN b.valorEstimadoImpMunicipais
                -- 190 Valor Custo Operação
                WHEN 190 THEN b.valorCustoOperacao
                -- 191 Valor CMV
                WHEN 191 THEN b.valorCMV
                -- 301 Valor Variação Indexador Redução
                WHEN 301 THEN
                  CASE
                    WHEN b.baixa_valorVariacaoIndexador < 0
                    THEN - b.baixa_valorVariacaoIndexador
                    ELSE 0
                  END
                -- 302 Valor Variação Indexador Acréscimo
                WHEN 302 THEN
                  CASE
                    WHEN b.baixa_valorVariacaoIndexador > 0
                    THEN b.baixa_valorVariacaoIndexador
                    ELSE 0
                  END
                -- 303 Valor Juros de Mora
                WHEN 303 THEN b.baixa_valorJurosDeMora
                -- 304 Valor Multa
                WHEN 304 THEN b.baixa_valorMulta
                -- 305 Valor Tarifa Cartão
                WHEN 305 THEN b.baixa_valorTarifaCartao
                -- 306 Valor Descontos
                WHEN 306 THEN b.baixa_valorDescontos
                -- 307 Valor Outros Acréscimos
                WHEN 307 THEN b.baixa_valorOutrosAcrescimos
                -- 100 Valor Contábil
                -- 200 Valor Contábil
                -- 300 Valor Contábil
                ELSE b.valorContabil + COALESCE ((
                  SELECT SUM (
                    CASE d.linhaContabil
                      -- 110 Valor Frete
                      WHEN 110 THEN b.valorFreteTotal
                      -- 111 Valor Seguro
                      WHEN 111 THEN b.valorSeguroTotal
                      -- 112 Valor Desconto
                      WHEN 112 THEN b.valorDescontoTotal
                      -- 113 Valor Outras Despesas
                      WHEN 113 THEN b.valorOutrasDespesasTotal
                      -- 114 Valor Adicional Frete Marinha Mercantil
                      WHEN 114 THEN b.valorAdicFreteMarinhaMerTotal
                      -- 115 Valor Despesas Aduaneiras
                      WHEN 115 THEN b.valorDespesasAduaneirasTotal
                      -- 116 Valor Outros Descontos Custo
                      WHEN 116 THEN b.valorDescontoCustoOpTotal
                      -- 117 Valor Outros Acréscimos Custo
                      WHEN 117 THEN b.valorAcrescimoCustoOpTotal
                      -- 118 Valor Acréscimo Extemporâneo
                      WHEN 118 THEN b.valorAcrescimoExtempTotal
                      -- 130 Valor ISSQN
                      WHEN 130 THEN
                        CASE
                          WHEN b.retidoISSQN = 1
                          THEN 0
                          ELSE b.valorISSQN
                        END
                      -- 131 Valor ISSQN Retido
                      WHEN 131 THEN
                        CASE
                          WHEN b.retidoISSQN = 1
                          THEN b.valorISSQN
                          ELSE 0
                        END
                      -- 132 Valor Retenção IRRF
                      WHEN 132 THEN b.valorRetIRRF
                      -- 133 Valor Retenção INSS
                      WHEN 133 THEN b.valorRetINSS
                      -- 134 Valor Retenção PIS
                      WHEN 134 THEN b.valorRetPIS
                      -- 135 Valor Retenção COFINS
                      WHEN 135 THEN b.valorRetCOFINS
                      -- 136 Valor Retenção CSLL
                      WHEN 136 THEN b.valorRetCSLL
                      -- 137 Valor Retenção Outros
                      WHEN 137 THEN b.valorRetOutros
                      -- 140 Valor Imposto Importação
                      WHEN 140 THEN b.valorII
                      -- 141 Valor IOF
                      WHEN 141 THEN b.valorIOF
                      -- 142 Valor IPI
                      WHEN 142 THEN b.valorIPI
                      -- 143 Valor IPI Devolução
                      WHEN 143 THEN b.valorIPIDevolucao
                      -- 144 Valor PIS
                      WHEN 144 THEN b.valorPIS
                      -- 145 Valor PIS ST
                      WHEN 145 THEN b.valorPISST
                      -- 146 Valor COFINS
                      WHEN 146 THEN b.valorCOFINS
                      -- 147 Valor COFINS ST
                      WHEN 147 THEN b.valorCOFINSST
                      -- 148 Valor Crédito Simples Nacional
                      WHEN 148 THEN b.valorCreditoSimplesNacional
                      -- 160 Valor ICMS Operação
                      WHEN 160 THEN b.valorICMSOperacao
                      -- 161 Valor ICMS Diferido
                      WHEN 161 THEN b.valorICMSDiferido
                      -- 162 Valor ICMS
                      WHEN 162 THEN b.valorICMS
                      -- 163 Valor ICMS Desoneração
                      WHEN 163 THEN b.valorICMSDesoneracao
                      -- 164 Valor ICMS ST
                      WHEN 164 THEN b.valorICMSST
                      -- 165 Valor ICMS ST Anteriormente
                      WHEN 165 THEN b.valorICMSSTAnteriormente
                      -- 166 Valor ICMS Próprio Substituto
                      WHEN 166 THEN b.valorICMSProprioSubstituto
                      -- 167 Valor ICMS Efetivo
                      WHEN 167 THEN b.valorICMSEfetivo
                      -- 168 Valor ICMS UF Destinatario
                      WHEN 168 THEN b.valorICMSUFDestinatario
                      -- 169 Valor ICMS UF Remetente
                      WHEN 169 THEN b.valorICMSUFRemetente
                      -- 180 Valor FCP
                      WHEN 180 THEN b.valorFCP
                      -- 181 Valor FCP ST
                      WHEN 181 THEN b.valorFCPST
                      -- 182 Valor FCP ST Anteriormente
                      WHEN 182 THEN b.valorFCPSTAnteriormente
                      -- 183 Valor FCP UF Destinatario
                      WHEN 183 THEN b.valorFCPUFDestinatario
                      -- 187 Valor Estimado Impostos Federais
                      WHEN 187 THEN b.valorEstimadoImpFederais
                      -- 188 Valor Estimado Impostos Estaduais
                      WHEN 188 THEN b.valorEstimadoImpEstaduais
                      -- 189 Valor Estimado Impostos Municipais
                      WHEN 189 THEN b.valorEstimadoImpMunicipais
                      -- 190 Valor Custo Operação
                      WHEN 190 THEN b.valorCustoOperacao
                      -- 191 Valor CMV
                      WHEN 191 THEN b.valorCMV
                      -- 301 Valor Variação Indexador Redução
                      WHEN 301 THEN
                        CASE
                          WHEN b.baixa_valorVariacaoIndexador < 0
                          THEN - b.baixa_valorVariacaoIndexador
                          ELSE 0
                        END
                      -- 302 Valor Variação Indexador Acréscimo
                      WHEN 302 THEN
                        CASE
                          WHEN b.baixa_valorVariacaoIndexador > 0
                          THEN b.baixa_valorVariacaoIndexador
                          ELSE 0
                        END
                      -- 303 Valor Juros de Mora
                      WHEN 303 THEN b.baixa_valorJurosDeMora
                      -- 304 Valor Multa
                      WHEN 304 THEN b.baixa_valorMulta
                      -- 305 Valor Tarifa Cartão
                      WHEN 305 THEN b.baixa_valorTarifaCartao
                      -- 306 Valor Descontos
                      WHEN 306 THEN b.baixa_valorDescontos
                      -- 307 Valor Outros Acréscimos
                      WHEN 307 THEN b.baixa_valorOutrosAcrescimos
                      -- 100 Valor Contábil
                      -- 200 Valor Contábil
                      -- 300 Valor Contábil
                      ELSE b.valorContabil
                    END
                    * CASE
                        WHEN c.debitoCredito = 'D'
                          AND d.tipoContabilizacaoDebito = '90'
                          OR c.debitoCredito = 'C'
                          AND d.tipoContabilizacaoCredito = '90'
                        THEN -1
                        ELSE 1
                      END)
                  FROM PAREGRACONTABXLINHAS d
                  WHERE d.idRegraContabilizacao = v_idRegraContabilizacao
                  AND (c.debitoCredito = 'D'
                    AND d.tipoContabilizacaoDebito IN (90,91)
                    OR c.debitoCredito = 'C'
                    AND d.tipoContabilizacaoCredito IN (90,91))), 0)
              END valor,
              c.historicoContabil 
            FROM (
              SELECT
                c.linhaContabil,
                'D' debitoCredito,
                c.tipoContabilizacaoDebito tipoContabilizacao,
                c.idContaContabilDebito idContaContabil,
                c.categoriaContabilDebito categoriaContabil,
                c.historicoContabil
                FROM PAREGRACONTABXLINHAS c
                WHERE c.idRegraContabilizacao = v_idRegraContabilizacao
                AND c.tipoContabilizacaoDebito IN (1,10,20,40,50)
              UNION ALL
              SELECT
                c.linhaContabil,
                'C' debitoCredito,
                c.tipoContabilizacaoCredito tipoContabilizacao,
                c.idContaContabilCredito idContaContabil,
                c.categoriaContabilCredito categoriaContabil,
                c.historicoContabil
                FROM PAREGRACONTABXLINHAS c
                WHERE c.idRegraContabilizacao = v_idRegraContabilizacao
                AND c.tipoContabilizacaoCredito IN (1,10,20,40,50)) c) c
          WHERE c.valor <> 0)
        LOOP
          IF b.origemContabil = 100
            AND c.tipoContabilizacao IN (40,50)
            AND b.valorContabil <> 0
          THEN
            v_valor   := 0;
            v_residuo := 0;
            v_saldo   := c.valor;
            FOR d IN (
              SELECT
                CASE
                  -- 40 Conta Financeira
                  WHEN c.tipoContabilizacao = 40
                  THEN financ.contaFinanceira
                  -- 50 Carteira Financeira
                  ELSE ' '
                END contaFinanceira,
                CASE
                  -- 40 Conta Financeira
                  WHEN c.tipoContabilizacao = 40
                  THEN 0
                  -- 50 Carteira Financeira
                  ELSE financ.carteiraFinanceira
                END carteiraFinanceira,
                SUM (financ.valor *
                  CASE
                    WHEN pag.pagamentoTroco = 'T'
                    THEN -1
                    ELSE 1
                  END) valor
              FROM MODOCFISCALXPAGAMENTOS pag
              JOIN MOFINANCEIROS financ
              ON financ.idPagamentoDocFiscal = pag.idPagamentoDocFiscal
              WHERE pag.idDocumentoFiscal = b.idDocumento
              GROUP BY
                CASE
                  -- 40 Conta Financeira
                  WHEN c.tipoContabilizacao = 40
                  THEN financ.contaFinanceira
                  -- 50 Carteira Financeira
                  ELSE ' '
                END,
                CASE
                  -- 40 Conta Financeira
                  WHEN c.tipoContabilizacao = 40
                  THEN 0
                  -- 50 Carteira Financeira
                  ELSE financ.carteiraFinanceira
                END)
            LOOP
              v_valor   := ROUND (((c.valor * d.valor / b.valorContabil) + v_residuo), 2);
              v_residuo := ((c.valor * d.valor / b.valorContabil) + v_residuo)
                  - ROUND (((c.valor * d.valor / b.valorContabil) + v_residuo), 2);
              v_saldo   := v_saldo - v_valor;
              v_idCriar := v_idCriar + 1;
              INSERT INTO TEMPCONTABILANALITICO (
                sessaoClient,
                contadorSessao,
                id,
                debitoCredito,
                idContaContabil,
                historicoContabil,
                linhaContabil,
                quebra,
                origemContabil,
                idDocumento,
                data,
                fatoContabil,
                estabelecimento,
                pessoa,
                documento,
                complemento,
                documentoAberto,
                valor)
              VALUES (
                p_sessaoClient,
                p_contadorSessao,
                v_idCriar,
                c.debitoCredito,
                CASE
                  -- 40 Conta Financeira
                  WHEN c.tipoContabilizacao = 40
                  THEN COALESCE ((
                    SELECT MAX (conta.idContaContabil)
                    FROM PACONTAFINANCEIRAXCONTAB conta
                    WHERE conta.contaFinanceira = d.contaFinanceira
                    AND conta.categoriaContabil = c.categoriaContabil
                    AND conta.idPlanoContaContabil = v_idPlanoContaContabil
                    AND conta.estabelecimento = b.estabelecimento
                    AND conta.ativo = 1), COALESCE ((
                      SELECT MAX (conta.idContaContabil)
                      FROM PACONTAFINANCEIRAXCONTAB conta
                      WHERE conta.contaFinanceira = d.contaFinanceira
                      AND conta.categoriaContabil = 0
                      AND conta.idPlanoContaContabil = v_idPlanoContaContabil
                      AND conta.estabelecimento = b.estabelecimento
                      AND conta.ativo = 1), 0))
                  -- 50 Carteira Financeira
                  ELSE COALESCE ((
                    SELECT MAX (conta.idContaContabil)
                    FROM PACARTFINANCXCONTASCONTAB conta
                    WHERE conta.carteiraFinanceira = d.carteiraFinanceira
                    AND conta.categoriaContabil = c.categoriaContabil
                    AND conta.idPlanoContaContabil = v_idPlanoContaContabil
                    AND conta.estabelecimento = b.estabelecimento
                    AND conta.ativo = 1), COALESCE ((
                      SELECT MAX (conta.idContaContabil)
                      FROM PACARTFINANCXCONTASCONTAB conta
                      WHERE conta.carteiraFinanceira = d.carteiraFinanceira
                      AND conta.categoriaContabil = 0
                      AND conta.idPlanoContaContabil = v_idPlanoContaContabil
                      AND conta.estabelecimento = b.estabelecimento
                      AND conta.ativo = 1), 0))
                END, -- idContaContabil
                c.historicoContabil,
                c.linhaContabil,
                CASE v_tipoAglutinacaoContabil
                  -- 2	Dia
                  WHEN 2 THEN '2' || TO_CHAR (b.data, 'YYYYMMDD')
                  -- 3	Mês
                  WHEN 3 THEN '3' || TO_CHAR (b.data, 'YYYYMM')
                  -- 1	Fato Contábil
                  ELSE '1' || LPAD (b.fatoContabil, 14, '0')
                END, -- quebra
                b.origemContabil,
                b.idDocumento,
                b.data,
                b.fatoContabil,
                b.estabelecimento,
                b.pessoa,
                b.documento,
                b.complemento,
                b.documentoAberto,
                v_valor);
            END LOOP;
            IF v_saldo <> 0 THEN
              v_idCriar := v_idCriar + 1;
              INSERT INTO TEMPCONTABILANALITICO (
                sessaoClient,
                contadorSessao,
                id,
                debitoCredito,
                idContaContabil,
                historicoContabil,
                linhaContabil,
                quebra,
                origemContabil,
                idDocumento,
                data,
                fatoContabil,
                estabelecimento,
                pessoa,
                documento,
                complemento,
                documentoAberto,
                valor)
              VALUES (
                p_sessaoClient,
                p_contadorSessao,
                v_idCriar,
                c.debitoCredito,
                c.idContaContabil,
                c.historicoContabil,
                c.linhaContabil,
                CASE v_tipoAglutinacaoContabil
                  -- 2	Dia
                  WHEN 2 THEN '2' || TO_CHAR (b.data, 'YYYYMMDD')
                  -- 3	Mês
                  WHEN 3 THEN '3' || TO_CHAR (b.data, 'YYYYMM')
                  -- 1	Fato Contábil
                  ELSE '1' || LPAD (b.fatoContabil, 14, '0')
                END, -- quebra
                b.origemContabil,
                b.idDocumento,
                b.data,
                b.fatoContabil,
                b.estabelecimento,
                b.pessoa,
                b.documento,
                b.complemento,
                b.documentoAberto,
                v_saldo);
            END IF;
          ELSIF b.origemContabil = 101
            AND c.tipoContabilizacao IN (40,50)
          THEN
            v_valor   := 0;
            v_residuo := 0;
            v_saldo   := c.valor;
            FOR d IN (
              SELECT
                CASE
                  -- 40 Conta Financeira
                  WHEN c.tipoContabilizacao = 40
                  THEN financ.contaFinanceira
                  -- 50 Carteira Financeira
                  ELSE ' '
                END contaFinanceira,
                CASE
                  -- 40 Conta Financeira
                  WHEN c.tipoContabilizacao = 40
                  THEN 0
                  -- 50 Carteira Financeira
                  ELSE financ.carteiraFinanceira
                END carteiraFinanceira,
                SUM (financ.valor *
                  CASE
                    WHEN pag.pagamentoTroco = 'T'
                    THEN -1
                    ELSE 1
                  END) valor
              FROM MOPREDOCUMXPAGAMENTOS pag
              JOIN MOFINANCEIROS financ
              ON financ.idPagamentoPreDocumento = pag.idPagamentoPreDocumento
              WHERE pag.preDocumento = b.idDocumento
              GROUP BY
                CASE
                  -- 40 Conta Financeira
                  WHEN c.tipoContabilizacao = 40
                  THEN financ.contaFinanceira
                  -- 50 Carteira Financeira
                  ELSE ' '
                END,
                CASE
                  -- 40 Conta Financeira
                  WHEN c.tipoContabilizacao = 40
                  THEN 0
                  -- 50 Carteira Financeira
                  ELSE financ.carteiraFinanceira
                END)
            LOOP
              v_valor   := ROUND (((c.valor * d.valor / b.valorContabil) + v_residuo), 2);
              v_residuo := ((c.valor * d.valor / b.valorContabil) + v_residuo)
                  - ROUND (((c.valor * d.valor / b.valorContabil) + v_residuo), 2);
              v_saldo   := v_saldo - v_valor;
              v_idCriar := v_idCriar + 1;
              INSERT INTO TEMPCONTABILANALITICO (
                sessaoClient,
                contadorSessao,
                id,
                debitoCredito,
                idContaContabil,
                historicoContabil,
                linhaContabil,
                quebra,
                origemContabil,
                idDocumento,
                data,
                fatoContabil,
                estabelecimento,
                pessoa,
                documento,
                complemento,
                documentoAberto,
                valor)
              VALUES (
                p_sessaoClient,
                p_contadorSessao,
                v_idCriar,
                c.debitoCredito,
                CASE
                  -- 40 Conta Financeira
                  WHEN c.tipoContabilizacao = 40
                  THEN COALESCE ((
                    SELECT MAX (conta.idContaContabil)
                    FROM PACONTAFINANCEIRAXCONTAB conta
                    WHERE conta.contaFinanceira = d.contaFinanceira
                    AND conta.categoriaContabil = c.categoriaContabil
                    AND conta.idPlanoContaContabil = v_idPlanoContaContabil
                    AND conta.estabelecimento = b.estabelecimento
                    AND conta.ativo = 1), COALESCE ((
                      SELECT MAX (conta.idContaContabil)
                      FROM PACONTAFINANCEIRAXCONTAB conta
                      WHERE conta.contaFinanceira = d.contaFinanceira
                      AND conta.categoriaContabil = 0
                      AND conta.idPlanoContaContabil = v_idPlanoContaContabil
                      AND conta.estabelecimento = b.estabelecimento
                      AND conta.ativo = 1), 0))
                  -- 50 Carteira Financeira
                  ELSE COALESCE ((
                    SELECT MAX (conta.idContaContabil)
                    FROM PACARTFINANCXCONTASCONTAB conta
                    WHERE conta.carteiraFinanceira = d.carteiraFinanceira
                    AND conta.categoriaContabil = c.categoriaContabil
                    AND conta.idPlanoContaContabil = v_idPlanoContaContabil
                    AND conta.estabelecimento = b.estabelecimento
                    AND conta.ativo = 1), COALESCE ((
                      SELECT MAX (conta.idContaContabil)
                      FROM PACARTFINANCXCONTASCONTAB conta
                      WHERE conta.carteiraFinanceira = d.carteiraFinanceira
                      AND conta.categoriaContabil = 0
                      AND conta.idPlanoContaContabil = v_idPlanoContaContabil
                      AND conta.estabelecimento = b.estabelecimento
                      AND conta.ativo = 1), 0))
                END, -- idContaContabil
                c.historicoContabil,
                c.linhaContabil,
                CASE v_tipoAglutinacaoContabil
                  -- 2	Dia
                  WHEN 2 THEN '2' || TO_CHAR (b.data, 'YYYYMMDD')
                  -- 3	Mês
                  WHEN 3 THEN '3' || TO_CHAR (b.data, 'YYYYMM')
                  -- 1	Fato Contábil
                  ELSE '1' || LPAD (b.fatoContabil, 14, '0')
                END, -- quebra
                b.origemContabil,
                b.idDocumento,
                b.data,
                b.fatoContabil,
                b.estabelecimento,
                b.pessoa,
                b.documento,
                b.complemento,
                b.documentoAberto,
                v_valor);
            END LOOP;
            IF v_saldo <> 0 THEN
              v_idCriar := v_idCriar + 1;
              INSERT INTO TEMPCONTABILANALITICO (
                sessaoClient,
                contadorSessao,
                id,
                debitoCredito,
                idContaContabil,
                historicoContabil,
                linhaContabil,
                quebra,
                origemContabil,
                idDocumento,
                data,
                fatoContabil,
                estabelecimento,
                pessoa,
                documento,
                complemento,
                documentoAberto,
                valor)
              VALUES (
                p_sessaoClient,
                p_contadorSessao,
                v_idCriar,
                c.debitoCredito,
                c.idContaContabil,
                c.historicoContabil,
                c.linhaContabil,
                CASE v_tipoAglutinacaoContabil
                  -- 2	Dia
                  WHEN 2 THEN '2' || TO_CHAR (b.data, 'YYYYMMDD')
                  -- 3	Mês
                  WHEN 3 THEN '3' || TO_CHAR (b.data, 'YYYYMM')
                  -- 1	Fato Contábil
                  ELSE '1' || LPAD (b.fatoContabil, 14, '0')
                END, -- quebra
                b.origemContabil,
                b.idDocumento,
                b.data,
                b.fatoContabil,
                b.estabelecimento,
                b.pessoa,
                b.documento,
                b.complemento,
                b.documentoAberto,
                v_saldo);
            END IF;
          ELSE
            v_idCriar := v_idCriar + 1;
            INSERT INTO TEMPCONTABILANALITICO (
              sessaoClient,
              contadorSessao,
              id,
              debitoCredito,
              idContaContabil,
              historicoContabil,
              linhaContabil,
              quebra,
              origemContabil,
              idDocumento,
              data,
              fatoContabil,
              estabelecimento,
              pessoa,
              documento,
              complemento,
              documentoAberto,
              valor)
            VALUES (
              p_sessaoClient,
              p_contadorSessao,
              v_idCriar,
              c.debitoCredito,
              CASE c.tipoContabilizacao
                -- 1 Conta Contábil
                WHEN 1 THEN c.idContaContabil
                -- 10 Pessoa
                WHEN 10 THEN COALESCE ((
                  SELECT MAX (conta.idContaContabil)
                  FROM CAPESSOAXCONTASCONTABEIS conta
                  WHERE conta.pessoa = b.pessoa
                  AND conta.categoriaContabil = c.categoriaContabil
                  AND conta.idPlanoContaContabil = v_idPlanoContaContabil
                  AND conta.estabelecimento = b.estabelecimento
                  AND conta.ativo = 1), COALESCE ((
                    SELECT MAX (conta.idContaContabil)
                    FROM CAPESSOAXCONTASCONTABEIS conta
                    WHERE conta.pessoa = b.pessoa
                    AND conta.categoriaContabil = 0
                    AND conta.idPlanoContaContabil = v_idPlanoContaContabil
                    AND conta.estabelecimento = b.estabelecimento
                    AND conta.ativo = 1), 0))
                -- 20 Produto
                WHEN 20 THEN COALESCE ((
                  SELECT MAX (conta.idContaContabil)
                  FROM CAPRODUTOXCONTASCONTABEIS conta
                  WHERE conta.produto = b.produto
                  AND conta.categoriaContabil = c.categoriaContabil
                  AND conta.idPlanoContaContabil = v_idPlanoContaContabil
                  AND conta.estabelecimento = b.estabelecimento
                  AND conta.ativo = 1), COALESCE ((
                    SELECT MAX (conta.idContaContabil)
                    FROM CAPRODUTOXCONTASCONTABEIS conta
                    WHERE conta.produto = b.produto
                    AND conta.categoriaContabil = 0
                    AND conta.idPlanoContaContabil = v_idPlanoContaContabil
                    AND conta.estabelecimento = b.estabelecimento
                    AND conta.ativo = 1), 0))
                -- 40 Conta Financeira
                WHEN 40 THEN COALESCE ((
                  SELECT MAX (conta.idContaContabil)
                  FROM PACONTAFINANCEIRAXCONTAB conta
                  WHERE conta.contaFinanceira = b.contaFinanceira
                  AND conta.categoriaContabil = c.categoriaContabil
                  AND conta.idPlanoContaContabil = v_idPlanoContaContabil
                  AND conta.estabelecimento = b.estabelecimento
                  AND conta.ativo = 1), COALESCE ((
                    SELECT MAX (conta.idContaContabil)
                    FROM PACONTAFINANCEIRAXCONTAB conta
                    WHERE conta.contaFinanceira = b.contaFinanceira
                    AND conta.categoriaContabil = 0
                    AND conta.idPlanoContaContabil = v_idPlanoContaContabil
                    AND conta.estabelecimento = b.estabelecimento
                    AND conta.ativo = 1), 0))
                -- 50 Carteira Financeira
                WHEN 50 THEN COALESCE ((
                  SELECT MAX (conta.idContaContabil)
                  FROM PACARTFINANCXCONTASCONTAB conta
                  WHERE conta.carteiraFinanceira = b.carteiraFinanceira
                  AND conta.categoriaContabil = c.categoriaContabil
                  AND conta.idPlanoContaContabil = v_idPlanoContaContabil
                  AND conta.estabelecimento = b.estabelecimento
                  AND conta.ativo = 1), COALESCE ((
                    SELECT MAX (conta.idContaContabil)
                    FROM PACARTFINANCXCONTASCONTAB conta
                    WHERE conta.carteiraFinanceira = b.carteiraFinanceira
                    AND conta.categoriaContabil = 0
                    AND conta.idPlanoContaContabil = v_idPlanoContaContabil
                    AND conta.estabelecimento = b.estabelecimento
                    AND conta.ativo = 1), 0))
                -- 90 Diminuir Valor Contábil
                -- 91 Somar Valor Contábil
                ELSE 0
              END, -- idContaContabil
              c.historicoContabil,
              c.linhaContabil,
              CASE v_tipoAglutinacaoContabil
                -- 2	Dia
                WHEN 2 THEN '2' || TO_CHAR (b.data, 'YYYYMMDD')
                -- 3	Mês
                WHEN 3 THEN '3' || TO_CHAR (b.data, 'YYYYMM')
                -- 1	Fato Contábil
                ELSE '1' || LPAD (b.fatoContabil, 14, '0')
              END, -- quebra
              b.origemContabil,
              b.idDocumento,
              b.data,
              b.fatoContabil,
              b.estabelecimento,
              b.pessoa,
              b.documento,
              b.complemento,
              b.documentoAberto,
              c.valor);
          END IF;
        END LOOP;
      END LOOP;
    END LOOP;
    -- Fim Gera TEMPCONTABILANALITICO
    -- Início Gera TEMPCONTABILSINTETICO
    v_idCriar := 0;
    FOR a IN (
      SELECT
        a.quebra,
        a.debitoCredito,
        a.idContaContabil,
        a.historicoContabil,
        a.linhaContabil,
        a.origemContabil,
        a.idDocumento,
        a.data,
        a.fatoContabil,
        a.estabelecimento,
        a.pessoa,
        a.documento,
        a.complemento,
        a.documentoAberto,
        a.valor,
        pess.nomeRazaoSocial,
        hist.descricaoMontada
      FROM (
        SELECT
          quebra,
          origemContabil,
          debitoCredito,
          idContaContabil,
          historicoContabil,
          MIN (linhaContabil) linhaContabil,
          MIN (idDocumento) idDocumento,
          MIN (data) data,
          MIN (fatoContabil) fatoContabil,
          MIN (estabelecimento) estabelecimento,
          MIN (pessoa) pessoa,
          MIN (documento) documento,
          MIN (complemento) complemento,
          MAX (documentoAberto) documentoAberto,
          SUM (valor) valor
        FROM TEMPCONTABILANALITICO
        WHERE sessaoClient = p_sessaoClient
        AND contadorSessao = p_contadorSessao
        GROUP BY
          quebra,
          origemContabil,
          debitoCredito,
          idContaContabil,
          historicoContabil) a
      JOIN CAPESSOAS pess
      ON pess.pessoa = a.pessoa
      JOIN PAHISTORICOSCONTABEIS hist
      ON hist.historicoContabil = a.historicoContabil
      ORDER BY
        a.quebra,
        a.linhaContabil,
        a.valor,
        a.debitoCredito DESC,
        a.idContaContabil,
        a.historicoContabil)
    LOOP
      IF a.debitoCredito = 'D' THEN
        SELECT COALESCE (MIN (b.id), 0)
        INTO v_idAtualizar
        FROM TEMPCONTABILSINTETICO b
        WHERE b.sessaoClient = p_sessaoClient
        AND b.contadorSessao = p_contadorSessao
        AND b.quebra = a.quebra
        AND b.valor = a.valor
        AND b.estabelecimento = a.estabelecimento
        AND b.historicoContabil = a.historicoContabil
        AND b.debitar = 0;
      ELSE
        SELECT COALESCE (MIN (b.id), 0)
        INTO v_idAtualizar
        FROM TEMPCONTABILSINTETICO b
        WHERE b.sessaoClient = p_sessaoClient
        AND b.contadorSessao = p_contadorSessao
        AND b.quebra = a.quebra
        AND b.valor = a.valor
        AND b.estabelecimento = a.estabelecimento
        AND b.historicoContabil = a.historicoContabil
        AND b.creditar = 0;
      END IF;
      IF v_idAtualizar = 0 THEN
        v_idCriar := v_idCriar + 1;
        INSERT INTO TEMPCONTABILSINTETICO (
          sessaoClient,
          contadorSessao,
          id,
          quebra,
          fato,
          sequencia,
          selecionado,
          estabelecimento,
          estabelecimentoCodigoDescricao,
          idPlanoContaContabil,
          data,
          pessoa,
          pessoaCodigoDescricao,
          documento,
          fatoContabil,
          debitar,
          debitoIdContabil,
          debitoIdContaContabil,
          debitoReduzido,
          debitoCodigoDescricao,
          creditar,
          creditoIdContabil,
          creditoIdContaContabil,
          creditoReduzido,
          creditoCodigoDescricao,
          valor,
          historicoContabil,
          complemento,
          historicoMontado,
          origemContabil,
          idDocumento,
          documentoAberto,
          erroDebito,
          erroCredito,
          erroHistorico,
          erroValor,
          erroGeral)
        VALUES (
          p_sessaoClient,
          p_contadorSessao,
          v_idCriar, -- id
          a.quebra,
          0, -- fato
          0, -- sequencia
          1, -- selecionado
          a.estabelecimento,
          ' ', -- estabelecimentoCodigoDescricao
          0, -- idPlanoContaContabil
          a.data,
          a.pessoa,
          ' ', -- pessoaCodigoDescricao
          a.documento,
          a.fatoContabil,
          CASE
            WHEN a.debitoCredito = 'D'
            THEN 1
            ELSE 0
          END, -- debitar
          0, -- debitoIdContabil
          CASE
            WHEN a.debitoCredito = 'D'
            THEN a.idContaContabil
            ELSE 0
          END, -- debitoIdContaContabil
          0, -- debitoReduzido
          ' ', -- debitoCodigoDescricao
          CASE
            WHEN a.debitoCredito = 'C'
            THEN 1
            ELSE 0
          END, -- creditar
          0, -- creditoIdContabil
          CASE
            WHEN a.debitoCredito = 'C'
            THEN a.idContaContabil
            ELSE 0
          END, -- creditoIdContaContabil
          0, -- creditoReduzido
          ' ', -- creditoCodigoDescricao
          a.valor,
          a.historicoContabil,
          a.complemento,
          REPLACE (
            REPLACE (
              REPLACE (
                REPLACE (
                  a.descricaoMontada,
                  '@DATA', COALESCE (TO_CHAR (a.data, 'DD/MM/YYYY'), '00/00/0000')),
                '@PESSOA',
                  CASE
                    WHEN a.pessoa = 0
                    THEN 'CONSUMIDOR FINAL'
                    ELSE a.nomeRazaoSocial
                  END),
              '@DOCUMENTO', a.documento),
            '@COMPLEMENTO', a.complemento), -- descricaoHistorico
          a.origemContabil,
          a.idDocumento,
          a.documentoAberto,
          ' ',
          ' ',
          ' ',
          ' ',
          ' ');
      ELSIF a.debitoCredito = 'D' THEN
        UPDATE TEMPCONTABILSINTETICO b SET
          b.debitar = 1,
          b.debitoIdContaContabil = a.idContaContabil
        WHERE b.sessaoClient = p_sessaoClient
        AND b.contadorSessao = p_contadorSessao
        AND b.id = v_idAtualizar;
      ELSE
        UPDATE TEMPCONTABILSINTETICO b SET
          b.creditar = 1,
          b.creditoIdContaContabil = a.idContaContabil
        WHERE b.sessaoClient = p_sessaoClient
        AND b.contadorSessao = p_contadorSessao
        AND b.id = v_idAtualizar;
      END IF;
    END LOOP;
  END IF;
  v_quebra    := ' ';
  v_fato      := 0;
  v_sequencia := 0;
  FOR a IN (
    SELECT
      a.id,
      a.quebra,
      CASE
        WHEN a.estabelecimento = 0
        THEN ' '
        ELSE COALESCE (estab.descricao, ' ')
      END estabelecimentoCodigoDescricao,
      estab.idPlanoContaContabil,
      CASE
        WHEN a.pessoa = 0
        THEN ' '
        ELSE COALESCE (pess.nomeRazaoSocial, ' ')
      END pessoaCodigoDescricao,
      CASE
        WHEN a.debitar = 0
          OR a.debitoIdContaContabil = 0
        THEN 0
        ELSE COALESCE (contDeb.reduzido, 0)
      END debitoReduzido,
      CASE
        WHEN a.debitar = 0
          OR a.debitoIdContaContabil = 0
        THEN ' '
        ELSE COALESCE (contDeb.contaEstruturada, ' ')
          || ' - '
          || COALESCE (contDeb.descricao, ' ')
      END debitoCodigoDescricao,
      CASE
        WHEN a.creditar = 0
          OR a.creditoIdContaContabil = 0
          THEN 0
          ELSE COALESCE (contCred.reduzido, 0)
      END creditoReduzido,
      CASE
        WHEN a.creditar = 0
          OR a.creditoIdContaContabil = 0
        THEN ' '
        ELSE COALESCE (contCred.contaEstruturada, ' ')
          || ' - '
          || COALESCE (contCred.descricao, ' ')
      END creditoCodigoDescricao
    FROM TEMPCONTABILSINTETICO a
    JOIN PAESTABELECIMENTOS estab
    ON estab.estabelecimento = a.estabelecimento
    JOIN CAPESSOAS pess
    ON pess.pessoa = a.pessoa
    JOIN PACONTASCONTABEIS contDeb
    ON contDeb.idContaContabil = a.debitoIdContaContabil
    JOIN PACONTASCONTABEIS contCred
    ON contCred.idContaContabil = a.creditoIdContaContabil
    WHERE a.sessaoClient = p_sessaoClient
    AND a.contadorSessao = p_contadorSessao
    ORDER BY
      a.quebra,
      a.id)
  LOOP
    IF v_quebra <> a.quebra THEN
      v_fato      := v_fato + 1;
      v_sequencia := 0;
      v_quebra    := a.quebra;
    END IF;
    v_sequencia := v_sequencia + 1;
    UPDATE TEMPCONTABILSINTETICO b SET
      b.fato = v_fato,
      b.sequencia = v_sequencia,
      b.estabelecimentoCodigoDescricao = a.estabelecimentoCodigoDescricao,
      b.idPlanoContaContabil = a.idPlanoContaContabil,
      b.pessoaCodigoDescricao = a.pessoaCodigoDescricao,
      b.debitoReduzido = a.debitoReduzido,
      b.debitoCodigoDescricao = a.debitoCodigoDescricao,
      b.creditoReduzido = a.creditoReduzido,
      b.creditoCodigoDescricao = a.creditoCodigoDescricao
    WHERE b.sessaoClient = p_sessaoClient
    AND b.contadorSessao = p_contadorSessao
    AND b.id = a.id;
  END LOOP;
  IF p_situacaoContabilizacao <> 'C' THEN
    -- Fim Gera TEMPCONTABILSINTETICO
    ADD_TEMPCONTABIL_VERIFICA_ERRO (
      p_sessaoClient,
      p_contadorSessao,
      0); -- p_fato
  END IF;
END ADD_TEMPCONTABIL_GERA_TEMP;

/

create or replace PROCEDURE ADD_TEMPMARGEMCONTRIB_GRAVA (
  p_sessaoClient                 IN VARCHAR2,
  p_usuarioLogado                IN NUMBER,
  p_perfilUsuarioLogado          IN NUMBER,
  p_config_65_casasDecEntrada    IN CHAR,
  p_config_209_filtrarGrupoEcon  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_taxaCapitacaoCustoFi IN NUMBER,
  p_regMarg_exibImagemMargemItem IN NUMBER,
  p_regMarg_regraImagemItem      IN NUMBER,
  p_contadorSessao               IN NUMBER,
  p_cab_estabelecimento          IN NUMBER,
  p_cab_dataEmissao              IN DATE,
  p_cab_prazoMedioPonderado      IN NUMBER,
  p_munEndEst_uf                 IN CHAR,
  p_munEndPess_uf                IN CHAR,
  p_item_id                      IN NUMBER,
  p_item_modeloDocumento         IN NUMBER,
  p_item_gradeProduto            IN NUMBER,
  p_item_idFormulaTinta          IN NUMBER,
  p_item_personalizacao          IN NUMBER,
  p_item_quantidade              IN NUMBER,
  p_item_valorFreteItem          IN NUMBER,
  p_item_valorSeguroItem         IN NUMBER,
  p_item_valorFreteGeral         IN NUMBER,
  p_item_valorSeguroGeral        IN NUMBER,
  p_item_valorAdicFreteMarTotal  IN NUMBER,
  p_item_valorDespesasAduanTotal IN NUMBER,
  p_item_valorRetIRRF            IN NUMBER,
  p_item_valorRetCSLL            IN NUMBER,
  p_item_valorII                 IN NUMBER,
  p_item_valorIOF                IN NUMBER,
  p_item_valorIPI                IN NUMBER,
  p_item_valorIPIDevolucao       IN NUMBER,
  p_item_valorPIS                IN NUMBER,
  p_item_valorPISST              IN NUMBER,
  p_item_valorCOFINS             IN NUMBER,
  p_item_valorCOFINSST           IN NUMBER,
  p_item_valorCreditoSimplesNac  IN NUMBER,
  p_item_valorICMSOperacao       IN NUMBER,
  p_item_valorICMSDiferido       IN NUMBER,
  p_item_valorICMS               IN NUMBER,
  p_item_valorICMSDesoneracao    IN NUMBER,
  p_item_valorICMSST             IN NUMBER,
  p_item_valorICMSUFDestinatario IN NUMBER,
  p_item_valorICMSUFRemetente    IN NUMBER,
  p_item_valorFCP                IN NUMBER,
  p_item_valorFCPST              IN NUMBER,
  p_item_valorFCPSTAnteriormente IN NUMBER,
  p_item_valorFCPUFDestinatario  IN NUMBER,
  p_item_valorLiquidoItem        IN NUMBER)
IS
  v_item_valorLiquidoSemFreteSeg NUMBER;
  v_item_valorCaptacao           NUMBER;
  v_item_valorTarifaCartao       NUMBER;
  v_item_valorImpostos           NUMBER;
  v_item_precoCusto              NUMBER;
  v_item_valorCusto              NUMBER;
  v_item_valorMargem             NUMBER;
  v_item_percentualMargem        NUMBER;
  v_item_imagemMargem            VARCHAR2(256);
BEGIN
  ADD_CALCULA_MARGEM_CONTRIB (
    p_usuarioLogado,
    p_perfilUsuarioLogado,
    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_taxaCapitacaoCustoFi,
    p_regMarg_exibImagemMargemItem,
    p_regMarg_regraImagemItem,
    p_cab_estabelecimento,
    p_cab_dataEmissao,
    p_cab_prazoMedioPonderado,
    p_munEndEst_uf,
    p_munEndPess_uf,
    p_item_modeloDocumento,
    p_item_gradeProduto,
    p_item_idFormulaTinta,
    p_item_personalizacao,
    p_item_quantidade,
    p_item_valorFreteItem,
    p_item_valorSeguroItem,
    p_item_valorFreteGeral,
    p_item_valorSeguroGeral,
    p_item_valorAdicFreteMarTotal,
    p_item_valorDespesasAduanTotal,
    p_item_valorRetIRRF,
    p_item_valorRetCSLL,
    p_item_valorII,
    p_item_valorIOF,
    p_item_valorIPI,
    p_item_valorIPIDevolucao,
    p_item_valorPIS,
    p_item_valorPISST,
    p_item_valorCOFINS,
    p_item_valorCOFINSST,
    p_item_valorCreditoSimplesNac,
    p_item_valorICMSOperacao,
    p_item_valorICMSDiferido,
    p_item_valorICMS,
    p_item_valorICMSDesoneracao,
    p_item_valorICMSST,
    p_item_valorICMSUFDestinatario,
    p_item_valorICMSUFRemetente,
    p_item_valorFCP,
    p_item_valorFCPST,
    p_item_valorFCPSTAnteriormente,
    p_item_valorFCPUFDestinatario,
    p_item_valorLiquidoItem,
    /* Retornos */
    v_item_valorLiquidoSemFreteSeg,
    v_item_valorCaptacao,
    v_item_valorImpostos,
    v_item_precoCusto,
    v_item_valorCusto,
    v_item_valorMargem,
    v_item_percentualMargem);
  IF p_regMarg_exibImagemMargemItem = 1
    AND p_regMarg_regraImagemItem <> 0
  THEN
    v_item_imagemMargem :=
      FUNC_ADD_BUSCA_IMAGEM_FAIXA (
        p_regMarg_regraImagemItem,
        v_item_percentualMargem);
  ELSE
    v_item_imagemMargem := ' ';
  END IF;
  MERGE INTO TEMPMARGEMCONTRIBUICAO a USING (
    SELECT
      p_sessaoClient                 sessaoClient,
      'O'                            orcamentoPredocumentoDocumento,
      p_contadorSessao               contadorSessao,
      p_item_id                      id,
      v_item_valorLiquidoSemFreteSeg valorLiquidoSemFreteSeguro,
      v_item_valorCaptacao           valorCaptacao,
      v_item_valorImpostos           valorImpostos,
      v_item_precoCusto              precoCusto,
      v_item_valorCusto              valorCusto,
      v_item_valorMargem             valorMargem,
      v_item_percentualMargem        percentualMargem,
      v_item_imagemMargem            imagemMargem
    FROM DUAL) b ON (
      a.sessaoClient = b.sessaoClient 
      AND a.contadorSessao = b.contadorSessao
      AND a.id = b.id)
  WHEN MATCHED THEN UPDATE SET
    a.valorLiquidoSemFreteSeguro = b.valorLiquidoSemFreteSeguro,
    a.valorCaptacao              = b.valorCaptacao,
    a.valorImpostos              = b.valorImpostos,
    a.precoCusto                 = b.precoCusto,
    a.valorCusto                 = b.valorCusto,
    a.valorMargem                = b.valorMargem,
    a.percentualMargem           = b.percentualMargem,
    a.imagemMargem               = b.imagemMargem
  WHEN NOT MATCHED THEN INSERT (
    sessaoClient,
    contadorSessao,
    id,
    valorLiquidoSemFreteSeguro,
    valorCaptacao,
    valorImpostos,
    precoCusto,
    valorCusto,
    valorMargem,
    percentualMargem,
    imagemMargem)
  VALUES (
    b.sessaoClient,
    b.contadorSessao,
    b.id,
    b.valorLiquidoSemFreteSeguro,
    b.valorCaptacao,
    b.valorImpostos,
    b.precoCusto,
    b.valorCusto,
    b.valorMargem,
    b.percentualMargem,
    b.imagemMargem);
END ADD_TEMPMARGEMCONTRIB_GRAVA;

/

create or replace PROCEDURE ADD_ENTREGA_CRIA_PENDENTE (
  p_sys_usuarioLogado            IN NUMBER,
  p_sys_estabelecimentoAtivo     IN NUMBER,
  p_config_209_filtrarGrupoEcon  IN NUMBER,
  p_config_354_estabProximoId    IN NUMBER,
  p_config_362_calcCustoPorGrade IN NUMBER,
  p_idItemOrcamento              IN NUMBER)
IS
  v_quantidadeSaldo NUMBER;
  v_auxNumber       NUMBER;
  v_auxVarchar      VARCHAR (32000);
BEGIN
  FOR a IN (
    SELECT
      a.modeloDocumentoEntrega,
      a.estabelecimento,
      a.dataEntrega,
      a.motorista,
      a.placa,
      (a.quantidadeConvertida - a.quantidadeEntrega) quantidadePendente
    FROM (
      SELECT
        contr.modeloDocumentoEntrega,
        orc.estabelecimento,
        COALESCE (item.dataEntrega, orc.dataEntrega) dataEntrega,
        orc.motorista,
        orc.placa,
        item.quantidadeConvertida,
        COALESCE ((
          SELECT SUM (entr.quantidade)
          FROM MOENTREGAS entr
          WHERE entr.idItemOrcamento = item.idItemOrcamento), 0) quantidadeEntrega
      FROM MOORCAMENTOXITENS item
      JOIN PACONTROLESENTREGA contr
      ON contr.controleEntrega = item.controleEntrega
      JOIN MOORCAMENTOS orc
      ON orc.orcamento = item.orcamento
      WHERE item.idItemOrcamento = p_idItemOrcamento
      AND item.cancelado = 0
      AND item.controleEntrega > 0) a
    WHERE a.quantidadeConvertida <> a.quantidadeEntrega)
  LOOP
    IF a.quantidadePendente > 0 THEN
      ADD_ENTREGA_CRIA (
        p_sys_usuarioLogado,
        p_sys_estabelecimentoAtivo,
        a.modeloDocumentoEntrega, -- p_modeloDocumento,
        a.estabelecimento, -- p_estabelecimento,
        a.dataEntrega, -- p_dataEntrega,
        TO_CHAR (a.dataEntrega, 'HH24MISS'), -- p_horaEntregaFinal,
        a.motorista, -- p_motorista,
        a.placa, -- p_placa,
        0, -- p_rota,
        p_idItemOrcamento,
        0, -- p_idItemPreDocumentoRemessa,
        0, -- p_idItemDocFiscalRemessa,
        a.quantidadePendente, -- p_quantidade,
        1, -- p_situacaoEntrega
        'ADD_ENTREGA_CRIA_PENDENTE'  -- p_observacoes
      );
    ELSIF a.quantidadePendente < 0 THEN
      v_quantidadeSaldo := - a.quantidadePendente;
      FOR b IN (
        SELECT
          entr.entrega,
          entr.modeloDocumento,
          entr.estabelecimento,
          entr.dataEntrega,
          entr.horaEntregaFinal,
          entr.motorista,
          entr.placa,
          entr.rota,
          entr.quantidade,
          entr.situacaoEntrega,
          entr.observacoes
        FROM MOENTREGAS entr
        WHERE entr.idItemOrcamento = p_idItemOrcamento
        AND entr.situacaoEntrega IN (1,2))
      LOOP
        IF v_quantidadeSaldo > 0
          AND b.quantidade > 0 THEN
          IF v_quantidadeSaldo < b.quantidade THEN
            ADD_ENTREGA_CRIA (
              p_sys_usuarioLogado,
              p_sys_estabelecimentoAtivo,
              b.modeloDocumento,
              b.estabelecimento,
              b.dataEntrega,
              b.horaEntregaFinal,
              b.motorista,
              b.placa,
              b.rota,
              p_idItemOrcamento,
              0,
              0,
              b.quantidade - v_quantidadeSaldo,
              b.situacaoEntrega,
              b.observacoes);
            UPDATE MOENTREGAS c SET
              c.quantidade = v_quantidadeSaldo
            WHERE c.entrega = b.entrega;
            ADD_ENTREGA_SITUACAO_CRIA (
              p_sys_usuarioLogado,
              p_sys_estabelecimentoAtivo,
              p_idItemOrcamento,
              b.entrega,
              b.situacaoEntrega,
              'ADD_ENTREGA_CRIA_PENDENTE - Ajusta Saldo');
            v_quantidadeSaldo := 0;
          ELSE
            ADD_ENTREGA_EXCLUI (
              p_sys_usuarioLogado,
              p_sys_estabelecimentoAtivo,
              b.entrega,
              0,
              'ADD_ENTREGA_CRIA_PENDENTE');
            v_quantidadeSaldo := v_quantidadeSaldo - b.quantidade;
          END IF;
        END IF;
      END LOOP;
    END IF;
  END LOOP;
  ADD_RESERVA_ESTOQUE_ORC_ITEM (
    p_sys_estabelecimentoAtivo,
    p_config_209_filtrarGrupoEcon,
    p_config_354_estabProximoId,
    p_config_362_calcCustoPorGrade,
    p_idItemOrcamento,
    '',
    '',
    v_auxVarchar,
    v_auxVarchar);
END ADD_ENTREGA_CRIA_PENDENTE;

/

create or replace PROCEDURE ADD_DOCTROCA_ITEM_EXCLUI (
  p_idItemDocTroca IN NUMBER)
IS
  v_quantidade              NUMBER;
  v_idItemPreDocumentoSaida NUMBER;
  v_idItemDocFiscalSaida    NUMBER;
  v_idEstoque               NUMBER;
BEGIN
  SELECT
    quantidade,
    idItemPreDocumentoSaida,
    idItemDocFiscalSaida,
    idEstoque
  INTO
    v_quantidade,
    v_idItemPreDocumentoSaida,
    v_idItemDocFiscalSaida,
    v_idEstoque
  FROM MODOCTROCAXITENS
  WHERE idItemDocTroca = p_idItemDocTroca;
  DELETE MODOCTROCAXITENS
  WHERE idItemDocTroca = p_idItemDocTroca;
  IF v_idItemPreDocumentoSaida > 0 THEN
    UPDATE MOPREDOCUMXITENS
    SET quantidadeDevolvidaRetornada =
      CASE
        WHEN quantidadeDevolvidaRetornada < v_quantidade
        THEN 0
        ELSE quantidadeDevolvidaRetornada - v_quantidade
      END
    WHERE idItemPreDocumento = v_idItemPreDocumentoSaida;
  END IF;
  IF v_idItemDocFiscalSaida > 0 THEN
    UPDATE MODOCFISCALXITENS
    SET quantidadeDevolvidaRetornada =
      CASE
        WHEN quantidadeDevolvidaRetornada < v_quantidade
        THEN 0
        ELSE quantidadeDevolvidaRetornada - v_quantidade
      END
    WHERE idItemDocFiscal = v_idItemDocFiscalSaida;
  END IF;
  IF v_idEstoque > 0 THEN
    ADD_ESTOQUE_EXCLUI (v_idEstoque);
  END IF;
END ADD_DOCTROCA_ITEM_EXCLUI;

/

create or replace PROCEDURE ADD_DOCTROCA_CAB_EXCLUI (
  p_documentoTroca IN NUMBER)
IS
  v_idFinanceiroAdiantamento NUMBER;
BEGIN
  SELECT idFinanceiroAdiantamento
  INTO v_idFinanceiroAdiantamento
  FROM MODOCUMENTOSTROCA
  WHERE documentoTroca = p_documentoTroca;
  FOR a IN (
    SELECT idItemDocTroca
    FROM MODOCTROCAXITENS
    WHERE documentoTroca = p_documentoTroca)
  LOOP
    ADD_DOCTROCA_ITEM_EXCLUI (a.idItemDocTroca);
  END LOOP;
  DELETE MODOCUMENTOSTROCA
  WHERE documentoTroca = p_documentoTroca;
  IF v_idFinanceiroAdiantamento > 0 THEN
    ADD_FINANC_EXCLUI (v_idFinanceiroAdiantamento);
  END IF;
END ADD_DOCTROCA_CAB_EXCLUI;

/

create or replace PROCEDURE ADD_ORCAMENTO_ITEM_N_SER_GRAVA (
  p_estabelecimentoAtivo         IN NUMBER,
  p_idNumeroSerieOrcamento       IN NUMBER,
  p_idItemOrcamento              IN NUMBER,
  p_gradeProduto                 IN NUMBER,
  p_idNumeroSerie                IN NUMBER,
  p_efetivado                    IN NUMBER,
  /* Retornos */
  r_idNumeroSerieOrcamento       OUT NUMBER)
IS
BEGIN
  r_idNumeroSerieOrcamento := p_idNumeroSerieOrcamento;
  IF r_idNumeroSerieOrcamento = 0 THEN
    SELECT COALESCE (MAX (idNumeroSerieOrcamento), 0)
    INTO r_idNumeroSerieOrcamento
    FROM MOORCAMENTOXNUMEROSSERIE
    WHERE idItemOrcamento = p_idItemOrcamento
    AND idNumeroSerie = p_idNumeroSerie;
  END IF; 
  IF r_idNumeroSerieOrcamento = 0 THEN
    r_idNumeroSerieOrcamento := FUNC_ADD_BUSCA_PROXIMO_ID('MOORCAMENTOXNUMEROSSERIE', 'idNumeroSerieOrcamento', 14, p_estabelecimentoAtivo, NULL);
  END IF;
  MERGE INTO MOORCAMENTOXNUMEROSSERIE a 
  USING (
    SELECT
      r_idNumeroSerieOrcamento idNumeroSerieOrcamento,
      p_idItemOrcamento        idItemOrcamento,
      p_gradeProduto           gradeProduto,
      p_idNumeroSerie          idNumeroSerie,
      p_efetivado              efetivado
    FROM DUAL
  ) b ON (a.idNumeroSerieOrcamento = b.idNumeroSerieOrcamento)
  WHEN MATCHED THEN UPDATE SET
    a.idItemOrcamento = b.idItemOrcamento,
    a.gradeProduto    = b.gradeProduto,
    a.idNumeroSerie   = b.idNumeroSerie,
    a.efetivado       = b.efetivado
  WHEN NOT MATCHED THEN INSERT (
    idNumeroSerieOrcamento,
    idItemOrcamento,
    gradeProduto,
    idNumeroSerie,
    efetivado)
  VALUES (
    b.idNumeroSerieOrcamento,
    b.idItemOrcamento,
    b.gradeProduto,
    b.idNumeroSerie,
    b.efetivado);
END ADD_ORCAMENTO_ITEM_N_SER_GRAVA;

/

create or replace PROCEDURE ADD_PRE_DOC_ITEM_N_SER_GRAVA (
  p_estabelecimentoAtivo         IN NUMBER,
  p_idNumeroSeriePreDocumento    IN NUMBER,
  p_idItemPreDocumento           IN NUMBER,
  p_gradeProduto                 IN NUMBER,
  p_idNumeroSerie                IN NUMBER,
  p_devolvidoRetornado           IN NUMBER,
  /* Retornos */
  r_idNumeroSeriePreDocumento    OUT NUMBER)
IS
BEGIN
  r_idNumeroSeriePreDocumento := p_idNumeroSeriePreDocumento;
  IF r_idNumeroSeriePreDocumento = 0 THEN
    SELECT COALESCE (MAX (idNumeroSeriePreDocumento), 0)
    INTO r_idNumeroSeriePreDocumento
    FROM MOPREDOCUMXNUMEROSSERIE
    WHERE idItemPreDocumento = p_idItemPreDocumento
    AND idNumeroSerie = p_idNumeroSerie;
  END IF; 
  IF r_idNumeroSeriePreDocumento = 0 THEN
    r_idNumeroSeriePreDocumento := FUNC_ADD_BUSCA_PROXIMO_ID('MOPREDOCUMXNUMEROSSERIE', 'idNumeroSeriePreDocumento', 14, p_estabelecimentoAtivo, NULL);
  END IF;
  MERGE INTO MOPREDOCUMXNUMEROSSERIE a 
  USING (
    SELECT
      r_idNumeroSeriePreDocumento idNumeroSeriePreDocumento,
      p_idItemPreDocumento        idItemPreDocumento,
      p_gradeProduto              gradeProduto,
      p_idNumeroSerie             idNumeroSerie,
      p_devolvidoRetornado        devolvidoRetornado
    FROM DUAL
  ) b ON (a.idNumeroSeriePreDocumento = b.idNumeroSeriePreDocumento)
  WHEN MATCHED THEN UPDATE SET
    a.idItemPreDocumento = b.idItemPreDocumento,
    a.gradeProduto       = b.gradeProduto,
    a.idNumeroSerie      = b.idNumeroSerie,
    a.devolvidoRetornado = b.devolvidoRetornado
  WHEN NOT MATCHED THEN INSERT (
    idNumeroSeriePreDocumento,
    idItemPreDocumento,
    gradeProduto,
    idNumeroSerie,
    devolvidoRetornado)
  VALUES (
    b.idNumeroSeriePreDocumento,
    b.idItemPreDocumento,
    b.gradeProduto,
    b.idNumeroSerie,
    b.devolvidoRetornado);
END ADD_PRE_DOC_ITEM_N_SER_GRAVA;

/

create or replace PROCEDURE ADD_DOC_FISC_ITEM_N_SER_GRAVA (
  p_estabelecimentoAtivo       IN NUMBER,
  p_idNumeroSerieDocFiscal     IN NUMBER,
  p_idItemDocFiscal            IN NUMBER,
  p_gradeProduto               IN NUMBER,
  p_idNumeroSerie              IN NUMBER,
  p_devolvidoRetornado         IN NUMBER,
  /* Retornos */
  r_idNumeroSerieDocFiscal     OUT NUMBER)
IS
BEGIN
  r_idNumeroSerieDocFiscal := p_idNumeroSerieDocFiscal;
  IF r_idNumeroSerieDocFiscal = 0 THEN
    SELECT COALESCE (MAX (idNumeroSerieDocFiscal), 0)
    INTO r_idNumeroSerieDocFiscal
    FROM MODOCFISCALXNUMEROSSERIE
    WHERE idItemDocFiscal = p_idItemDocFiscal
    AND idNumeroSerie = p_idNumeroSerie;
  END IF; 
  IF r_idNumeroSerieDocFiscal = 0 THEN
    r_idNumeroSerieDocFiscal := FUNC_ADD_BUSCA_PROXIMO_ID('MODOCFISCALXNUMEROSSERIE', 'idNumeroSerieDocFiscal', 14, p_estabelecimentoAtivo, NULL);
  END IF;
  MERGE INTO MODOCFISCALXNUMEROSSERIE a 
  USING (
    SELECT
      r_idNumeroSerieDocFiscal idNumeroSerieDocFiscal,
      p_idItemDocFiscal        idItemDocFiscal,
      p_gradeProduto           gradeProduto,
      p_idNumeroSerie          idNumeroSerie,
      p_devolvidoRetornado     devolvidoRetornado
    FROM DUAL
  ) b ON (a.idNumeroSerieDocFiscal = b.idNumeroSerieDocFiscal)
  WHEN MATCHED THEN UPDATE SET
    a.idItemDocFiscal    = b.idItemDocFiscal,
    a.gradeProduto       = b.gradeProduto,
    a.idNumeroSerie      = b.idNumeroSerie,
    a.devolvidoRetornado = b.devolvidoRetornado
  WHEN NOT MATCHED THEN INSERT (
    idNumeroSerieDocFiscal,
    idItemDocFiscal,
    gradeProduto,
    idNumeroSerie,
    devolvidoRetornado)
  VALUES (
    b.idNumeroSerieDocFiscal,
    b.idItemDocFiscal,
    b.gradeProduto,
    b.idNumeroSerie,
    b.devolvidoRetornado);
END ADD_DOC_FISC_ITEM_N_SER_GRAVA;

/

create or replace PROCEDURE ADD_DOCTRANSF_ITEM_N_SER_GRAVA (
  p_estabelecimentoAtivo   IN NUMBER,
  p_idNumeroSerieDocTransf IN NUMBER,
  p_idItemDocTransferencia IN NUMBER,
  p_gradeProduto           IN NUMBER,
  p_idNumeroSerie          IN NUMBER,
  /* Retornos */
  r_idNumeroSerieDocTransf OUT NUMBER)
IS
BEGIN
  r_idNumeroSerieDocTransf := p_idNumeroSerieDocTransf;
  IF r_idNumeroSerieDocTransf = 0 THEN
    SELECT COALESCE (MAX (idNumeroSerieDocTransf), 0)
    INTO r_idNumeroSerieDocTransf
    FROM MODOCTRANSFXNUMEROSSERIE
    WHERE idItemDocTransferencia = p_idItemDocTransferencia
    AND idNumeroSerie = p_idNumeroSerie;
  END IF; 
  IF r_idNumeroSerieDocTransf = 0 THEN
    r_idNumeroSerieDocTransf := FUNC_ADD_BUSCA_PROXIMO_ID('MODOCTRANSFXNUMEROSSERIE', 'idNumeroSerieDocTransf', 14, p_estabelecimentoAtivo, NULL);
  END IF;
  MERGE INTO MODOCTRANSFXNUMEROSSERIE a 
  USING (
    SELECT
      r_idNumeroSerieDocTransf idNumeroSerieDocTransf,
      p_idItemDocTransferencia idItemDocTransferencia,
      p_gradeProduto           gradeProduto,
      p_idNumeroSerie          idNumeroSerie
    FROM DUAL
  ) b ON (a.idNumeroSerieDocTransf = b.idNumeroSerieDocTransf)
  WHEN MATCHED THEN UPDATE SET
    a.idItemDocTransferencia = b.idItemDocTransferencia,
    a.gradeProduto           = b.gradeProduto,
    a.idNumeroSerie          = b.idNumeroSerie
  WHEN NOT MATCHED THEN INSERT (
    idNumeroSerieDocTransf,
    idItemDocTransferencia,
    gradeProduto,
    idNumeroSerie)
  VALUES (
    b.idNumeroSerieDocTransf,
    b.idItemDocTransferencia,
    b.gradeProduto,
    b.idNumeroSerie);
END ADD_DOCTRANSF_ITEM_N_SER_GRAVA;

/

create or replace PROCEDURE ADD_ORCAMENTO_ITEM_N_SER_ORC (
  p_estabelecimentoAtivo IN NUMBER,
  p_idItemOrcamentoDe    IN NUMBER,
  p_idItemOrcamentoPara  IN NUMBER,
  p_quantidade           IN NUMBER,
  p_efetivar             IN NUMBER,
  p_atualizarObservacoes IN NUMBER,
  /* Retornos */
  r_atualizarObservacoes OUT NUMBER)
IS
  v_quantidadeSaldo NUMBER;
  v_auxNumber       NUMBER;
BEGIN
  r_atualizarObservacoes := p_atualizarObservacoes;
  v_quantidadeSaldo      := p_quantidade;
  FOR a IN (
    SELECT
      idNumeroSerieOrcamento,
      gradeProduto,
      idNumeroSerie
    FROM MOORCAMENTOXNUMEROSSERIE
    WHERE idItemOrcamento = p_idItemOrcamentoDe
    AND (p_efetivar = 0
      OR efetivado = 0))
  LOOP
    IF v_quantidadeSaldo >= 1 THEN
      v_quantidadeSaldo := v_quantidadeSaldo - 1;
      r_atualizarObservacoes := 1;
      ADD_ORCAMENTO_ITEM_N_SER_GRAVA (
        p_estabelecimentoAtivo,
        0,
        p_idItemOrcamentoPara,
        a.gradeProduto,
        a.idNumeroSerie,
        0,
        /* Retornos */
        v_auxNumber);
      IF p_efetivar = 1 THEN
        UPDATE MOORCAMENTOXNUMEROSSERIE b
        SET b.efetivado = 1
        WHERE b.idNumeroSerieOrcamento = a.idNumeroSerieOrcamento;
      END IF;
    END IF;
  END LOOP;
  IF v_quantidadeSaldo >= 1 THEN
    FOR a IN (
      SELECT
        a.gradeProduto,
        a.idNumeroSerie
      FROM (
        SELECT
          numSer.gradeProduto,
          numSer.idNumeroSerie
        FROM MOENTREGAS entr
        JOIN MOPREDOCUMXNUMEROSSERIE numSer
        ON numSer.idItemPreDocumento = entr.idItemPreDocumentoRemessa
        WHERE entr.idItemOrcamento = p_idItemOrcamentoDe
        AND entr.idItemPreDocumentoRemessa > 0
        UNION ALL
        SELECT
          numSer.gradeProduto,
          numSer.idNumeroSerie
        FROM MOENTREGAS entr
        JOIN MODOCFISCALXNUMEROSSERIE numSer
        ON numSer.idItemDocFiscal = entr.idItemDocFiscalRemessa
        WHERE entr.idItemOrcamento = p_idItemOrcamentoDe
        AND entr.idItemDocFiscalRemessa > 0) a
      GROUP BY
        a.gradeProduto,
        a.idNumeroSerie)
    LOOP
      IF v_quantidadeSaldo >= 1 THEN
        v_quantidadeSaldo := v_quantidadeSaldo - 1;
        r_atualizarObservacoes := 1;
        ADD_ORCAMENTO_ITEM_N_SER_GRAVA (
          p_estabelecimentoAtivo,
          0,
          p_idItemOrcamentoPara,
          a.gradeProduto,
          a.idNumeroSerie,
          0,
          /* Retornos */
          v_auxNumber);
      END IF;
    END LOOP;
  END IF;
END ADD_ORCAMENTO_ITEM_N_SER_ORC;

/

create or replace PROCEDURE ADD_PRE_DOC_ITEM_N_SER_ORCAMEN (
  p_estabelecimentoAtivo   IN NUMBER,
  p_idItemOrcamentoDe      IN NUMBER,
  p_idItemPreDocumentoPara IN NUMBER,
  p_quantidade             IN NUMBER,
  p_efetivar               IN NUMBER,
  p_atualizarObservacoes   IN NUMBER,
  /* Retornos */
  r_atualizarObservacoes   OUT NUMBER)
IS
  v_quantidadeSaldo NUMBER;
  v_auxNumber       NUMBER;
BEGIN
  r_atualizarObservacoes := p_atualizarObservacoes;
  v_quantidadeSaldo      := p_quantidade;
  FOR a IN (
    SELECT
      idNumeroSerieOrcamento,
      gradeProduto,
      idNumeroSerie
    FROM MOORCAMENTOXNUMEROSSERIE
    WHERE idItemOrcamento = p_idItemOrcamentoDe
    AND (p_efetivar = 0
      OR efetivado = 0))
  LOOP
    IF v_quantidadeSaldo >= 1 THEN
      v_quantidadeSaldo := v_quantidadeSaldo - 1;
      r_atualizarObservacoes := 1;
      ADD_PRE_DOC_ITEM_N_SER_GRAVA (
        p_estabelecimentoAtivo,
        0,
        p_idItemPreDocumentoPara,
        a.gradeProduto,
        a.idNumeroSerie,
        0,
        /* Retornos */
        v_auxNumber);
      IF p_efetivar = 1 THEN
        UPDATE MOORCAMENTOXNUMEROSSERIE b
        SET b.efetivado = 1
        WHERE b.idNumeroSerieOrcamento = a.idNumeroSerieOrcamento;
      END IF;
    END IF;
  END LOOP;
  IF v_quantidadeSaldo >= 1 THEN
    FOR a IN (
      SELECT
        a.gradeProduto,
        a.idNumeroSerie
      FROM (
        SELECT
          numSer.gradeProduto,
          numSer.idNumeroSerie
        FROM MOENTREGAS entr
        JOIN MOPREDOCUMXNUMEROSSERIE numSer
        ON numSer.idItemPreDocumento = entr.idItemPreDocumentoRemessa
        WHERE entr.idItemOrcamento = p_idItemOrcamentoDe
        AND entr.idItemPreDocumentoRemessa > 0
        UNION ALL
        SELECT
          numSer.gradeProduto,
          numSer.idNumeroSerie
        FROM MOENTREGAS entr
        JOIN MODOCFISCALXNUMEROSSERIE numSer
        ON numSer.idItemDocFiscal = entr.idItemDocFiscalRemessa
        WHERE entr.idItemOrcamento = p_idItemOrcamentoDe
        AND entr.idItemDocFiscalRemessa > 0) a
      GROUP BY
        a.gradeProduto,
        a.idNumeroSerie)
    LOOP
      IF v_quantidadeSaldo >= 1 THEN
        v_quantidadeSaldo := v_quantidadeSaldo - 1;
        r_atualizarObservacoes := 1;
        ADD_PRE_DOC_ITEM_N_SER_GRAVA (
          p_estabelecimentoAtivo,
          0,
          p_idItemPreDocumentoPara,
          a.gradeProduto,
          a.idNumeroSerie,
          0,
          /* Retornos */
          v_auxNumber);
      END IF;
    END LOOP;
  END IF;
END ADD_PRE_DOC_ITEM_N_SER_ORCAMEN;

/

create or replace PROCEDURE ADD_DOC_FISC_ITEM_N_SER_ORCAM (
  p_estabelecimentoAtivo IN NUMBER,
  p_idItemOrcamentoDe    IN NUMBER,
  p_idItemDocFiscalPara  IN NUMBER,
  p_quantidade           IN NUMBER,
  p_efetivar             IN NUMBER,
  p_atualizarObservacoes IN NUMBER,
  /* Retornos */
  r_atualizarObservacoes OUT NUMBER)
IS
  v_quantidadeSaldo NUMBER;
  v_auxNumber       NUMBER;
BEGIN
  r_atualizarObservacoes := p_atualizarObservacoes;
  v_quantidadeSaldo      := p_quantidade;
  FOR a IN (
    SELECT
      idNumeroSerieOrcamento,
      gradeProduto,
      idNumeroSerie
    FROM MOORCAMENTOXNUMEROSSERIE
    WHERE idItemOrcamento = p_idItemOrcamentoDe
    AND (p_efetivar = 0
      OR efetivado = 0))
  LOOP
    IF v_quantidadeSaldo >= 1 THEN
      v_quantidadeSaldo := v_quantidadeSaldo - 1;
      r_atualizarObservacoes := 1;
      ADD_DOC_FISC_ITEM_N_SER_GRAVA (
        p_estabelecimentoAtivo,
        0,
        p_idItemDocFiscalPara,
        a.gradeProduto,
        a.idNumeroSerie,
        0,
        /* Retornos */
        v_auxNumber);
      IF p_efetivar = 1 THEN
        UPDATE MOORCAMENTOXNUMEROSSERIE b
        SET b.efetivado = 1
        WHERE b.idNumeroSerieOrcamento = a.idNumeroSerieOrcamento;
      END IF;
    END IF;
  END LOOP;
  IF v_quantidadeSaldo >= 1 THEN
    FOR a IN (
      SELECT
        a.gradeProduto,
        a.idNumeroSerie
      FROM (
        SELECT
          numSer.gradeProduto,
          numSer.idNumeroSerie
        FROM MOENTREGAS entr
        JOIN MOPREDOCUMXNUMEROSSERIE numSer
        ON numSer.idItemPreDocumento = entr.idItemPreDocumentoRemessa
        WHERE entr.idItemOrcamento = p_idItemOrcamentoDe
        AND entr.idItemPreDocumentoRemessa > 0
        UNION ALL
        SELECT
          numSer.gradeProduto,
          numSer.idNumeroSerie
        FROM MOENTREGAS entr
        JOIN MODOCFISCALXNUMEROSSERIE numSer
        ON numSer.idItemDocFiscal = entr.idItemDocFiscalRemessa
        WHERE entr.idItemOrcamento = p_idItemOrcamentoDe
        AND entr.idItemDocFiscalRemessa > 0) a
      GROUP BY
        a.gradeProduto,
        a.idNumeroSerie)
    LOOP
      IF v_quantidadeSaldo >= 1 THEN
        v_quantidadeSaldo := v_quantidadeSaldo - 1;
        r_atualizarObservacoes := 1;
        ADD_DOC_FISC_ITEM_N_SER_GRAVA (
          p_estabelecimentoAtivo,
          0,
          p_idItemDocFiscalPara,
          a.gradeProduto,
          a.idNumeroSerie,
          0,
          /* Retornos */
          v_auxNumber);
      END IF;
    END LOOP;
  END IF;
END ADD_DOC_FISC_ITEM_N_SER_ORCAM;

/

create or replace PROCEDURE ADD_PRE_DOC_ITEM_N_SER_PRE_DOC (
  p_estabelecimentoAtivo   IN NUMBER,
  p_idItemPreDocumentoDe   IN NUMBER,
  p_idItemPreDocumentoPara IN NUMBER,
  p_quantidade             IN NUMBER,
  p_efetivar               IN NUMBER,
  p_atualizarObservacoes   IN NUMBER,
  /* Retornos */
  r_atualizarObservacoes   OUT NUMBER)
IS
  v_quantidadeSaldo NUMBER;
  v_auxNumber       NUMBER;
BEGIN
  r_atualizarObservacoes := p_atualizarObservacoes;
  v_quantidadeSaldo      := p_quantidade;
  FOR a IN (
    SELECT
      idNumeroSeriePreDocumento,
      gradeProduto,
      idNumeroSerie
    FROM MOPREDOCUMXNUMEROSSERIE
    WHERE idItemPreDocumento = p_idItemPreDocumentoDe
    AND (p_efetivar = 0
      OR devolvidoRetornado = 0))
  LOOP
    IF v_quantidadeSaldo >= 1 THEN
      v_quantidadeSaldo := v_quantidadeSaldo - 1;
      r_atualizarObservacoes := 1;
      ADD_PRE_DOC_ITEM_N_SER_GRAVA (
        p_estabelecimentoAtivo,
        0,
        p_idItemPreDocumentoPara,
        a.gradeProduto,
        a.idNumeroSerie,
        0,
        /* Retornos */
        v_auxNumber);
      IF p_efetivar = 1 THEN
        UPDATE MOPREDOCUMXNUMEROSSERIE b
        SET b.devolvidoRetornado = 1
        WHERE b.idNumeroSeriePreDocumento = a.idNumeroSeriePreDocumento;
      END IF;
    END IF;
  END LOOP;
  IF v_quantidadeSaldo >= 1 THEN
    FOR a IN (
      SELECT
        a.gradeProduto,
        a.idNumeroSerie
      FROM (
        SELECT
          numSer.gradeProduto,
          numSer.idNumeroSerie
        FROM MOPREDOCUMXORCAMENTOITEM docXOrc
        JOIN MOENTREGAS entr
        ON entr.idItemOrcamento = docXOrc.idItemOrcamento
        JOIN MOPREDOCUMXNUMEROSSERIE numSer
        ON numSer.idItemPreDocumento = entr.idItemPreDocumentoRemessa
        WHERE docXOrc.idItemPreDocumento = p_idItemPreDocumentoDe
        AND entr.idItemPreDocumentoRemessa > 0
        UNION ALL
        SELECT
          numSer.gradeProduto,
          numSer.idNumeroSerie
        FROM MOPREDOCUMXORCAMENTOITEM docXOrc
        JOIN MOENTREGAS entr
        ON entr.idItemOrcamento = docXOrc.idItemOrcamento
        JOIN MODOCFISCALXNUMEROSSERIE numSer
        ON numSer.idItemDocFiscal = entr.idItemDocFiscalRemessa
        WHERE docXOrc.idItemPreDocumento = p_idItemPreDocumentoDe
        AND entr.idItemDocFiscalRemessa > 0) a
      GROUP BY
        a.gradeProduto,
        a.idNumeroSerie)
    LOOP
      IF v_quantidadeSaldo >= 1 THEN
        v_quantidadeSaldo := v_quantidadeSaldo - 1;
        r_atualizarObservacoes := 1;
        ADD_PRE_DOC_ITEM_N_SER_GRAVA (
          p_estabelecimentoAtivo,
          0,
          p_idItemPreDocumentoPara,
          a.gradeProduto,
          a.idNumeroSerie,
          0,
          /* Retornos */
          v_auxNumber);
      END IF;
    END LOOP;
  END IF;
END ADD_PRE_DOC_ITEM_N_SER_PRE_DOC;

/

create or replace PROCEDURE ADD_DOC_FISC_ITEM_N_SER_PRE (
  p_estabelecimentoAtivo IN NUMBER,
  p_idItemPreDocumentoDe IN NUMBER,
  p_idItemDocFiscalPara  IN NUMBER,
  p_quantidade           IN NUMBER,
  p_efetivar             IN NUMBER,
  p_atualizarObservacoes IN NUMBER,
  /* Retornos */
  r_atualizarObservacoes OUT NUMBER)
IS
  v_quantidadeSaldo NUMBER;
  v_auxNumber       NUMBER;
BEGIN
  r_atualizarObservacoes := p_atualizarObservacoes;
  v_quantidadeSaldo      := p_quantidade;
  FOR a IN (
    SELECT
      idNumeroSeriePreDocumento,
      gradeProduto,
      idNumeroSerie
    FROM MOPREDOCUMXNUMEROSSERIE
    WHERE idItemPreDocumento = p_idItemPreDocumentoDe
    AND (p_efetivar = 0
      OR devolvidoRetornado = 0))
  LOOP
    IF v_quantidadeSaldo >= 1 THEN
      v_quantidadeSaldo := v_quantidadeSaldo - 1;
      r_atualizarObservacoes := 1;
      ADD_DOC_FISC_ITEM_N_SER_GRAVA (
        p_estabelecimentoAtivo,
        0,
        p_idItemDocFiscalPara,
        a.gradeProduto,
        a.idNumeroSerie,
        0,
        /* Retornos */
        v_auxNumber);
      IF p_efetivar = 1 THEN
        UPDATE MOPREDOCUMXNUMEROSSERIE b
        SET b.devolvidoRetornado = 1
        WHERE b.idNumeroSeriePreDocumento = a.idNumeroSeriePreDocumento;
      END IF;
    END IF;
  END LOOP;
  IF v_quantidadeSaldo >= 1 THEN
    FOR a IN (
      SELECT
        a.gradeProduto,
        a.idNumeroSerie
      FROM (
        SELECT
          numSer.gradeProduto,
          numSer.idNumeroSerie
        FROM MOPREDOCUMXORCAMENTOITEM docXOrc
        JOIN MOENTREGAS entr
        ON entr.idItemOrcamento = docXOrc.idItemOrcamento
        JOIN MOPREDOCUMXNUMEROSSERIE numSer
        ON numSer.idItemPreDocumento = entr.idItemPreDocumentoRemessa
        WHERE docXOrc.idItemPreDocumento = p_idItemPreDocumentoDe
        AND entr.idItemPreDocumentoRemessa > 0
        UNION ALL
        SELECT
          numSer.gradeProduto,
          numSer.idNumeroSerie
        FROM MOPREDOCUMXORCAMENTOITEM docXOrc
        JOIN MOENTREGAS entr
        ON entr.idItemOrcamento = docXOrc.idItemOrcamento
        JOIN MODOCFISCALXNUMEROSSERIE numSer
        ON numSer.idItemDocFiscal = entr.idItemDocFiscalRemessa
        WHERE docXOrc.idItemPreDocumento = p_idItemPreDocumentoDe
        AND entr.idItemDocFiscalRemessa > 0) a
      GROUP BY
        a.gradeProduto,
        a.idNumeroSerie)
    LOOP
      IF v_quantidadeSaldo >= 1 THEN
        v_quantidadeSaldo := v_quantidadeSaldo - 1;
        r_atualizarObservacoes := 1;
        ADD_DOC_FISC_ITEM_N_SER_GRAVA (
          p_estabelecimentoAtivo,
          0,
          p_idItemDocFiscalPara,
          a.gradeProduto,
          a.idNumeroSerie,
          0,
          /* Retornos */
          v_auxNumber);
      END IF;
    END LOOP;
  END IF;
END ADD_DOC_FISC_ITEM_N_SER_PRE;

/

create or replace PROCEDURE ADD_PRE_DOC_ITEM_N_SER_DOC_FIS (
  p_estabelecimentoAtivo   IN NUMBER,
  p_idItemDocFiscalDe      IN NUMBER,
  p_idItemPreDocumentoPara IN NUMBER,
  p_quantidade             IN NUMBER,
  p_efetivar               IN NUMBER,
  p_atualizarObservacoes   IN NUMBER,
  /* Retornos */
  r_atualizarObservacoes   OUT NUMBER)
IS
  v_quantidadeSaldo NUMBER;
  v_auxNumber       NUMBER;
BEGIN
  r_atualizarObservacoes := p_atualizarObservacoes;
  v_quantidadeSaldo      := p_quantidade;
  FOR a IN (
    SELECT
      idNumeroSerieDocFiscal,
      gradeProduto,
      idNumeroSerie
    FROM MODOCFISCALXNUMEROSSERIE
    WHERE idItemDocFiscal = p_idItemDocFiscalDe
    AND (p_efetivar = 0
      OR devolvidoRetornado = 0))
  LOOP
    IF v_quantidadeSaldo >= 1 THEN
      v_quantidadeSaldo := v_quantidadeSaldo - 1;
      r_atualizarObservacoes := 1;
      ADD_PRE_DOC_ITEM_N_SER_GRAVA (
        p_estabelecimentoAtivo,
        0,
        p_idItemPreDocumentoPara,
        a.gradeProduto,
        a.idNumeroSerie,
        0,
        /* Retornos */
        v_auxNumber);
      IF p_efetivar = 1 THEN
        UPDATE MODOCFISCALXNUMEROSSERIE b
        SET b.devolvidoRetornado = 1
        WHERE b.idNumeroSerieDocFiscal = a.idNumeroSerieDocFiscal;
      END IF;
    END IF;
  END LOOP;
  IF v_quantidadeSaldo >= 1 THEN
    FOR a IN (
      SELECT
        a.gradeProduto,
        a.idNumeroSerie
      FROM (
        SELECT
          numSer.gradeProduto,
          numSer.idNumeroSerie
        FROM MODOCFISCALXORCAMENTOITEM docXOrc
        JOIN MOENTREGAS entr
        ON entr.idItemOrcamento = docXOrc.idItemOrcamento
        JOIN MOPREDOCUMXNUMEROSSERIE numSer
        ON numSer.idItemPreDocumento = entr.idItemPreDocumentoRemessa
        WHERE docXOrc.idItemDocFiscal = p_idItemDocFiscalDe
        AND entr.idItemPreDocumentoRemessa > 0
        UNION ALL
        SELECT
          numSer.gradeProduto,
          numSer.idNumeroSerie
        FROM MODOCFISCALXORCAMENTOITEM docXOrc
        JOIN MOENTREGAS entr
        ON entr.idItemOrcamento = docXOrc.idItemOrcamento
        JOIN MODOCFISCALXNUMEROSSERIE numSer
        ON numSer.idItemDocFiscal = entr.idItemDocFiscalRemessa
        WHERE docXOrc.idItemDocFiscal = p_idItemDocFiscalDe
        AND entr.idItemDocFiscalRemessa > 0) a
      GROUP BY
        a.gradeProduto,
        a.idNumeroSerie)
    LOOP
      IF v_quantidadeSaldo >= 1 THEN
        v_quantidadeSaldo := v_quantidadeSaldo - 1;
        r_atualizarObservacoes := 1;
        ADD_PRE_DOC_ITEM_N_SER_GRAVA (
          p_estabelecimentoAtivo,
          0,
          p_idItemPreDocumentoPara,
          a.gradeProduto,
          a.idNumeroSerie,
          0,
          /* Retornos */
          v_auxNumber);
      END IF;
    END LOOP;
  END IF;
END ADD_PRE_DOC_ITEM_N_SER_DOC_FIS;

/

create or replace PROCEDURE ADD_DOC_FISC_ITEM_N_SER_DOC (
  p_estabelecimentoAtivo IN NUMBER,
  p_idItemDocFiscalDe    IN NUMBER,
  p_idItemDocFiscalPara  IN NUMBER,
  p_quantidade           IN NUMBER,
  p_efetivar             IN NUMBER,
  p_atualizarObservacoes IN NUMBER,
  /* Retornos */
  r_atualizarObservacoes OUT NUMBER)
IS
  v_quantidadeSaldo NUMBER;
  v_auxNumber       NUMBER;
BEGIN
  r_atualizarObservacoes := p_atualizarObservacoes;
  v_quantidadeSaldo      := p_quantidade;
  FOR a IN (
    SELECT
      idNumeroSerieDocFiscal,
      gradeProduto,
      idNumeroSerie
    FROM MODOCFISCALXNUMEROSSERIE
    WHERE idItemDocFiscal = p_idItemDocFiscalDe
    AND (p_efetivar = 0
      OR devolvidoRetornado = 0))
  LOOP
    IF v_quantidadeSaldo >= 1 THEN
      v_quantidadeSaldo := v_quantidadeSaldo - 1;
      r_atualizarObservacoes := 1;
      ADD_DOC_FISC_ITEM_N_SER_GRAVA (
        p_estabelecimentoAtivo,
        0,
        p_idItemDocFiscalPara,
        a.gradeProduto,
        a.idNumeroSerie,
        0,
        /* Retornos */
        v_auxNumber);
      IF p_efetivar = 1 THEN
        UPDATE MODOCFISCALXNUMEROSSERIE b
        SET b.devolvidoRetornado = 1
        WHERE b.idNumeroSerieDocFiscal = a.idNumeroSerieDocFiscal;
      END IF;
    END IF;
  END LOOP;
  IF v_quantidadeSaldo >= 1 THEN
    FOR a IN (
      SELECT
        a.gradeProduto,
        a.idNumeroSerie
      FROM (
        SELECT
          numSer.gradeProduto,
          numSer.idNumeroSerie
        FROM MODOCFISCALXORCAMENTOITEM docXOrc
        JOIN MOENTREGAS entr
        ON entr.idItemOrcamento = docXOrc.idItemOrcamento
        JOIN MOPREDOCUMXNUMEROSSERIE numSer
        ON numSer.idItemPreDocumento = entr.idItemPreDocumentoRemessa
        WHERE docXOrc.idItemDocFiscal = p_idItemDocFiscalDe
        AND entr.idItemPreDocumentoRemessa > 0
        UNION ALL
        SELECT
          numSer.gradeProduto,
          numSer.idNumeroSerie
        FROM MODOCFISCALXORCAMENTOITEM docXOrc
        JOIN MOENTREGAS entr
        ON entr.idItemOrcamento = docXOrc.idItemOrcamento
        JOIN MODOCFISCALXNUMEROSSERIE numSer
        ON numSer.idItemDocFiscal = entr.idItemDocFiscalRemessa
        WHERE docXOrc.idItemDocFiscal = p_idItemDocFiscalDe
        AND entr.idItemDocFiscalRemessa > 0) a
      GROUP BY
        a.gradeProduto,
        a.idNumeroSerie)
    LOOP
      IF v_quantidadeSaldo >= 1 THEN
        v_quantidadeSaldo := v_quantidadeSaldo - 1;
        r_atualizarObservacoes := 1;
        ADD_DOC_FISC_ITEM_N_SER_GRAVA (
          p_estabelecimentoAtivo,
          0,
          p_idItemDocFiscalPara,
          a.gradeProduto,
          a.idNumeroSerie,
          0,
          /* Retornos */
          v_auxNumber);
      END IF;
    END LOOP;
  END IF;
END ADD_DOC_FISC_ITEM_N_SER_DOC;

/

create or replace PROCEDURE ADD_ORCAMENTO_ITEM_REF_ORCAMEN (
  p_estabelecimentoAtivo        IN NUMBER,
  p_cab_tipoDocumento           IN NUMBER,
  p_idItemOrcamento             IN NUMBER,
  p_item_quantidade             IN NUMBER,
  p_idItemOrcamentoReferenciado IN NUMBER,
  p_quantidadeReferenciada      IN NUMBER,
  p_atualizarObservacoes        IN NUMBER,
  /* Retornos */
  r_atualizarObservacoes        OUT NUMBER)
IS
  v_id NUMBER;
BEGIN
  r_atualizarObservacoes := p_atualizarObservacoes;
  ADD_ORCAMENTO_ITEM_N_SER_ORC (
    p_estabelecimentoAtivo,
    p_idItemOrcamentoReferenciado,
    p_idItemOrcamento,
    CASE WHEN p_quantidadeReferenciada > 0 THEN p_quantidadeReferenciada ELSE p_item_quantidade END,
    0,
    r_atualizarObservacoes,
    r_atualizarObservacoes);
  ADD_ORCAMENTO_ITEM_CUSTO_ORC (
    p_estabelecimentoAtivo,
    p_idItemOrcamentoReferenciado,
    p_idItemOrcamento);
  ADD_ORCAMENTO_ITEM_COMP_ORC (
    p_estabelecimentoAtivo,
    p_idItemOrcamentoReferenciado,
    p_idItemOrcamento,
    r_atualizarObservacoes,
    r_atualizarObservacoes);
  IF p_cab_tipoDocumento = 103 THEN
    UPDATE MOORCAMENTOXITENS
    SET quantidadeSaldo = quantidadeSaldo - p_quantidadeReferenciada
    WHERE idItemOrcamento = p_idItemOrcamentoReferenciado;
  END IF;
  SELECT COALESCE (MAX (id),0)
  INTO v_id
  FROM MOORCAMENTOXORCAMENTO
  WHERE idItemOrcamento = p_idItemOrcamento
  AND idItemOrcamentoReferenc = p_idItemOrcamentoReferenciado;
  IF v_id > 0 THEN
    IF p_quantidadeReferenciada <> 0 THEN
      UPDATE MOORCAMENTOXORCAMENTO
      SET quantidade = quantidade + p_quantidadeReferenciada
      WHERE id = v_id;
    END IF;
  ELSE
    v_id := FUNC_ADD_BUSCA_PROXIMO_ID ('MOORCAMENTOXORCAMENTO', 'id', 14, p_estabelecimentoAtivo, NULL);
    INSERT INTO MOORCAMENTOXORCAMENTO (
      id,
      idItemOrcamento,
      idItemOrcamentoReferenc,
      quantidade)
    VALUES (
      v_id,
      p_idItemOrcamento,
      p_idItemOrcamentoReferenciado,
      p_quantidadeReferenciada);
  END IF;
  IF p_item_quantidade > 0
  AND p_quantidadeReferenciada = 0
  THEN
    FOR a IN (
      SELECT
        a.idItemOrcamentoReferenc,
        a.quantidade,
        b.quantidade quantidadeOrcamento
      FROM MOORCAMENTOXORCAMENTO a
      JOIN MOORCAMENTOXITENS b
      ON b.idItemOrcamento = a.idItemOrcamento
      WHERE a.idItemOrcamento = p_idItemOrcamento
      AND a.quantidade > 0 
      AND b.quantidade > 0)
    LOOP
      IF ROUND (a.quantidade * p_item_quantidade / a.quantidadeOrcamento,7) > 0 THEN
        SELECT COALESCE (MAX (id),0)
        INTO v_id
        FROM MOORCAMENTOXORCAMENTO
        WHERE idItemOrcamento = p_idItemOrcamento
        AND idItemOrcamentoReferenc = a.idItemOrcamentoReferenc;
        IF v_id > 0 THEN
          UPDATE MOORCAMENTOXORCAMENTO
          SET quantidade = quantidade + ROUND(a.quantidade * p_item_quantidade / a.quantidadeOrcamento,7)
          WHERE id = v_id;
        ELSE
          v_id := FUNC_ADD_BUSCA_PROXIMO_ID ('MOORCAMENTOXORCAMENTO', 'id', 14, p_estabelecimentoAtivo, NULL);
          INSERT INTO MOORCAMENTOXORCAMENTO (
            id,
            idItemOrcamento,
            idItemOrcamentoReferenc,
            quantidade)
          VALUES (
            v_id,
            p_idItemOrcamento,
            a.idItemOrcamentoReferenc,
            ROUND (a.quantidade * p_item_quantidade / a.quantidadeOrcamento, 7));
        END IF;
       END IF;
    END LOOP;
  END IF;
END ADD_ORCAMENTO_ITEM_REF_ORCAMEN;

/

create or replace PROCEDURE ADD_ORCAMENTO_ITEM_REAL_FIC_EX (
  p_idFichaProdutoRealOrcamento IN NUMBER,
  p_bufferIdEstoque             IN VARCHAR,
  r_bufferIdEstoque             OUT VARCHAR)
IS
BEGIN
  r_bufferIdEstoque := p_bufferIdEstoque;
  ADD_ESTOQUE_FIC_TEC_EXCLUI (
    p_idFichaProdutoRealOrcamento,
    r_bufferIdEstoque,
    r_bufferIdEstoque);
  DELETE MOORCAMENTOXFICHAPRODREAL
  WHERE idFichaProdutoRealOrcamento = p_idFichaProdutoRealOrcamento;
END ADD_ORCAMENTO_ITEM_REAL_FIC_EX;

/

create or replace PROCEDURE ADD_ORCAMENTO_ITEM_REAL_EXCLUI (
  p_idAtividadeRealOrcamento IN NUMBER,
  p_bufferIdEstoque          IN VARCHAR,
  r_bufferIdEstoque          OUT VARCHAR)
IS
BEGIN
  r_bufferIdEstoque := p_bufferIdEstoque;
  FOR a IN (
    SELECT idFichaProdutoRealOrcamento
    FROM MOORCAMENTOXFICHAPRODREAL
    WHERE idAtividadeRealOrcamento = p_idAtividadeRealOrcamento
  	AND idFichaProdutoRealOrcamento > 0)
  LOOP
    ADD_ORCAMENTO_ITEM_REAL_FIC_EX (
      a.idFichaProdutoRealOrcamento,
      r_bufferIdEstoque,
      r_bufferIdEstoque);
  END LOOP;
  DELETE MOORCAMENTOXATIVIDADEREAL
  WHERE idAtividadeRealOrcamento = p_idAtividadeRealOrcamento;
END ADD_ORCAMENTO_ITEM_REAL_EXCLUI;

/

create or replace PROCEDURE ADD_ORCAMENTO_ITEM_PREV_FIC_EX (
  p_idFichaProdutoPrevOrcamento IN NUMBER,
  p_bufferIdReservaEstoque      IN VARCHAR2,
  p_bufferIdEstoque             IN VARCHAR,
  r_bufferIdReservaEstoque      OUT VARCHAR2,
  r_bufferIdEstoque             OUT VARCHAR)
IS
BEGIN
  r_bufferIdReservaEstoque := p_bufferIdReservaEstoque;
  r_bufferIdEstoque        := p_bufferIdEstoque;
  FOR a IN (
    SELECT idFichaProdutoRealOrcamento
    FROM MOORCAMENTOXFICHAPRODREAL
    WHERE idFichaProdutoPrevOrcamento = p_idFichaProdutoPrevOrcamento
	  AND idFichaProdutoRealOrcamento > 0)
  LOOP
    ADD_ORCAMENTO_ITEM_REAL_FIC_EX (
      a.idFichaProdutoRealOrcamento,
      r_bufferIdEstoque,
      r_bufferIdEstoque);
  END LOOP;
  ADD_RESERVA_ESTOQUE_FIC_EXCLUI (
    p_idFichaProdutoPrevOrcamento,
    r_bufferIdReservaEstoque,
    r_bufferIdReservaEstoque);
  DELETE MOORCAMENTOXFICHAPRODPREV
  WHERE idFichaProdutoPrevOrcamento = p_idFichaProdutoPrevOrcamento;
END ADD_ORCAMENTO_ITEM_PREV_FIC_EX;

/

create or replace PROCEDURE ADD_ORCAMENTO_ITEM_PREV_EXCLUI (
  p_idAtividadePrevOrcamento IN NUMBER,
  p_bufferIdReservaEstoque   IN VARCHAR2,
  p_bufferIdEstoque          IN VARCHAR,
  r_bufferIdReservaEstoque   OUT VARCHAR2,
  r_bufferIdEstoque          OUT VARCHAR)
IS
BEGIN
  r_bufferIdReservaEstoque := p_bufferIdReservaEstoque;
  r_bufferIdEstoque        := p_bufferIdEstoque;
  FOR a IN (
    SELECT idAtividadeRealOrcamento
    FROM MOORCAMENTOXATIVIDADEREAL
    WHERE idAtividadePrevOrcamento = p_idAtividadePrevOrcamento
	  AND idAtividadeRealOrcamento > 0)
  LOOP
    ADD_ORCAMENTO_ITEM_REAL_EXCLUI (
      a.idAtividadeRealOrcamento,
      r_bufferIdEstoque,
      r_bufferIdEstoque);
  END LOOP;
  FOR a IN (
    SELECT idFichaProdutoPrevOrcamento
    FROM MOORCAMENTOXFICHAPRODPREV
    WHERE idAtividadePrevOrcamento = p_idAtividadePrevOrcamento
	  AND idFichaProdutoPrevOrcamento > 0)
  LOOP
    ADD_ORCAMENTO_ITEM_PREV_FIC_EX (
      a.idFichaProdutoPrevOrcamento,
      r_bufferIdReservaEstoque,
      r_bufferIdEstoque,
      r_bufferIdReservaEstoque,
      r_bufferIdEstoque);
  END LOOP;
  DELETE MOORCAMENTOXTAREFAS
  WHERE idAtividadePrevOrcamento = p_idAtividadePrevOrcamento;
  DELETE MOORCAMENTOXATIVIDADEPREV
  WHERE idAtividadePrevOrcamento = p_idAtividadePrevOrcamento;
END ADD_ORCAMENTO_ITEM_PREV_EXCLUI;

/

create or replace PROCEDURE ADD_ORCAMENTO_ITEM_PREV_CANC (
  p_idItemOrcamento IN NUMBER)    
IS
BEGIN
  FOR a IN (
    SELECT idAtividadePrevOrcamento
    FROM MOORCAMENTOXATIVIDADEPREV
    WHERE idItemOrcamento = p_idItemOrcamento
    AND statusAtividadeServico IN ('A','I','P'))
  LOOP
    UPDATE MOORCAMENTOXATIVIDADEPREV b
    SET b.statusAtividadeServico = 'C'
    WHERE b.idAtividadePrevOrcamento = a.idAtividadePrevOrcamento;
    UPDATE MOORCAMENTOXATIVIDADEREAL b
    SET b.statusAtividadeServico = 'C'
    WHERE b.idAtividadePrevOrcamento = a.idAtividadePrevOrcamento
    AND b.statusAtividadeServico IN ('A','I','P');
  END LOOP;
  UPDATE MOORCAMENTOXITENS
  SET statusAtividadeServico = 'C'
  WHERE idItemOrcamento = p_idItemOrcamento
  AND statusAtividadeServico <> 'C';
END ADD_ORCAMENTO_ITEM_PREV_CANC;

/

create or replace PROCEDURE ADD_ORCAMENTO_ITEM_REAL_GRAVA (
  p_sys_estabelecimentoAtivo  IN NUMBER,
  p_config_354_estabProximoId IN NUMBER,
  p_idAtividadeRealOrcamento  IN NUMBER,
  p_idAtividadePrevOrcamento  IN NUMBER,
  p_sequencia                 IN NUMBER,
  p_atividadeServico          IN NUMBER,
  p_descricao                 IN VARCHAR2,
  p_tecnico                   IN NUMBER,
  p_statusAtividadeServico    IN CHAR,
  p_dataInicio                IN DATE,
  p_dataTermino               IN DATE,
  p_modeloDocumento           IN NUMBER,
  p_motivoEstoque             IN NUMBER,
  p_quantidade                IN NUMBER,
  p_observacoes               IN VARCHAR2,
  /* Retornos */
  r_idAtividadeRealOrcamento  OUT NUMBER)
IS
BEGIN
  r_idAtividadeRealOrcamento := p_idAtividadeRealOrcamento;
  IF (r_idAtividadeRealOrcamento = 0) THEN
    r_idAtividadeRealOrcamento := FUNC_ADD_PROXIMO_ID (
      p_sys_estabelecimentoAtivo,
      p_config_354_estabProximoId,
      'MOORCAMENTOXATIVIDADEREAL',
      'idAtividadeRealOrcamento',
      14);
  END IF;
  MERGE INTO MOORCAMENTOXATIVIDADEREAL a 
  USING (
    SELECT
      r_idAtividadeRealOrcamento idAtividadeRealOrcamento,
      p_idAtividadePrevOrcamento idAtividadePrevOrcamento,
      p_sequencia                sequencia,
      p_atividadeServico         atividadeServico,
      p_descricao                descricao,
      p_tecnico                  tecnico,
      p_statusAtividadeServico   statusAtividadeServico,
      p_dataInicio               dataInicio,
      p_dataTermino              dataTermino,
      p_modeloDocumento          modeloDocumento,
      p_motivoEstoque            motivoEstoque,
      p_quantidade               quantidade,
      p_observacoes              observacoes
    FROM DUAL) b
  ON (a.idAtividadeRealOrcamento = b.idAtividadeRealOrcamento)
  WHEN MATCHED THEN UPDATE SET
    a.idAtividadePrevOrcamento = b.idAtividadePrevOrcamento,
    a.sequencia                = b.sequencia,
    a.atividadeServico         = b.atividadeServico,
    a.descricao                = b.descricao,
    a.tecnico                  = b.tecnico,
    a.statusAtividadeServico   = b.statusAtividadeServico,
    a.dataInicio               = b.dataInicio,
    a.dataTermino              = b.dataTermino,
    a.modeloDocumento          = b.modeloDocumento,
    a.motivoEstoque            = b.motivoEstoque,
    a.quantidade               = b.quantidade,
    a.observacoes              = b.observacoes
  WHEN NOT MATCHED THEN INSERT (
    idAtividadeRealOrcamento,
    idAtividadePrevOrcamento,
    sequencia,
    atividadeServico,
    descricao,
    tecnico,
    statusAtividadeServico,
    dataInicio,
    dataTermino,
    modeloDocumento,
    motivoEstoque,
    quantidade,
    observacoes)
  VALUES (
    b.idAtividadeRealOrcamento,
    b.idAtividadePrevOrcamento,
    b.sequencia,
    b.atividadeServico,
    b.descricao,
    b.tecnico,
    b.statusAtividadeServico,
    b.dataInicio,
    b.dataTermino,
    b.modeloDocumento,
    b.motivoEstoque,
    b.quantidade,
    b.observacoes);
END ADD_ORCAMENTO_ITEM_REAL_GRAVA;

/

create or replace PROCEDURE ADD_ORCAMENTO_ITEM_SALDO_VOLTA (
  p_sys_usuarioLogado            IN NUMBER,
  p_sys_estabelecimentoAtivo     IN NUMBER,
  p_person_184_tipoEventoCancCon IN NUMBER,
  p_config_95_etapaOrcamentoCanc IN NUMBER,
  p_config_96_etapaOrdemServCanc IN NUMBER,
  p_config_97_etapaPedCompraCanc IN NUMBER,
  p_config_209_filtrarGrupoEcon  IN NUMBER,
  p_config_354_estabProximoId    IN NUMBER,
  p_config_362_calcCustoPorGrade IN NUMBER,
  p_config_415_etapaFatContrCanc IN NUMBER,
  p_idItemOrcamento              IN NUMBER,
  p_quantidade                   IN NUMBER)
IS  
  v_orcamento                NUMBER;
  v_cancelado                NUMBER;
  v_quantidadeSaldo          NUMBER;
  v_tipoDocumento            NUMBER;
  v_novaEtapaOrcamento       NUMBER;  
  v_situacaoOrcamento        NUMBER;
  v_quantidadeSaldoOrcamento NUMBER;
  v_auxAlpha                 VARCHAR (32000);
  v_auxNumber                NUMBER;
BEGIN
  SELECT
    item.orcamento,
    item.cancelado,
    item.quantidadeSaldo,
    cab.tipoDocumento
  INTO
    v_orcamento,
    v_cancelado,
    v_quantidadeSaldo,
    v_tipoDocumento
  FROM MOORCAMENTOXITENS item
  JOIN MOORCAMENTOS cab
  ON cab.orcamento = item.orcamento
  WHERE item.idItemOrcamento = p_idItemOrcamento;
  IF v_tipoDocumento = 201 THEN
    v_novaEtapaOrcamento := p_config_97_etapaPedCompraCanc;
    IF v_novaEtapaOrcamento = 0 THEN
      SELECT COALESCE (MAX (a.etapaOrcamento), 0)
      INTO v_novaEtapaOrcamento
      FROM (
        SELECT
          etapaOrcamento,
          ROW_NUMBER() OVER (
            ORDER BY
              ordenacao,
              etapaOrcamento) ordenacao
        FROM PAETAPASORCAMENTO
        WHERE etapaOrcamento > 0
        AND ativo = 1
        AND situacaoOrcamento = 60
        AND validoPedidoCompra = 1) a
      WHERE a.ordenacao = 1;
    END IF;
  ELSIF v_tipoDocumento = 102 THEN
    v_novaEtapaOrcamento := p_config_96_etapaOrdemServCanc;
    IF v_novaEtapaOrcamento = 0 THEN
      SELECT COALESCE (MAX (a.etapaOrcamento), 0)
      INTO v_novaEtapaOrcamento
      FROM (
        SELECT
          etapaOrcamento,
          ROW_NUMBER() OVER (
            ORDER BY
              ordenacao,
              etapaOrcamento) ordenacao
        FROM PAETAPASORCAMENTO
        WHERE etapaOrcamento > 0
        AND ativo = 1
        AND situacaoOrcamento = 90
        AND validoOrdemServico = 1) a
      WHERE a.ordenacao = 1;
    END IF;
    IF v_novaEtapaOrcamento = 0 THEN
      SELECT COALESCE (MAX (a.etapaOrcamento), 0)
      INTO v_novaEtapaOrcamento
      FROM (
        SELECT
          etapaOrcamento,
          ROW_NUMBER() OVER (
            ORDER BY
              ordenacao,
              etapaOrcamento) ordenacao
        FROM PAETAPASORCAMENTO
        WHERE etapaOrcamento > 0
        AND ativo = 1
        AND situacaoOrcamento = 90) a
      WHERE a.ordenacao = 1;
    END IF;
  ELSIF v_tipoDocumento = 103 THEN
    v_novaEtapaOrcamento := p_config_415_etapaFatContrCanc;
    IF v_novaEtapaOrcamento = 0 THEN
      SELECT COALESCE (MAX (a.etapaOrcamento), 0)
      INTO v_novaEtapaOrcamento
      FROM (
        SELECT
          etapaOrcamento,
          ROW_NUMBER() OVER (
            ORDER BY
              ordenacao,
              etapaOrcamento) ordenacao
        FROM PAETAPASORCAMENTO
        WHERE etapaOrcamento > 0
        AND ativo = 1
        AND situacaoOrcamento = 90
        AND validoContrato = 1) a
      WHERE a.ordenacao = 1;
    END IF;
    IF v_novaEtapaOrcamento = 0 THEN
      SELECT COALESCE (MAX (a.etapaOrcamento), 0)
      INTO v_novaEtapaOrcamento
      FROM (
        SELECT
          etapaOrcamento,
          ROW_NUMBER() OVER (
            ORDER BY
              ordenacao,
              etapaOrcamento) ordenacao
        FROM PAETAPASORCAMENTO
        WHERE etapaOrcamento > 0
        AND ativo = 1
        AND situacaoOrcamento = 90) a
      WHERE a.ordenacao = 1;
    END IF;
  ELSE
    v_novaEtapaOrcamento := p_config_95_etapaOrcamentoCanc;
    IF v_novaEtapaOrcamento = 0 THEN
      SELECT COALESCE (MAX (a.etapaOrcamento), 0)
      INTO v_novaEtapaOrcamento
      FROM (
        SELECT
          etapaOrcamento,
          ROW_NUMBER() OVER (
            ORDER BY
              ordenacao,
              etapaOrcamento) ordenacao
        FROM PAETAPASORCAMENTO
        WHERE etapaOrcamento > 0
        AND ativo = 1
        AND situacaoOrcamento = 90
        AND validoOrcamento = 1) a
      WHERE a.ordenacao = 1;
    END IF;
    IF v_novaEtapaOrcamento = 0 THEN
      SELECT COALESCE (MAX (a.etapaOrcamento), 0)
      INTO v_novaEtapaOrcamento
      FROM (
        SELECT
          etapaOrcamento,
          ROW_NUMBER() OVER (
            ORDER BY
              ordenacao,
              etapaOrcamento) ordenacao
        FROM PAETAPASORCAMENTO
        WHERE etapaOrcamento > 0
        AND ativo = 1
        AND situacaoOrcamento = 90) a
      WHERE a.ordenacao = 1;
    END IF;
  END IF;
  IF v_novaEtapaOrcamento = 0 THEN
    v_situacaoOrcamento := 0;
  ELSE
    SELECT COALESCE (MAX (situacaoOrcamento), 0)
    INTO v_situacaoOrcamento
    FROM PAETAPASORCAMENTO
    WHERE etapaOrcamento = v_novaEtapaOrcamento;
  END IF;
  IF p_quantidade <> 0
    AND (v_novaEtapaOrcamento = 0
      OR v_situacaoOrcamento <= 63)
  THEN
    v_quantidadeSaldo := v_quantidadeSaldo + p_quantidade;
  END IF;
  IF v_novaEtapaOrcamento <> 0
    AND v_situacaoOrcamento = 90
  THEN
    v_cancelado := 1;
  END IF;
  UPDATE MOORCAMENTOXITENS SET
    cancelado = v_cancelado,
    quantidadeSaldo = v_quantidadeSaldo
  WHERE idItemOrcamento = p_idItemOrcamento;
  IF v_cancelado = 1 THEN
    SELECT COALESCE (SUM (quantidadeSaldo), 0)
    INTO v_quantidadeSaldoOrcamento
    FROM MOORCAMENTOXITENS
    WHERE orcamento = v_orcamento
    AND cancelado = 0;
    IF v_quantidadeSaldoOrcamento <= 0 THEN
      UPDATE MOORCAMENTOS
      SET etapaOrcamento = v_novaEtapaOrcamento
      WHERE orcamento = v_orcamento;
    END IF;
  ELSIF v_novaEtapaOrcamento <> 0 THEN
    UPDATE MOORCAMENTOS
    SET etapaOrcamento = v_novaEtapaOrcamento
    WHERE orcamento = v_orcamento;
  END IF;
  IF v_novaEtapaOrcamento <> 0 THEN
    IF v_situacaoOrcamento = 90 THEN
      FOR a IN (
        SELECT
          entrega,
          quantidade
        FROM MOENTREGAS
        WHERE idItemOrcamento = p_idItemOrcamento
        AND situacaoEntrega <= 4)
      LOOP
        ADD_ENTREGA_SITUACAO_TROCA (
          p_sys_usuarioLogado,
          p_sys_estabelecimentoAtivo,
          p_idItemOrcamento,
          a.entrega,
          a.quantidade,
          8,
          'ADD_ORCAMENTO_ITEM_SALDO_VOLTA');
      END LOOP;
    ELSE
      FOR a IN (
        SELECT entrega
        FROM MOENTREGAS
        WHERE idItemOrcamento = p_idItemOrcamento
        AND situacaoEntrega <= 4)
      LOOP
        ADD_ENTREGA_EXCLUI (
          p_sys_usuarioLogado,
          p_sys_estabelecimentoAtivo,
          a.entrega,
          0,
          'ADD_ORCAMENTO_ITEM_SALDO_VOLTA');
      END LOOP;
    END IF;
  END IF;
  ADD_RESERVA_ESTOQUE_ORC_ITEM (
    p_sys_estabelecimentoAtivo,
    p_config_209_filtrarGrupoEcon,
    p_config_354_estabProximoId,
    p_config_362_calcCustoPorGrade,
    p_idItemOrcamento,
    '',
    '',
    v_auxAlpha,
    v_auxAlpha);
END ADD_ORCAMENTO_ITEM_SALDO_VOLTA;

/

create or replace PROCEDURE ADD_ORCAMENTO_ITEM_PREV_REABRE (
  p_sys_estabelecimentoAtivo     IN NUMBER,
  p_config_354_estabProximoId    IN NUMBER,
  p_cab_estabelecimento          IN NUMBER,
  p_cab_dataEmissao              IN DATE,
  p_cab_dataEntrega              IN DATE,
  p_item_modeloDocumento         IN NUMBER,
  p_ativ_idAtividadePrevOrcament IN NUMBER,
  p_ativ_dataInicio              IN DATE,
  p_ativ_dataTermino             IN DATE,
  p_bufferIdReservaEstoque       IN VARCHAR2,
  p_bufferIdEstoque              IN VARCHAR2,
  r_bufferIdReservaEstoque       OUT VARCHAR2,
  r_bufferIdEstoque              OUT VARCHAR2)
IS
BEGIN
  r_bufferIdReservaEstoque := p_bufferIdReservaEstoque;
  r_bufferIdEstoque        := p_bufferIdEstoque;
  FOR a IN (
    SELECT idAtividadeRealOrcamento
    FROM MOORCAMENTOXATIVIDADEREAL
    WHERE idAtividadePrevOrcamento = p_ativ_idAtividadePrevOrcament
	  AND idAtividadeRealOrcamento > 0)
  LOOP
    ADD_ORCAMENTO_ITEM_REAL_EXCLUI (
      a.idAtividadeRealOrcamento,
      r_bufferIdEstoque,
      r_bufferIdEstoque);
  END LOOP;
  FOR a IN (
    SELECT
      idFichaProdutoPrevOrcamento,
      quantidade
    FROM MOORCAMENTOXFICHAPRODPREV
    WHERE idAtividadePrevOrcamento = p_ativ_idAtividadePrevOrcament
	  AND idFichaProdutoPrevOrcamento > 0)
  LOOP
    FOR b IN (
      SELECT b.idFichaProdutoRealOrcamento
      FROM MOORCAMENTOXFICHAPRODREAL b
      WHERE b.idFichaProdutoPrevOrcamento = a.idFichaProdutoPrevOrcamento
      AND b.idFichaProdutoRealOrcamento > 0)
    LOOP
      ADD_ORCAMENTO_ITEM_REAL_FIC_EX (
        b.idFichaProdutoRealOrcamento,
        r_bufferIdEstoque,
        r_bufferIdEstoque);
    END LOOP;
    UPDATE MOORCAMENTOXFICHAPRODPREV b
    SET b.quantidadeSaldo = a.quantidade
    WHERE b.idFichaProdutoPrevOrcamento = a.idFichaProdutoPrevOrcamento;
    ADD_RESERVA_ESTOQUE_FIC_EXCLUI (
      a.idFichaProdutoPrevOrcamento,
      r_bufferIdReservaEstoque,
      r_bufferIdReservaEstoque);
  END LOOP;
  ADD_RESERVA_ESTOQUE_ORC_FICHA (
    p_sys_estabelecimentoAtivo,
    p_config_354_estabProximoId,
    p_cab_estabelecimento,
    p_cab_dataEmissao,
    p_cab_dataEntrega,
    p_item_modeloDocumento,
    p_ativ_idAtividadePrevOrcament,
    p_ativ_dataInicio,
    p_ativ_dataTermino,
    r_bufferIdReservaEstoque,
    r_bufferIdReservaEstoque);
END ADD_ORCAMENTO_ITEM_PREV_REABRE;

/

create or replace PROCEDURE ADD_ORCAMENTO_ITEM_BLOEST_GRAV (
  p_estabelecimentoAtivo IN NUMBER,
  p_id                   IN NUMBER,
  p_orcamento            IN NUMERIC,
  p_sequencia            IN NUMERIC,
  p_dataBloqueio         IN DATE,
  p_estabelecimento      IN NUMERIC,
  p_localEstoque         IN NUMERIC,
  p_pessoaParticipante   IN NUMERIC,
  p_gradeProduto         IN NUMERIC,
  p_personalizacao       IN NUMERIC,
  p_idLoteEstoque        IN NUMERIC,
  p_idNumeroSerie        IN NUMERIC,
  p_quantidade           IN NUMERIC,
  p_quantidadeEstoque    IN NUMERIC,
  p_quantidadeReservas   IN NUMERIC,
  p_situacaoLiberacao    IN CHAR,
  p_usuarioLiberacao     IN NUMERIC,
  p_dataLiberacao        IN DATE,
  p_observacoes          IN VARCHAR,
  /* Retornos */
  r_id                   OUT NUMBER)
IS
BEGIN
  r_id := p_id;
  IF r_id = 0 THEN
    r_id := FUNC_ADD_BUSCA_PROXIMO_ID ('MOORCAMENTOXBLOQUEIOSEST', 'id', 14, p_estabelecimentoAtivo, NULL);
  END IF;
  MERGE INTO MOORCAMENTOXBLOQUEIOSEST a 
  USING (
    SELECT
      r_id                 id,
      p_orcamento          orcamento,
      p_sequencia          sequencia,
      p_dataBloqueio       dataBloqueio,
      p_estabelecimento    estabelecimento,
      p_localEstoque       localEstoque,
      p_pessoaParticipante pessoaParticipante,
      p_gradeProduto       gradeProduto,
      p_personalizacao     personalizacao,
      p_idLoteEstoque      idLoteEstoque,
      p_idNumeroSerie      idNumeroSerie,
      p_quantidade         quantidade,
      p_quantidadeEstoque  quantidadeEstoque,
      p_quantidadeReservas quantidadeReservas,
      p_situacaoLiberacao  situacaoLiberacao,
      p_usuarioLiberacao   usuarioLiberacao,
      p_dataLiberacao      dataLiberacao,
      p_observacoes        observacoes
    FROM DUAL) b
  ON (a.id = b.id)
  WHEN MATCHED THEN UPDATE SET
    a.orcamento          = b.orcamento,
    a.sequencia          = b.sequencia,
    a.dataBloqueio       = b.dataBloqueio,
    a.estabelecimento    = b.estabelecimento,
    a.localEstoque       = b.localEstoque,
    a.pessoaParticipante = b.pessoaParticipante,
    a.gradeProduto       = b.gradeProduto,
    a.personalizacao     = b.personalizacao,
    a.idLoteEstoque      = b.idLoteEstoque,
    a.idNumeroSerie      = b.idNumeroSerie,
    a.quantidade         = b.quantidade,
    a.quantidadeEstoque  = b.quantidadeEstoque,
    a.quantidadeReservas = b.quantidadeReservas,
    a.situacaoLiberacao  = b.situacaoLiberacao,
    a.usuarioLiberacao   = b.usuarioLiberacao,
    a.dataLiberacao      = b.dataLiberacao,
    a.observacoes        = b.observacoes
  WHEN NOT MATCHED THEN INSERT (
    id,
    orcamento,
    sequencia,
    dataBloqueio,
    estabelecimento,
    localEstoque,
    pessoaParticipante,
    gradeProduto,
    personalizacao,
    idLoteEstoque,
    idNumeroSerie,
    quantidade,
    quantidadeEstoque,
    quantidadeReservas,
    situacaoLiberacao,
    usuarioLiberacao,
    dataLiberacao,
    observacoes)
  VALUES (
    b.id,
    b.orcamento,
    b.sequencia,
    b.dataBloqueio,
    b.estabelecimento,
    b.localEstoque,
    b.pessoaParticipante,
    b.gradeProduto,
    b.personalizacao,
    b.idLoteEstoque,
    b.idNumeroSerie,
    b.quantidade,
    b.quantidadeEstoque,
    b.quantidadeReservas,
    b.situacaoLiberacao,
    b.usuarioLiberacao,
    b.dataLiberacao,
    b.observacoes);
END ADD_ORCAMENTO_ITEM_BLOEST_GRAV;

/

create or replace PROCEDURE ADD_PRE_DOC_ITEM_BLOEST_GRAVA (
  p_estabelecimentoAtivo IN NUMBER,
  p_id                   IN NUMBER,
  p_preDocumento         IN NUMERIC,
  p_sequencia            IN NUMERIC,
  p_dataBloqueio         IN DATE,
  p_estabelecimento      IN NUMERIC,
  p_localEstoque         IN NUMERIC,
  p_pessoaParticipante   IN NUMERIC,
  p_gradeProduto         IN NUMERIC,
  p_personalizacao       IN NUMERIC,
  p_idLoteEstoque        IN NUMERIC,
  p_idNumeroSerie        IN NUMERIC,
  p_quantidade           IN NUMERIC,
  p_quantidadeEstoque    IN NUMERIC,
  p_quantidadeReservas   IN NUMERIC,
  p_situacaoLiberacao    IN CHAR,
  p_usuarioLiberacao     IN NUMERIC,
  p_dataLiberacao        IN DATE,
  p_observacoes          IN VARCHAR,
  /* Retornos */
  r_id                   OUT NUMBER)
IS
BEGIN
  r_id := p_id;
  IF r_id = 0 THEN
    r_id := FUNC_ADD_BUSCA_PROXIMO_ID ('MOPREDOCUMXBLOQUEIOSEST', 'id', 14, p_estabelecimentoAtivo, NULL);
  END IF;
  MERGE INTO MOPREDOCUMXBLOQUEIOSEST a 
  USING (
    SELECT
      r_id                 id,
      p_preDocumento       preDocumento,
      p_sequencia          sequencia,
      p_dataBloqueio       dataBloqueio,
      p_estabelecimento    estabelecimento,
      p_localEstoque       localEstoque,
      p_pessoaParticipante pessoaParticipante,
      p_gradeProduto       gradeProduto,
      p_personalizacao     personalizacao,
      p_idLoteEstoque      idLoteEstoque,
      p_idNumeroSerie      idNumeroSerie,
      p_quantidade         quantidade,
      p_quantidadeEstoque  quantidadeEstoque,
      p_quantidadeReservas quantidadeReservas,
      p_situacaoLiberacao  situacaoLiberacao,
      p_usuarioLiberacao   usuarioLiberacao,
      p_dataLiberacao      dataLiberacao,
      p_observacoes        observacoes
    FROM DUAL) b
  ON (a.id = b.id)
  WHEN MATCHED THEN UPDATE SET
    a.preDocumento       = b.preDocumento,
    a.sequencia          = b.sequencia,
    a.dataBloqueio       = b.dataBloqueio,
    a.estabelecimento    = b.estabelecimento,
    a.localEstoque       = b.localEstoque,
    a.pessoaParticipante = b.pessoaParticipante,
    a.gradeProduto       = b.gradeProduto,
    a.personalizacao     = b.personalizacao,
    a.idLoteEstoque      = b.idLoteEstoque,
    a.idNumeroSerie      = b.idNumeroSerie,
    a.quantidade         = b.quantidade,
    a.quantidadeEstoque  = b.quantidadeEstoque,
    a.quantidadeReservas = b.quantidadeReservas,
    a.situacaoLiberacao  = b.situacaoLiberacao,
    a.usuarioLiberacao   = b.usuarioLiberacao,
    a.dataLiberacao      = b.dataLiberacao,
    a.observacoes        = b.observacoes
  WHEN NOT MATCHED THEN INSERT (
    id,
    preDocumento,
    sequencia,
    dataBloqueio,
    estabelecimento,
    localEstoque,
    pessoaParticipante,
    gradeProduto,
    personalizacao,
    idLoteEstoque,
    idNumeroSerie,
    quantidade,
    quantidadeEstoque,
    quantidadeReservas,
    situacaoLiberacao,
    usuarioLiberacao,
    dataLiberacao,
    observacoes)
  VALUES (
    b.id,
    b.preDocumento,
    b.sequencia,
    b.dataBloqueio,
    b.estabelecimento,
    b.localEstoque,
    b.pessoaParticipante,
    b.gradeProduto,
    b.personalizacao,
    b.idLoteEstoque,
    b.idNumeroSerie,
    b.quantidade,
    b.quantidadeEstoque,
    b.quantidadeReservas,
    b.situacaoLiberacao,
    b.usuarioLiberacao,
    b.dataLiberacao,
    b.observacoes);
END ADD_PRE_DOC_ITEM_BLOEST_GRAVA;

/

create or replace PROCEDURE ADD_DOC_FISC_ITEM_BLOEST_GRAVA (
  p_estabelecimentoAtivo IN NUMBER,
  p_id                   IN NUMBER,
  p_idDocumentoFiscal    IN NUMERIC,
  p_sequencia            IN NUMERIC,
  p_dataBloqueio         IN DATE,
  p_estabelecimento      IN NUMERIC,
  p_localEstoque         IN NUMERIC,
  p_pessoaParticipante   IN NUMERIC,
  p_gradeProduto         IN NUMERIC,
  p_personalizacao       IN NUMERIC,
  p_idLoteEstoque        IN NUMERIC,
  p_idNumeroSerie        IN NUMERIC,
  p_quantidade           IN NUMERIC,
  p_quantidadeEstoque    IN NUMERIC,
  p_quantidadeReservas   IN NUMERIC,
  p_situacaoLiberacao    IN CHAR,
  p_usuarioLiberacao     IN NUMERIC,
  p_dataLiberacao        IN DATE,
  p_observacoes          IN VARCHAR,
  /* Retornos */
  r_id                   OUT NUMBER)
IS
BEGIN
  r_id := p_id;
  IF r_id = 0 THEN
    r_id := FUNC_ADD_BUSCA_PROXIMO_ID ('MODOCFISCALXBLOQUEIOSEST', 'id', 14, p_estabelecimentoAtivo, NULL);
  END IF;
  MERGE INTO MODOCFISCALXBLOQUEIOSEST a 
  USING (
    SELECT
      r_id                 id,
      p_idDocumentoFiscal  idDocumentoFiscal,
      p_sequencia          sequencia,
      p_dataBloqueio       dataBloqueio,
      p_estabelecimento    estabelecimento,
      p_localEstoque       localEstoque,
      p_pessoaParticipante pessoaParticipante,
      p_gradeProduto       gradeProduto,
      p_personalizacao     personalizacao,
      p_idLoteEstoque      idLoteEstoque,
      p_idNumeroSerie      idNumeroSerie,
      p_quantidade         quantidade,
      p_quantidadeEstoque  quantidadeEstoque,
      p_quantidadeReservas quantidadeReservas,
      p_situacaoLiberacao  situacaoLiberacao,
      p_usuarioLiberacao   usuarioLiberacao,
      p_dataLiberacao      dataLiberacao,
      p_observacoes        observacoes
    FROM DUAL) b
  ON (a.id = b.id)
  WHEN MATCHED THEN UPDATE SET
    a.idDocumentoFiscal  = b.idDocumentoFiscal,
    a.sequencia          = b.sequencia,
    a.dataBloqueio       = b.dataBloqueio,
    a.estabelecimento    = b.estabelecimento,
    a.localEstoque       = b.localEstoque,
    a.pessoaParticipante = b.pessoaParticipante,
    a.gradeProduto       = b.gradeProduto,
    a.personalizacao     = b.personalizacao,
    a.idLoteEstoque      = b.idLoteEstoque,
    a.idNumeroSerie      = b.idNumeroSerie,
    a.quantidade         = b.quantidade,
    a.quantidadeEstoque  = b.quantidadeEstoque,
    a.quantidadeReservas = b.quantidadeReservas,
    a.situacaoLiberacao  = b.situacaoLiberacao,
    a.usuarioLiberacao   = b.usuarioLiberacao,
    a.dataLiberacao      = b.dataLiberacao,
    a.observacoes        = b.observacoes
  WHEN NOT MATCHED THEN INSERT (
    id,
    idDocumentoFiscal,
    sequencia,
    dataBloqueio,
    estabelecimento,
    localEstoque,
    pessoaParticipante,
    gradeProduto,
    personalizacao,
    idLoteEstoque,
    idNumeroSerie,
    quantidade,
    quantidadeEstoque,
    quantidadeReservas,
    situacaoLiberacao,
    usuarioLiberacao,
    dataLiberacao,
    observacoes)
  VALUES (
    b.id,
    b.idDocumentoFiscal,
    b.sequencia,
    b.dataBloqueio,
    b.estabelecimento,
    b.localEstoque,
    b.pessoaParticipante,
    b.gradeProduto,
    b.personalizacao,
    b.idLoteEstoque,
    b.idNumeroSerie,
    b.quantidade,
    b.quantidadeEstoque,
    b.quantidadeReservas,
    b.situacaoLiberacao,
    b.usuarioLiberacao,
    b.dataLiberacao,
    b.observacoes);
END ADD_DOC_FISC_ITEM_BLOEST_GRAVA;

/

create or replace PROCEDURE ADD_PRE_DOC_ITEM_BLOEST_ORC (
  p_estabelecimentoAtivo IN NUMBER,
  p_orcamentoDe          IN NUMBER,
  p_sequenciaDe          IN NUMBER,
  p_preDocumentolPara    IN NUMBER,
  p_sequenciaPara        IN NUMBER)
IS
  v_auxNumber NUMBER;
BEGIN
  FOR a IN (
    SELECT
      dataBloqueio,
      estabelecimento,
      localEstoque,
      pessoaParticipante,
      gradeProduto,
      personalizacao,
      idLoteEstoque,
      idNumeroSerie,
      quantidade,
      quantidadeEstoque,
      quantidadeReservas,
      situacaoLiberacao,
      usuarioLiberacao,
      dataLiberacao,
      observacoes
    FROM MOORCAMENTOXBLOQUEIOSEST
    WHERE orcamento = p_orcamentoDe
    AND sequencia = p_sequenciaDe)
  LOOP
    ADD_PRE_DOC_ITEM_BLOEST_GRAVA (
      p_estabelecimentoAtivo,
      0,
      p_preDocumentolPara,
      p_sequenciaPara,
      a.dataBloqueio,
      a.estabelecimento,
      a.localEstoque,
      a.pessoaParticipante,
      a.gradeProduto,
      a.personalizacao,
      a.idLoteEstoque,
      a.idNumeroSerie,
      a.quantidade,
      a.quantidadeEstoque,
      a.quantidadeReservas,
      a.situacaoLiberacao,
      a.usuarioLiberacao,
      a.dataLiberacao,
      a.observacoes,
      /* Retornos */
      v_auxNumber);
  END LOOP;
END ADD_PRE_DOC_ITEM_BLOEST_ORC;

/

create or replace PROCEDURE ADD_PRE_DOC_ITEM_BLOEST_PRE (
  p_estabelecimentoAtivo IN NUMBER,
  p_preDocumentoDe       IN NUMBER,
  p_sequenciaDe          IN NUMBER,
  p_preDocumentolPara    IN NUMBER,
  p_sequenciaPara        IN NUMBER)
IS
  v_auxNumber NUMBER;
BEGIN
  FOR a IN (
    SELECT
      dataBloqueio,
      estabelecimento,
      localEstoque,
      pessoaParticipante,
      gradeProduto,
      personalizacao,
      idLoteEstoque,
      idNumeroSerie,
      quantidade,
      quantidadeEstoque,
      quantidadeReservas,
      situacaoLiberacao,
      usuarioLiberacao,
      dataLiberacao,
      observacoes
    FROM MOPREDOCUMXBLOQUEIOSEST
    WHERE preDocumento = p_preDocumentoDe
    AND sequencia = p_sequenciaDe)
  LOOP
    ADD_PRE_DOC_ITEM_BLOEST_GRAVA (
      p_estabelecimentoAtivo,
      0,
      p_preDocumentolPara,
      p_sequenciaPara,
      a.dataBloqueio,
      a.estabelecimento,
      a.localEstoque,
      a.pessoaParticipante,
      a.gradeProduto,
      a.personalizacao,
      a.idLoteEstoque,
      a.idNumeroSerie,
      a.quantidade,
      a.quantidadeEstoque,
      a.quantidadeReservas,
      a.situacaoLiberacao,
      a.usuarioLiberacao,
      a.dataLiberacao,
      a.observacoes,
      /* Retornos */
      v_auxNumber);
  END LOOP;
END ADD_PRE_DOC_ITEM_BLOEST_PRE;

/

create or replace PROCEDURE ADD_PRE_DOC_ITEM_BLOEST_DOC (
  p_estabelecimentoAtivo IN NUMBER,
  p_idDocumentoFiscalDe  IN NUMBER,
  p_sequenciaDe          IN NUMBER,
  p_preDocumentolPara    IN NUMBER,
  p_sequenciaPara        IN NUMBER)
IS
  v_auxNumber NUMBER;
BEGIN
  FOR a IN (
    SELECT
      dataBloqueio,
      estabelecimento,
      localEstoque,
      pessoaParticipante,
      gradeProduto,
      personalizacao,
      idLoteEstoque,
      idNumeroSerie,
      quantidade,
      quantidadeEstoque,
      quantidadeReservas,
      situacaoLiberacao,
      usuarioLiberacao,
      dataLiberacao,
      observacoes
    FROM MODOCFISCALXBLOQUEIOSEST
    WHERE idDocumentoFiscal = p_idDocumentoFiscalDe
    AND sequencia = p_sequenciaDe)
  LOOP
    ADD_PRE_DOC_ITEM_BLOEST_GRAVA (
      p_estabelecimentoAtivo,
      0,
      p_preDocumentolPara,
      p_sequenciaPara,
      a.dataBloqueio,
      a.estabelecimento,
      a.localEstoque,
      a.pessoaParticipante,
      a.gradeProduto,
      a.personalizacao,
      a.idLoteEstoque,
      a.idNumeroSerie,
      a.quantidade,
      a.quantidadeEstoque,
      a.quantidadeReservas,
      a.situacaoLiberacao,
      a.usuarioLiberacao,
      a.dataLiberacao,
      a.observacoes,
      /* Retornos */
      v_auxNumber);
  END LOOP;
END ADD_PRE_DOC_ITEM_BLOEST_DOC;

/

create or replace PROCEDURE ADD_DOC_FISC_ITEM_BLOEST_ORC (
  p_estabelecimentoAtivo  IN NUMBER,
  p_orcamentoDe           IN NUMBER,
  p_sequenciaDe           IN NUMBER,
  p_idDocumentoFiscalPara IN NUMBER,
  p_sequenciaPara         IN NUMBER)
IS
  v_auxNumber NUMBER;
BEGIN
  FOR a IN (
    SELECT
      dataBloqueio,
      estabelecimento,
      localEstoque,
      pessoaParticipante,
      gradeProduto,
      personalizacao,
      idLoteEstoque,
      idNumeroSerie,
      quantidade,
      quantidadeEstoque,
      quantidadeReservas,
      situacaoLiberacao,
      usuarioLiberacao,
      dataLiberacao,
      observacoes
    FROM MOORCAMENTOXBLOQUEIOSEST
    WHERE orcamento = p_orcamentoDe
    AND sequencia = p_sequenciaDe)
  LOOP
    ADD_DOC_FISC_ITEM_BLOEST_GRAVA (
      p_estabelecimentoAtivo,
      0,
      p_idDocumentoFiscalPara,
      p_sequenciaPara,
      a.dataBloqueio,
      a.estabelecimento,
      a.localEstoque,
      a.pessoaParticipante,
      a.gradeProduto,
      a.personalizacao,
      a.idLoteEstoque,
      a.idNumeroSerie,
      a.quantidade,
      a.quantidadeEstoque,
      a.quantidadeReservas,
      a.situacaoLiberacao,
      a.usuarioLiberacao,
      a.dataLiberacao,
      a.observacoes,
      /* Retornos */
      v_auxNumber);
  END LOOP;
END ADD_DOC_FISC_ITEM_BLOEST_ORC;

/

create or replace PROCEDURE ADD_DOC_FISC_ITEM_BLOEST_PRE (
  p_estabelecimentoAtivo  IN NUMBER,
  p_preDocumentoDe        IN NUMBER,
  p_sequenciaDe           IN NUMBER,
  p_idDocumentoFiscalPara IN NUMBER,
  p_sequenciaPara         IN NUMBER)
IS
  v_auxNumber NUMBER;
BEGIN
  FOR a IN (
    SELECT
      dataBloqueio,
      estabelecimento,
      localEstoque,
      pessoaParticipante,
      gradeProduto,
      personalizacao,
      idLoteEstoque,
      idNumeroSerie,
      quantidade,
      quantidadeEstoque,
      quantidadeReservas,
      situacaoLiberacao,
      usuarioLiberacao,
      dataLiberacao,
      observacoes
    FROM MOPREDOCUMXBLOQUEIOSEST
    WHERE preDocumento = p_preDocumentoDe
    AND sequencia = p_sequenciaDe)
  LOOP
    ADD_DOC_FISC_ITEM_BLOEST_GRAVA (
      p_estabelecimentoAtivo,
      0,
      p_idDocumentoFiscalPara,
      p_sequenciaPara,
      a.dataBloqueio,
      a.estabelecimento,
      a.localEstoque,
      a.pessoaParticipante,
      a.gradeProduto,
      a.personalizacao,
      a.idLoteEstoque,
      a.idNumeroSerie,
      a.quantidade,
      a.quantidadeEstoque,
      a.quantidadeReservas,
      a.situacaoLiberacao,
      a.usuarioLiberacao,
      a.dataLiberacao,
      a.observacoes,
      /* Retornos */
      v_auxNumber);
  END LOOP;
END ADD_DOC_FISC_ITEM_BLOEST_PRE;

/

create or replace PROCEDURE ADD_DOC_FISC_ITEM_BLOEST_DOC (
  p_estabelecimentoAtivo  IN NUMBER,
  p_idDocumentoFiscalDe   IN NUMBER,
  p_sequenciaDe           IN NUMBER,
  p_idDocumentoFiscalPara IN NUMBER,
  p_sequenciaPara         IN NUMBER)
IS
  v_auxNumber NUMBER;
BEGIN
  FOR a IN (
    SELECT
      dataBloqueio,
      estabelecimento,
      localEstoque,
      pessoaParticipante,
      gradeProduto,
      personalizacao,
      idLoteEstoque,
      idNumeroSerie,
      quantidade,
      quantidadeEstoque,
      quantidadeReservas,
      situacaoLiberacao,
      usuarioLiberacao,
      dataLiberacao,
      observacoes
    FROM MODOCFISCALXBLOQUEIOSEST
    WHERE idDocumentoFiscal = p_idDocumentoFiscalDe
    AND sequencia = p_sequenciaDe)
  LOOP
    ADD_DOC_FISC_ITEM_BLOEST_GRAVA (
      p_estabelecimentoAtivo,
      0,
      p_idDocumentoFiscalPara,
      p_sequenciaPara,
      a.dataBloqueio,
      a.estabelecimento,
      a.localEstoque,
      a.pessoaParticipante,
      a.gradeProduto,
      a.personalizacao,
      a.idLoteEstoque,
      a.idNumeroSerie,
      a.quantidade,
      a.quantidadeEstoque,
      a.quantidadeReservas,
      a.situacaoLiberacao,
      a.usuarioLiberacao,
      a.dataLiberacao,
      a.observacoes,
      /* Retornos */
      v_auxNumber);
  END LOOP;
END ADD_DOC_FISC_ITEM_BLOEST_DOC;

/

create or replace PROCEDURE ADD_ORCAMENTO_CALC_IMP_RESIDUO (
  p_troca_tipoPagamentoFrete     IN NUMBER,
  p_a_cab_tipoPagamentoFrete     IN CHAR,
  p_cab_origemDocumento          IN NUMBER,
  p_cab_atualizaCustoMedio       IN NUMBER,
  p_cab_tipoPagamentoFrete       IN CHAR,
  p_cab_valorProdutos            IN NUMBER,
  p_cab_valorServicos            IN NUMBER,
  p_cab_valorBasePagamento       IN NUMBER,
  p_cab_valorAVistaMinimo        IN NUMBER,
  p_cab_valorFreteTotal          IN NUMBER,
  p_cab_valorSeguroTotal         IN NUMBER,
  p_cab_valorDescontoTotal       IN NUMBER,
  p_cab_valorOutrasDespesasTotal IN NUMBER,
  p_cab_valorAdicFreteMarinTotal IN NUMBER,
  p_cab_valorDespesasAduanTotal  IN NUMBER,
  p_cab_impostosEditados         IN NUMBER,
  p_cab_valorLiquidoItem         IN NUMBER,
  p_item_idItemOrcamento         IN NUMBER,
  p_saldoRatFreteGeral           IN NUMBER,
  p_saldoRatSeguroGeral          IN NUMBER,
  p_saldoRatDescontoGeral        IN NUMBER,
  p_saldoRatOutrasDespesasGeral  IN NUMBER,
  p_saldoRatAdicFreteMarinGeral  IN NUMBER,
  p_saldoRatDespesasAduanGeral   IN NUMBER,
  p_saldoRatDescontoPagamento    IN NUMBER,
  p_saldoRatOutrasDespPagamento  IN NUMBER,
  p_saldoRatJurosPagamento       IN NUMBER,
  p_calcularImpostosItem         IN NUMBER,
  /* Retornos */
  r_cab_valorProdutos            OUT NUMBER,
  r_cab_valorServicos            OUT NUMBER,
  r_cab_valorBasePagamento       OUT NUMBER,
  r_cab_valorAVistaMinimo        OUT NUMBER,
  r_cab_valorFreteTotal          OUT NUMBER,
  r_cab_valorSeguroTotal         OUT NUMBER,
  r_cab_valorDescontoTotal       OUT NUMBER,
  r_cab_valorOutrasDespesasTotal OUT NUMBER,
  r_cab_valorAdicFreteMarinTotal OUT NUMBER,
  r_cab_valorDespesasAduanTotal  OUT NUMBER,
  r_cab_valorLiquidoItem         OUT NUMBER,
  r_calcularImpostosItem         OUT NUMBER)
IS
  v_auxNumber                    NUMBER;
  v_precoUnitario                NUMBER;
  v_precoUnitarioConvertido      NUMBER;
  v_valorProdutoServico          NUMBER;
  v_valorFreteGeral              NUMBER;
  v_valorSeguroGeral             NUMBER;
  v_valorDescontoGeral           NUMBER;
  v_valorOutrasDespesasGeral     NUMBER;
  v_valorAdicFreteMarinMerGeral  NUMBER;
  v_valorDespesasAduaneirasGeral NUMBER;
  v_valorBasePagamento           NUMBER;
  v_valorDescontoPagamento       NUMBER;
  v_valorOutrasDespesasPagamento NUMBER;
  v_valorJurosPagamento          NUMBER;
  v_valorFreteTotal              NUMBER;
  v_valorSeguroTotal             NUMBER;
  v_valorDescontoTotal           NUMBER;
  v_valorOutrasDespesasTotal     NUMBER;
  v_valorAdicFreteMarinMerTotal  NUMBER;
  v_valorDespesasAduaneirasTotal NUMBER;
  v_valorLiquidoItem             NUMBER;
BEGIN
  r_cab_valorProdutos            := p_cab_valorProdutos;
  r_cab_valorServicos            := p_cab_valorServicos;
  r_cab_valorBasePagamento       := p_cab_valorBasePagamento;
  r_cab_valorAVistaMinimo        := p_cab_valorAVistaMinimo;
  r_cab_valorFreteTotal          := p_cab_valorFreteTotal;
  r_cab_valorSeguroTotal         := p_cab_valorSeguroTotal;
  r_cab_valorDescontoTotal       := p_cab_valorDescontoTotal;
  r_cab_valorOutrasDespesasTotal := p_cab_valorOutrasDespesasTotal;
  r_cab_valorAdicFreteMarinTotal := p_cab_valorAdicFreteMarinTotal;
  r_cab_valorDespesasAduanTotal  := p_cab_valorDespesasAduanTotal;
  r_cab_valorLiquidoItem         := p_cab_valorLiquidoItem;
  r_calcularImpostosItem         := p_calcularImpostosItem;
  FOR a IN (
    SELECT
      a.geraFinanceiro,
      a.quantidade,
      a.quantidadeConvertida,
      a.usarPrecoAVista,
      a.precoUnitarioBruto,
      a.acrescimoUnitarioComposicao,
      a.precoUnitario,
      a.precoUnitarioConvertido,
      a.valorProdutoServicoBruto,
      a.valorProdutoServico,
      a.valorDescontoItem,
      a.valorAcrescimoItem,
      a.valorFreteItem,
      a.valorSeguroItem,
      a.valorAdicFreteMarinhaMerItem,
      a.valorDespesasAduaneirasItem,
      a.valorFreteGeral,
      a.valorSeguroGeral,
      a.valorDescontoGeral,
      a.valorOutrasDespesasGeral,
      a.valorAdicFreteMarinhaMerGeral,
      a.valorDespesasAduaneirasGeral,
      a.valorBasePagamento,
      a.valorDescontoPagamento,
      a.valorOutrasDespesasPagamento,
      a.valorJurosPagamento,
      a.valorFreteTotal,
      a.valorSeguroTotal,
      a.valorDescontoTotal,
      a.valorOutrasDespesasTotal,
      a.valorAdicFreteMarinhaMerTotal,
      a.valorDespesasAduaneirasTotal,
      a.retidoISSQN,
      a.valorISSQN,
      a.valorRetIRRF,
      a.valorRetINSS,
      a.valorRetPIS,
      a.valorRetCOFINS,
      a.valorRetCSLL,
      a.valorRetOutros,
      a.valorII,
      a.valorIOF,
      a.valorIPI,
      a.valorPIS,
      a.valorPISST,
      a.valorCOFINS,
      a.valorCOFINSST,
      a.valorCreditoSimplesNacional,
      a.valorICMS,
      a.valorICMSST,
      a.valorLiquidoItem,
      modDoc.geraFinanceiro modDoc_geraFinanceiro,
      modDoc.diminuiDescontoPrUnit,
      modDoc.somaAcrescimosPrUnit,
      modDoc.somaFreteSeguroPrUnit,
      prod.tipoProduto,
      CASE
        WHEN EXISTS (
          SELECT 1
          FROM CAPRODUTOXCOMPOSICOESPREC compPrec
          WHERE compPrec.produto = gradProd.produto
          AND compPrec.ativo = 1)
        THEN 1
        ELSE 0
      END composicaoPreco
    FROM MOORCAMENTOXITENS a
    JOIN PAMODELOSDOCUMENTO modDoc
    ON modDoc.modeloDocumento = a.modeloDocumento
    JOIN CAGRADESPRODUTO gradProd
    ON gradProd.gradeProduto = a.gradeProduto
    JOIN CAPRODUTOS prod
    ON prod.produto = gradProd.produto
    WHERE a.idItemOrcamento = p_item_idItemOrcamento)
  LOOP
    v_precoUnitario                := a.precoUnitario;
    v_precoUnitarioConvertido      := a.precoUnitarioConvertido;
    v_valorProdutoServico          := a.valorProdutoServico;
    v_valorFreteGeral              := a.valorFreteGeral;
    v_valorSeguroGeral             := a.valorSeguroGeral;
    v_valorDescontoGeral           := a.valorDescontoGeral;
    v_valorOutrasDespesasGeral     := a.valorOutrasDespesasGeral;
    v_valorAdicFreteMarinMerGeral  := a.valorAdicFreteMarinhaMerGeral;
    v_valorDespesasAduaneirasGeral := a.valorDespesasAduaneirasGeral;
    v_valorBasePagamento           := a.valorBasePagamento;
    v_valorDescontoPagamento       := a.valorDescontoPagamento;
    v_valorOutrasDespesasPagamento := a.valorOutrasDespesasPagamento;
    v_valorJurosPagamento          := a.valorJurosPagamento;
    v_valorFreteTotal              := a.valorFreteTotal;
    v_valorSeguroTotal             := a.valorSeguroTotal;
    v_valorDescontoTotal           := a.valorDescontoTotal;
    v_valorOutrasDespesasTotal     := a.valorOutrasDespesasTotal;
    v_valorAdicFreteMarinMerTotal  := a.valorAdicFreteMarinhaMerTotal;
    v_valorDespesasAduaneirasTotal := a.valorDespesasAduaneirasTotal;
    v_valorLiquidoItem             := a.valorLiquidoItem;
    IF a.tipoProduto = '09' THEN
      r_cab_valorServicos          := r_cab_valorServicos - v_valorProdutoServico;
    ELSE
      r_cab_valorProdutos          := r_cab_valorProdutos - v_valorProdutoServico;
    END IF;
    r_cab_valorBasePagamento       := r_cab_valorBasePagamento - v_valorBasePagamento;
    IF a.usarPrecoAVista = 1 AND a.geraFinanceiro = 1 THEN
      r_cab_valorAVistaMinimo      := r_cab_valorAVistaMinimo - v_valorProdutoServico - v_valorDescontoPagamento + v_valorOutrasDespesasPagamento + v_valorJurosPagamento + v_valorDescontoTotal - v_valorOutrasDespesasTotal;
    END IF;
    r_cab_valorFreteTotal          := r_cab_valorFreteTotal - v_valorFreteTotal;
    r_cab_valorSeguroTotal         := r_cab_valorSeguroTotal - v_valorSeguroTotal;
    r_cab_valorDescontoTotal       := r_cab_valorDescontoTotal - v_valorDescontoTotal;
    r_cab_valorOutrasDespesasTotal := r_cab_valorOutrasDespesasTotal - v_valorOutrasDespesasTotal;
    r_cab_valorAdicFreteMarinTotal := r_cab_valorAdicFreteMarinTotal - v_valorAdicFreteMarinMerTotal;
    r_cab_valorDespesasAduanTotal  := r_cab_valorDespesasAduanTotal - v_valorDespesasAduaneirasTotal;
    r_cab_valorLiquidoItem         := r_cab_valorLiquidoItem - v_valorLiquidoItem;
    v_valorFreteGeral              := v_valorFreteGeral + p_saldoRatFreteGeral;
    v_valorSeguroGeral             := v_valorSeguroGeral + p_saldoRatSeguroGeral;
    v_valorAdicFreteMarinMerGeral  := v_valorAdicFreteMarinMerGeral + p_saldoRatAdicFreteMarinGeral;
    v_valorDespesasAduaneirasGeral := v_valorDespesasAduaneirasGeral + p_saldoRatDespesasAduanGeral;
    v_valorDescontoGeral           := v_valorDescontoGeral + p_saldoRatDescontoGeral;
    v_valorOutrasDespesasGeral     := v_valorDespesasAduaneirasGeral + p_saldoRatOutrasDespesasGeral;
    v_valorDescontoPagamento       := v_valorDescontoPagamento + p_saldoRatDescontoPagamento;
    v_valorOutrasDespesasPagamento := v_valorOutrasDespesasPagamento + p_saldoRatOutrasDespPagamento;
    v_valorJurosPagamento          := v_valorJurosPagamento + p_saldoRatJurosPagamento;
    ADD_CALCULA_TOTAIS_ITEM (
      p_cab_tipoPagamentoFrete,
      a.quantidade,
      a.quantidadeConvertida,
      a.precoUnitarioBruto,
      a.acrescimoUnitarioComposicao,
      a.precoUnitario,
      a.valorDescontoItem,
      a.valorAcrescimoItem,
      a.valorFreteItem,
      a.valorSeguroItem,
      a.valorAdicFreteMarinhaMerItem,
      a.valorDespesasAduaneirasItem,
      v_valorFreteGeral,
      v_valorSeguroGeral,
      v_valorDescontoGeral,
      v_valorOutrasDespesasGeral,
      v_valorAdicFreteMarinMerGeral,
      v_valorDespesasAduaneirasGeral,
      v_valorDescontoPagamento,
      v_valorOutrasDespesasPagamento,
      v_valorJurosPagamento,
      a.diminuiDescontoPrUnit,
      a.somaAcrescimosPrUnit,
      a.somaFreteSeguroPrUnit,
      a.composicaoPreco,
      /* Retornos */
      v_precoUnitario,
      v_precoUnitarioConvertido,
      v_valorProdutoServico,
      v_valorFreteTotal,
      v_valorSeguroTotal,
      v_valorDescontoTotal,
      v_valorOutrasDespesasTotal,
      v_valorAdicFreteMarinMerTotal,
      v_valorDespesasAduaneirasTotal);
    IF p_cab_impostosEditados = 0 
        OR v_valorProdutoServico <> a.valorProdutoServico
        OR CASE WHEN p_cab_tipoPagamentoFrete = 'V' THEN 0 ELSE v_valorFreteTotal END
          <> CASE WHEN CASE WHEN p_troca_tipoPagamentoFrete = 1 THEN p_a_cab_tipoPagamentoFrete ELSE p_cab_tipoPagamentoFrete END = 'V' THEN 0 ELSE a.valorFreteTotal END
        OR CASE WHEN p_cab_tipoPagamentoFrete   = 'V' THEN 0 ELSE v_valorSeguroTotal END
          <> CASE WHEN CASE WHEN p_troca_tipoPagamentoFrete = 1 THEN p_a_cab_tipoPagamentoFrete ELSE p_cab_tipoPagamentoFrete END = 'V' THEN 0 ELSE a.valorSeguroTotal END
        OR v_valorDescontoTotal <> a.valorDescontoTotal
        OR v_valorOutrasDespesasTotal <> a.valorOutrasDespesasTotal
        OR v_valorAdicFreteMarinMerTotal <> a.valorAdicFreteMarinhaMerTotal
        OR v_valorDespesasAduaneirasTotal <> a.valorDespesasAduaneirasTotal
        OR v_precoUnitario <> a.precoUnitario
        OR v_valorProdutoServico <> a.valorProdutoServico
    THEN
      r_calcularImpostosItem := 1;
    END IF;
    v_valorBasePagamento := FUNC_ADD_CALC_BASE_PAGAMENTO (
      p_cab_origemDocumento,
      0, -- p_cab_nfFornecedor
      p_cab_tipoPagamentoFrete,
      a.geraFinanceiro,
      v_valorProdutoServico,
      v_valorDescontoPagamento,
      v_valorOutrasDespesasPagamento,
      v_valorJurosPagamento,
      v_valorFreteTotal,
      v_valorSeguroTotal,
      v_valorDescontoTotal,
      v_valorOutrasDespesasTotal,
      0, -- p_item_valorIPIDevolucao
      a.retidoISSQN,
      a.valorISSQN,
      a.valorRetIRRF,
      a.valorRetINSS,
      a.valorRetPIS,
      a.valorRetCOFINS,
      a.valorRetCSLL,
      a.valorRetOutros,
      a.valorII,
      a.valorIOF,
      a.valorIPI,
      a.valorICMSST,
      0, -- p_item_valorICMSSTEscrit
      0, -- p_item_somarICMSST
      0, -- p_item_valorAcrescExtempTotal
      a.modDoc_geraFinanceiro);
    v_valorLiquidoItem := FUNC_ADD_CALC_VALOR_LIQUIDO (
      0, -- p_cab_nfFornecedor
      p_cab_tipoPagamentoFrete,
      v_valorProdutoServico,
      v_valorFreteTotal,
      v_valorSeguroTotal,
      v_valorDescontoTotal,
      v_valorOutrasDespesasTotal,
      0, -- p_item_valorIPIDevolucao
      a.valorII,
      a.valorIOF,
      a.valorIPI,
      a.valorICMSST,
      0, -- p_item_valorICMSSTEscrit
      0 -- p_item_somarICMSST
      );
    UPDATE MOORCAMENTOXITENS SET
      precoUnitario                 = v_precoUnitario,
      precoUnitarioConvertido       = v_precoUnitarioConvertido,
      valorProdutoServico           = v_valorProdutoServico,
      valorFreteGeral               = v_valorFreteGeral,
      valorSeguroGeral              = v_valorSeguroGeral,
      valorDescontoGeral            = v_valorDescontoGeral,
      valorOutrasDespesasGeral      = v_valorOutrasDespesasGeral,
      valorAdicFreteMarinhaMerGeral = v_valorAdicFreteMarinMerGeral,
      valorDespesasAduaneirasGeral  = v_valorDespesasAduaneirasGeral,
      valorBasePagamento            = v_valorBasePagamento,
      valorDescontoPagamento        = v_valorDescontoPagamento,
      valorOutrasDespesasPagamento  = v_valorOutrasDespesasPagamento,
      valorJurosPagamento           = v_valorJurosPagamento,
      valorFreteTotal               = v_valorFreteTotal,
      valorSeguroTotal              = v_valorSeguroTotal,
      valorDescontoTotal            = v_valorDescontoTotal,
      valorOutrasDespesasTotal      = v_valorOutrasDespesasTotal,
      valorAdicFreteMarinhaMerTotal = v_valorAdicFreteMarinMerTotal,
      valorDespesasAduaneirasTotal  = v_valorDespesasAduaneirasTotal,
      valorLiquidoItem              = v_valorLiquidoItem
    WHERE idItemOrcamento           = p_item_idItemOrcamento;
    IF a.tipoProduto = '09' THEN
      r_cab_valorServicos          := r_cab_valorServicos + v_valorProdutoServico;
    ELSE
      r_cab_valorProdutos          := r_cab_valorProdutos + v_valorProdutoServico;
    END IF;
    r_cab_valorBasePagamento       := r_cab_valorBasePagamento + v_valorBasePagamento;
    IF a.usarPrecoAVista = 1
      AND a.geraFinanceiro = 1
    THEN
      r_cab_valorAVistaMinimo      := r_cab_valorAVistaMinimo + v_valorProdutoServico + v_valorDescontoPagamento - v_valorOutrasDespesasPagamento - v_valorJurosPagamento - v_valorDescontoTotal + v_valorOutrasDespesasTotal;
    END IF;
    r_cab_valorFreteTotal          := r_cab_valorFreteTotal + v_valorFreteTotal;
    r_cab_valorSeguroTotal         := r_cab_valorSeguroTotal + v_valorSeguroTotal;
    r_cab_valorDescontoTotal       := r_cab_valorDescontoTotal + v_valorDescontoTotal;
    r_cab_valorOutrasDespesasTotal := r_cab_valorOutrasDespesasTotal + v_valorOutrasDespesasTotal;
    r_cab_valorAdicFreteMarinTotal := r_cab_valorAdicFreteMarinTotal + v_valorAdicFreteMarinMerTotal;
    r_cab_valorDespesasAduanTotal  := r_cab_valorDespesasAduanTotal + v_valorDespesasAduaneirasTotal;
    r_cab_valorLiquidoItem         := r_cab_valorLiquidoItem + v_valorLiquidoItem;
  END LOOP;
END ADD_ORCAMENTO_CALC_IMP_RESIDUO;

/

