SET DEFINE OFF;

create or replace PROCEDURE ADD_ORCAMENTO_REGRA_DESC_CAB (
  p_usuarioLogado                IN NUMBER,
  p_perfilUsuarioLogado          IN NUMBER,
  p_orcamento                    IN NUMBER,
  /* Retornos */
  r_possuiRegra                  OUT NUMBER,
  r_valorDescontoSugestao        OUT NUMBER,
  r_valorDescontoMaximoSemSenha  OUT NUMBER)
IS
BEGIN
  WITH
  CABECALHO AS (
    SELECT
      a.estabelecimento,
      a.pessoa,
      COALESCE((
        CASE
          WHEN a.pessoa = 0
          THEN (
            SELECT MAX(munPess.uf)
            FROM CAENDERECOSPESSOA endPess
            JOIN SIMUNICIPIOS munPess
            ON munPess.municipio = endPess.municipio
            WHERE endPess.pessoa = est.pessoaEstabelecimento
            AND endPess.ativo = 1
            AND endPess.principal = 1)
          ELSE COALESCE((
            SELECT MAX(munPess.uf)
            FROM CAENDERECOSPESSOA endPess
            JOIN SIMUNICIPIOS munPess
            ON munPess.municipio = endPess.municipio
            WHERE endPess.pessoa = a.pessoa
            AND endPess.ativo = 1
            AND endPess.principal = 1),(
            SELECT MAX(munPess.uf)
            FROM CAENDERECOSPESSOA endPess
            JOIN SIMUNICIPIOS munPess
            ON munPess.municipio = endPess.municipio
            WHERE endPess.pessoa = est.pessoaEstabelecimento
            AND endPess.ativo = 1
            AND endPess.principal = 1))
        END
      ),'  ') uf,
      CASE
        WHEN pess.nascimentoFundacao IS NULL
          OR TRUNC (pess.nascimentoFundacao) > TRUNC (SYSDATE)
        THEN 0
        ELSE TRUNC (SYSDATE, 'YYYY')
          - TRUNC (pess.nascimentoFundacao, 'YYYY')
          - CASE
              WHEN TO_CHAR (SYSDATE, 'MMDD') < TO_CHAR (pess.nascimentoFundacao, 'MMDD')
              THEN 1
              ELSE 0
            END
      END idade,
      a.valorBasePagamento
    FROM (
      SELECT
        a.estabelecimento,
        a.pessoa,
        a.valorBasePagamento
      FROM MOORCAMENTOS a
      WHERE a.orcamento = p_orcamento
      AND a.valorBasePagamento > 0) a
    JOIN PAESTABELECIMENTOS est
    ON est.estabelecimento = a.estabelecimento
    JOIN CAPESSOAS pess
    ON pess.pessoa = a.pessoa),
  ITENS AS (
    SELECT
      a.sequencia,
      a.vendedor,
      a.gradeProduto,
      a.localEstoque,
      a.personalizacao,
      a.quantidade,
      ROUND (a.quantidade * (a.precoUnitarioBruto + a.acrescimoUnitarioComposicao),2) valorBaseRegra,
      a.valorDescontoItem,
      a.tabelaPreco,
      gradProd.produto,
      gradProd.cor,
      gradProd.tamanho,
      prod.subcategoriaProduto,
      prod.marca,
      prod.caracteristicaA,
      prod.caracteristicaB,
      prod.caracteristicaC,
      prod.caracteristicaD,
      prod.caracteristicaE,
      prod.idNcm,
      prod.listaServicos,
      subCatProd.categoriaProduto
    FROM MOORCAMENTOXITENS a
    JOIN CAGRADESPRODUTO gradProd
    ON gradProd.gradeProduto = a.gradeProduto
    JOIN CAPRODUTOS prod
    ON prod.produto = gradProd.produto
    JOIN PASUBCATEGORIASPRODUTO subCatProd
    ON subCatProd.subCategoriaProduto = prod.subCategoriaProduto
    WHERE a.orcamento = p_orcamento
    AND a.cancelado = 0
    AND a.quantidade > 0),
  REGRAS AS (
    SELECT
      a.regraDescontoMargem,
      a.ordenacao,
      a.tipoRegraDescontoMargem,
      a.valorSugestao,
      a.valorMaximoSemSenha,
      a.filtrarTabelaPreco,
      cab.idade,
      cab.valorBasePagamento
    FROM PAREGRASDESCONTOSMARGEM a
    JOIN CABECALHO cab
    ON 1=1
    JOIN PAFILTROSCABECALHO filtroCab
    ON filtroCab.filtroCabecalho = a.filtroCabecalho
    JOIN CAPESSOAS pess
    ON pess.pessoa = cab.pessoa
    JOIN PAFILTROSPAGAMENTO filtroPag
    ON filtroPag.filtroPagamento = a.filtroPagamento
    WHERE a.regraDescontoMargem > 0
    AND a.ativo = 1
    AND a.dataValidadeInicial <= TRUNC(SYSDATE)
    AND a.dataValidadeFinal >= TRUNC(SYSDATE)
    AND a.cabecalhoItemPagamento = 'C'
    AND a.tipoRegraDescontoMargem BETWEEN 1 AND 6
    -- Filtro Cabeçalho
    AND (a.filtroCabecalho = 0
      OR (filtroCab.filtrarEstabelecimentos = 0
        OR EXISTS (
          SELECT 1
          FROM PAFILTROCABECXESTABELEC filtroCabX
          WHERE filtroCabX.filtroCabecalho = a.filtroCabecalho
          AND filtroCabX.estabelecimento = cab.estabelecimento
          AND filtroCabX.ativo = 1))
      AND (filtroCab.filtrarUfs = 0
        OR EXISTS (
          SELECT 1
          FROM PAFILTROCABECXUFS filtroCabX
          WHERE filtroCabX.filtroCabecalho = a.filtroCabecalho
          AND filtroCabX.uf = cab.uf
          AND filtroCabX.ativo = 1))
      AND (filtroCab.filtrarPessoas = 0
        OR EXISTS (
          SELECT 1
          FROM PAFILTROCABECXPESSOAS filtroCabX
          WHERE filtroCabX.filtroCabecalho = a.filtroCabecalho
          AND filtroCabX.pessoa = cab.pessoa
          AND filtroCabX.ativo = 1))
      AND (filtroCab.filtrarPerfisUsuario = 0
        AND filtroCab.filtrarUsuarios = 0
        OR filtroCab.filtrarPerfisUsuario = 1
        AND EXISTS (
          SELECT 1
          FROM PAFILTROCABECXPERFISUSUAR filtroCabX
          WHERE filtroCabX.filtroCabecalho = a.filtroCabecalho
          AND filtroCabX.perfilUsuario = p_perfilUsuarioLogado
          AND filtroCabX.ativo = 1)
        OR filtroCab.filtrarUsuarios = 1
        AND EXISTS (
          SELECT 1
          FROM PAFILTROCABECXUSUARIOS filtroCabX
          WHERE filtroCabX.filtroCabecalho = a.filtroCabecalho
          AND filtroCabX.usuario = p_usuarioLogado
          AND filtroCabX.ativo = 1))
      AND (filtroCab.indicadorPessoa = ' '
        OR filtroCab.indicadorPessoa = pess.indicadorPessoa)
      AND (filtroCab.colaborador = ' '
        OR filtroCab.colaborador = 'N'
        AND (cab.pessoa = 0
          OR NOT (EXISTS (
            SELECT 1
            FROM CACOLABORADORES colab
            WHERE colab.colaborador = cab.pessoa
            AND colab.ativo = 1 )))
        OR filtroCab.colaborador = 'S'
        AND cab.pessoa <> 0
        AND EXISTS (
          SELECT 1
          FROM CACOLABORADORES colab
          WHERE colab.colaborador = cab.pessoa
          AND colab.ativo = 1)))),
  FILTROSPRODUTOS AS (
    SELECT
      a.regraDescontoMargem,
      a.filtroProduto,
      b.quantidadeMinima,
      b.quantidadeMaxima,
      b.filtrarVendedores,
      b.filtrarLocaisEstoque,
      b.filtrarPersonalizacoes,
      b.filtrarProdutos,
      b.filtrarCategoriasProdutos,
      b.filtrarSubcategoriasProdutos,
      b.filtrarMarcas,
      b.filtrarCaracteristicasA,
      b.filtrarCaracteristicasB,
      b.filtrarCaracteristicasC,
      b.filtrarCaracteristicasD,
      b.filtrarCaracteristicasE,
      b.filtrarCores,
      b.filtrarTamanhos,
      b.filtrarNCMs,
      b.filtrarListasServicos,
      c.filtrarTabelaPreco
    FROM PAREGRADESCMARGXFILTPROD a
    JOIN PAFILTROSPRODUTO b
    ON b.filtroProduto = a.filtroProduto
    JOIN REGRAS c
    ON c.regraDescontoMargem = a.regraDescontoMargem
    AND a.filtroProduto > 0
    AND a.ativo = 1),
  REGRASXITENS AS (
    SELECT
      a.regraDescontoMargem,
      a.filtroProduto,
      a.quantidadeMinima,
      a.quantidadeMaxima,
      b.sequencia,
      b.quantidade,
      b.valorBaseRegra,
      b.valorDescontoItem
    FROM FILTROSPRODUTOS a
    JOIN ITENS b
	  ON 1=1
    WHERE (a.filtrarTabelaPreco = 0
      OR EXISTS (
        SELECT 1
        FROM PAREGRADESCMARGXTABELASPR x
        WHERE x.regraDescontoMargem = a.regraDescontoMargem
        AND x.tabelaPreco = b.tabelaPreco
        AND x.ativo = 1))
    AND (a.filtrarVendedores = 0
    OR EXISTS (
      SELECT 1
      FROM PAFILTROPRODUTOXVENDEDOR x
      WHERE x.filtroProduto = a.filtroProduto
      AND x.vendedor = b.vendedor
      AND x.ativo = 1))
    AND (a.filtrarLocaisEstoque = 0
    OR EXISTS (
      SELECT 1
      FROM PAFILTROPRODUTOXLOCAISEST x
      WHERE x.filtroProduto = a.filtroProduto
      AND x.localEstoque = b.localEstoque
      AND x.ativo = 1))
    AND (a.filtrarPersonalizacoes = 0
    OR EXISTS (
      SELECT 1
      FROM PAFILTROPRODUTOXPERSONAL x
      WHERE x.filtroProduto = a.filtroProduto
      AND x.personalizacao = b.personalizacao
      AND x.ativo = 1))
    AND (a.filtrarProdutos = 0
      AND a.filtrarCategoriasProdutos = 0
      AND a.filtrarSubcategoriasProdutos = 0
      AND a.filtrarMarcas = 0
      AND a.filtrarCaracteristicasA = 0
      AND a.filtrarCaracteristicasB = 0
      AND a.filtrarCaracteristicasC = 0
      AND a.filtrarCaracteristicasD = 0
      AND a.filtrarCaracteristicasE = 0
      AND a.filtrarCores = 0
      AND a.filtrarTamanhos = 0
      AND a.filtrarNCMs = 0
      AND a.filtrarListasServicos = 0
      OR a.filtrarProdutos = 1
      AND EXISTS (
        SELECT 1
        FROM PAFILTROPRODUTOXPRODUTOS x
        WHERE x.filtroProduto = a.filtroProduto
        AND x.produto = b.produto
        AND x.ativo = 1)
      OR (a.filtrarCategoriasProdutos = 1
        OR a.filtrarSubcategoriasProdutos = 1
        OR a.filtrarMarcas = 1
        OR a.filtrarCaracteristicasA = 1
        OR a.filtrarCaracteristicasB = 1
        OR a.filtrarCaracteristicasC = 1
        OR a.filtrarCaracteristicasD = 1
        OR a.filtrarCaracteristicasE = 1
        OR a.filtrarCores = 1
        OR a.filtrarTamanhos = 1
        OR a.filtrarNCMs = 1
        OR a.filtrarListasServicos = 1)
      AND (a.filtrarCategoriasProdutos = 0
        OR EXISTS (
          SELECT 1
          FROM PAFILTROPRODUTOXCATEGPROD x
          WHERE x.filtroProduto = a.filtroProduto
          AND x.categoriaProduto = b.categoriaProduto
          AND x.ativo = 1))
      AND (a.filtrarSubcategoriasProdutos = 0
        OR EXISTS (
          SELECT 1
          FROM PAFILTROPRODUTOXSUBCAPROD x
          WHERE x.filtroProduto = a.filtroProduto
          AND x.subcategoriaProduto = b.subcategoriaProduto
          AND x.ativo = 1))
      AND (a.filtrarMarcas = 0
        OR EXISTS (
          SELECT 1
          FROM PAFILTROPRODUTOXMARCAS x
          WHERE x.filtroProduto = a.filtroProduto
          AND x.marca = b.marca
          AND x.ativo = 1))
      AND (a.filtrarCaracteristicasA = 0
        OR EXISTS (
          SELECT 1
          FROM PAFILTROPRODUTOXCARACTERA x
          WHERE x.filtroProduto = a.filtroProduto
          AND x.caracteristicaA = b.caracteristicaA
          AND x.ativo = 1))
      AND (a.filtrarCaracteristicasB = 0
        OR EXISTS (
          SELECT 1
          FROM PAFILTROPRODUTOXCARACTERB x
          WHERE x.filtroProduto = a.filtroProduto
          AND x.caracteristicaB = b.caracteristicaB
          AND x.ativo = 1))
      AND (a.filtrarCaracteristicasC = 0
        OR EXISTS (
          SELECT 1
          FROM PAFILTROPRODUTOXCARACTERC x
          WHERE x.filtroProduto = a.filtroProduto
          AND x.caracteristicaC = b.caracteristicaC
          AND x.ativo = 1))
      AND (a.filtrarCaracteristicasD = 0
        OR EXISTS (
          SELECT 1
          FROM PAFILTROPRODUTOXCARACTERD x
          WHERE x.filtroProduto = a.filtroProduto
          AND x.caracteristicaD = b.caracteristicaD
          AND x.ativo = 1))
      AND (a.filtrarCaracteristicasE = 0
        OR EXISTS (
          SELECT 1
          FROM PAFILTROPRODUTOXCARACTERE x
          WHERE x.filtroProduto = a.filtroProduto
          AND x.caracteristicaE = b.caracteristicaE
          AND x.ativo = 1))
      AND (a.filtrarCores = 0
        OR EXISTS (
          SELECT 1
          FROM PAFILTROPRODUTOXCORES x
          WHERE x.filtroProduto = a.filtroProduto
          AND x.cor = b.cor
          AND x.ativo = 1))
      AND (a.filtrarTamanhos = 0
        OR EXISTS (
          SELECT 1
          FROM PAFILTROPRODUTOXTAMANHOS x
          WHERE x.filtroProduto = a.filtroProduto
          AND x.tamanho = b.tamanho
          AND x.ativo = 1))
      AND (a.filtrarNCMs = 0
        OR EXISTS (
          SELECT 1
          FROM PAFILTROPRODUTOXNCMS x
          WHERE x.filtroProduto = a.filtroProduto
          AND x.idNcm = b.idNcm
          AND x.ativo = 1))
      AND (a.filtrarListasServicos = 0
        OR EXISTS (
          SELECT 1
          FROM PAFILTROPRODUTOXLISTASSE x
          WHERE x.filtroProduto = a.filtroProduto
          AND x.listaServicos = b.listaServicos
          AND x.ativo = 1)))),
  REGRASXFILTROS AS (
    SELECT
      a.regraDescontoMargem,
      a.filtroProduto
    FROM (
      SELECT
        a.regraDescontoMargem,
        a.filtroProduto,
        a.quantidadeMinima,
        a.quantidadeMaxima,
        SUM (a.quantidade) quantidade
      FROM REGRASXITENS a
      GROUP BY
        a.regraDescontoMargem,
        a.filtroProduto,
        a.quantidadeMinima,
        a.quantidadeMaxima) a
    WHERE a.quantidade >= a.quantidadeMinima
    AND (a.quantidadeMaxima = 0
      OR a.quantidade <= a.quantidadeMaxima)),
  REGRASVALIDAS AS (
    SELECT
      a.regraDescontoMargem,
      a.ordenacao,
      a.tipoRegraDescontoMargem,
      a.valorSugestao,
      a.valorMaximoSemSenha,
      a.filtrarTabelaPreco,
      a.idade,
      a.valorBasePagamento,
      COALESCE((
        SELECT COUNT(1)
        FROM FILTROSPRODUTOS b
        WHERE b.regraDescontoMargem = a.regraDescontoMargem),0) filtrosProdutos
    FROM REGRAS a
    WHERE
      ( SELECT COUNT(1)
        FROM FILTROSPRODUTOS b
        WHERE b.regraDescontoMargem = a.regraDescontoMargem)
    = ( SELECT COUNT(1)
        FROM REGRASXFILTROS b
        WHERE b.regraDescontoMargem = a.regraDescontoMargem))
  SELECT
    COALESCE (MAX(a.possuiRegra), 0) possuiRegra,
    COALESCE (ROUND(
      CASE
        WHEN SUM (
          CASE
            WHEN a.valorDescontoSugestao < 0
            THEN 0
            ELSE a.valorDescontoSugestao
          END) >= MAX(a.valorBasePagamento)
        THEN MAX(a.valorBasePagamento) - 0.01
        ELSE SUM (
          CASE
            WHEN a.valorDescontoSugestao < 0
            THEN 0
            ELSE a.valorDescontoSugestao
          END)
      END, 2), 0) valorDescontoSugestao,
    COALESCE (ROUND(
      CASE
        WHEN SUM (
          CASE
            WHEN a.valorDescontoMaximoSemSenha < 0
            THEN 0
            ELSE a.valorDescontoMaximoSemSenha
          END) >= MAX(a.valorBasePagamento)
        THEN MAX(a.valorBasePagamento) - 0.01
        ELSE SUM (
          CASE
            WHEN a.valorDescontoMaximoSemSenha < 0
            THEN 0
            ELSE a.valorDescontoMaximoSemSenha
          END)
      END, 2), 0) valorDescontoMaximoSemSenha
  INTO
    r_possuiRegra,
    r_valorDescontoSugestao,
    r_valorDescontoMaximoSemSenha
  FROM (
    SELECT
      1 possuiRegra,
      a.valorBasePagamento,
      ROUND (
        CASE a.tipoRegraDescontoMargem
          -- Desconto em percentual
          WHEN 1
          THEN a.valorBaseRegra * a.valorSugestao / 100
          -- Desconto em valor
          WHEN 2
          THEN a.valorSugestao * a.multiplicador
           -- Preço unitário fixo
          WHEN 3
          THEN a.valorBaseRegra-ROUND (a.quantidadeRegra*a.valorSugestao,2)
          -- Desconto igual a idade em percentual
          WHEN 4
          THEN a.valorBaseRegra * a.idade / 100
          -- Desconto igual a idade em valor
          WHEN 5
          THEN a.idade * a.multiplicador
          -- Preço total fixado
          WHEN 6
          THEN a.valorBaseRegra
          ELSE 0
        END - a.valorDescontoItem, 2) valorDescontoSugestao,
      ROUND (
        CASE a.tipoRegraDescontoMargem
          -- Desconto em percentual
          WHEN 1
          THEN a.valorBaseRegra * a.valorMaximoSemSenha / 100
          -- Desconto em valor
          WHEN 2
          THEN a.valorMaximoSemSenha * a.multiplicador
          -- Preço unitário fixo
          WHEN 3
          THEN a.valorBaseRegra-ROUND (a.quantidadeRegra*a.valorMaximoSemSenha,2)
          -- Desconto igual a idade em percentual
          WHEN 4
          THEN a.valorBaseRegra * a.idade / 100
          -- Desconto igual a idade em valor
          WHEN 5
          THEN a.idade * a.multiplicador
          -- Preço total fixado
          WHEN 6
          THEN a.valorBaseRegra
          ELSE 0
        END, 2) valorDescontoMaximoSemSenha
    FROM (
      SELECT
        a.tipoRegraDescontoMargem,
        a.valorSugestao,
        a.valorMaximoSemSenha,
        a.idade,
        a.valorBasePagamento,
        SUM(a.quantidade) quantidadeRegra,
        CASE
          WHEN SUM (a.valorBaseRegraTodos - a.valorDescontoItemTodos) = 0
          THEN 0
          ELSE SUM (a.valorBaseRegra - a.valorDescontoItem)
            / SUM (a.valorBaseRegraTodos - a.valorDescontoItemTodos)
        END multiplicador,
        SUM (a.valorBaseRegra) valorBaseRegra,
        SUM (a.valorDescontoItem) valorDescontoItem
      FROM (
        SELECT DISTINCT
          a.regraDescontoMargem,
          a.ordenacao,
          a.tipoRegraDescontoMargem,
          a.valorSugestao,
          a.valorMaximoSemSenha,
          a.idade,
          a.valorBasePagamento,
          b.sequencia,
          b.quantidade,
          b.valorBaseRegra,
          b.valorDescontoItem,
          0 valorBaseRegraTodos,
          0 valorDescontoItemTodos
        FROM REGRASVALIDAS a
        JOIN ITENS b
        ON 1=1
        WHERE a.filtrosProdutos = 0
        AND (a.filtrarTabelaPreco = 0
          OR EXISTS (
            SELECT 1
            FROM PAREGRADESCMARGXTABELASPR x
            WHERE x.regraDescontoMargem = a.regraDescontoMargem
            AND x.tabelaPreco = b.tabelaPreco
            AND x.ativo = 1))
        UNION ALL
        SELECT DISTINCT
          a.regraDescontoMargem,
          a.ordenacao,
          a.tipoRegraDescontoMargem,
          a.valorSugestao,
          a.valorMaximoSemSenha,
          a.idade,
          a.valorBasePagamento,
          b.sequencia,
          b.quantidade,
          b.valorBaseRegra,
          b.valorDescontoItem,
          0 valorBaseRegraTodos,
          0 valorDescontoItemTodos
        FROM REGRASVALIDAS a
        JOIN REGRASXITENS b
        ON b.regraDescontoMargem = a.regraDescontoMargem
        WHERE a.filtrosProdutos > 0
        UNION ALL
        SELECT DISTINCT
          a.regraDescontoMargem,
          a.ordenacao,
          a.tipoRegraDescontoMargem,
          a.valorSugestao,
          a.valorMaximoSemSenha,
          a.idade,
          a.valorBasePagamento,
          b.sequencia,
          b.quantidade,
          0 valorBaseRegra,
          0 valorDescontoItem,
          b.valorBaseRegra valorBaseRegraTodos,
          b.valorDescontoItem valorDescontoItemTodos
        FROM REGRASVALIDAS a
        JOIN ITENS b
        ON 1=1) a
      GROUP BY
        a.regraDescontoMargem,
        a.ordenacao,
        a.tipoRegraDescontoMargem,
        a.valorSugestao,
        a.valorMaximoSemSenha,
        a.idade,
        a.valorBasePagamento) a) a;
END ADD_ORCAMENTO_REGRA_DESC_CAB;

/

create or replace PROCEDURE ADD_PRE_DOC_REGRA_DESC_CAB (
  p_usuarioLogado                IN NUMBER,
  p_perfilUsuarioLogado          IN NUMBER,
  p_config_227_manterPessoaOrcam IN NUMBER,
  p_preDocumento                 IN NUMBER,
  p_orc_pessoa                   IN NUMBER,
  /* Retornos */
  r_possuiRegra                  OUT NUMBER,
  r_valorDescontoSugestao        OUT NUMBER,
  r_valorDescontoMaximoSemSenha  OUT NUMBER)
IS
BEGIN
  WITH
  CABECALHO AS (
    SELECT
      a.estabelecimento,
      a.pessoa,
      COALESCE((
        CASE
          WHEN a.pessoa = 0
          THEN (
            SELECT MAX(munPess.uf)
            FROM CAENDERECOSPESSOA endPess
            JOIN SIMUNICIPIOS munPess
            ON munPess.municipio = endPess.municipio
            WHERE endPess.pessoa = est.pessoaEstabelecimento
            AND endPess.ativo = 1
            AND endPess.principal = 1)
          ELSE COALESCE((
            SELECT MAX(munPess.uf)
            FROM CAENDERECOSPESSOA endPess
            JOIN SIMUNICIPIOS munPess
            ON munPess.municipio = endPess.municipio
            WHERE endPess.pessoa = a.pessoa
            AND endPess.ativo = 1
            AND endPess.principal = 1),(
            SELECT MAX(munPess.uf)
            FROM CAENDERECOSPESSOA endPess
            JOIN SIMUNICIPIOS munPess
            ON munPess.municipio = endPess.municipio
            WHERE endPess.pessoa = est.pessoaEstabelecimento
            AND endPess.ativo = 1
            AND endPess.principal = 1))
        END
      ),'  ') uf,
      CASE
        WHEN pess.nascimentoFundacao IS NULL
          OR TRUNC (pess.nascimentoFundacao) > TRUNC (SYSDATE)
        THEN 0
        ELSE TRUNC (SYSDATE, 'YYYY')
          - TRUNC (pess.nascimentoFundacao, 'YYYY')
          - CASE
              WHEN TO_CHAR (SYSDATE, 'MMDD') < TO_CHAR (pess.nascimentoFundacao, 'MMDD')
              THEN 1
              ELSE 0
            END
      END idade,
      a.valorBasePagamento
    FROM (
      SELECT
        a.estabelecimento,
        CASE
          WHEN p_orc_pessoa = 0
            OR p_config_227_manterPessoaOrcam = 1
          THEN a.pessoa
          ELSE p_orc_pessoa
        END pessoa,
        a.valorBasePagamento
      FROM MOPREDOCUMENTOS a
      WHERE a.preDocumento = p_preDocumento
      AND a.valorBasePagamento > 0) a
    JOIN PAESTABELECIMENTOS est
    ON est.estabelecimento = a.estabelecimento
    JOIN CAPESSOAS pess
    ON pess.pessoa = a.pessoa),
  ITENS AS (
    SELECT
      a.sequencia,
      a.vendedor,
      a.gradeProduto,
      a.localEstoque,
      a.personalizacao,
      a.quantidade,
      ROUND (a.quantidade * (a.precoUnitarioBruto + a.acrescimoUnitarioComposicao),2) valorBaseRegra,
      a.valorDescontoItem,
      a.tabelaPreco,
      gradProd.produto,
      gradProd.cor,
      gradProd.tamanho,
      prod.subcategoriaProduto,
      prod.marca,
      prod.caracteristicaA,
      prod.caracteristicaB,
      prod.caracteristicaC,
      prod.caracteristicaD,
      prod.caracteristicaE,
      prod.idNcm,
      prod.listaServicos,
      subCatProd.categoriaProduto
    FROM MOPREDOCUMXITENS a
    JOIN CAGRADESPRODUTO gradProd
    ON gradProd.gradeProduto = a.gradeProduto
    JOIN CAPRODUTOS prod
    ON prod.produto = gradProd.produto
    JOIN PASUBCATEGORIASPRODUTO subCatProd
    ON subCatProd.subCategoriaProduto = prod.subCategoriaProduto
    WHERE a.preDocumento = p_preDocumento
    AND a.cancelado = 0
    AND a.quantidade > 0),
  REGRAS AS (
    SELECT
      a.regraDescontoMargem,
      a.ordenacao,
      a.tipoRegraDescontoMargem,
      a.valorSugestao,
      a.valorMaximoSemSenha,
      a.filtrarTabelaPreco,
      cab.idade,
      cab.valorBasePagamento
    FROM PAREGRASDESCONTOSMARGEM a
    JOIN CABECALHO cab
    ON 1=1
    JOIN PAFILTROSCABECALHO filtroCab
    ON filtroCab.filtroCabecalho = a.filtroCabecalho
    JOIN CAPESSOAS pess
    ON pess.pessoa = cab.pessoa
    JOIN PAFILTROSPAGAMENTO filtroPag
    ON filtroPag.filtroPagamento = a.filtroPagamento
    WHERE a.regraDescontoMargem > 0
    AND a.ativo = 1
    AND a.dataValidadeInicial <= TRUNC(SYSDATE)
    AND a.dataValidadeFinal >= TRUNC(SYSDATE)
    AND a.cabecalhoItemPagamento = 'C'
    AND a.tipoRegraDescontoMargem BETWEEN 1 AND 6
    -- Filtro Cabeçalho
    AND (a.filtroCabecalho = 0
      OR (filtroCab.filtrarEstabelecimentos = 0
        OR EXISTS (
          SELECT 1
          FROM PAFILTROCABECXESTABELEC filtroCabX
          WHERE filtroCabX.filtroCabecalho = a.filtroCabecalho
          AND filtroCabX.estabelecimento = cab.estabelecimento
          AND filtroCabX.ativo = 1))
      AND (filtroCab.filtrarUfs = 0
        OR EXISTS (
          SELECT 1
          FROM PAFILTROCABECXUFS filtroCabX
          WHERE filtroCabX.filtroCabecalho = a.filtroCabecalho
          AND filtroCabX.uf = cab.uf
          AND filtroCabX.ativo = 1))
      AND (filtroCab.filtrarPessoas = 0
        OR EXISTS (
          SELECT 1
          FROM PAFILTROCABECXPESSOAS filtroCabX
          WHERE filtroCabX.filtroCabecalho = a.filtroCabecalho
          AND filtroCabX.pessoa = cab.pessoa
          AND filtroCabX.ativo = 1))
      AND (filtroCab.filtrarPerfisUsuario = 0
        AND filtroCab.filtrarUsuarios = 0
        OR filtroCab.filtrarPerfisUsuario = 1
        AND EXISTS (
          SELECT 1
          FROM PAFILTROCABECXPERFISUSUAR filtroCabX
          WHERE filtroCabX.filtroCabecalho = a.filtroCabecalho
          AND filtroCabX.perfilUsuario = p_perfilUsuarioLogado
          AND filtroCabX.ativo = 1)
        OR filtroCab.filtrarUsuarios = 1
        AND EXISTS (
          SELECT 1
          FROM PAFILTROCABECXUSUARIOS filtroCabX
          WHERE filtroCabX.filtroCabecalho = a.filtroCabecalho
          AND filtroCabX.usuario = p_usuarioLogado
          AND filtroCabX.ativo = 1))
      AND (filtroCab.indicadorPessoa = ' '
        OR filtroCab.indicadorPessoa = pess.indicadorPessoa)
      AND (filtroCab.colaborador = ' '
        OR filtroCab.colaborador = 'N'
        AND (cab.pessoa = 0
          OR NOT (EXISTS (
            SELECT 1
            FROM CACOLABORADORES colab
            WHERE colab.colaborador = cab.pessoa
            AND colab.ativo = 1 )))
        OR filtroCab.colaborador = 'S'
        AND cab.pessoa <> 0
        AND EXISTS (
          SELECT 1
          FROM CACOLABORADORES colab
          WHERE colab.colaborador = cab.pessoa
          AND colab.ativo = 1)))),
  FILTROSPRODUTOS AS (
    SELECT
      a.regraDescontoMargem,
      a.filtroProduto,
      b.quantidadeMinima,
      b.quantidadeMaxima,
      b.filtrarVendedores,
      b.filtrarLocaisEstoque,
      b.filtrarPersonalizacoes,
      b.filtrarProdutos,
      b.filtrarCategoriasProdutos,
      b.filtrarSubcategoriasProdutos,
      b.filtrarMarcas,
      b.filtrarCaracteristicasA,
      b.filtrarCaracteristicasB,
      b.filtrarCaracteristicasC,
      b.filtrarCaracteristicasD,
      b.filtrarCaracteristicasE,
      b.filtrarCores,
      b.filtrarTamanhos,
      b.filtrarNCMs,
      b.filtrarListasServicos,
      c.filtrarTabelaPreco
    FROM PAREGRADESCMARGXFILTPROD a
    JOIN PAFILTROSPRODUTO b
    ON b.filtroProduto = a.filtroProduto
    JOIN REGRAS c
    ON c.regraDescontoMargem = a.regraDescontoMargem
    AND a.filtroProduto > 0
    AND a.ativo = 1),
  REGRASXITENS AS (
    SELECT
      a.regraDescontoMargem,
      a.filtroProduto,
      a.quantidadeMinima,
      a.quantidadeMaxima,
      b.sequencia,
      b.quantidade,
      b.valorBaseRegra,
      b.valorDescontoItem
    FROM FILTROSPRODUTOS a
    JOIN ITENS b
	  ON 1=1
    WHERE (a.filtrarTabelaPreco = 0
      OR EXISTS (
        SELECT 1
        FROM PAREGRADESCMARGXTABELASPR x
        WHERE x.regraDescontoMargem = a.regraDescontoMargem
        AND x.tabelaPreco = b.tabelaPreco
        AND x.ativo = 1))
    AND (a.filtrarVendedores = 0
    OR EXISTS (
      SELECT 1
      FROM PAFILTROPRODUTOXVENDEDOR x
      WHERE x.filtroProduto = a.filtroProduto
      AND x.vendedor = b.vendedor
      AND x.ativo = 1))
    AND (a.filtrarLocaisEstoque = 0
    OR EXISTS (
      SELECT 1
      FROM PAFILTROPRODUTOXLOCAISEST x
      WHERE x.filtroProduto = a.filtroProduto
      AND x.localEstoque = b.localEstoque
      AND x.ativo = 1))
    AND (a.filtrarPersonalizacoes = 0
    OR EXISTS (
      SELECT 1
      FROM PAFILTROPRODUTOXPERSONAL x
      WHERE x.filtroProduto = a.filtroProduto
      AND x.personalizacao = b.personalizacao
      AND x.ativo = 1))
    AND (a.filtrarProdutos = 0
      AND a.filtrarCategoriasProdutos = 0
      AND a.filtrarSubcategoriasProdutos = 0
      AND a.filtrarMarcas = 0
      AND a.filtrarCaracteristicasA = 0
      AND a.filtrarCaracteristicasB = 0
      AND a.filtrarCaracteristicasC = 0
      AND a.filtrarCaracteristicasD = 0
      AND a.filtrarCaracteristicasE = 0
      AND a.filtrarCores = 0
      AND a.filtrarTamanhos = 0
      AND a.filtrarNCMs = 0
      AND a.filtrarListasServicos = 0
      OR a.filtrarProdutos = 1
      AND EXISTS (
        SELECT 1
        FROM PAFILTROPRODUTOXPRODUTOS x
        WHERE x.filtroProduto = a.filtroProduto
        AND x.produto = b.produto
        AND x.ativo = 1)
      OR (a.filtrarCategoriasProdutos = 1
        OR a.filtrarSubcategoriasProdutos = 1
        OR a.filtrarMarcas = 1
        OR a.filtrarCaracteristicasA = 1
        OR a.filtrarCaracteristicasB = 1
        OR a.filtrarCaracteristicasC = 1
        OR a.filtrarCaracteristicasD = 1
        OR a.filtrarCaracteristicasE = 1
        OR a.filtrarCores = 1
        OR a.filtrarTamanhos = 1
        OR a.filtrarNCMs = 1
        OR a.filtrarListasServicos = 1)
      AND (a.filtrarCategoriasProdutos = 0
        OR EXISTS (
          SELECT 1
          FROM PAFILTROPRODUTOXCATEGPROD x
          WHERE x.filtroProduto = a.filtroProduto
          AND x.categoriaProduto = b.categoriaProduto
          AND x.ativo = 1))
      AND (a.filtrarSubcategoriasProdutos = 0
        OR EXISTS (
          SELECT 1
          FROM PAFILTROPRODUTOXSUBCAPROD x
          WHERE x.filtroProduto = a.filtroProduto
          AND x.subcategoriaProduto = b.subcategoriaProduto
          AND x.ativo = 1))
      AND (a.filtrarMarcas = 0
        OR EXISTS (
          SELECT 1
          FROM PAFILTROPRODUTOXMARCAS x
          WHERE x.filtroProduto = a.filtroProduto
          AND x.marca = b.marca
          AND x.ativo = 1))
      AND (a.filtrarCaracteristicasA = 0
        OR EXISTS (
          SELECT 1
          FROM PAFILTROPRODUTOXCARACTERA x
          WHERE x.filtroProduto = a.filtroProduto
          AND x.caracteristicaA = b.caracteristicaA
          AND x.ativo = 1))
      AND (a.filtrarCaracteristicasB = 0
        OR EXISTS (
          SELECT 1
          FROM PAFILTROPRODUTOXCARACTERB x
          WHERE x.filtroProduto = a.filtroProduto
          AND x.caracteristicaB = b.caracteristicaB
          AND x.ativo = 1))
      AND (a.filtrarCaracteristicasC = 0
        OR EXISTS (
          SELECT 1
          FROM PAFILTROPRODUTOXCARACTERC x
          WHERE x.filtroProduto = a.filtroProduto
          AND x.caracteristicaC = b.caracteristicaC
          AND x.ativo = 1))
      AND (a.filtrarCaracteristicasD = 0
        OR EXISTS (
          SELECT 1
          FROM PAFILTROPRODUTOXCARACTERD x
          WHERE x.filtroProduto = a.filtroProduto
          AND x.caracteristicaD = b.caracteristicaD
          AND x.ativo = 1))
      AND (a.filtrarCaracteristicasE = 0
        OR EXISTS (
          SELECT 1
          FROM PAFILTROPRODUTOXCARACTERE x
          WHERE x.filtroProduto = a.filtroProduto
          AND x.caracteristicaE = b.caracteristicaE
          AND x.ativo = 1))
      AND (a.filtrarCores = 0
        OR EXISTS (
          SELECT 1
          FROM PAFILTROPRODUTOXCORES x
          WHERE x.filtroProduto = a.filtroProduto
          AND x.cor = b.cor
          AND x.ativo = 1))
      AND (a.filtrarTamanhos = 0
        OR EXISTS (
          SELECT 1
          FROM PAFILTROPRODUTOXTAMANHOS x
          WHERE x.filtroProduto = a.filtroProduto
          AND x.tamanho = b.tamanho
          AND x.ativo = 1))
      AND (a.filtrarNCMs = 0
        OR EXISTS (
          SELECT 1
          FROM PAFILTROPRODUTOXNCMS x
          WHERE x.filtroProduto = a.filtroProduto
          AND x.idNcm = b.idNcm
          AND x.ativo = 1))
      AND (a.filtrarListasServicos = 0
        OR EXISTS (
          SELECT 1
          FROM PAFILTROPRODUTOXLISTASSE x
          WHERE x.filtroProduto = a.filtroProduto
          AND x.listaServicos = b.listaServicos
          AND x.ativo = 1)))),
  REGRASXFILTROS AS (
    SELECT
      a.regraDescontoMargem,
      a.filtroProduto
    FROM (
      SELECT
        a.regraDescontoMargem,
        a.filtroProduto,
        a.quantidadeMinima,
        a.quantidadeMaxima,
        SUM (a.quantidade) quantidade
      FROM REGRASXITENS a
      GROUP BY
        a.regraDescontoMargem,
        a.filtroProduto,
        a.quantidadeMinima,
        a.quantidadeMaxima) a
    WHERE a.quantidade >= a.quantidadeMinima
    AND (a.quantidadeMaxima = 0
      OR a.quantidade <= a.quantidadeMaxima)),
  REGRASVALIDAS AS (
    SELECT
      a.regraDescontoMargem,
      a.ordenacao,
      a.tipoRegraDescontoMargem,
      a.valorSugestao,
      a.valorMaximoSemSenha,
      a.filtrarTabelaPreco,
      a.idade,
      a.valorBasePagamento,
      COALESCE((
        SELECT COUNT(1)
        FROM FILTROSPRODUTOS b
        WHERE b.regraDescontoMargem = a.regraDescontoMargem),0) filtrosProdutos
    FROM REGRAS a
    WHERE
      ( SELECT COUNT(1)
        FROM FILTROSPRODUTOS b
        WHERE b.regraDescontoMargem = a.regraDescontoMargem)
    = ( SELECT COUNT(1)
        FROM REGRASXFILTROS b
        WHERE b.regraDescontoMargem = a.regraDescontoMargem))
  SELECT
    COALESCE (MAX(a.possuiRegra), 0) possuiRegra,
    COALESCE (ROUND(
      CASE
        WHEN SUM (
          CASE
            WHEN a.valorDescontoSugestao < 0
            THEN 0
            ELSE a.valorDescontoSugestao
          END) >= MAX(a.valorBasePagamento)
        THEN MAX(a.valorBasePagamento) - 0.01
        ELSE SUM (
          CASE
            WHEN a.valorDescontoSugestao < 0
            THEN 0
            ELSE a.valorDescontoSugestao
          END)
      END, 2), 0) valorDescontoSugestao,
    COALESCE (ROUND(
      CASE
        WHEN SUM (
          CASE
            WHEN a.valorDescontoMaximoSemSenha < 0
            THEN 0
            ELSE a.valorDescontoMaximoSemSenha
          END) >= MAX(a.valorBasePagamento)
        THEN MAX(a.valorBasePagamento) - 0.01
        ELSE SUM (
          CASE
            WHEN a.valorDescontoMaximoSemSenha < 0
            THEN 0
            ELSE a.valorDescontoMaximoSemSenha
          END)
      END, 2), 0) valorDescontoMaximoSemSenha
  INTO
    r_possuiRegra,
    r_valorDescontoSugestao,
    r_valorDescontoMaximoSemSenha
  FROM (
    SELECT
      1 possuiRegra,
      a.valorBasePagamento,
      ROUND (
        CASE a.tipoRegraDescontoMargem
          -- Desconto em percentual
          WHEN 1
          THEN a.valorBaseRegra * a.valorSugestao / 100
          -- Desconto em valor
          WHEN 2
          THEN a.valorSugestao * a.multiplicador
           -- Preço unitário fixo
          WHEN 3
          THEN a.valorBaseRegra-ROUND (a.quantidadeRegra*a.valorSugestao,2)
          -- Desconto igual a idade em percentual
          WHEN 4
          THEN a.valorBaseRegra * a.idade / 100
          -- Desconto igual a idade em valor
          WHEN 5
          THEN a.idade * a.multiplicador
          -- Preço total fixado
          WHEN 6
          THEN a.valorBaseRegra
          ELSE 0
        END - a.valorDescontoItem, 2) valorDescontoSugestao,
      ROUND (
        CASE a.tipoRegraDescontoMargem
          -- Desconto em percentual
          WHEN 1
          THEN a.valorBaseRegra * a.valorMaximoSemSenha / 100
          -- Desconto em valor
          WHEN 2
          THEN a.valorMaximoSemSenha * a.multiplicador
          -- Preço unitário fixo
          WHEN 3
          THEN a.valorBaseRegra-ROUND (a.quantidadeRegra*a.valorMaximoSemSenha,2)
          -- Desconto igual a idade em percentual
          WHEN 4
          THEN a.valorBaseRegra * a.idade / 100
          -- Desconto igual a idade em valor
          WHEN 5
          THEN a.idade * a.multiplicador
          -- Preço total fixado
          WHEN 6
          THEN a.valorBaseRegra
          ELSE 0
        END, 2) valorDescontoMaximoSemSenha
    FROM (
      SELECT
        a.tipoRegraDescontoMargem,
        a.valorSugestao,
        a.valorMaximoSemSenha,
        a.idade,
        a.valorBasePagamento,
        SUM(a.quantidade) quantidadeRegra,
        CASE
          WHEN SUM (a.valorBaseRegraTodos - a.valorDescontoItemTodos) = 0
          THEN 0
          ELSE SUM (a.valorBaseRegra - a.valorDescontoItem)
            / SUM (a.valorBaseRegraTodos - a.valorDescontoItemTodos)
        END multiplicador,
        SUM (a.valorBaseRegra) valorBaseRegra,
        SUM (a.valorDescontoItem) valorDescontoItem
      FROM (
        SELECT DISTINCT
          a.regraDescontoMargem,
          a.ordenacao,
          a.tipoRegraDescontoMargem,
          a.valorSugestao,
          a.valorMaximoSemSenha,
          a.idade,
          a.valorBasePagamento,
          b.sequencia,
          b.quantidade,
          b.valorBaseRegra,
          b.valorDescontoItem,
          0 valorBaseRegraTodos,
          0 valorDescontoItemTodos
        FROM REGRASVALIDAS a
        JOIN ITENS b
        ON 1=1
        WHERE a.filtrosProdutos = 0
        AND (a.filtrarTabelaPreco = 0
          OR EXISTS (
            SELECT 1
            FROM PAREGRADESCMARGXTABELASPR x
            WHERE x.regraDescontoMargem = a.regraDescontoMargem
            AND x.tabelaPreco = b.tabelaPreco
            AND x.ativo = 1))
        UNION ALL
        SELECT DISTINCT
          a.regraDescontoMargem,
          a.ordenacao,
          a.tipoRegraDescontoMargem,
          a.valorSugestao,
          a.valorMaximoSemSenha,
          a.idade,
          a.valorBasePagamento,
          b.sequencia,
          b.quantidade,
          b.valorBaseRegra,
          b.valorDescontoItem,
          0 valorBaseRegraTodos,
          0 valorDescontoItemTodos
        FROM REGRASVALIDAS a
        JOIN REGRASXITENS b
        ON b.regraDescontoMargem = a.regraDescontoMargem
        WHERE a.filtrosProdutos > 0
        UNION ALL
        SELECT DISTINCT
          a.regraDescontoMargem,
          a.ordenacao,
          a.tipoRegraDescontoMargem,
          a.valorSugestao,
          a.valorMaximoSemSenha,
          a.idade,
          a.valorBasePagamento,
          b.sequencia,
          b.quantidade,
          0 valorBaseRegra,
          0 valorDescontoItem,
          b.valorBaseRegra valorBaseRegraTodos,
          b.valorDescontoItem valorDescontoItemTodos
        FROM REGRASVALIDAS a
        JOIN ITENS b
        ON 1=1) a
      GROUP BY
        a.regraDescontoMargem,
        a.ordenacao,
        a.tipoRegraDescontoMargem,
        a.valorSugestao,
        a.valorMaximoSemSenha,
        a.idade,
        a.valorBasePagamento) a) a;
END ADD_PRE_DOC_REGRA_DESC_CAB;

/

create or replace PROCEDURE ADD_DOC_FISC_REGRA_DESC_CAB (
  p_usuarioLogado                IN NUMBER,
  p_perfilUsuarioLogado          IN NUMBER,
  p_config_227_manterPessoaOrcam IN NUMBER,
  p_idDocumentoFiscal            IN NUMBER,
  p_orc_pessoa                   IN NUMBER,
  /* Retornos */
  r_possuiRegra                  OUT NUMBER,
  r_valorDescontoSugestao        OUT NUMBER,
  r_valorDescontoMaximoSemSenha  OUT NUMBER)
IS
BEGIN
  WITH
  CABECALHO AS (
    SELECT
      a.estabelecimento,
      a.pessoa,
      COALESCE((
        CASE
          WHEN a.pessoa = 0
          THEN (
            SELECT MAX(munPess.uf)
            FROM CAENDERECOSPESSOA endPess
            JOIN SIMUNICIPIOS munPess
            ON munPess.municipio = endPess.municipio
            WHERE endPess.pessoa = est.pessoaEstabelecimento
            AND endPess.ativo = 1
            AND endPess.principal = 1)
          ELSE COALESCE((
            SELECT MAX(munPess.uf)
            FROM CAENDERECOSPESSOA endPess
            JOIN SIMUNICIPIOS munPess
            ON munPess.municipio = endPess.municipio
            WHERE endPess.pessoa = a.pessoa
            AND endPess.ativo = 1
            AND endPess.principal = 1),(
            SELECT MAX(munPess.uf)
            FROM CAENDERECOSPESSOA endPess
            JOIN SIMUNICIPIOS munPess
            ON munPess.municipio = endPess.municipio
            WHERE endPess.pessoa = est.pessoaEstabelecimento
            AND endPess.ativo = 1
            AND endPess.principal = 1))
        END
      ),'  ') uf,
      CASE
        WHEN pess.nascimentoFundacao IS NULL
          OR TRUNC (pess.nascimentoFundacao) > TRUNC (SYSDATE)
        THEN 0
        ELSE TRUNC (SYSDATE, 'YYYY')
          - TRUNC (pess.nascimentoFundacao, 'YYYY')
          - CASE
              WHEN TO_CHAR (SYSDATE, 'MMDD') < TO_CHAR (pess.nascimentoFundacao, 'MMDD')
              THEN 1
              ELSE 0
            END
      END idade,
      a.valorBasePagamento
    FROM (
      SELECT
        a.estabelecimento,
        CASE
          WHEN p_orc_pessoa = 0
            OR p_config_227_manterPessoaOrcam = 1
          THEN a.pessoa
          ELSE p_orc_pessoa
        END pessoa,
        a.valorBasePagamento
      FROM MODOCUMENTOSFISCAIS a
      WHERE a.idDocumentoFiscal = p_idDocumentoFiscal
      AND a.valorBasePagamento > 0) a
    JOIN PAESTABELECIMENTOS est
    ON est.estabelecimento = a.estabelecimento
    JOIN CAPESSOAS pess
    ON pess.pessoa = a.pessoa),
  ITENS AS (
    SELECT
      a.sequencia,
      a.vendedor,
      a.gradeProduto,
      a.localEstoque,
      a.personalizacao,
      a.quantidade,
      ROUND (a.quantidade * (a.precoUnitarioBruto + a.acrescimoUnitarioComposicao),2) valorBaseRegra,
      a.valorDescontoItem,
      a.tabelaPreco,
      gradProd.produto,
      gradProd.cor,
      gradProd.tamanho,
      prod.subcategoriaProduto,
      prod.marca,
      prod.caracteristicaA,
      prod.caracteristicaB,
      prod.caracteristicaC,
      prod.caracteristicaD,
      prod.caracteristicaE,
      prod.idNcm,
      prod.listaServicos,
      subCatProd.categoriaProduto
    FROM MODOCFISCALXITENS a
    JOIN CAGRADESPRODUTO gradProd
    ON gradProd.gradeProduto = a.gradeProduto
    JOIN CAPRODUTOS prod
    ON prod.produto = gradProd.produto
    JOIN PASUBCATEGORIASPRODUTO subCatProd
    ON subCatProd.subCategoriaProduto = prod.subCategoriaProduto
    WHERE a.idDocumentoFiscal = p_idDocumentoFiscal
    AND a.cancelado = 0
    AND a.quantidade > 0),
  REGRAS AS (
    SELECT
      a.regraDescontoMargem,
      a.ordenacao,
      a.tipoRegraDescontoMargem,
      a.valorSugestao,
      a.valorMaximoSemSenha,
      a.filtrarTabelaPreco,
      cab.idade,
      cab.valorBasePagamento
    FROM PAREGRASDESCONTOSMARGEM a
    JOIN CABECALHO cab
    ON 1=1
    JOIN PAFILTROSCABECALHO filtroCab
    ON filtroCab.filtroCabecalho = a.filtroCabecalho
    JOIN CAPESSOAS pess
    ON pess.pessoa = cab.pessoa
    JOIN PAFILTROSPAGAMENTO filtroPag
    ON filtroPag.filtroPagamento = a.filtroPagamento
    WHERE a.regraDescontoMargem > 0
    AND a.ativo = 1
    AND a.dataValidadeInicial <= TRUNC(SYSDATE)
    AND a.dataValidadeFinal >= TRUNC(SYSDATE)
    AND a.cabecalhoItemPagamento = 'C'
    AND a.tipoRegraDescontoMargem BETWEEN 1 AND 6
    -- Filtro Cabeçalho
    AND (a.filtroCabecalho = 0
      OR (filtroCab.filtrarEstabelecimentos = 0
        OR EXISTS (
          SELECT 1
          FROM PAFILTROCABECXESTABELEC filtroCabX
          WHERE filtroCabX.filtroCabecalho = a.filtroCabecalho
          AND filtroCabX.estabelecimento = cab.estabelecimento
          AND filtroCabX.ativo = 1))
      AND (filtroCab.filtrarUfs = 0
        OR EXISTS (
          SELECT 1
          FROM PAFILTROCABECXUFS filtroCabX
          WHERE filtroCabX.filtroCabecalho = a.filtroCabecalho
          AND filtroCabX.uf = cab.uf
          AND filtroCabX.ativo = 1))
      AND (filtroCab.filtrarPessoas = 0
        OR EXISTS (
          SELECT 1
          FROM PAFILTROCABECXPESSOAS filtroCabX
          WHERE filtroCabX.filtroCabecalho = a.filtroCabecalho
          AND filtroCabX.pessoa = cab.pessoa
          AND filtroCabX.ativo = 1))
      AND (filtroCab.filtrarPerfisUsuario = 0
        AND filtroCab.filtrarUsuarios = 0
        OR filtroCab.filtrarPerfisUsuario = 1
        AND EXISTS (
          SELECT 1
          FROM PAFILTROCABECXPERFISUSUAR filtroCabX
          WHERE filtroCabX.filtroCabecalho = a.filtroCabecalho
          AND filtroCabX.perfilUsuario = p_perfilUsuarioLogado
          AND filtroCabX.ativo = 1)
        OR filtroCab.filtrarUsuarios = 1
        AND EXISTS (
          SELECT 1
          FROM PAFILTROCABECXUSUARIOS filtroCabX
          WHERE filtroCabX.filtroCabecalho = a.filtroCabecalho
          AND filtroCabX.usuario = p_usuarioLogado
          AND filtroCabX.ativo = 1))
      AND (filtroCab.indicadorPessoa = ' '
        OR filtroCab.indicadorPessoa = pess.indicadorPessoa)
      AND (filtroCab.colaborador = ' '
        OR filtroCab.colaborador = 'N'
        AND (cab.pessoa = 0
          OR NOT (EXISTS (
            SELECT 1
            FROM CACOLABORADORES colab
            WHERE colab.colaborador = cab.pessoa
            AND colab.ativo = 1 )))
        OR filtroCab.colaborador = 'S'
        AND cab.pessoa <> 0
        AND EXISTS (
          SELECT 1
          FROM CACOLABORADORES colab
          WHERE colab.colaborador = cab.pessoa
          AND colab.ativo = 1)))),
  FILTROSPRODUTOS AS (
    SELECT
      a.regraDescontoMargem,
      a.filtroProduto,
      b.quantidadeMinima,
      b.quantidadeMaxima,
      b.filtrarVendedores,
      b.filtrarLocaisEstoque,
      b.filtrarPersonalizacoes,
      b.filtrarProdutos,
      b.filtrarCategoriasProdutos,
      b.filtrarSubcategoriasProdutos,
      b.filtrarMarcas,
      b.filtrarCaracteristicasA,
      b.filtrarCaracteristicasB,
      b.filtrarCaracteristicasC,
      b.filtrarCaracteristicasD,
      b.filtrarCaracteristicasE,
      b.filtrarCores,
      b.filtrarTamanhos,
      b.filtrarNCMs,
      b.filtrarListasServicos,
      c.filtrarTabelaPreco
    FROM PAREGRADESCMARGXFILTPROD a
    JOIN PAFILTROSPRODUTO b
    ON b.filtroProduto = a.filtroProduto
    JOIN REGRAS c
    ON c.regraDescontoMargem = a.regraDescontoMargem
    AND a.filtroProduto > 0
    AND a.ativo = 1),
  REGRASXITENS AS (
    SELECT
      a.regraDescontoMargem,
      a.filtroProduto,
      a.quantidadeMinima,
      a.quantidadeMaxima,
      b.sequencia,
      b.quantidade,
      b.valorBaseRegra,
      b.valorDescontoItem
    FROM FILTROSPRODUTOS a
    JOIN ITENS b
	  ON 1=1
    WHERE (a.filtrarTabelaPreco = 0
      OR EXISTS (
        SELECT 1
        FROM PAREGRADESCMARGXTABELASPR x
        WHERE x.regraDescontoMargem = a.regraDescontoMargem
        AND x.tabelaPreco = b.tabelaPreco
        AND x.ativo = 1))
    AND (a.filtrarVendedores = 0
    OR EXISTS (
      SELECT 1
      FROM PAFILTROPRODUTOXVENDEDOR x
      WHERE x.filtroProduto = a.filtroProduto
      AND x.vendedor = b.vendedor
      AND x.ativo = 1))
    AND (a.filtrarLocaisEstoque = 0
    OR EXISTS (
      SELECT 1
      FROM PAFILTROPRODUTOXLOCAISEST x
      WHERE x.filtroProduto = a.filtroProduto
      AND x.localEstoque = b.localEstoque
      AND x.ativo = 1))
    AND (a.filtrarPersonalizacoes = 0
    OR EXISTS (
      SELECT 1
      FROM PAFILTROPRODUTOXPERSONAL x
      WHERE x.filtroProduto = a.filtroProduto
      AND x.personalizacao = b.personalizacao
      AND x.ativo = 1))
    AND (a.filtrarProdutos = 0
      AND a.filtrarCategoriasProdutos = 0
      AND a.filtrarSubcategoriasProdutos = 0
      AND a.filtrarMarcas = 0
      AND a.filtrarCaracteristicasA = 0
      AND a.filtrarCaracteristicasB = 0
      AND a.filtrarCaracteristicasC = 0
      AND a.filtrarCaracteristicasD = 0
      AND a.filtrarCaracteristicasE = 0
      AND a.filtrarCores = 0
      AND a.filtrarTamanhos = 0
      AND a.filtrarNCMs = 0
      AND a.filtrarListasServicos = 0
      OR a.filtrarProdutos = 1
      AND EXISTS (
        SELECT 1
        FROM PAFILTROPRODUTOXPRODUTOS x
        WHERE x.filtroProduto = a.filtroProduto
        AND x.produto = b.produto
        AND x.ativo = 1)
      OR (a.filtrarCategoriasProdutos = 1
        OR a.filtrarSubcategoriasProdutos = 1
        OR a.filtrarMarcas = 1
        OR a.filtrarCaracteristicasA = 1
        OR a.filtrarCaracteristicasB = 1
        OR a.filtrarCaracteristicasC = 1
        OR a.filtrarCaracteristicasD = 1
        OR a.filtrarCaracteristicasE = 1
        OR a.filtrarCores = 1
        OR a.filtrarTamanhos = 1
        OR a.filtrarNCMs = 1
        OR a.filtrarListasServicos = 1)
      AND (a.filtrarCategoriasProdutos = 0
        OR EXISTS (
          SELECT 1
          FROM PAFILTROPRODUTOXCATEGPROD x
          WHERE x.filtroProduto = a.filtroProduto
          AND x.categoriaProduto = b.categoriaProduto
          AND x.ativo = 1))
      AND (a.filtrarSubcategoriasProdutos = 0
        OR EXISTS (
          SELECT 1
          FROM PAFILTROPRODUTOXSUBCAPROD x
          WHERE x.filtroProduto = a.filtroProduto
          AND x.subcategoriaProduto = b.subcategoriaProduto
          AND x.ativo = 1))
      AND (a.filtrarMarcas = 0
        OR EXISTS (
          SELECT 1
          FROM PAFILTROPRODUTOXMARCAS x
          WHERE x.filtroProduto = a.filtroProduto
          AND x.marca = b.marca
          AND x.ativo = 1))
      AND (a.filtrarCaracteristicasA = 0
        OR EXISTS (
          SELECT 1
          FROM PAFILTROPRODUTOXCARACTERA x
          WHERE x.filtroProduto = a.filtroProduto
          AND x.caracteristicaA = b.caracteristicaA
          AND x.ativo = 1))
      AND (a.filtrarCaracteristicasB = 0
        OR EXISTS (
          SELECT 1
          FROM PAFILTROPRODUTOXCARACTERB x
          WHERE x.filtroProduto = a.filtroProduto
          AND x.caracteristicaB = b.caracteristicaB
          AND x.ativo = 1))
      AND (a.filtrarCaracteristicasC = 0
        OR EXISTS (
          SELECT 1
          FROM PAFILTROPRODUTOXCARACTERC x
          WHERE x.filtroProduto = a.filtroProduto
          AND x.caracteristicaC = b.caracteristicaC
          AND x.ativo = 1))
      AND (a.filtrarCaracteristicasD = 0
        OR EXISTS (
          SELECT 1
          FROM PAFILTROPRODUTOXCARACTERD x
          WHERE x.filtroProduto = a.filtroProduto
          AND x.caracteristicaD = b.caracteristicaD
          AND x.ativo = 1))
      AND (a.filtrarCaracteristicasE = 0
        OR EXISTS (
          SELECT 1
          FROM PAFILTROPRODUTOXCARACTERE x
          WHERE x.filtroProduto = a.filtroProduto
          AND x.caracteristicaE = b.caracteristicaE
          AND x.ativo = 1))
      AND (a.filtrarCores = 0
        OR EXISTS (
          SELECT 1
          FROM PAFILTROPRODUTOXCORES x
          WHERE x.filtroProduto = a.filtroProduto
          AND x.cor = b.cor
          AND x.ativo = 1))
      AND (a.filtrarTamanhos = 0
        OR EXISTS (
          SELECT 1
          FROM PAFILTROPRODUTOXTAMANHOS x
          WHERE x.filtroProduto = a.filtroProduto
          AND x.tamanho = b.tamanho
          AND x.ativo = 1))
      AND (a.filtrarNCMs = 0
        OR EXISTS (
          SELECT 1
          FROM PAFILTROPRODUTOXNCMS x
          WHERE x.filtroProduto = a.filtroProduto
          AND x.idNcm = b.idNcm
          AND x.ativo = 1))
      AND (a.filtrarListasServicos = 0
        OR EXISTS (
          SELECT 1
          FROM PAFILTROPRODUTOXLISTASSE x
          WHERE x.filtroProduto = a.filtroProduto
          AND x.listaServicos = b.listaServicos
          AND x.ativo = 1)))),
  REGRASXFILTROS AS (
    SELECT
      a.regraDescontoMargem,
      a.filtroProduto
    FROM (
      SELECT
        a.regraDescontoMargem,
        a.filtroProduto,
        a.quantidadeMinima,
        a.quantidadeMaxima,
        SUM (a.quantidade) quantidade
      FROM REGRASXITENS a
      GROUP BY
        a.regraDescontoMargem,
        a.filtroProduto,
        a.quantidadeMinima,
        a.quantidadeMaxima) a
    WHERE a.quantidade >= a.quantidadeMinima
    AND (a.quantidadeMaxima = 0
      OR a.quantidade <= a.quantidadeMaxima)),
  REGRASVALIDAS AS (
    SELECT
      a.regraDescontoMargem,
      a.ordenacao,
      a.tipoRegraDescontoMargem,
      a.valorSugestao,
      a.valorMaximoSemSenha,
      a.filtrarTabelaPreco,
      a.idade,
      a.valorBasePagamento,
      COALESCE((
        SELECT COUNT(1)
        FROM FILTROSPRODUTOS b
        WHERE b.regraDescontoMargem = a.regraDescontoMargem),0) filtrosProdutos
    FROM REGRAS a
    WHERE
      ( SELECT COUNT(1)
        FROM FILTROSPRODUTOS b
        WHERE b.regraDescontoMargem = a.regraDescontoMargem)
    = ( SELECT COUNT(1)
        FROM REGRASXFILTROS b
        WHERE b.regraDescontoMargem = a.regraDescontoMargem))
  SELECT
    COALESCE (MAX(a.possuiRegra), 0) possuiRegra,
    COALESCE (ROUND(
      CASE
        WHEN SUM (
          CASE
            WHEN a.valorDescontoSugestao < 0
            THEN 0
            ELSE a.valorDescontoSugestao
          END) >= MAX(a.valorBasePagamento)
        THEN MAX(a.valorBasePagamento) - 0.01
        ELSE SUM (
          CASE
            WHEN a.valorDescontoSugestao < 0
            THEN 0
            ELSE a.valorDescontoSugestao
          END)
      END, 2), 0) valorDescontoSugestao,
    COALESCE (ROUND(
      CASE
        WHEN SUM (
          CASE
            WHEN a.valorDescontoMaximoSemSenha < 0
            THEN 0
            ELSE a.valorDescontoMaximoSemSenha
          END) >= MAX(a.valorBasePagamento)
        THEN MAX(a.valorBasePagamento) - 0.01
        ELSE SUM (
          CASE
            WHEN a.valorDescontoMaximoSemSenha < 0
            THEN 0
            ELSE a.valorDescontoMaximoSemSenha
          END)
      END, 2), 0) valorDescontoMaximoSemSenha
  INTO
    r_possuiRegra,
    r_valorDescontoSugestao,
    r_valorDescontoMaximoSemSenha
  FROM (
    SELECT
      1 possuiRegra,
      a.valorBasePagamento,
      ROUND (
        CASE a.tipoRegraDescontoMargem
          -- Desconto em percentual
          WHEN 1
          THEN a.valorBaseRegra * a.valorSugestao / 100
          -- Desconto em valor
          WHEN 2
          THEN a.valorSugestao * a.multiplicador
           -- Preço unitário fixo
          WHEN 3
          THEN a.valorBaseRegra-ROUND (a.quantidadeRegra*a.valorSugestao,2)
          -- Desconto igual a idade em percentual
          WHEN 4
          THEN a.valorBaseRegra * a.idade / 100
          -- Desconto igual a idade em valor
          WHEN 5
          THEN a.idade * a.multiplicador
          -- Preço total fixado
          WHEN 6
          THEN a.valorBaseRegra
          ELSE 0
        END - a.valorDescontoItem, 2) valorDescontoSugestao,
      ROUND (
        CASE a.tipoRegraDescontoMargem
          -- Desconto em percentual
          WHEN 1
          THEN a.valorBaseRegra * a.valorMaximoSemSenha / 100
          -- Desconto em valor
          WHEN 2
          THEN a.valorMaximoSemSenha * a.multiplicador
          -- Preço unitário fixo
          WHEN 3
          THEN a.valorBaseRegra-ROUND (a.quantidadeRegra*a.valorMaximoSemSenha,2)
          -- Desconto igual a idade em percentual
          WHEN 4
          THEN a.valorBaseRegra * a.idade / 100
          -- Desconto igual a idade em valor
          WHEN 5
          THEN a.idade * a.multiplicador
          -- Preço total fixado
          WHEN 6
          THEN a.valorBaseRegra
          ELSE 0
        END, 2) valorDescontoMaximoSemSenha
    FROM (
      SELECT
        a.tipoRegraDescontoMargem,
        a.valorSugestao,
        a.valorMaximoSemSenha,
        a.idade,
        a.valorBasePagamento,
        SUM(a.quantidade) quantidadeRegra,
        CASE
          WHEN SUM (a.valorBaseRegraTodos - a.valorDescontoItemTodos) = 0
          THEN 0
          ELSE SUM (a.valorBaseRegra - a.valorDescontoItem)
            / SUM (a.valorBaseRegraTodos - a.valorDescontoItemTodos)
        END multiplicador,
        SUM (a.valorBaseRegra) valorBaseRegra,
        SUM (a.valorDescontoItem) valorDescontoItem
      FROM (
        SELECT DISTINCT
          a.regraDescontoMargem,
          a.ordenacao,
          a.tipoRegraDescontoMargem,
          a.valorSugestao,
          a.valorMaximoSemSenha,
          a.idade,
          a.valorBasePagamento,
          b.sequencia,
          b.quantidade,
          b.valorBaseRegra,
          b.valorDescontoItem,
          0 valorBaseRegraTodos,
          0 valorDescontoItemTodos
        FROM REGRASVALIDAS a
        JOIN ITENS b
        ON 1=1
        WHERE a.filtrosProdutos = 0
        AND (a.filtrarTabelaPreco = 0
          OR EXISTS (
            SELECT 1
            FROM PAREGRADESCMARGXTABELASPR x
            WHERE x.regraDescontoMargem = a.regraDescontoMargem
            AND x.tabelaPreco = b.tabelaPreco
            AND x.ativo = 1))
        UNION ALL
        SELECT DISTINCT
          a.regraDescontoMargem,
          a.ordenacao,
          a.tipoRegraDescontoMargem,
          a.valorSugestao,
          a.valorMaximoSemSenha,
          a.idade,
          a.valorBasePagamento,
          b.sequencia,
          b.quantidade,
          b.valorBaseRegra,
          b.valorDescontoItem,
          0 valorBaseRegraTodos,
          0 valorDescontoItemTodos
        FROM REGRASVALIDAS a
        JOIN REGRASXITENS b
        ON b.regraDescontoMargem = a.regraDescontoMargem
        WHERE a.filtrosProdutos > 0
        UNION ALL
        SELECT DISTINCT
          a.regraDescontoMargem,
          a.ordenacao,
          a.tipoRegraDescontoMargem,
          a.valorSugestao,
          a.valorMaximoSemSenha,
          a.idade,
          a.valorBasePagamento,
          b.sequencia,
          b.quantidade,
          0 valorBaseRegra,
          0 valorDescontoItem,
          b.valorBaseRegra valorBaseRegraTodos,
          b.valorDescontoItem valorDescontoItemTodos
        FROM REGRASVALIDAS a
        JOIN ITENS b
        ON 1=1) a
      GROUP BY
        a.regraDescontoMargem,
        a.ordenacao,
        a.tipoRegraDescontoMargem,
        a.valorSugestao,
        a.valorMaximoSemSenha,
        a.idade,
        a.valorBasePagamento) a) a;
END ADD_DOC_FISC_REGRA_DESC_CAB;

/

create or replace PROCEDURE ADD_ORCAMENTO_REGRA_DESC_PAG (
  p_usuarioLogado                IN NUMBER,
  p_perfilUsuarioLogado          IN NUMBER,
  p_config_246_baseDescontoPagam IN CHAR,
  p_config_337_descontoSobreFret IN NUMBER,
  p_orcamento                    IN NUMBER,
  p_soma_valorPagamentoBruto     IN NUMBER,
  p_pag_meioPagamento            IN NUMBER,
  p_pag_condicaoPagamento        IN NUMBER,
  p_pag_valorPagamentoBruto      IN NUMBER,
  /* Retornos */
  r_possuiRegra                  OUT NUMBER,
  r_percentualDescontoSugestao   OUT NUMBER,
  r_valorDescontoSugestao        OUT NUMBER,
  r_valorDescontoMaximoSemSenha  OUT NUMBER)
IS
BEGIN
  WITH
  CABECALHO AS (
    SELECT
      a.estabelecimento,
      a.pessoa,
      COALESCE((
        CASE
          WHEN a.pessoa = 0
          THEN (
            SELECT MAX(munPess.uf)
            FROM CAENDERECOSPESSOA endPess
            JOIN SIMUNICIPIOS munPess
            ON munPess.municipio = endPess.municipio
            WHERE endPess.pessoa = est.pessoaEstabelecimento
            AND endPess.ativo = 1
            AND endPess.principal = 1)
          ELSE COALESCE((
            SELECT MAX(munPess.uf)
            FROM CAENDERECOSPESSOA endPess
            JOIN SIMUNICIPIOS munPess
            ON munPess.municipio = endPess.municipio
            WHERE endPess.pessoa = a.pessoa
            AND endPess.ativo = 1
            AND endPess.principal = 1),(
            SELECT MAX(munPess.uf)
            FROM CAENDERECOSPESSOA endPess
            JOIN SIMUNICIPIOS munPess
            ON munPess.municipio = endPess.municipio
            WHERE endPess.pessoa = est.pessoaEstabelecimento
            AND endPess.ativo = 1
            AND endPess.principal = 1))
        END
      ),'  ') uf,
      CASE
        WHEN pess.nascimentoFundacao IS NULL
          OR TRUNC (pess.nascimentoFundacao) > TRUNC (SYSDATE)
        THEN 0
        ELSE TRUNC (SYSDATE, 'YYYY')
          - TRUNC (pess.nascimentoFundacao, 'YYYY')
          - CASE
              WHEN TO_CHAR (SYSDATE, 'MMDD') < TO_CHAR (pess.nascimentoFundacao, 'MMDD')
              THEN 1
              ELSE 0
            END
      END idade,
      CASE
        WHEN p_config_246_baseDescontoPagam = 'S'
        THEN a.valorBasePagamento
          - CASE
              WHEN p_config_337_descontoSobreFret = 1
                OR a.tipoPagamentoFrete = 'V'
              THEN 0
              ELSE a.valorFreteTotal + a.valorSeguroTotal
            END
        WHEN p_soma_valorPagamentoBruto >= a.valorBasePagamento
        THEN 0
        WHEN p_soma_valorPagamentoBruto + p_pag_valorPagamentoBruto > a.valorBasePagamento
        THEN a.valorBasePagamento - p_soma_valorPagamentoBruto
          - CASE
              WHEN p_config_337_descontoSobreFret = 1
                OR a.tipoPagamentoFrete = 'V'
              THEN 0
              ELSE ROUND (
                (a.valorFreteTotal + a.valorSeguroTotal)
                * (a.valorBasePagamento - p_soma_valorPagamentoBruto)
                / a.valorBasePagamento,2)
            END
        ELSE p_pag_valorPagamentoBruto
          - CASE
              WHEN p_config_337_descontoSobreFret = 1
                OR a.tipoPagamentoFrete = 'V'
              THEN 0
              ELSE ROUND (
                (a.valorFreteTotal + a.valorSeguroTotal)
                * p_pag_valorPagamentoBruto
                / a.valorBasePagamento,2)
            END
      END valorBaseDesconto,
      ( CASE
          WHEN p_soma_valorPagamentoBruto >= a.valorBasePagamento
          THEN 0
          WHEN p_soma_valorPagamentoBruto + p_pag_valorPagamentoBruto > a.valorBasePagamento
          THEN a.valorBasePagamento - p_soma_valorPagamentoBruto
          ELSE p_pag_valorPagamentoBruto
        END
        / a.valorBasePagamento) proporcaoPagamento
    FROM (
      SELECT
        a.estabelecimento,
        a.pessoa,
        a.valorBasePagamento,
        a.tipoPagamentoFrete,
        a.valorFreteTotal,
        a.valorSeguroTotal
      FROM MOORCAMENTOS a
      WHERE a.orcamento = p_orcamento
      AND a.valorBasePagamento > 0) a
    JOIN PAESTABELECIMENTOS est
    ON est.estabelecimento = a.estabelecimento
    JOIN CAPESSOAS pess
    ON pess.pessoa = a.pessoa),
  ITENS AS (
    SELECT
      a.sequencia,
      a.vendedor,
      a.gradeProduto,
      a.localEstoque,
      a.personalizacao,
      a.quantidade,
      ROUND (a.quantidade * (a.precoUnitarioBruto + a.acrescimoUnitarioComposicao),2) valorBaseRegra,
      a.valorDescontoItem,
      a.valorDescontoGeral,
      a.tabelaPreco,
      gradProd.produto,
      gradProd.cor,
      gradProd.tamanho,
      prod.subcategoriaProduto,
      prod.marca,
      prod.caracteristicaA,
      prod.caracteristicaB,
      prod.caracteristicaC,
      prod.caracteristicaD,
      prod.caracteristicaE,
      prod.idNcm,
      prod.listaServicos,
      subCatProd.categoriaProduto
    FROM MOORCAMENTOXITENS a
    JOIN CAGRADESPRODUTO gradProd
    ON gradProd.gradeProduto = a.gradeProduto
    JOIN CAPRODUTOS prod
    ON prod.produto = gradProd.produto
    JOIN PASUBCATEGORIASPRODUTO subCatProd
    ON subCatProd.subCategoriaProduto = prod.subCategoriaProduto
    WHERE a.orcamento = p_orcamento
    AND a.cancelado = 0
    AND a.quantidade > 0),
  REGRAS AS (
    SELECT
      a.regraDescontoMargem,
      a.ordenacao,
      a.tipoRegraDescontoMargem,
      a.valorSugestao,
      a.valorMaximoSemSenha,
      a.filtrarTabelaPreco,
      cab.idade,
      cab.valorBaseDesconto,
      cab.proporcaoPagamento
    FROM PAREGRASDESCONTOSMARGEM a
    JOIN CABECALHO cab
    ON 1=1
    JOIN PAFILTROSCABECALHO filtroCab
    ON filtroCab.filtroCabecalho = a.filtroCabecalho
    JOIN CAPESSOAS pess
    ON pess.pessoa = cab.pessoa
    JOIN PAFILTROSPAGAMENTO filtroPag
    ON filtroPag.filtroPagamento = a.filtroPagamento
    WHERE a.regraDescontoMargem > 0
    AND a.ativo = 1
    AND a.dataValidadeInicial <= TRUNC(SYSDATE)
    AND a.dataValidadeFinal >= TRUNC(SYSDATE)
    AND a.cabecalhoItemPagamento = 'P'
    AND a.tipoRegraDescontoMargem BETWEEN 1 AND 6
    -- Filtro Cabeçalho
    AND (a.filtroCabecalho = 0
      OR (filtroCab.filtrarEstabelecimentos = 0
        OR EXISTS (
          SELECT 1
          FROM PAFILTROCABECXESTABELEC filtroCabX
          WHERE filtroCabX.filtroCabecalho = a.filtroCabecalho
          AND filtroCabX.estabelecimento = cab.estabelecimento
          AND filtroCabX.ativo = 1))
      AND (filtroCab.filtrarUfs = 0
        OR EXISTS (
          SELECT 1
          FROM PAFILTROCABECXUFS filtroCabX
          WHERE filtroCabX.filtroCabecalho = a.filtroCabecalho
          AND filtroCabX.uf = cab.uf
          AND filtroCabX.ativo = 1))
      AND (filtroCab.filtrarPessoas = 0
        OR EXISTS (
          SELECT 1
          FROM PAFILTROCABECXPESSOAS filtroCabX
          WHERE filtroCabX.filtroCabecalho = a.filtroCabecalho
          AND filtroCabX.pessoa = cab.pessoa
          AND filtroCabX.ativo = 1))
      AND (filtroCab.filtrarPerfisUsuario = 0
        AND filtroCab.filtrarUsuarios = 0
        OR filtroCab.filtrarPerfisUsuario = 1
        AND EXISTS (
          SELECT 1
          FROM PAFILTROCABECXPERFISUSUAR filtroCabX
          WHERE filtroCabX.filtroCabecalho = a.filtroCabecalho
          AND filtroCabX.perfilUsuario = p_perfilUsuarioLogado
          AND filtroCabX.ativo = 1)
        OR filtroCab.filtrarUsuarios = 1
        AND EXISTS (
          SELECT 1
          FROM PAFILTROCABECXUSUARIOS filtroCabX
          WHERE filtroCabX.filtroCabecalho = a.filtroCabecalho
          AND filtroCabX.usuario = p_usuarioLogado
          AND filtroCabX.ativo = 1))
      AND (filtroCab.indicadorPessoa = ' '
        OR filtroCab.indicadorPessoa = pess.indicadorPessoa)
      AND (filtroCab.colaborador = ' '
        OR filtroCab.colaborador = 'N'
        AND (cab.pessoa = 0
          OR NOT (EXISTS (
            SELECT 1
            FROM CACOLABORADORES colab
            WHERE colab.colaborador = cab.pessoa
            AND colab.ativo = 1 )))
        OR filtroCab.colaborador = 'S'
        AND cab.pessoa <> 0
        AND EXISTS (
          SELECT 1
          FROM CACOLABORADORES colab
          WHERE colab.colaborador = cab.pessoa
          AND colab.ativo = 1)))
    -- Filtro Pagamento
    AND (a.filtroPagamento = 0
      OR (filtroPag.filtrarMeiosPagamento = 0
        OR EXISTS (
          SELECT 1
          FROM PAFILTROPAGAMENTOXMEIOPAG filtroPagX
          WHERE filtroPagX.filtroPagamento = a.filtroPagamento
          AND filtroPagX.meioPagamento = p_pag_meioPagamento
          AND filtroPagX.ativo = 1))
      AND (filtroPag.filtrarCondicoesPagamento = 0
        OR EXISTS (
          SELECT 1
          FROM PAFILTROPAGAMENTOXCONDPAG filtroPagX
          WHERE filtroPagX.filtroPagamento = a.filtroPagamento
          AND filtroPagX.condicaoPagamento = p_pag_condicaoPagamento
          AND filtroPagX.ativo = 1)))),
  FILTROSPRODUTOS AS (
    SELECT
      a.regraDescontoMargem,
      a.filtroProduto,
      b.quantidadeMinima,
      b.quantidadeMaxima,
      b.filtrarVendedores,
      b.filtrarLocaisEstoque,
      b.filtrarPersonalizacoes,
      b.filtrarProdutos,
      b.filtrarCategoriasProdutos,
      b.filtrarSubcategoriasProdutos,
      b.filtrarMarcas,
      b.filtrarCaracteristicasA,
      b.filtrarCaracteristicasB,
      b.filtrarCaracteristicasC,
      b.filtrarCaracteristicasD,
      b.filtrarCaracteristicasE,
      b.filtrarCores,
      b.filtrarTamanhos,
      b.filtrarNCMs,
      b.filtrarListasServicos,
      c.filtrarTabelaPreco
    FROM PAREGRADESCMARGXFILTPROD a
    JOIN PAFILTROSPRODUTO b
    ON b.filtroProduto = a.filtroProduto
    JOIN REGRAS c
    ON c.regraDescontoMargem = a.regraDescontoMargem
    AND a.filtroProduto > 0
    AND a.ativo = 1),
  REGRASXITENS AS (
    SELECT
      a.regraDescontoMargem,
      a.filtroProduto,
      a.quantidadeMinima,
      a.quantidadeMaxima,
      b.sequencia,
      b.quantidade,
      b.valorBaseRegra,
      b.valorDescontoItem,
      b.valorDescontoGeral
    FROM FILTROSPRODUTOS a
    JOIN ITENS b
	  ON 1=1
    WHERE (a.filtrarTabelaPreco = 0
      OR EXISTS (
        SELECT 1
        FROM PAREGRADESCMARGXTABELASPR x
        WHERE x.regraDescontoMargem = a.regraDescontoMargem
        AND x.tabelaPreco = b.tabelaPreco
        AND x.ativo = 1))
    AND (a.filtrarVendedores = 0
    OR EXISTS (
      SELECT 1
      FROM PAFILTROPRODUTOXVENDEDOR x
      WHERE x.filtroProduto = a.filtroProduto
      AND x.vendedor = b.vendedor
      AND x.ativo = 1))
    AND (a.filtrarLocaisEstoque = 0
    OR EXISTS (
      SELECT 1
      FROM PAFILTROPRODUTOXLOCAISEST x
      WHERE x.filtroProduto = a.filtroProduto
      AND x.localEstoque = b.localEstoque
      AND x.ativo = 1))
    AND (a.filtrarPersonalizacoes = 0
    OR EXISTS (
      SELECT 1
      FROM PAFILTROPRODUTOXPERSONAL x
      WHERE x.filtroProduto = a.filtroProduto
      AND x.personalizacao = b.personalizacao
      AND x.ativo = 1))
    AND (a.filtrarProdutos = 0
      AND a.filtrarCategoriasProdutos = 0
      AND a.filtrarSubcategoriasProdutos = 0
      AND a.filtrarMarcas = 0
      AND a.filtrarCaracteristicasA = 0
      AND a.filtrarCaracteristicasB = 0
      AND a.filtrarCaracteristicasC = 0
      AND a.filtrarCaracteristicasD = 0
      AND a.filtrarCaracteristicasE = 0
      AND a.filtrarCores = 0
      AND a.filtrarTamanhos = 0
      AND a.filtrarNCMs = 0
      AND a.filtrarListasServicos = 0
      OR a.filtrarProdutos = 1
      AND EXISTS (
        SELECT 1
        FROM PAFILTROPRODUTOXPRODUTOS x
        WHERE x.filtroProduto = a.filtroProduto
        AND x.produto = b.produto
        AND x.ativo = 1)
      OR (a.filtrarCategoriasProdutos = 1
        OR a.filtrarSubcategoriasProdutos = 1
        OR a.filtrarMarcas = 1
        OR a.filtrarCaracteristicasA = 1
        OR a.filtrarCaracteristicasB = 1
        OR a.filtrarCaracteristicasC = 1
        OR a.filtrarCaracteristicasD = 1
        OR a.filtrarCaracteristicasE = 1
        OR a.filtrarCores = 1
        OR a.filtrarTamanhos = 1
        OR a.filtrarNCMs = 1
        OR a.filtrarListasServicos = 1)
      AND (a.filtrarCategoriasProdutos = 0
        OR EXISTS (
          SELECT 1
          FROM PAFILTROPRODUTOXCATEGPROD x
          WHERE x.filtroProduto = a.filtroProduto
          AND x.categoriaProduto = b.categoriaProduto
          AND x.ativo = 1))
      AND (a.filtrarSubcategoriasProdutos = 0
        OR EXISTS (
          SELECT 1
          FROM PAFILTROPRODUTOXSUBCAPROD x
          WHERE x.filtroProduto = a.filtroProduto
          AND x.subcategoriaProduto = b.subcategoriaProduto
          AND x.ativo = 1))
      AND (a.filtrarMarcas = 0
        OR EXISTS (
          SELECT 1
          FROM PAFILTROPRODUTOXMARCAS x
          WHERE x.filtroProduto = a.filtroProduto
          AND x.marca = b.marca
          AND x.ativo = 1))
      AND (a.filtrarCaracteristicasA = 0
        OR EXISTS (
          SELECT 1
          FROM PAFILTROPRODUTOXCARACTERA x
          WHERE x.filtroProduto = a.filtroProduto
          AND x.caracteristicaA = b.caracteristicaA
          AND x.ativo = 1))
      AND (a.filtrarCaracteristicasB = 0
        OR EXISTS (
          SELECT 1
          FROM PAFILTROPRODUTOXCARACTERB x
          WHERE x.filtroProduto = a.filtroProduto
          AND x.caracteristicaB = b.caracteristicaB
          AND x.ativo = 1))
      AND (a.filtrarCaracteristicasC = 0
        OR EXISTS (
          SELECT 1
          FROM PAFILTROPRODUTOXCARACTERC x
          WHERE x.filtroProduto = a.filtroProduto
          AND x.caracteristicaC = b.caracteristicaC
          AND x.ativo = 1))
      AND (a.filtrarCaracteristicasD = 0
        OR EXISTS (
          SELECT 1
          FROM PAFILTROPRODUTOXCARACTERD x
          WHERE x.filtroProduto = a.filtroProduto
          AND x.caracteristicaD = b.caracteristicaD
          AND x.ativo = 1))
      AND (a.filtrarCaracteristicasE = 0
        OR EXISTS (
          SELECT 1
          FROM PAFILTROPRODUTOXCARACTERE x
          WHERE x.filtroProduto = a.filtroProduto
          AND x.caracteristicaE = b.caracteristicaE
          AND x.ativo = 1))
      AND (a.filtrarCores = 0
        OR EXISTS (
          SELECT 1
          FROM PAFILTROPRODUTOXCORES x
          WHERE x.filtroProduto = a.filtroProduto
          AND x.cor = b.cor
          AND x.ativo = 1))
      AND (a.filtrarTamanhos = 0
        OR EXISTS (
          SELECT 1
          FROM PAFILTROPRODUTOXTAMANHOS x
          WHERE x.filtroProduto = a.filtroProduto
          AND x.tamanho = b.tamanho
          AND x.ativo = 1))
      AND (a.filtrarNCMs = 0
        OR EXISTS (
          SELECT 1
          FROM PAFILTROPRODUTOXNCMS x
          WHERE x.filtroProduto = a.filtroProduto
          AND x.idNcm = b.idNcm
          AND x.ativo = 1))
      AND (a.filtrarListasServicos = 0
        OR EXISTS (
          SELECT 1
          FROM PAFILTROPRODUTOXLISTASSE x
          WHERE x.filtroProduto = a.filtroProduto
          AND x.listaServicos = b.listaServicos
          AND x.ativo = 1)))),
  REGRASXFILTROS AS (
    SELECT
      a.regraDescontoMargem,
      a.filtroProduto
    FROM (
      SELECT
        a.regraDescontoMargem,
        a.filtroProduto,
        a.quantidadeMinima,
        a.quantidadeMaxima,
        SUM (a.quantidade) quantidade
      FROM REGRASXITENS a
      GROUP BY
        a.regraDescontoMargem,
        a.filtroProduto,
        a.quantidadeMinima,
        a.quantidadeMaxima) a
    WHERE a.quantidade >= a.quantidadeMinima
    AND (a.quantidadeMaxima = 0
      OR a.quantidade <= a.quantidadeMaxima)),
  REGRASVALIDAS AS (
    SELECT
      a.regraDescontoMargem,
      a.ordenacao,
      a.tipoRegraDescontoMargem,
      a.valorSugestao,
      a.valorMaximoSemSenha,
      a.filtrarTabelaPreco,
      a.idade,
      a.valorBaseDesconto,
      a.proporcaoPagamento,
      COALESCE((
        SELECT COUNT(1)
        FROM FILTROSPRODUTOS b
        WHERE b.regraDescontoMargem = a.regraDescontoMargem),0) filtrosProdutos
    FROM REGRAS a
    WHERE
      ( SELECT COUNT(1)
        FROM FILTROSPRODUTOS b
        WHERE b.regraDescontoMargem = a.regraDescontoMargem)
    = ( SELECT COUNT(1)
        FROM REGRASXFILTROS b
        WHERE b.regraDescontoMargem = a.regraDescontoMargem))
  SELECT
    COALESCE (MAX(a.possuiRegra), 0) possuiRegra,
    COALESCE (ROUND((
      CASE
        WHEN MIN (a.valorDescontoSugestao) < 0
          OR SUM (
          CASE
            WHEN a.valorDescontoSugestao < 0
            THEN 0
            ELSE a.valorDescontoSugestao
          END) >= p_pag_valorPagamentoBruto
          OR SUM(a.valorBaseDescontoSugestao) <> MAX(a.valorBaseDesconto)
          OR SUM(a.valorDescontoItem) <> 0
          OR SUM(a.valorDescontoGeral) <> 0
          OR SUM(a.possuiRegra) > 1
        THEN 100
          * ROUND(
              CASE
                WHEN SUM (
                  CASE
                    WHEN a.valorDescontoSugestao < 0
                    THEN 0
                    ELSE a.valorDescontoSugestao
                  END) >= p_pag_valorPagamentoBruto
                THEN p_pag_valorPagamentoBruto - 0.01
                ELSE SUM (
                  CASE
                    WHEN a.valorDescontoSugestao < 0
                    THEN 0
                    ELSE a.valorDescontoSugestao
                  END)
              END, 2) / MAX(a.valorBaseDesconto)
        ELSE MAX(a.percentualDescontoSugestao)
      END), 8), 0) percentualDescontoSugestao,
    COALESCE (ROUND(
      CASE
        WHEN SUM (
          CASE
            WHEN a.valorDescontoSugestao < 0
            THEN 0
            ELSE a.valorDescontoSugestao
          END) >= p_pag_valorPagamentoBruto
        THEN p_pag_valorPagamentoBruto - 0.01
        ELSE SUM (
          CASE
            WHEN a.valorDescontoSugestao < 0
            THEN 0
            ELSE a.valorDescontoSugestao
          END)
      END, 2), 0) valorDescontoSugestao,
    COALESCE (ROUND(
      CASE
        WHEN SUM (
          CASE
            WHEN a.valorDescontoMaximoSemSenha < 0
            THEN 0
            ELSE a.valorDescontoMaximoSemSenha
          END) >= p_pag_valorPagamentoBruto
        THEN p_pag_valorPagamentoBruto - 0.01
        ELSE SUM (
          CASE
            WHEN a.valorDescontoMaximoSemSenha < 0
            THEN 0
            ELSE a.valorDescontoMaximoSemSenha
          END)
      END, 2), 0) valorDescontoMaximoSemSenha
  INTO
    r_possuiRegra,
    r_percentualDescontoSugestao,
    r_valorDescontoSugestao,
    r_valorDescontoMaximoSemSenha
  FROM (
    SELECT
      1 possuiRegra,
      a.valorBaseDesconto,
      a.valorDescontoItem,
      a.valorDescontoGeral,
      ROUND (
        CASE a.tipoRegraDescontoMargem
          -- Desconto em percentual
          WHEN 1
          THEN a.valorBaseRegra
          -- Desconto em valor
          WHEN 2
          THEN a.valorBaseDesconto
          -- Preço unitário fixo
          WHEN 3
          THEN a.valorBaseDesconto
          -- Desconto igual a idade em percentual
          WHEN 4
          THEN a.valorBaseRegra
          -- Desconto igual a idade em valor
          WHEN 5
          THEN a.valorBaseDesconto
          -- Preço total fixado
          WHEN 6
          THEN a.valorBaseDesconto
          ELSE 0
        END, 2) valorBaseDescontoSugestao,
      ROUND (
        CASE a.tipoRegraDescontoMargem
          -- Desconto em percentual
          WHEN 1
          THEN a.valorSugestao
          -- Desconto em valor
          WHEN 2
          THEN 100 * a.valorSugestao * a.multiplicador / a.valorBaseDesconto
          -- Preço unitário fixo
          WHEN 3
          THEN 100 * (a.valorBaseRegra-ROUND (a.quantidadeRegra*a.valorMaximoSemSenha,2)) / a.valorBaseDesconto
          -- Desconto igual a idade em percentual
          WHEN 4
          THEN a.idade
          -- Desconto igual a idade em valor
          WHEN 5
          THEN 100 * a.idade * a.multiplicador / a.valorBaseDesconto
          -- Preço total fixado
          WHEN 6
          THEN 100 * a.valorBaseRegra / a.valorBaseDesconto
          ELSE 0
        END, 8) percentualDescontoSugestao,
      ROUND (
        ( CASE a.tipoRegraDescontoMargem
            -- Desconto em percentual
            WHEN 1
            THEN a.valorBaseRegra * a.valorSugestao / 100
            -- Desconto em valor
            WHEN 2
            THEN a.valorSugestao * a.multiplicador
             -- Preço unitário fixo
            WHEN 3
            THEN a.valorBaseRegra-ROUND (a.quantidadeRegra*a.valorSugestao,2)
            -- Desconto igual a idade em percentual
            WHEN 4
            THEN a.valorBaseRegra * a.idade / 100
            -- Desconto igual a idade em valor
            WHEN 5
            THEN a.idade * a.multiplicador
            -- Preço total fixado
            WHEN 6
            THEN a.valorBaseRegra
            ELSE 0
          END
          - a.valorDescontoItem
          - a.valorDescontoGeral)
        * a.proporcaoPagamento, 2) valorDescontoSugestao,
      ROUND (
        CASE a.tipoRegraDescontoMargem
          -- Desconto em percentual
          WHEN 1
          THEN a.valorBaseRegra * a.valorMaximoSemSenha / 100
          -- Desconto em valor
          WHEN 2
          THEN a.valorMaximoSemSenha * a.multiplicador
          -- Preço unitário fixo
          WHEN 3
          THEN a.valorBaseRegra-ROUND (a.quantidadeRegra*a.valorMaximoSemSenha,2)
          -- Desconto igual a idade em percentual
          WHEN 4
          THEN a.valorBaseRegra * a.idade / 100
          -- Desconto igual a idade em valor
          WHEN 5
          THEN a.idade * a.multiplicador
          -- Preço total fixado
          WHEN 6
          THEN a.valorBaseRegra
          ELSE 0
        END * a.proporcaoPagamento, 2) valorDescontoMaximoSemSenha
    FROM (
      SELECT
        a.tipoRegraDescontoMargem,
        a.valorSugestao,
        a.valorMaximoSemSenha,
        a.idade,
        a.valorBaseDesconto,
        a.proporcaoPagamento,
        SUM(a.quantidade) quantidadeRegra,
        CASE
          WHEN SUM (a.valorBaseRegraTodos - a.valorDescontoItemTodos - a.valorDescontoGeralTodos) = 0
          THEN 0
          ELSE SUM (a.valorBaseRegra - a.valorDescontoItem - a.valorDescontoGeral)
            / SUM (a.valorBaseRegraTodos - a.valorDescontoItemTodos - a.valorDescontoGeralTodos)
        END multiplicador,
        SUM (a.valorBaseRegra) valorBaseRegra,
        SUM (a.valorDescontoItem) valorDescontoItem,
        SUM (a.valorDescontoGeral) valorDescontoGeral
      FROM (
        SELECT DISTINCT
          a.regraDescontoMargem,
          a.ordenacao,
          a.tipoRegraDescontoMargem,
          a.valorSugestao,
          a.valorMaximoSemSenha,
          a.idade,
          a.valorBaseDesconto,
          a.proporcaoPagamento,
          b.sequencia,
          b.quantidade,
          b.valorBaseRegra,
          b.valorDescontoItem,
          b.valorDescontoGeral,
          0 valorBaseRegraTodos,
          0 valorDescontoItemTodos,
          0 valorDescontoGeralTodos
        FROM REGRASVALIDAS a
        JOIN ITENS b
        ON 1=1
        WHERE a.filtrosProdutos = 0
        AND (a.filtrarTabelaPreco = 0
          OR EXISTS (
            SELECT 1
            FROM PAREGRADESCMARGXTABELASPR x
            WHERE x.regraDescontoMargem = a.regraDescontoMargem
            AND x.tabelaPreco = b.tabelaPreco
            AND x.ativo = 1))
        UNION ALL
        SELECT DISTINCT
          a.regraDescontoMargem,
          a.ordenacao,
          a.tipoRegraDescontoMargem,
          a.valorSugestao,
          a.valorMaximoSemSenha,
          a.idade,
          a.valorBaseDesconto,
          a.proporcaoPagamento,
          b.sequencia,
          b.quantidade,
          b.valorBaseRegra,
          b.valorDescontoItem,
          b.valorDescontoGeral,
          0 valorBaseRegraTodos,
          0 valorDescontoItemTodos,
          0 valorDescontoGeralTodos
        FROM REGRASVALIDAS a
        JOIN REGRASXITENS b
        ON b.regraDescontoMargem = a.regraDescontoMargem
        WHERE a.filtrosProdutos > 0
        UNION ALL
        SELECT DISTINCT
          a.regraDescontoMargem,
          a.ordenacao,
          a.tipoRegraDescontoMargem,
          a.valorSugestao,
          a.valorMaximoSemSenha,
          a.idade,
          a.valorBaseDesconto,
          a.proporcaoPagamento,
          b.sequencia,
          b.quantidade,
          0 valorBaseRegra,
          0 valorDescontoItem,
          0 valorDescontoGeral,
          b.valorBaseRegra valorBaseRegraTodos,
          b.valorDescontoItem valorDescontoItemTodos,
          b.valorDescontoGeral valorDescontoGeralTodos
        FROM REGRASVALIDAS a
        JOIN ITENS b
        ON 1=1) a
      GROUP BY
        a.regraDescontoMargem,
        a.ordenacao,
        a.tipoRegraDescontoMargem,
        a.valorSugestao,
        a.valorMaximoSemSenha,
        a.idade,
        a.valorBaseDesconto,
        a.proporcaoPagamento) a) a;
END ADD_ORCAMENTO_REGRA_DESC_PAG;

/

create or replace PROCEDURE ADD_PRE_DOC_REGRA_DESC_PAG (
  p_usuarioLogado                IN NUMBER,
  p_perfilUsuarioLogado          IN NUMBER,
  p_config_227_manterPessoaOrcam IN NUMBER,
  p_config_246_baseDescontoPagam IN CHAR,
  p_config_337_descontoSobreFret IN NUMBER,
  p_preDocumento                 IN NUMBER,
  p_soma_valorPagamentoBruto     IN NUMBER,
  p_orc_pessoa                   IN NUMBER,
  p_pag_meioPagamento            IN NUMBER,
  p_pag_condicaoPagamento        IN NUMBER,
  p_pag_valorPagamentoBruto      IN NUMBER,
  /* Retornos */
  r_possuiRegra                  OUT NUMBER,
  r_percentualDescontoSugestao   OUT NUMBER,
  r_valorDescontoSugestao        OUT NUMBER,
  r_valorDescontoMaximoSemSenha  OUT NUMBER)
IS
BEGIN
  WITH
  CABECALHO AS (
    SELECT
      a.estabelecimento,
      a.pessoa,
      COALESCE((
        CASE
          WHEN a.pessoa = 0
          THEN (
            SELECT MAX(munPess.uf)
            FROM CAENDERECOSPESSOA endPess
            JOIN SIMUNICIPIOS munPess
            ON munPess.municipio = endPess.municipio
            WHERE endPess.pessoa = est.pessoaEstabelecimento
            AND endPess.ativo = 1
            AND endPess.principal = 1)
          ELSE COALESCE((
            SELECT MAX(munPess.uf)
            FROM CAENDERECOSPESSOA endPess
            JOIN SIMUNICIPIOS munPess
            ON munPess.municipio = endPess.municipio
            WHERE endPess.pessoa = a.pessoa
            AND endPess.ativo = 1
            AND endPess.principal = 1),(
            SELECT MAX(munPess.uf)
            FROM CAENDERECOSPESSOA endPess
            JOIN SIMUNICIPIOS munPess
            ON munPess.municipio = endPess.municipio
            WHERE endPess.pessoa = est.pessoaEstabelecimento
            AND endPess.ativo = 1
            AND endPess.principal = 1))
        END
      ),'  ') uf,
      CASE
        WHEN pess.nascimentoFundacao IS NULL
          OR TRUNC (pess.nascimentoFundacao) > TRUNC (SYSDATE)
        THEN 0
        ELSE TRUNC (SYSDATE, 'YYYY')
          - TRUNC (pess.nascimentoFundacao, 'YYYY')
          - CASE
              WHEN TO_CHAR (SYSDATE, 'MMDD') < TO_CHAR (pess.nascimentoFundacao, 'MMDD')
              THEN 1
              ELSE 0
            END
      END idade,
      CASE
        WHEN p_config_246_baseDescontoPagam = 'S'
        THEN a.valorBasePagamento
          - CASE
              WHEN p_config_337_descontoSobreFret = 1
                OR a.tipoPagamentoFrete = 'V'
              THEN 0
              ELSE a.valorFreteTotal + a.valorSeguroTotal
            END
        WHEN p_soma_valorPagamentoBruto >= a.valorBasePagamento
        THEN 0
        WHEN p_soma_valorPagamentoBruto + p_pag_valorPagamentoBruto > a.valorBasePagamento
        THEN a.valorBasePagamento - p_soma_valorPagamentoBruto
          - CASE
              WHEN p_config_337_descontoSobreFret = 1
                OR a.tipoPagamentoFrete = 'V'
              THEN 0
              ELSE ROUND (
                (a.valorFreteTotal + a.valorSeguroTotal)
                * (a.valorBasePagamento - p_soma_valorPagamentoBruto)
                / a.valorBasePagamento,2)
            END
        ELSE p_pag_valorPagamentoBruto
          - CASE
              WHEN p_config_337_descontoSobreFret = 1
                OR a.tipoPagamentoFrete = 'V'
              THEN 0
              ELSE ROUND (
                (a.valorFreteTotal + a.valorSeguroTotal)
                * p_pag_valorPagamentoBruto
                / a.valorBasePagamento,2)
            END
      END valorBaseDesconto,
      ( CASE
          WHEN p_soma_valorPagamentoBruto >= a.valorBasePagamento
          THEN 0
          WHEN p_soma_valorPagamentoBruto + p_pag_valorPagamentoBruto > a.valorBasePagamento
          THEN a.valorBasePagamento - p_soma_valorPagamentoBruto
          ELSE p_pag_valorPagamentoBruto
        END
        / a.valorBasePagamento) proporcaoPagamento
    FROM (
      SELECT
        a.estabelecimento,
        CASE
          WHEN p_orc_pessoa = 0
            OR p_config_227_manterPessoaOrcam = 1
          THEN a.pessoa
          ELSE p_orc_pessoa
        END pessoa,
        a.valorBasePagamento,
        a.tipoPagamentoFrete,
        a.valorFreteTotal,
        a.valorSeguroTotal
      FROM MOPREDOCUMENTOS a
      WHERE a.preDocumento = p_preDocumento
      AND a.valorBasePagamento > 0) a
    JOIN PAESTABELECIMENTOS est
    ON est.estabelecimento = a.estabelecimento
    JOIN CAPESSOAS pess
    ON pess.pessoa = a.pessoa),
  ITENS AS (
    SELECT
      a.sequencia,
      a.vendedor,
      a.gradeProduto,
      a.localEstoque,
      a.personalizacao,
      a.quantidade,
      ROUND (a.quantidade * (a.precoUnitarioBruto + a.acrescimoUnitarioComposicao),2) valorBaseRegra,
      a.valorDescontoItem,
      a.valorDescontoGeral,
      a.tabelaPreco,
      gradProd.produto,
      gradProd.cor,
      gradProd.tamanho,
      prod.subcategoriaProduto,
      prod.marca,
      prod.caracteristicaA,
      prod.caracteristicaB,
      prod.caracteristicaC,
      prod.caracteristicaD,
      prod.caracteristicaE,
      prod.idNcm,
      prod.listaServicos,
      subCatProd.categoriaProduto
    FROM MOPREDOCUMXITENS a
    JOIN CAGRADESPRODUTO gradProd
    ON gradProd.gradeProduto = a.gradeProduto
    JOIN CAPRODUTOS prod
    ON prod.produto = gradProd.produto
    JOIN PASUBCATEGORIASPRODUTO subCatProd
    ON subCatProd.subCategoriaProduto = prod.subCategoriaProduto
    WHERE a.preDocumento = p_preDocumento
    AND a.cancelado = 0
    AND a.quantidade > 0),
  REGRAS AS (
    SELECT
      a.regraDescontoMargem,
      a.ordenacao,
      a.tipoRegraDescontoMargem,
      a.valorSugestao,
      a.valorMaximoSemSenha,
      a.filtrarTabelaPreco,
      cab.idade,
      cab.valorBaseDesconto,
      cab.proporcaoPagamento
    FROM PAREGRASDESCONTOSMARGEM a
    JOIN CABECALHO cab
    ON 1=1
    JOIN PAFILTROSCABECALHO filtroCab
    ON filtroCab.filtroCabecalho = a.filtroCabecalho
    JOIN CAPESSOAS pess
    ON pess.pessoa = cab.pessoa
    JOIN PAFILTROSPAGAMENTO filtroPag
    ON filtroPag.filtroPagamento = a.filtroPagamento
    WHERE a.regraDescontoMargem > 0
    AND a.ativo = 1
    AND a.dataValidadeInicial <= TRUNC(SYSDATE)
    AND a.dataValidadeFinal >= TRUNC(SYSDATE)
    AND a.cabecalhoItemPagamento = 'P'
    AND a.tipoRegraDescontoMargem BETWEEN 1 AND 6
    -- Filtro Cabeçalho
    AND (a.filtroCabecalho = 0
      OR (filtroCab.filtrarEstabelecimentos = 0
        OR EXISTS (
          SELECT 1
          FROM PAFILTROCABECXESTABELEC filtroCabX
          WHERE filtroCabX.filtroCabecalho = a.filtroCabecalho
          AND filtroCabX.estabelecimento = cab.estabelecimento
          AND filtroCabX.ativo = 1))
      AND (filtroCab.filtrarUfs = 0
        OR EXISTS (
          SELECT 1
          FROM PAFILTROCABECXUFS filtroCabX
          WHERE filtroCabX.filtroCabecalho = a.filtroCabecalho
          AND filtroCabX.uf = cab.uf
          AND filtroCabX.ativo = 1))
      AND (filtroCab.filtrarPessoas = 0
        OR EXISTS (
          SELECT 1
          FROM PAFILTROCABECXPESSOAS filtroCabX
          WHERE filtroCabX.filtroCabecalho = a.filtroCabecalho
          AND filtroCabX.pessoa = cab.pessoa
          AND filtroCabX.ativo = 1))
      AND (filtroCab.filtrarPerfisUsuario = 0
        AND filtroCab.filtrarUsuarios = 0
        OR filtroCab.filtrarPerfisUsuario = 1
        AND EXISTS (
          SELECT 1
          FROM PAFILTROCABECXPERFISUSUAR filtroCabX
          WHERE filtroCabX.filtroCabecalho = a.filtroCabecalho
          AND filtroCabX.perfilUsuario = p_perfilUsuarioLogado
          AND filtroCabX.ativo = 1)
        OR filtroCab.filtrarUsuarios = 1
        AND EXISTS (
          SELECT 1
          FROM PAFILTROCABECXUSUARIOS filtroCabX
          WHERE filtroCabX.filtroCabecalho = a.filtroCabecalho
          AND filtroCabX.usuario = p_usuarioLogado
          AND filtroCabX.ativo = 1))
      AND (filtroCab.indicadorPessoa = ' '
        OR filtroCab.indicadorPessoa = pess.indicadorPessoa)
      AND (filtroCab.colaborador = ' '
        OR filtroCab.colaborador = 'N'
        AND (cab.pessoa = 0
          OR NOT (EXISTS (
            SELECT 1
            FROM CACOLABORADORES colab
            WHERE colab.colaborador = cab.pessoa
            AND colab.ativo = 1 )))
        OR filtroCab.colaborador = 'S'
        AND cab.pessoa <> 0
        AND EXISTS (
          SELECT 1
          FROM CACOLABORADORES colab
          WHERE colab.colaborador = cab.pessoa
          AND colab.ativo = 1)))
    -- Filtro Pagamento
    AND (a.filtroPagamento = 0
      OR (filtroPag.filtrarMeiosPagamento = 0
        OR EXISTS (
          SELECT 1
          FROM PAFILTROPAGAMENTOXMEIOPAG filtroPagX
          WHERE filtroPagX.filtroPagamento = a.filtroPagamento
          AND filtroPagX.meioPagamento = p_pag_meioPagamento
          AND filtroPagX.ativo = 1))
      AND (filtroPag.filtrarCondicoesPagamento = 0
        OR EXISTS (
          SELECT 1
          FROM PAFILTROPAGAMENTOXCONDPAG filtroPagX
          WHERE filtroPagX.filtroPagamento = a.filtroPagamento
          AND filtroPagX.condicaoPagamento = p_pag_condicaoPagamento
          AND filtroPagX.ativo = 1)))),
  FILTROSPRODUTOS AS (
    SELECT
      a.regraDescontoMargem,
      a.filtroProduto,
      b.quantidadeMinima,
      b.quantidadeMaxima,
      b.filtrarVendedores,
      b.filtrarLocaisEstoque,
      b.filtrarPersonalizacoes,
      b.filtrarProdutos,
      b.filtrarCategoriasProdutos,
      b.filtrarSubcategoriasProdutos,
      b.filtrarMarcas,
      b.filtrarCaracteristicasA,
      b.filtrarCaracteristicasB,
      b.filtrarCaracteristicasC,
      b.filtrarCaracteristicasD,
      b.filtrarCaracteristicasE,
      b.filtrarCores,
      b.filtrarTamanhos,
      b.filtrarNCMs,
      b.filtrarListasServicos,
      c.filtrarTabelaPreco
    FROM PAREGRADESCMARGXFILTPROD a
    JOIN PAFILTROSPRODUTO b
    ON b.filtroProduto = a.filtroProduto
    JOIN REGRAS c
    ON c.regraDescontoMargem = a.regraDescontoMargem
    AND a.filtroProduto > 0
    AND a.ativo = 1),
  REGRASXITENS AS (
    SELECT
      a.regraDescontoMargem,
      a.filtroProduto,
      a.quantidadeMinima,
      a.quantidadeMaxima,
      b.sequencia,
      b.quantidade,
      b.valorBaseRegra,
      b.valorDescontoItem,
      b.valorDescontoGeral
    FROM FILTROSPRODUTOS a
    JOIN ITENS b
	  ON 1=1
    WHERE (a.filtrarTabelaPreco = 0
      OR EXISTS (
        SELECT 1
        FROM PAREGRADESCMARGXTABELASPR x
        WHERE x.regraDescontoMargem = a.regraDescontoMargem
        AND x.tabelaPreco = b.tabelaPreco
        AND x.ativo = 1))
    AND (a.filtrarVendedores = 0
    OR EXISTS (
      SELECT 1
      FROM PAFILTROPRODUTOXVENDEDOR x
      WHERE x.filtroProduto = a.filtroProduto
      AND x.vendedor = b.vendedor
      AND x.ativo = 1))
    AND (a.filtrarLocaisEstoque = 0
    OR EXISTS (
      SELECT 1
      FROM PAFILTROPRODUTOXLOCAISEST x
      WHERE x.filtroProduto = a.filtroProduto
      AND x.localEstoque = b.localEstoque
      AND x.ativo = 1))
    AND (a.filtrarPersonalizacoes = 0
    OR EXISTS (
      SELECT 1
      FROM PAFILTROPRODUTOXPERSONAL x
      WHERE x.filtroProduto = a.filtroProduto
      AND x.personalizacao = b.personalizacao
      AND x.ativo = 1))
    AND (a.filtrarProdutos = 0
      AND a.filtrarCategoriasProdutos = 0
      AND a.filtrarSubcategoriasProdutos = 0
      AND a.filtrarMarcas = 0
      AND a.filtrarCaracteristicasA = 0
      AND a.filtrarCaracteristicasB = 0
      AND a.filtrarCaracteristicasC = 0
      AND a.filtrarCaracteristicasD = 0
      AND a.filtrarCaracteristicasE = 0
      AND a.filtrarCores = 0
      AND a.filtrarTamanhos = 0
      AND a.filtrarNCMs = 0
      AND a.filtrarListasServicos = 0
      OR a.filtrarProdutos = 1
      AND EXISTS (
        SELECT 1
        FROM PAFILTROPRODUTOXPRODUTOS x
        WHERE x.filtroProduto = a.filtroProduto
        AND x.produto = b.produto
        AND x.ativo = 1)
      OR (a.filtrarCategoriasProdutos = 1
        OR a.filtrarSubcategoriasProdutos = 1
        OR a.filtrarMarcas = 1
        OR a.filtrarCaracteristicasA = 1
        OR a.filtrarCaracteristicasB = 1
        OR a.filtrarCaracteristicasC = 1
        OR a.filtrarCaracteristicasD = 1
        OR a.filtrarCaracteristicasE = 1
        OR a.filtrarCores = 1
        OR a.filtrarTamanhos = 1
        OR a.filtrarNCMs = 1
        OR a.filtrarListasServicos = 1)
      AND (a.filtrarCategoriasProdutos = 0
        OR EXISTS (
          SELECT 1
          FROM PAFILTROPRODUTOXCATEGPROD x
          WHERE x.filtroProduto = a.filtroProduto
          AND x.categoriaProduto = b.categoriaProduto
          AND x.ativo = 1))
      AND (a.filtrarSubcategoriasProdutos = 0
        OR EXISTS (
          SELECT 1
          FROM PAFILTROPRODUTOXSUBCAPROD x
          WHERE x.filtroProduto = a.filtroProduto
          AND x.subcategoriaProduto = b.subcategoriaProduto
          AND x.ativo = 1))
      AND (a.filtrarMarcas = 0
        OR EXISTS (
          SELECT 1
          FROM PAFILTROPRODUTOXMARCAS x
          WHERE x.filtroProduto = a.filtroProduto
          AND x.marca = b.marca
          AND x.ativo = 1))
      AND (a.filtrarCaracteristicasA = 0
        OR EXISTS (
          SELECT 1
          FROM PAFILTROPRODUTOXCARACTERA x
          WHERE x.filtroProduto = a.filtroProduto
          AND x.caracteristicaA = b.caracteristicaA
          AND x.ativo = 1))
      AND (a.filtrarCaracteristicasB = 0
        OR EXISTS (
          SELECT 1
          FROM PAFILTROPRODUTOXCARACTERB x
          WHERE x.filtroProduto = a.filtroProduto
          AND x.caracteristicaB = b.caracteristicaB
          AND x.ativo = 1))
      AND (a.filtrarCaracteristicasC = 0
        OR EXISTS (
          SELECT 1
          FROM PAFILTROPRODUTOXCARACTERC x
          WHERE x.filtroProduto = a.filtroProduto
          AND x.caracteristicaC = b.caracteristicaC
          AND x.ativo = 1))
      AND (a.filtrarCaracteristicasD = 0
        OR EXISTS (
          SELECT 1
          FROM PAFILTROPRODUTOXCARACTERD x
          WHERE x.filtroProduto = a.filtroProduto
          AND x.caracteristicaD = b.caracteristicaD
          AND x.ativo = 1))
      AND (a.filtrarCaracteristicasE = 0
        OR EXISTS (
          SELECT 1
          FROM PAFILTROPRODUTOXCARACTERE x
          WHERE x.filtroProduto = a.filtroProduto
          AND x.caracteristicaE = b.caracteristicaE
          AND x.ativo = 1))
      AND (a.filtrarCores = 0
        OR EXISTS (
          SELECT 1
          FROM PAFILTROPRODUTOXCORES x
          WHERE x.filtroProduto = a.filtroProduto
          AND x.cor = b.cor
          AND x.ativo = 1))
      AND (a.filtrarTamanhos = 0
        OR EXISTS (
          SELECT 1
          FROM PAFILTROPRODUTOXTAMANHOS x
          WHERE x.filtroProduto = a.filtroProduto
          AND x.tamanho = b.tamanho
          AND x.ativo = 1))
      AND (a.filtrarNCMs = 0
        OR EXISTS (
          SELECT 1
          FROM PAFILTROPRODUTOXNCMS x
          WHERE x.filtroProduto = a.filtroProduto
          AND x.idNcm = b.idNcm
          AND x.ativo = 1))
      AND (a.filtrarListasServicos = 0
        OR EXISTS (
          SELECT 1
          FROM PAFILTROPRODUTOXLISTASSE x
          WHERE x.filtroProduto = a.filtroProduto
          AND x.listaServicos = b.listaServicos
          AND x.ativo = 1)))),
  REGRASXFILTROS AS (
    SELECT
      a.regraDescontoMargem,
      a.filtroProduto
    FROM (
      SELECT
        a.regraDescontoMargem,
        a.filtroProduto,
        a.quantidadeMinima,
        a.quantidadeMaxima,
        SUM (a.quantidade) quantidade
      FROM REGRASXITENS a
      GROUP BY
        a.regraDescontoMargem,
        a.filtroProduto,
        a.quantidadeMinima,
        a.quantidadeMaxima) a
    WHERE a.quantidade >= a.quantidadeMinima
    AND (a.quantidadeMaxima = 0
      OR a.quantidade <= a.quantidadeMaxima)),
  REGRASVALIDAS AS (
    SELECT
      a.regraDescontoMargem,
      a.ordenacao,
      a.tipoRegraDescontoMargem,
      a.valorSugestao,
      a.valorMaximoSemSenha,
      a.filtrarTabelaPreco,
      a.idade,
      a.valorBaseDesconto,
      a.proporcaoPagamento,
      COALESCE((
        SELECT COUNT(1)
        FROM FILTROSPRODUTOS b
        WHERE b.regraDescontoMargem = a.regraDescontoMargem),0) filtrosProdutos
    FROM REGRAS a
    WHERE
      ( SELECT COUNT(1)
        FROM FILTROSPRODUTOS b
        WHERE b.regraDescontoMargem = a.regraDescontoMargem)
    = ( SELECT COUNT(1)
        FROM REGRASXFILTROS b
        WHERE b.regraDescontoMargem = a.regraDescontoMargem))
  SELECT
    COALESCE (MAX(a.possuiRegra), 0) possuiRegra,
    COALESCE (ROUND((
      CASE
        WHEN MIN (a.valorDescontoSugestao) < 0
          OR SUM (
          CASE
            WHEN a.valorDescontoSugestao < 0
            THEN 0
            ELSE a.valorDescontoSugestao
          END) >= p_pag_valorPagamentoBruto
          OR SUM(a.valorBaseDescontoSugestao) <> MAX(a.valorBaseDesconto)
          OR SUM(a.valorDescontoItem) <> 0
          OR SUM(a.valorDescontoGeral) <> 0
          OR SUM(a.possuiRegra) > 1
        THEN 100
          * ROUND(
              CASE
                WHEN SUM (
                  CASE
                    WHEN a.valorDescontoSugestao < 0
                    THEN 0
                    ELSE a.valorDescontoSugestao
                  END) >= p_pag_valorPagamentoBruto
                THEN p_pag_valorPagamentoBruto - 0.01
                ELSE SUM (
                  CASE
                    WHEN a.valorDescontoSugestao < 0
                    THEN 0
                    ELSE a.valorDescontoSugestao
                  END)
              END, 2) / MAX(a.valorBaseDesconto)
        ELSE MAX(a.percentualDescontoSugestao)
      END), 8), 0) percentualDescontoSugestao,
    COALESCE (ROUND(
      CASE
        WHEN SUM (
          CASE
            WHEN a.valorDescontoSugestao < 0
            THEN 0
            ELSE a.valorDescontoSugestao
          END) >= p_pag_valorPagamentoBruto
        THEN p_pag_valorPagamentoBruto - 0.01
        ELSE SUM (
          CASE
            WHEN a.valorDescontoSugestao < 0
            THEN 0
            ELSE a.valorDescontoSugestao
          END)
      END, 2), 0) valorDescontoSugestao,
    COALESCE (ROUND(
      CASE
        WHEN SUM (
          CASE
            WHEN a.valorDescontoMaximoSemSenha < 0
            THEN 0
            ELSE a.valorDescontoMaximoSemSenha
          END) >= p_pag_valorPagamentoBruto
        THEN p_pag_valorPagamentoBruto - 0.01
        ELSE SUM (
          CASE
            WHEN a.valorDescontoMaximoSemSenha < 0
            THEN 0
            ELSE a.valorDescontoMaximoSemSenha
          END)
      END, 2), 0) valorDescontoMaximoSemSenha
  INTO
    r_possuiRegra,
    r_percentualDescontoSugestao,
    r_valorDescontoSugestao,
    r_valorDescontoMaximoSemSenha
  FROM (
    SELECT
      1 possuiRegra,
      a.valorBaseDesconto,
      a.valorDescontoItem,
      a.valorDescontoGeral,
      ROUND (
        CASE a.tipoRegraDescontoMargem
          -- Desconto em percentual
          WHEN 1
          THEN a.valorBaseRegra
          -- Desconto em valor
          WHEN 2
          THEN a.valorBaseDesconto
          -- Preço unitário fixo
          WHEN 3
          THEN a.valorBaseDesconto
          -- Desconto igual a idade em percentual
          WHEN 4
          THEN a.valorBaseRegra
          -- Desconto igual a idade em valor
          WHEN 5
          THEN a.valorBaseDesconto
          -- Preço total fixado
          WHEN 6
          THEN a.valorBaseDesconto
          ELSE 0
        END, 2) valorBaseDescontoSugestao,
      ROUND (
        CASE a.tipoRegraDescontoMargem
          -- Desconto em percentual
          WHEN 1
          THEN a.valorSugestao
          -- Desconto em valor
          WHEN 2
          THEN 100 * a.valorSugestao * a.multiplicador / a.valorBaseDesconto
          -- Preço unitário fixo
          WHEN 3
          THEN 100 * (a.valorBaseRegra-ROUND (a.quantidadeRegra*a.valorMaximoSemSenha,2)) / a.valorBaseDesconto
          -- Desconto igual a idade em percentual
          WHEN 4
          THEN a.idade
          -- Desconto igual a idade em valor
          WHEN 5
          THEN 100 * a.idade * a.multiplicador / a.valorBaseDesconto
          -- Preço total fixado
          WHEN 6
          THEN 100 * a.valorBaseRegra / a.valorBaseDesconto
          ELSE 0
        END, 8) percentualDescontoSugestao,
      ROUND (
        ( CASE a.tipoRegraDescontoMargem
            -- Desconto em percentual
            WHEN 1
            THEN a.valorBaseRegra * a.valorSugestao / 100
            -- Desconto em valor
            WHEN 2
            THEN a.valorSugestao * a.multiplicador
             -- Preço unitário fixo
            WHEN 3
            THEN a.valorBaseRegra-ROUND (a.quantidadeRegra*a.valorSugestao,2)
            -- Desconto igual a idade em percentual
            WHEN 4
            THEN a.valorBaseRegra * a.idade / 100
            -- Desconto igual a idade em valor
            WHEN 5
            THEN a.idade * a.multiplicador
            -- Preço total fixado
            WHEN 6
            THEN a.valorBaseRegra
            ELSE 0
          END
          - a.valorDescontoItem
          - a.valorDescontoGeral)
        * a.proporcaoPagamento, 2) valorDescontoSugestao,
      ROUND (
        CASE a.tipoRegraDescontoMargem
          -- Desconto em percentual
          WHEN 1
          THEN a.valorBaseRegra * a.valorMaximoSemSenha / 100
          -- Desconto em valor
          WHEN 2
          THEN a.valorMaximoSemSenha * a.multiplicador
          -- Preço unitário fixo
          WHEN 3
          THEN a.valorBaseRegra-ROUND (a.quantidadeRegra*a.valorMaximoSemSenha,2)
          -- Desconto igual a idade em percentual
          WHEN 4
          THEN a.valorBaseRegra * a.idade / 100
          -- Desconto igual a idade em valor
          WHEN 5
          THEN a.idade * a.multiplicador
          -- Preço total fixado
          WHEN 6
          THEN a.valorBaseRegra
          ELSE 0
        END * a.proporcaoPagamento, 2) valorDescontoMaximoSemSenha
    FROM (
      SELECT
        a.tipoRegraDescontoMargem,
        a.valorSugestao,
        a.valorMaximoSemSenha,
        a.idade,
        a.valorBaseDesconto,
        a.proporcaoPagamento,
        SUM(a.quantidade) quantidadeRegra,
        CASE
          WHEN SUM (a.valorBaseRegraTodos - a.valorDescontoItemTodos - a.valorDescontoGeralTodos) = 0
          THEN 0
          ELSE SUM (a.valorBaseRegra - a.valorDescontoItem - a.valorDescontoGeral)
            / SUM (a.valorBaseRegraTodos - a.valorDescontoItemTodos - a.valorDescontoGeralTodos)
        END multiplicador,
        SUM (a.valorBaseRegra) valorBaseRegra,
        SUM (a.valorDescontoItem) valorDescontoItem,
        SUM (a.valorDescontoGeral) valorDescontoGeral
      FROM (
        SELECT DISTINCT
          a.regraDescontoMargem,
          a.ordenacao,
          a.tipoRegraDescontoMargem,
          a.valorSugestao,
          a.valorMaximoSemSenha,
          a.idade,
          a.valorBaseDesconto,
          a.proporcaoPagamento,
          b.sequencia,
          b.quantidade,
          b.valorBaseRegra,
          b.valorDescontoItem,
          b.valorDescontoGeral,
          0 valorBaseRegraTodos,
          0 valorDescontoItemTodos,
          0 valorDescontoGeralTodos
        FROM REGRASVALIDAS a
        JOIN ITENS b
        ON 1=1
        WHERE a.filtrosProdutos = 0
        AND (a.filtrarTabelaPreco = 0
          OR EXISTS (
            SELECT 1
            FROM PAREGRADESCMARGXTABELASPR x
            WHERE x.regraDescontoMargem = a.regraDescontoMargem
            AND x.tabelaPreco = b.tabelaPreco
            AND x.ativo = 1))
        UNION ALL
        SELECT DISTINCT
          a.regraDescontoMargem,
          a.ordenacao,
          a.tipoRegraDescontoMargem,
          a.valorSugestao,
          a.valorMaximoSemSenha,
          a.idade,
          a.valorBaseDesconto,
          a.proporcaoPagamento,
          b.sequencia,
          b.quantidade,
          b.valorBaseRegra,
          b.valorDescontoItem,
          b.valorDescontoGeral,
          0 valorBaseRegraTodos,
          0 valorDescontoItemTodos,
          0 valorDescontoGeralTodos
        FROM REGRASVALIDAS a
        JOIN REGRASXITENS b
        ON b.regraDescontoMargem = a.regraDescontoMargem
        WHERE a.filtrosProdutos > 0
        UNION ALL
        SELECT DISTINCT
          a.regraDescontoMargem,
          a.ordenacao,
          a.tipoRegraDescontoMargem,
          a.valorSugestao,
          a.valorMaximoSemSenha,
          a.idade,
          a.valorBaseDesconto,
          a.proporcaoPagamento,
          b.sequencia,
          b.quantidade,
          0 valorBaseRegra,
          0 valorDescontoItem,
          0 valorDescontoGeral,
          b.valorBaseRegra valorBaseRegraTodos,
          b.valorDescontoItem valorDescontoItemTodos,
          b.valorDescontoGeral valorDescontoGeralTodos
        FROM REGRASVALIDAS a
        JOIN ITENS b
        ON 1=1) a
      GROUP BY
        a.regraDescontoMargem,
        a.ordenacao,
        a.tipoRegraDescontoMargem,
        a.valorSugestao,
        a.valorMaximoSemSenha,
        a.idade,
        a.valorBaseDesconto,
        a.proporcaoPagamento) a) a;
END ADD_PRE_DOC_REGRA_DESC_PAG;

/

create or replace PROCEDURE ADD_DOC_FISC_REGRA_DESC_PAG (
  p_usuarioLogado                IN NUMBER,
  p_perfilUsuarioLogado          IN NUMBER,
  p_config_227_manterPessoaOrcam IN NUMBER,
  p_config_246_baseDescontoPagam IN CHAR,
  p_config_337_descontoSobreFret IN NUMBER,
  p_idDocumentoFiscal            IN NUMBER,
  p_soma_valorPagamentoBruto     IN NUMBER,
  p_orc_pessoa                   IN NUMBER,
  p_pag_meioPagamento            IN NUMBER,
  p_pag_condicaoPagamento        IN NUMBER,
  p_pag_valorPagamentoBruto      IN NUMBER,
  /* Retornos */
  r_possuiRegra                  OUT NUMBER,
  r_percentualDescontoSugestao   OUT NUMBER,
  r_valorDescontoSugestao        OUT NUMBER,
  r_valorDescontoMaximoSemSenha  OUT NUMBER)
IS
BEGIN
  WITH
  CABECALHO AS (
    SELECT
      a.estabelecimento,
      a.pessoa,
      COALESCE((
        CASE
          WHEN a.pessoa = 0
          THEN (
            SELECT MAX(munPess.uf)
            FROM CAENDERECOSPESSOA endPess
            JOIN SIMUNICIPIOS munPess
            ON munPess.municipio = endPess.municipio
            WHERE endPess.pessoa = est.pessoaEstabelecimento
            AND endPess.ativo = 1
            AND endPess.principal = 1)
          ELSE COALESCE((
            SELECT MAX(munPess.uf)
            FROM CAENDERECOSPESSOA endPess
            JOIN SIMUNICIPIOS munPess
            ON munPess.municipio = endPess.municipio
            WHERE endPess.pessoa = a.pessoa
            AND endPess.ativo = 1
            AND endPess.principal = 1),(
            SELECT MAX(munPess.uf)
            FROM CAENDERECOSPESSOA endPess
            JOIN SIMUNICIPIOS munPess
            ON munPess.municipio = endPess.municipio
            WHERE endPess.pessoa = est.pessoaEstabelecimento
            AND endPess.ativo = 1
            AND endPess.principal = 1))
        END
      ),'  ') uf,
      CASE
        WHEN pess.nascimentoFundacao IS NULL
          OR TRUNC (pess.nascimentoFundacao) > TRUNC (SYSDATE)
        THEN 0
        ELSE TRUNC (SYSDATE, 'YYYY')
          - TRUNC (pess.nascimentoFundacao, 'YYYY')
          - CASE
              WHEN TO_CHAR (SYSDATE, 'MMDD') < TO_CHAR (pess.nascimentoFundacao, 'MMDD')
              THEN 1
              ELSE 0
            END
      END idade,
      CASE
        WHEN p_config_246_baseDescontoPagam = 'S'
        THEN a.valorBasePagamento
          - CASE
              WHEN p_config_337_descontoSobreFret = 1
                OR a.tipoPagamentoFrete = 'V'
              THEN 0
              ELSE a.valorFreteTotal + a.valorSeguroTotal
            END
        WHEN p_soma_valorPagamentoBruto >= a.valorBasePagamento
        THEN 0
        WHEN p_soma_valorPagamentoBruto + p_pag_valorPagamentoBruto > a.valorBasePagamento
        THEN a.valorBasePagamento - p_soma_valorPagamentoBruto
          - CASE
              WHEN p_config_337_descontoSobreFret = 1
                OR a.tipoPagamentoFrete = 'V'
              THEN 0
              ELSE ROUND (
                (a.valorFreteTotal + a.valorSeguroTotal)
                * (a.valorBasePagamento - p_soma_valorPagamentoBruto)
                / a.valorBasePagamento,2)
            END
        ELSE p_pag_valorPagamentoBruto
          - CASE
              WHEN p_config_337_descontoSobreFret = 1
                OR a.tipoPagamentoFrete = 'V'
              THEN 0
              ELSE ROUND (
                (a.valorFreteTotal + a.valorSeguroTotal)
                * p_pag_valorPagamentoBruto
                / a.valorBasePagamento,2)
            END
      END valorBaseDesconto,
      ( CASE
          WHEN p_soma_valorPagamentoBruto >= a.valorBasePagamento
          THEN 0
          WHEN p_soma_valorPagamentoBruto + p_pag_valorPagamentoBruto > a.valorBasePagamento
          THEN a.valorBasePagamento - p_soma_valorPagamentoBruto
          ELSE p_pag_valorPagamentoBruto
        END
        / a.valorBasePagamento) proporcaoPagamento
    FROM (
      SELECT
        a.estabelecimento,
        CASE
          WHEN p_orc_pessoa = 0
            OR p_config_227_manterPessoaOrcam = 1
          THEN a.pessoa
          ELSE p_orc_pessoa
        END pessoa,
        a.valorBasePagamento,
        a.tipoPagamentoFrete,
        a.valorFreteTotal,
        a.valorSeguroTotal
      FROM MODOCUMENTOSFISCAIS a
      WHERE a.idDocumentoFiscal = p_idDocumentoFiscal
      AND a.valorBasePagamento > 0) a
    JOIN PAESTABELECIMENTOS est
    ON est.estabelecimento = a.estabelecimento
    JOIN CAPESSOAS pess
    ON pess.pessoa = a.pessoa),
  ITENS AS (
    SELECT
      a.sequencia,
      a.vendedor,
      a.gradeProduto,
      a.localEstoque,
      a.personalizacao,
      a.quantidade,
      ROUND (a.quantidade * (a.precoUnitarioBruto + a.acrescimoUnitarioComposicao),2) valorBaseRegra,
      a.valorDescontoItem,
      a.valorDescontoGeral,
      a.tabelaPreco,
      gradProd.produto,
      gradProd.cor,
      gradProd.tamanho,
      prod.subcategoriaProduto,
      prod.marca,
      prod.caracteristicaA,
      prod.caracteristicaB,
      prod.caracteristicaC,
      prod.caracteristicaD,
      prod.caracteristicaE,
      prod.idNcm,
      prod.listaServicos,
      subCatProd.categoriaProduto
    FROM MODOCFISCALXITENS a
    JOIN CAGRADESPRODUTO gradProd
    ON gradProd.gradeProduto = a.gradeProduto
    JOIN CAPRODUTOS prod
    ON prod.produto = gradProd.produto
    JOIN PASUBCATEGORIASPRODUTO subCatProd
    ON subCatProd.subCategoriaProduto = prod.subCategoriaProduto
    WHERE a.idDocumentoFiscal = p_idDocumentoFiscal
    AND a.cancelado = 0
    AND a.quantidade > 0),
  REGRAS AS (
    SELECT
      a.regraDescontoMargem,
      a.ordenacao,
      a.tipoRegraDescontoMargem,
      a.valorSugestao,
      a.valorMaximoSemSenha,
      a.filtrarTabelaPreco,
      cab.idade,
      cab.valorBaseDesconto,
      cab.proporcaoPagamento
    FROM PAREGRASDESCONTOSMARGEM a
    JOIN CABECALHO cab
    ON 1=1
    JOIN PAFILTROSCABECALHO filtroCab
    ON filtroCab.filtroCabecalho = a.filtroCabecalho
    JOIN CAPESSOAS pess
    ON pess.pessoa = cab.pessoa
    JOIN PAFILTROSPAGAMENTO filtroPag
    ON filtroPag.filtroPagamento = a.filtroPagamento
    WHERE a.regraDescontoMargem > 0
    AND a.ativo = 1
    AND a.dataValidadeInicial <= TRUNC(SYSDATE)
    AND a.dataValidadeFinal >= TRUNC(SYSDATE)
    AND a.cabecalhoItemPagamento = 'P'
    AND a.tipoRegraDescontoMargem BETWEEN 1 AND 6
    -- Filtro Cabeçalho
    AND (a.filtroCabecalho = 0
      OR (filtroCab.filtrarEstabelecimentos = 0
        OR EXISTS (
          SELECT 1
          FROM PAFILTROCABECXESTABELEC filtroCabX
          WHERE filtroCabX.filtroCabecalho = a.filtroCabecalho
          AND filtroCabX.estabelecimento = cab.estabelecimento
          AND filtroCabX.ativo = 1))
      AND (filtroCab.filtrarUfs = 0
        OR EXISTS (
          SELECT 1
          FROM PAFILTROCABECXUFS filtroCabX
          WHERE filtroCabX.filtroCabecalho = a.filtroCabecalho
          AND filtroCabX.uf = cab.uf
          AND filtroCabX.ativo = 1))
      AND (filtroCab.filtrarPessoas = 0
        OR EXISTS (
          SELECT 1
          FROM PAFILTROCABECXPESSOAS filtroCabX
          WHERE filtroCabX.filtroCabecalho = a.filtroCabecalho
          AND filtroCabX.pessoa = cab.pessoa
          AND filtroCabX.ativo = 1))
      AND (filtroCab.filtrarPerfisUsuario = 0
        AND filtroCab.filtrarUsuarios = 0
        OR filtroCab.filtrarPerfisUsuario = 1
        AND EXISTS (
          SELECT 1
          FROM PAFILTROCABECXPERFISUSUAR filtroCabX
          WHERE filtroCabX.filtroCabecalho = a.filtroCabecalho
          AND filtroCabX.perfilUsuario = p_perfilUsuarioLogado
          AND filtroCabX.ativo = 1)
        OR filtroCab.filtrarUsuarios = 1
        AND EXISTS (
          SELECT 1
          FROM PAFILTROCABECXUSUARIOS filtroCabX
          WHERE filtroCabX.filtroCabecalho = a.filtroCabecalho
          AND filtroCabX.usuario = p_usuarioLogado
          AND filtroCabX.ativo = 1))
      AND (filtroCab.indicadorPessoa = ' '
        OR filtroCab.indicadorPessoa = pess.indicadorPessoa)
      AND (filtroCab.colaborador = ' '
        OR filtroCab.colaborador = 'N'
        AND (cab.pessoa = 0
          OR NOT (EXISTS (
            SELECT 1
            FROM CACOLABORADORES colab
            WHERE colab.colaborador = cab.pessoa
            AND colab.ativo = 1 )))
        OR filtroCab.colaborador = 'S'
        AND cab.pessoa <> 0
        AND EXISTS (
          SELECT 1
          FROM CACOLABORADORES colab
          WHERE colab.colaborador = cab.pessoa
          AND colab.ativo = 1)))
    -- Filtro Pagamento
    AND (a.filtroPagamento = 0
      OR (filtroPag.filtrarMeiosPagamento = 0
        OR EXISTS (
          SELECT 1
          FROM PAFILTROPAGAMENTOXMEIOPAG filtroPagX
          WHERE filtroPagX.filtroPagamento = a.filtroPagamento
          AND filtroPagX.meioPagamento = p_pag_meioPagamento
          AND filtroPagX.ativo = 1))
      AND (filtroPag.filtrarCondicoesPagamento = 0
        OR EXISTS (
          SELECT 1
          FROM PAFILTROPAGAMENTOXCONDPAG filtroPagX
          WHERE filtroPagX.filtroPagamento = a.filtroPagamento
          AND filtroPagX.condicaoPagamento = p_pag_condicaoPagamento
          AND filtroPagX.ativo = 1)))),
  FILTROSPRODUTOS AS (
    SELECT
      a.regraDescontoMargem,
      a.filtroProduto,
      b.quantidadeMinima,
      b.quantidadeMaxima,
      b.filtrarVendedores,
      b.filtrarLocaisEstoque,
      b.filtrarPersonalizacoes,
      b.filtrarProdutos,
      b.filtrarCategoriasProdutos,
      b.filtrarSubcategoriasProdutos,
      b.filtrarMarcas,
      b.filtrarCaracteristicasA,
      b.filtrarCaracteristicasB,
      b.filtrarCaracteristicasC,
      b.filtrarCaracteristicasD,
      b.filtrarCaracteristicasE,
      b.filtrarCores,
      b.filtrarTamanhos,
      b.filtrarNCMs,
      b.filtrarListasServicos,
      c.filtrarTabelaPreco
    FROM PAREGRADESCMARGXFILTPROD a
    JOIN PAFILTROSPRODUTO b
    ON b.filtroProduto = a.filtroProduto
    JOIN REGRAS c
    ON c.regraDescontoMargem = a.regraDescontoMargem
    AND a.filtroProduto > 0
    AND a.ativo = 1),
  REGRASXITENS AS (
    SELECT
      a.regraDescontoMargem,
      a.filtroProduto,
      a.quantidadeMinima,
      a.quantidadeMaxima,
      b.sequencia,
      b.quantidade,
      b.valorBaseRegra,
      b.valorDescontoItem,
      b.valorDescontoGeral
    FROM FILTROSPRODUTOS a
    JOIN ITENS b
	  ON 1=1
    WHERE (a.filtrarTabelaPreco = 0
      OR EXISTS (
        SELECT 1
        FROM PAREGRADESCMARGXTABELASPR x
        WHERE x.regraDescontoMargem = a.regraDescontoMargem
        AND x.tabelaPreco = b.tabelaPreco
        AND x.ativo = 1))
    AND (a.filtrarVendedores = 0
    OR EXISTS (
      SELECT 1
      FROM PAFILTROPRODUTOXVENDEDOR x
      WHERE x.filtroProduto = a.filtroProduto
      AND x.vendedor = b.vendedor
      AND x.ativo = 1))
    AND (a.filtrarLocaisEstoque = 0
    OR EXISTS (
      SELECT 1
      FROM PAFILTROPRODUTOXLOCAISEST x
      WHERE x.filtroProduto = a.filtroProduto
      AND x.localEstoque = b.localEstoque
      AND x.ativo = 1))
    AND (a.filtrarPersonalizacoes = 0
    OR EXISTS (
      SELECT 1
      FROM PAFILTROPRODUTOXPERSONAL x
      WHERE x.filtroProduto = a.filtroProduto
      AND x.personalizacao = b.personalizacao
      AND x.ativo = 1))
    AND (a.filtrarProdutos = 0
      AND a.filtrarCategoriasProdutos = 0
      AND a.filtrarSubcategoriasProdutos = 0
      AND a.filtrarMarcas = 0
      AND a.filtrarCaracteristicasA = 0
      AND a.filtrarCaracteristicasB = 0
      AND a.filtrarCaracteristicasC = 0
      AND a.filtrarCaracteristicasD = 0
      AND a.filtrarCaracteristicasE = 0
      AND a.filtrarCores = 0
      AND a.filtrarTamanhos = 0
      AND a.filtrarNCMs = 0
      AND a.filtrarListasServicos = 0
      OR a.filtrarProdutos = 1
      AND EXISTS (
        SELECT 1
        FROM PAFILTROPRODUTOXPRODUTOS x
        WHERE x.filtroProduto = a.filtroProduto
        AND x.produto = b.produto
        AND x.ativo = 1)
      OR (a.filtrarCategoriasProdutos = 1
        OR a.filtrarSubcategoriasProdutos = 1
        OR a.filtrarMarcas = 1
        OR a.filtrarCaracteristicasA = 1
        OR a.filtrarCaracteristicasB = 1
        OR a.filtrarCaracteristicasC = 1
        OR a.filtrarCaracteristicasD = 1
        OR a.filtrarCaracteristicasE = 1
        OR a.filtrarCores = 1
        OR a.filtrarTamanhos = 1
        OR a.filtrarNCMs = 1
        OR a.filtrarListasServicos = 1)
      AND (a.filtrarCategoriasProdutos = 0
        OR EXISTS (
          SELECT 1
          FROM PAFILTROPRODUTOXCATEGPROD x
          WHERE x.filtroProduto = a.filtroProduto
          AND x.categoriaProduto = b.categoriaProduto
          AND x.ativo = 1))
      AND (a.filtrarSubcategoriasProdutos = 0
        OR EXISTS (
          SELECT 1
          FROM PAFILTROPRODUTOXSUBCAPROD x
          WHERE x.filtroProduto = a.filtroProduto
          AND x.subcategoriaProduto = b.subcategoriaProduto
          AND x.ativo = 1))
      AND (a.filtrarMarcas = 0
        OR EXISTS (
          SELECT 1
          FROM PAFILTROPRODUTOXMARCAS x
          WHERE x.filtroProduto = a.filtroProduto
          AND x.marca = b.marca
          AND x.ativo = 1))
      AND (a.filtrarCaracteristicasA = 0
        OR EXISTS (
          SELECT 1
          FROM PAFILTROPRODUTOXCARACTERA x
          WHERE x.filtroProduto = a.filtroProduto
          AND x.caracteristicaA = b.caracteristicaA
          AND x.ativo = 1))
      AND (a.filtrarCaracteristicasB = 0
        OR EXISTS (
          SELECT 1
          FROM PAFILTROPRODUTOXCARACTERB x
          WHERE x.filtroProduto = a.filtroProduto
          AND x.caracteristicaB = b.caracteristicaB
          AND x.ativo = 1))
      AND (a.filtrarCaracteristicasC = 0
        OR EXISTS (
          SELECT 1
          FROM PAFILTROPRODUTOXCARACTERC x
          WHERE x.filtroProduto = a.filtroProduto
          AND x.caracteristicaC = b.caracteristicaC
          AND x.ativo = 1))
      AND (a.filtrarCaracteristicasD = 0
        OR EXISTS (
          SELECT 1
          FROM PAFILTROPRODUTOXCARACTERD x
          WHERE x.filtroProduto = a.filtroProduto
          AND x.caracteristicaD = b.caracteristicaD
          AND x.ativo = 1))
      AND (a.filtrarCaracteristicasE = 0
        OR EXISTS (
          SELECT 1
          FROM PAFILTROPRODUTOXCARACTERE x
          WHERE x.filtroProduto = a.filtroProduto
          AND x.caracteristicaE = b.caracteristicaE
          AND x.ativo = 1))
      AND (a.filtrarCores = 0
        OR EXISTS (
          SELECT 1
          FROM PAFILTROPRODUTOXCORES x
          WHERE x.filtroProduto = a.filtroProduto
          AND x.cor = b.cor
          AND x.ativo = 1))
      AND (a.filtrarTamanhos = 0
        OR EXISTS (
          SELECT 1
          FROM PAFILTROPRODUTOXTAMANHOS x
          WHERE x.filtroProduto = a.filtroProduto
          AND x.tamanho = b.tamanho
          AND x.ativo = 1))
      AND (a.filtrarNCMs = 0
        OR EXISTS (
          SELECT 1
          FROM PAFILTROPRODUTOXNCMS x
          WHERE x.filtroProduto = a.filtroProduto
          AND x.idNcm = b.idNcm
          AND x.ativo = 1))
      AND (a.filtrarListasServicos = 0
        OR EXISTS (
          SELECT 1
          FROM PAFILTROPRODUTOXLISTASSE x
          WHERE x.filtroProduto = a.filtroProduto
          AND x.listaServicos = b.listaServicos
          AND x.ativo = 1)))),
  REGRASXFILTROS AS (
    SELECT
      a.regraDescontoMargem,
      a.filtroProduto
    FROM (
      SELECT
        a.regraDescontoMargem,
        a.filtroProduto,
        a.quantidadeMinima,
        a.quantidadeMaxima,
        SUM (a.quantidade) quantidade
      FROM REGRASXITENS a
      GROUP BY
        a.regraDescontoMargem,
        a.filtroProduto,
        a.quantidadeMinima,
        a.quantidadeMaxima) a
    WHERE a.quantidade >= a.quantidadeMinima
    AND (a.quantidadeMaxima = 0
      OR a.quantidade <= a.quantidadeMaxima)),
  REGRASVALIDAS AS (
    SELECT
      a.regraDescontoMargem,
      a.ordenacao,
      a.tipoRegraDescontoMargem,
      a.valorSugestao,
      a.valorMaximoSemSenha,
      a.filtrarTabelaPreco,
      a.idade,
      a.valorBaseDesconto,
      a.proporcaoPagamento,
      COALESCE((
        SELECT COUNT(1)
        FROM FILTROSPRODUTOS b
        WHERE b.regraDescontoMargem = a.regraDescontoMargem),0) filtrosProdutos
    FROM REGRAS a
    WHERE
      ( SELECT COUNT(1)
        FROM FILTROSPRODUTOS b
        WHERE b.regraDescontoMargem = a.regraDescontoMargem)
    = ( SELECT COUNT(1)
        FROM REGRASXFILTROS b
        WHERE b.regraDescontoMargem = a.regraDescontoMargem))
  SELECT
    COALESCE (MAX(a.possuiRegra), 0) possuiRegra,
    COALESCE (ROUND((
      CASE
        WHEN MIN (a.valorDescontoSugestao) < 0
          OR SUM (
          CASE
            WHEN a.valorDescontoSugestao < 0
            THEN 0
            ELSE a.valorDescontoSugestao
          END) >= p_pag_valorPagamentoBruto
          OR SUM(a.valorBaseDescontoSugestao) <> MAX(a.valorBaseDesconto)
          OR SUM(a.valorDescontoItem) <> 0
          OR SUM(a.valorDescontoGeral) <> 0
          OR SUM(a.possuiRegra) > 1
        THEN 100
          * ROUND(
              CASE
                WHEN SUM (
                  CASE
                    WHEN a.valorDescontoSugestao < 0
                    THEN 0
                    ELSE a.valorDescontoSugestao
                  END) >= p_pag_valorPagamentoBruto
                THEN p_pag_valorPagamentoBruto - 0.01
                ELSE SUM (
                  CASE
                    WHEN a.valorDescontoSugestao < 0
                    THEN 0
                    ELSE a.valorDescontoSugestao
                  END)
              END, 2) / MAX(a.valorBaseDesconto)
        ELSE MAX(a.percentualDescontoSugestao)
      END), 8), 0) percentualDescontoSugestao,
    COALESCE (ROUND(
      CASE
        WHEN SUM (
          CASE
            WHEN a.valorDescontoSugestao < 0
            THEN 0
            ELSE a.valorDescontoSugestao
          END) >= p_pag_valorPagamentoBruto
        THEN p_pag_valorPagamentoBruto - 0.01
        ELSE SUM (
          CASE
            WHEN a.valorDescontoSugestao < 0
            THEN 0
            ELSE a.valorDescontoSugestao
          END)
      END, 2), 0) valorDescontoSugestao,
    COALESCE (ROUND(
      CASE
        WHEN SUM (
          CASE
            WHEN a.valorDescontoMaximoSemSenha < 0
            THEN 0
            ELSE a.valorDescontoMaximoSemSenha
          END) >= p_pag_valorPagamentoBruto
        THEN p_pag_valorPagamentoBruto - 0.01
        ELSE SUM (
          CASE
            WHEN a.valorDescontoMaximoSemSenha < 0
            THEN 0
            ELSE a.valorDescontoMaximoSemSenha
          END)
      END, 2), 0) valorDescontoMaximoSemSenha
  INTO
    r_possuiRegra,
    r_percentualDescontoSugestao,
    r_valorDescontoSugestao,
    r_valorDescontoMaximoSemSenha
  FROM (
    SELECT
      1 possuiRegra,
      a.valorBaseDesconto,
      a.valorDescontoItem,
      a.valorDescontoGeral,
      ROUND (
        CASE a.tipoRegraDescontoMargem
          -- Desconto em percentual
          WHEN 1
          THEN a.valorBaseRegra
          -- Desconto em valor
          WHEN 2
          THEN a.valorBaseDesconto
          -- Preço unitário fixo
          WHEN 3
          THEN a.valorBaseDesconto
          -- Desconto igual a idade em percentual
          WHEN 4
          THEN a.valorBaseRegra
          -- Desconto igual a idade em valor
          WHEN 5
          THEN a.valorBaseDesconto
          -- Preço total fixado
          WHEN 6
          THEN a.valorBaseDesconto
          ELSE 0
        END, 2) valorBaseDescontoSugestao,
      ROUND (
        CASE a.tipoRegraDescontoMargem
          -- Desconto em percentual
          WHEN 1
          THEN a.valorSugestao
          -- Desconto em valor
          WHEN 2
          THEN 100 * a.valorSugestao * a.multiplicador / a.valorBaseDesconto
          -- Preço unitário fixo
          WHEN 3
          THEN 100 * (a.valorBaseRegra-ROUND (a.quantidadeRegra*a.valorMaximoSemSenha,2)) / a.valorBaseDesconto
          -- Desconto igual a idade em percentual
          WHEN 4
          THEN a.idade
          -- Desconto igual a idade em valor
          WHEN 5
          THEN 100 * a.idade * a.multiplicador / a.valorBaseDesconto
          -- Preço total fixado
          WHEN 6
          THEN 100 * a.valorBaseRegra / a.valorBaseDesconto
          ELSE 0
        END, 8) percentualDescontoSugestao,
      ROUND (
        ( CASE a.tipoRegraDescontoMargem
            -- Desconto em percentual
            WHEN 1
            THEN a.valorBaseRegra * a.valorSugestao / 100
            -- Desconto em valor
            WHEN 2
            THEN a.valorSugestao * a.multiplicador
             -- Preço unitário fixo
            WHEN 3
            THEN a.valorBaseRegra-ROUND (a.quantidadeRegra*a.valorSugestao,2)
            -- Desconto igual a idade em percentual
            WHEN 4
            THEN a.valorBaseRegra * a.idade / 100
            -- Desconto igual a idade em valor
            WHEN 5
            THEN a.idade * a.multiplicador
            -- Preço total fixado
            WHEN 6
            THEN a.valorBaseRegra
            ELSE 0
          END
          - a.valorDescontoItem
          - a.valorDescontoGeral)
        * a.proporcaoPagamento, 2) valorDescontoSugestao,
      ROUND (
        CASE a.tipoRegraDescontoMargem
          -- Desconto em percentual
          WHEN 1
          THEN a.valorBaseRegra * a.valorMaximoSemSenha / 100
          -- Desconto em valor
          WHEN 2
          THEN a.valorMaximoSemSenha * a.multiplicador
          -- Preço unitário fixo
          WHEN 3
          THEN a.valorBaseRegra-ROUND (a.quantidadeRegra*a.valorMaximoSemSenha,2)
          -- Desconto igual a idade em percentual
          WHEN 4
          THEN a.valorBaseRegra * a.idade / 100
          -- Desconto igual a idade em valor
          WHEN 5
          THEN a.idade * a.multiplicador
          -- Preço total fixado
          WHEN 6
          THEN a.valorBaseRegra
          ELSE 0
        END * a.proporcaoPagamento, 2) valorDescontoMaximoSemSenha
    FROM (
      SELECT
        a.tipoRegraDescontoMargem,
        a.valorSugestao,
        a.valorMaximoSemSenha,
        a.idade,
        a.valorBaseDesconto,
        a.proporcaoPagamento,
        SUM(a.quantidade) quantidadeRegra,
        CASE
          WHEN SUM (a.valorBaseRegraTodos - a.valorDescontoItemTodos - a.valorDescontoGeralTodos) = 0
          THEN 0
          ELSE SUM (a.valorBaseRegra - a.valorDescontoItem - a.valorDescontoGeral)
            / SUM (a.valorBaseRegraTodos - a.valorDescontoItemTodos - a.valorDescontoGeralTodos)
        END multiplicador,
        SUM (a.valorBaseRegra) valorBaseRegra,
        SUM (a.valorDescontoItem) valorDescontoItem,
        SUM (a.valorDescontoGeral) valorDescontoGeral
      FROM (
        SELECT DISTINCT
          a.regraDescontoMargem,
          a.ordenacao,
          a.tipoRegraDescontoMargem,
          a.valorSugestao,
          a.valorMaximoSemSenha,
          a.idade,
          a.valorBaseDesconto,
          a.proporcaoPagamento,
          b.sequencia,
          b.quantidade,
          b.valorBaseRegra,
          b.valorDescontoItem,
          b.valorDescontoGeral,
          0 valorBaseRegraTodos,
          0 valorDescontoItemTodos,
          0 valorDescontoGeralTodos
        FROM REGRASVALIDAS a
        JOIN ITENS b
        ON 1=1
        WHERE a.filtrosProdutos = 0
        AND (a.filtrarTabelaPreco = 0
          OR EXISTS (
            SELECT 1
            FROM PAREGRADESCMARGXTABELASPR x
            WHERE x.regraDescontoMargem = a.regraDescontoMargem
            AND x.tabelaPreco = b.tabelaPreco
            AND x.ativo = 1))
        UNION ALL
        SELECT DISTINCT
          a.regraDescontoMargem,
          a.ordenacao,
          a.tipoRegraDescontoMargem,
          a.valorSugestao,
          a.valorMaximoSemSenha,
          a.idade,
          a.valorBaseDesconto,
          a.proporcaoPagamento,
          b.sequencia,
          b.quantidade,
          b.valorBaseRegra,
          b.valorDescontoItem,
          b.valorDescontoGeral,
          0 valorBaseRegraTodos,
          0 valorDescontoItemTodos,
          0 valorDescontoGeralTodos
        FROM REGRASVALIDAS a
        JOIN REGRASXITENS b
        ON b.regraDescontoMargem = a.regraDescontoMargem
        WHERE a.filtrosProdutos > 0
        UNION ALL
        SELECT DISTINCT
          a.regraDescontoMargem,
          a.ordenacao,
          a.tipoRegraDescontoMargem,
          a.valorSugestao,
          a.valorMaximoSemSenha,
          a.idade,
          a.valorBaseDesconto,
          a.proporcaoPagamento,
          b.sequencia,
          b.quantidade,
          0 valorBaseRegra,
          0 valorDescontoItem,
          0 valorDescontoGeral,
          b.valorBaseRegra valorBaseRegraTodos,
          b.valorDescontoItem valorDescontoItemTodos,
          b.valorDescontoGeral valorDescontoGeralTodos
        FROM REGRASVALIDAS a
        JOIN ITENS b
        ON 1=1) a
      GROUP BY
        a.regraDescontoMargem,
        a.ordenacao,
        a.tipoRegraDescontoMargem,
        a.valorSugestao,
        a.valorMaximoSemSenha,
        a.idade,
        a.valorBaseDesconto,
        a.proporcaoPagamento) a) a;
END ADD_DOC_FISC_REGRA_DESC_PAG;

/

UPDATE SIUFS SET
  urlConsultaNFCeProducao = 'https://sat.sef.sc.gov.br/nfce/consulta',
  urlConsultaNFCeHomologacao = 'https://hom.sat.sef.sc.gov.br/nfce/consulta',
  urlQrCodeNFCeProducao = 'https://sat.sef.sc.gov.br/nfce/consulta',
  urlQrCodeNFCeHomologacao = 'https://hom.sat.sef.sc.gov.br/nfce/consulta'
WHERE UF = 'SC';

COMMIT;


create or replace PROCEDURE ADD_BUSCA_REGRA_DESCONTO_ITEM (
  p_usuarioLogado                IN NUMBER,
  p_perfilUsuarioLogado          IN NUMBER,
  p_config_227_manterPessoaOrcam IN NUMBER,
  p_cab_entradaSaida             IN CHAR,
  p_cab_devolucaoAnulacaoRetorno IN NUMBER,
  p_cab_estabelecimento          IN NUMBER,
  p_cab_pessoa                   IN NUMBER,
  p_orc_pessoa                   IN NUMBER,
  p_item_modeloDocumento         IN NUMBER,
  p_item_vendedor                IN NUMBER,
  p_item_gradeProduto            IN NUMBER,
  p_item_personalizacao          IN NUMBER,
  p_item_localEstoque            IN NUMBER,
  p_item_quantidade              IN NUMBER,
  p_item_tabelaPreco             IN VARCHAR2,
  p_item_valorProdutoServicoBrut IN NUMBER,
  p_item_valorProdutoServico     IN NUMBER,
  /* Retornos */
  r_possuiRegra                  OUT NUMBER,
  r_percentualDescontoSugestao   OUT NUMBER,
  r_valorDescontoSugestao        OUT NUMBER,
  r_valorDescontoMaximoSemSenha  OUT NUMBER)
IS
  v_pessoa              NUMBER;
  v_indicadorPessoa     CHAR(1);
  v_idade               NUMBER;
  v_uf                  CHAR(2);
  v_produto             NUMBER;
  v_cor                 NUMBER;
  v_tamanho             VARCHAR2(10);
  v_categoriaProduto    NUMBER;
  v_subcategoriaProduto NUMBER;
  v_marca               NUMBER;
  v_caracteristicaA     NUMBER;
  v_caracteristicaB     NUMBER;
  v_caracteristicaC     NUMBER;
  v_caracteristicaD     NUMBER;
  v_caracteristicaE     NUMBER;
  v_idNcm               NUMBER;
  v_listaServicos       NUMBER;
  v_baseDesconto        NUMBER;
BEGIN
  SELECT
    pess.pessoa,
    pess.indicadorPessoa,
    CASE
      WHEN pess.nascimentoFundacao IS NULL
        OR TRUNC (pess.nascimentoFundacao) > TRUNC (SYSDATE)
      THEN 0
      ELSE TRUNC (SYSDATE, 'YYYY')
        - TRUNC (pess.nascimentoFundacao, 'YYYY')
        - CASE
            WHEN TO_CHAR (SYSDATE, 'MMDD') < TO_CHAR (pess.nascimentoFundacao, 'MMDD')
            THEN 1
            ELSE 0
          END
    END idade,
    COALESCE((
      CASE
        WHEN pess.pessoa = 0
        THEN (
          SELECT MAX(munPess.uf)
          FROM PAESTABELECIMENTOS est
          JOIN CAENDERECOSPESSOA endPess
          ON endPess.pessoa = est.pessoaEstabelecimento
          JOIN SIMUNICIPIOS munPess
          ON munPess.municipio = endPess.municipio
          WHERE est.estabelecimento = p_cab_estabelecimento
          AND endPess.ativo = 1
          AND endPess.principal = 1)
        ELSE COALESCE((
          SELECT MAX(munPess.uf)
          FROM CAENDERECOSPESSOA endPess
          JOIN SIMUNICIPIOS munPess
          ON munPess.municipio = endPess.municipio
          WHERE endPess.pessoa = pess.pessoa
          AND endPess.ativo = 1
          AND endPess.principal = 1),(
          SELECT MAX(munPess.uf)
          FROM PAESTABELECIMENTOS est
          JOIN CAENDERECOSPESSOA endPess
          ON endPess.pessoa = est.pessoaEstabelecimento
          JOIN SIMUNICIPIOS munPess
          ON munPess.municipio = endPess.municipio
          WHERE est.estabelecimento = p_cab_estabelecimento
          AND endPess.ativo = 1
          AND endPess.principal = 1))
      END),'  ') uf
  INTO
    v_pessoa,
    v_indicadorPessoa,
    v_idade,
    v_uf
  FROM CAPESSOAS pess
  WHERE pess.pessoa =
    CASE
      WHEN p_orc_pessoa = 0
        OR p_config_227_manterPessoaOrcam = 1
      THEN p_cab_pessoa
      ELSE p_orc_pessoa
    END;
  SELECT
    gradProd.produto,
    gradProd.cor,
    gradProd.tamanho,
    subCatProd.categoriaProduto,
    prod.subcategoriaProduto,
    prod.marca,
    prod.caracteristicaA,
    prod.caracteristicaB,
    prod.caracteristicaC,
    prod.caracteristicaD,
    prod.caracteristicaE,
    prod.idNcm,
    prod.listaServicos,
    CASE
      WHEN modDoc.diminuiDescontoPrUnit= 1
        OR modDoc.somaAcrescimosPrUnit = 1
        OR modDoc.somaFreteSeguroPrUnit = 1
        OR p_cab_entradaSaida =
          CASE
            WHEN p_cab_devolucaoAnulacaoRetorno = 1
            THEN 'E'
            ELSE 'S'
          END
        AND EXISTS (
          SELECT 1
          FROM CAPRODUTOXCOMPOSICOESPREC compPres
          WHERE compPres.produto = gradProd.produto
          AND compPres.ativo = 1)
      THEN p_item_valorProdutoServicoBrut
      ELSE p_item_valorProdutoServico
    END baseDesconto
  INTO
    v_produto,
    v_cor,
    v_tamanho,
    v_categoriaProduto,
    v_subcategoriaProduto,
    v_marca,
    v_caracteristicaA,
    v_caracteristicaB,
    v_caracteristicaC,
    v_caracteristicaD,
    v_caracteristicaE,
    v_idNcm,
    v_listaServicos,
    v_baseDesconto
  FROM CAGRADESPRODUTO gradProd
  JOIN CAPRODUTOS prod
  ON prod.produto = gradProd.produto
  JOIN PASUBCATEGORIASPRODUTO subCatProd
  ON subCatProd.subCategoriaProduto = prod.subCategoriaProduto
  JOIN PAMODELOSDOCUMENTO modDoc
  ON modDoc.modeloDocumento = p_item_modeloDocumento
  WHERE gradProd.gradeProduto = p_item_gradeProduto;
  SELECT
    COALESCE (MAX(a.possuiRegra), 0) possuiRegra,
    COALESCE (ROUND((
      CASE
        WHEN SUM (
            CASE
              WHEN a.valorDescontoSugestao < 0
              THEN 0
              ELSE a.valorDescontoSugestao
            END) >= v_baseDesconto
        THEN 100
        WHEN MIN (a.valorDescontoSugestao) < 0
          OR SUM(a.possuiRegra) > 1
        THEN
          CASE
            WHEN v_baseDesconto <= 0
            THEN 0
            ELSE 100 * COALESCE (SUM (
              CASE
                WHEN a.valorDescontoSugestao < 0
                THEN 0
                ELSE a.valorDescontoSugestao
              END), 0) / v_baseDesconto
          END
        ELSE MAX(a.percentualDescontoSugestao)
      END), 8), 0) percentualDescontoSugestao,
    COALESCE (ROUND((
      CASE
        WHEN SUM (
          CASE
            WHEN a.valorDescontoSugestao < 0
            THEN 0
            ELSE a.valorDescontoSugestao
          END) >= v_baseDesconto
        THEN v_baseDesconto - 0.01
        ELSE SUM (
          CASE
            WHEN a.valorDescontoSugestao < 0
            THEN 0
            ELSE a.valorDescontoSugestao
          END)
      END), 2), 0) valorDescontoSugestao,
    COALESCE (ROUND((
      CASE
        WHEN SUM (
          CASE
            WHEN a.valorDescontoMaximoSemSenha < 0
            THEN 0
            ELSE a.valorDescontoMaximoSemSenha
          END) >= v_baseDesconto
        THEN v_baseDesconto - 0.01
        ELSE SUM (
          CASE
            WHEN a.valorDescontoMaximoSemSenha < 0
            THEN 0
            ELSE a.valorDescontoMaximoSemSenha
          END)
      END), 2), 0) valorDescontoMaximoSemSenha
  INTO
    r_possuiRegra,
    r_percentualDescontoSugestao,
    r_valorDescontoSugestao,
    r_valorDescontoMaximoSemSenha
  FROM (
    SELECT
      1 possuiRegra,
      a.tipoRegraDescontoMargem,
      ROUND ((
        CASE a.tipoRegraDescontoMargem
          -- Desconto em percentual
          WHEN 1
          THEN a.valorSugestao
          -- Desconto em valor
          WHEN 2
          THEN
            CASE
              WHEN v_baseDesconto <= 0
              THEN 0
              ELSE 100 * a.valorSugestao / v_baseDesconto
            END
          -- Preço unitário fixo
          WHEN 3
          THEN
            CASE
              WHEN v_baseDesconto <= 0
              THEN 0
              ELSE 100 * (v_baseDesconto - ROUND (p_item_quantidade * a.valorMaximoSemSenha,2)) / v_baseDesconto
            END
          -- Desconto igual a idade em percentual
          WHEN 4
          THEN v_idade
          -- Desconto igual a idade em valor
          WHEN 5
          THEN
            CASE
              WHEN v_baseDesconto <= 0
              THEN 0
              ELSE 100 * v_idade / v_baseDesconto
            END
          -- Preço total fixado
          WHEN 6
          THEN 100
          ELSE 0
        END), 8) percentualDescontoSugestao,
      ROUND ((
        CASE a.tipoRegraDescontoMargem
          -- Desconto em percentual
          WHEN 1
          THEN v_baseDesconto * a.valorSugestao / 100
          -- Desconto em valor
          WHEN 2
          THEN a.valorSugestao
           -- Preço unitário fixo
          WHEN 3
          THEN v_baseDesconto - ROUND (p_item_quantidade * a.valorSugestao,2)
          -- Desconto igual a idade em percentual
          WHEN 4
          THEN v_baseDesconto * v_idade / 100
          -- Desconto igual a idade em valor
          WHEN 5
          THEN v_idade
          -- Preço total fixado
          WHEN 6
          THEN v_baseDesconto
          ELSE 0
        END), 2) valorDescontoSugestao,
      ROUND ((
        CASE a.tipoRegraDescontoMargem
          -- Desconto em percentual
          WHEN 1
          THEN v_baseDesconto * a.valorMaximoSemSenha / 100
          -- Desconto em valor
          WHEN 2
          THEN a.valorMaximoSemSenha
          -- Preço unitário fixo
          WHEN 3
          THEN v_baseDesconto - ROUND (p_item_quantidade * a.valorMaximoSemSenha,2)
          WHEN 4
          THEN v_baseDesconto * v_idade / 100
          -- Desconto igual a idade em valor
          WHEN 5
          THEN v_idade
          -- Preço total fixado
          WHEN 6
          THEN v_baseDesconto
          ELSE 0
        END), 2) valorDescontoMaximoSemSenha
    FROM PAREGRASDESCONTOSMARGEM a
    JOIN PAFILTROSCABECALHO filtroCab
    ON filtroCab.filtroCabecalho = a.filtroCabecalho
    WHERE a.regraDescontoMargem > 0
    AND a.ativo = 1
    AND a.dataValidadeInicial <= TRUNC(SYSDATE)
    AND a.dataValidadeFinal >= TRUNC(SYSDATE)
    AND a.cabecalhoItemPagamento = 'I'
    AND a.tipoRegraDescontoMargem BETWEEN 1 AND 6
    -- Filtro Cabeçalho
    AND (a.filtroCabecalho = 0
      OR (filtroCab.filtrarEstabelecimentos = 0
        OR EXISTS (
          SELECT 1
          FROM PAFILTROCABECXESTABELEC filtroCabX
          WHERE filtroCabX.filtroCabecalho = a.filtroCabecalho
          AND filtroCabX.estabelecimento = p_cab_estabelecimento
          AND filtroCabX.ativo = 1))
      AND (filtroCab.filtrarUfs = 0
        OR EXISTS (
          SELECT 1
          FROM PAFILTROCABECXUFS filtroCabX
          WHERE filtroCabX.filtroCabecalho = a.filtroCabecalho
          AND filtroCabX.uf = v_uf
          AND filtroCabX.ativo = 1))
      AND (filtroCab.filtrarPessoas = 0
        OR EXISTS (
          SELECT 1
          FROM PAFILTROCABECXPESSOAS filtroCabX
          WHERE filtroCabX.filtroCabecalho = a.filtroCabecalho
          AND filtroCabX.pessoa = v_pessoa
          AND filtroCabX.ativo = 1))
      AND (filtroCab.filtrarPerfisUsuario = 0
        AND filtroCab.filtrarUsuarios = 0
        OR filtroCab.filtrarPerfisUsuario = 1
        AND EXISTS (
          SELECT 1
          FROM PAFILTROCABECXPERFISUSUAR filtroCabX
          WHERE filtroCabX.filtroCabecalho = a.filtroCabecalho
          AND filtroCabX.perfilUsuario = p_perfilUsuarioLogado
          AND filtroCabX.ativo = 1)
        OR filtroCab.filtrarUsuarios = 1
        AND EXISTS (
          SELECT 1
          FROM PAFILTROCABECXUSUARIOS filtroCabX
          WHERE filtroCabX.filtroCabecalho = a.filtroCabecalho
          AND filtroCabX.usuario = p_usuarioLogado
          AND filtroCabX.ativo = 1))
      AND (filtroCab.indicadorPessoa = ' '
        OR filtroCab.indicadorPessoa = v_indicadorPessoa)
      AND (filtroCab.colaborador = ' '
        OR filtroCab.colaborador = 'N'
        AND (v_pessoa = 0
          OR NOT (EXISTS (
            SELECT 1
            FROM CACOLABORADORES colab
            WHERE colab.colaborador = v_pessoa
            AND colab.ativo = 1 )))
        OR filtroCab.colaborador = 'S'
        AND v_pessoa <> 0
        AND EXISTS (
          SELECT 1
          FROM CACOLABORADORES colab
          WHERE colab.colaborador = v_pessoa
          AND colab.ativo = 1)))
    -- Tabela de Preço
    AND (a.filtrarTabelaPreco = 0
      OR EXISTS (
        SELECT 1
        FROM PAREGRADESCMARGXTABELASPR x
        WHERE x.regraDescontoMargem = a.regraDescontoMargem
        AND x.tabelaPreco = p_item_tabelaPreco
        AND x.ativo = 1))
    -- Filtro Produto
    AND (
      SELECT COUNT(1)
      FROM PAREGRADESCMARGXFILTPROD b
      WHERE b.regraDescontoMargem = a.regraDescontoMargem
      AND b.filtroProduto > 0
      AND b.ativo = 1) = (
      SELECT COUNT(1)
      FROM PAREGRADESCMARGXFILTPROD b
      JOIN PAFILTROSPRODUTO c
      ON c.filtroProduto = b.filtroProduto
      WHERE b.regraDescontoMargem = a.regraDescontoMargem
      AND b.filtroProduto > 0
      AND b.ativo = 1
      AND (c.filtrarVendedores = 0
      OR EXISTS (
        SELECT 1
        FROM PAFILTROPRODUTOXVENDEDOR x
        WHERE x.filtroProduto = b.filtroProduto
        AND x.vendedor = p_item_vendedor
        AND x.ativo = 1))
      AND (c.filtrarLocaisEstoque = 0
      OR EXISTS (
        SELECT 1
        FROM PAFILTROPRODUTOXLOCAISEST x
        WHERE x.filtroProduto = b.filtroProduto
        AND x.localEstoque = p_item_localEstoque
        AND x.ativo = 1))
      AND (c.filtrarPersonalizacoes = 0
      OR EXISTS (
        SELECT 1
        FROM PAFILTROPRODUTOXPERSONAL x
        WHERE x.filtroProduto = b.filtroProduto
        AND x.personalizacao = p_item_personalizacao
        AND x.ativo = 1))
      AND (c.filtrarProdutos = 0
        AND c.filtrarCategoriasProdutos = 0
        AND c.filtrarSubcategoriasProdutos = 0
        AND c.filtrarMarcas = 0
        AND c.filtrarCaracteristicasA = 0
        AND c.filtrarCaracteristicasB = 0
        AND c.filtrarCaracteristicasC = 0
        AND c.filtrarCaracteristicasD = 0
        AND c.filtrarCaracteristicasE = 0
        AND c.filtrarCores = 0
        AND c.filtrarTamanhos = 0
        AND c.filtrarNCMs = 0
        AND c.filtrarListasServicos = 0
        OR c.filtrarProdutos = 1
        AND EXISTS (
          SELECT 1
          FROM PAFILTROPRODUTOXPRODUTOS x
          WHERE x.filtroProduto = b.filtroProduto
          AND x.produto = v_produto
          AND x.ativo = 1)
        OR (c.filtrarCategoriasProdutos = 1
          OR c.filtrarSubcategoriasProdutos = 1
          OR c.filtrarMarcas = 1
          OR c.filtrarCaracteristicasA = 1
          OR c.filtrarCaracteristicasB = 1
          OR c.filtrarCaracteristicasC = 1
          OR c.filtrarCaracteristicasD = 1
          OR c.filtrarCaracteristicasE = 1
          OR c.filtrarCores = 1
          OR c.filtrarTamanhos = 1
          OR c.filtrarNCMs = 1
          OR c.filtrarListasServicos = 1)
        AND (c.filtrarCategoriasProdutos = 0
          OR EXISTS (
            SELECT 1
            FROM PAFILTROPRODUTOXCATEGPROD x
            WHERE x.filtroProduto = b.filtroProduto
            AND x.categoriaProduto = v_categoriaProduto
            AND x.ativo = 1))
        AND (c.filtrarSubcategoriasProdutos = 0
          OR EXISTS (
            SELECT 1
            FROM PAFILTROPRODUTOXSUBCAPROD x
            WHERE x.filtroProduto = b.filtroProduto
            AND x.subcategoriaProduto = v_subcategoriaProduto
            AND x.ativo = 1))
        AND (c.filtrarMarcas = 0
          OR EXISTS (
            SELECT 1
            FROM PAFILTROPRODUTOXMARCAS x
            WHERE x.filtroProduto = b.filtroProduto
            AND x.marca = v_marca
            AND x.ativo = 1))
        AND (c.filtrarCaracteristicasA = 0
          OR EXISTS (
            SELECT 1
            FROM PAFILTROPRODUTOXCARACTERA x
            WHERE x.filtroProduto = b.filtroProduto
            AND x.caracteristicaA = v_caracteristicaA
            AND x.ativo = 1))
        AND (c.filtrarCaracteristicasB = 0
          OR EXISTS (
            SELECT 1
            FROM PAFILTROPRODUTOXCARACTERB x
            WHERE x.filtroProduto = b.filtroProduto
            AND x.caracteristicaB = v_caracteristicaB
            AND x.ativo = 1))
        AND (c.filtrarCaracteristicasC = 0
          OR EXISTS (
            SELECT 1
            FROM PAFILTROPRODUTOXCARACTERC x
            WHERE x.filtroProduto = b.filtroProduto
            AND x.caracteristicaC = v_caracteristicaC
            AND x.ativo = 1))
        AND (c.filtrarCaracteristicasD = 0
          OR EXISTS (
            SELECT 1
            FROM PAFILTROPRODUTOXCARACTERD x
            WHERE x.filtroProduto = b.filtroProduto
            AND x.caracteristicaD = v_caracteristicaD
            AND x.ativo = 1))
        AND (c.filtrarCaracteristicasE = 0
          OR EXISTS (
            SELECT 1
            FROM PAFILTROPRODUTOXCARACTERE x
            WHERE x.filtroProduto = b.filtroProduto
            AND x.caracteristicaE = v_caracteristicaE
            AND x.ativo = 1))
        AND (c.filtrarCores = 0
          OR EXISTS (
            SELECT 1
            FROM PAFILTROPRODUTOXCORES x
            WHERE x.filtroProduto = b.filtroProduto
            AND x.cor = v_cor
            AND x.ativo = 1))
        AND (c.filtrarTamanhos = 0
          OR EXISTS (
            SELECT 1
            FROM PAFILTROPRODUTOXTAMANHOS x
            WHERE x.filtroProduto = b.filtroProduto
            AND x.tamanho = v_tamanho
            AND x.ativo = 1))
        AND (c.filtrarNCMs = 0
          OR EXISTS (
            SELECT 1
            FROM PAFILTROPRODUTOXNCMS x
            WHERE x.filtroProduto = b.filtroProduto
            AND x.idNcm = v_idNcm
            AND x.ativo = 1))
        AND (c.filtrarListasServicos = 0
          OR EXISTS (
            SELECT 1
            FROM PAFILTROPRODUTOXLISTASSE x
            WHERE x.filtroProduto = b.filtroProduto
            AND x.listaServicos = v_listaServicos
            AND x.ativo = 1))
        AND p_item_quantidade >= c.quantidadeMinima
        AND (c.quantidadeMaxima = 0
          OR p_item_quantidade <= c.quantidadeMaxima)))) a;
END ADD_BUSCA_REGRA_DESCONTO_ITEM;

/

create or replace PROCEDURE ADD_BUSCA_PRECO(
    p_config_64_casasDecSaidas     IN CHAR,
    p_config_65_casasDecEntrada    IN CHAR,
    p_config_209_filtrarGrupoEcon  IN NUMBER,
    p_config_362_calcCustoPorGrade IN NUMBER,
    p_perfilUsuarioLogado          IN NUMBER,
    p_usuarioLogado                IN NUMBER,
    p_cab_entradaSaida             IN CHAR,
    p_cab_devolucaoAnulacaoRetorno IN NUMBER,
    p_cab_estabelecimento          IN NUMBER,
    p_cab_dataPrecoInicial         IN DATE,
    p_cab_dataPrecoFinal           IN DATE,
    p_cab_pessoa                   IN NUMBER,
    p_modDoc_capituloNaturezaFisc  IN NUMBER,
    p_modDoc_tipoPreco             IN CHAR,
    p_modDoc_tabelaPreco           IN VARCHAR,
    p_modDoc_fatorMultiplicador    IN NUMBER,
    p_modDoc_tipoPrecoB            IN CHAR,
    p_modDoc_tabelaPrecoB          IN VARCHAR,
    p_modDoc_fatorMultiplicadorB   IN NUMBER,
    p_endPessEst_uf                IN CHAR,
    p_endPess_uf                   IN CHAR,
    p_item_vendedor                IN NUMBER,
    p_item_idFormulaTinta          IN NUMBER,
    p_item_personalizacao          IN NUMBER,
    p_item_localEstoque            IN NUMBER,
    p_item_pessoaParticipante      IN NUMBER,
    p_item_quantidade              IN NUMBER,
    p_gradProd_produto             IN NUMBER,
    p_gradProd_cor                 IN NUMBER,
    p_gradProd_tamanho             IN VARCHAR,
    p_prod_controleEstoque         IN NUMBER,
    p_locEst_indicadorPropPosseIt  IN CHAR,
    p_manterPreco                  IN NUMBER,
    p_precoSugestaoAPrazoOriginal  IN NUMBER,
    p_precoSugestaoAVistaOriginal  IN NUMBER,
    p_tipoPreco                    IN CHAR,
    p_tabelaPreco                  IN VARCHAR,
    r_tipoPreco                    OUT CHAR,
    r_tabelaPreco                  OUT VARCHAR,
    r_precoSugestaoAPrazo          OUT NUMBER,
    r_precoSugestaoAVista          OUT NUMBER,
    r_precoDesconto                OUT NUMBER,
    r_precoMinimo                  OUT NUMBER,
    r_informarPrecoManualmente     OUT NUMBER,
    r_precoAPrazo                  OUT NUMBER,
    r_precoAVista                  OUT NUMBER,
    r_promocao                     OUT NUMBER,
    r_precoPromocaoAPrazo          OUT NUMBER,
    r_precoPromocaoAVista          OUT NUMBER,
    r_precoIndexadoAPrazo          OUT NUMBER,
    r_precoIndexadoAVista          OUT NUMBER)
IS
BEGIN
  r_tipoPreco                := ' ';
  r_tabelaPreco              := ' ';
  r_precoSugestaoAPrazo      := 0;
  r_precoSugestaoAVista      := 0;
  r_precoDesconto            := 0;
  r_precoMinimo              := 0;
  r_informarPrecoManualmente := 0;
  r_precoAPrazo              := 0;
  r_precoAVista              := 0;
  r_promocao                 := 0;
  r_precoPromocaoAPrazo      := 0;
  r_precoPromocaoAVista      := 0;
  r_precoIndexadoAPrazo      := 0;
  r_precoIndexadoAVista      := 0;
  IF p_gradProd_produto > 0 THEN
    IF CASE WHEN p_manterPreco = 1 AND p_tipoPreco <> ' ' THEN p_tipoPreco ELSE p_modDoc_tipoPreco END = 'I' THEN
      r_tipoPreco := 'I';
    ELSE
      IF p_prod_controleEstoque = 12 AND p_item_idFormulaTinta > 0 THEN
        ADD_BUSCA_PRECO_INTERNO_TINTA(
          p_config_209_filtrarGrupoEcon,
          p_config_362_calcCustoPorGrade,
          p_perfilUsuarioLogado,
          p_usuarioLogado,
          p_cab_entradaSaida,
          p_cab_devolucaoAnulacaoRetorno,
          p_cab_estabelecimento,
          p_cab_dataPrecoInicial,
          p_cab_dataPrecoFinal,
          p_cab_pessoa,
          p_modDoc_capituloNaturezaFisc,
          p_endPessEst_uf,
          p_endPess_uf,
          p_item_vendedor,
          p_item_idFormulaTinta,
          p_item_personalizacao,
          p_item_localEstoque,
          p_item_pessoaParticipante,
          p_item_quantidade,
          p_locEst_indicadorPropPosseIt,
          p_manterPreco,
          CASE WHEN p_manterPreco = 1 AND p_tipoPreco <> ' ' THEN p_tipoPreco ELSE p_modDoc_tipoPreco END, --p_tipoPreco
          CASE WHEN p_manterPreco = 1 AND p_tipoPreco <> ' ' THEN p_tabelaPreco ELSE p_modDoc_tabelaPreco END, --p_tabelaPreco
          r_tabelaPreco,
          r_precoSugestaoAPrazo,
          r_precoSugestaoAVista,
          r_precoDesconto,
          r_precoMinimo,
          r_informarPrecoManualmente,
          r_precoAPrazo,
          r_precoAVista,
          r_promocao,
          r_precoPromocaoAPrazo,
          r_precoPromocaoAVista,
          r_precoIndexadoAPrazo,
          r_precoIndexadoAVista);
      ELSE
        -- A Tabela de Preço Anterior
        IF CASE WHEN p_manterPreco = 1 AND p_tipoPreco <> ' ' THEN p_tipoPreco ELSE p_modDoc_tipoPreco END = 'A' THEN
          ADD_BUSCA_PRECO_INTERNO_ANTER(
            p_perfilUsuarioLogado,
            p_usuarioLogado,
            p_cab_entradaSaida,
            p_cab_devolucaoAnulacaoRetorno,
            p_cab_estabelecimento,
            p_cab_dataPrecoFinal,
            p_cab_pessoa,
            p_modDoc_capituloNaturezaFisc,
            p_endPessEst_uf,
            p_endPess_uf,
            p_item_vendedor,
            p_item_personalizacao,
            p_item_localEstoque,
            p_item_quantidade,
            p_gradProd_produto,
            p_gradProd_cor,
            p_gradProd_tamanho,
            p_manterPreco,
            p_precoSugestaoAPrazoOriginal,
            p_precoSugestaoAVistaOriginal,
            CASE WHEN p_manterPreco = 1 AND p_tipoPreco <> ' ' THEN p_tabelaPreco ELSE p_modDoc_tabelaPreco END,
            r_tabelaPreco,
            r_precoSugestaoAPrazo,
            r_precoSugestaoAVista,
            r_precoDesconto,
            r_precoMinimo,
            r_informarPrecoManualmente,
            r_precoAPrazo,
            r_precoAVista,
            r_promocao,
            r_precoPromocaoAPrazo,
            r_precoPromocaoAVista,
            r_precoIndexadoAPrazo,
            r_precoIndexadoAVista);
        -- C Custo Médio da Venda (CMV)
        ELSIF CASE WHEN p_manterPreco = 1 AND p_tipoPreco <> ' ' THEN p_tipoPreco ELSE p_modDoc_tipoPreco END = 'C' AND NOT(p_prod_controleEstoque IN (3,4)) THEN
          r_precoSugestaoAPrazo := FUNC_ADD_BUSCA_PRECO_MEDIO_FIS(
            p_config_209_filtrarGrupoEcon,
            p_config_362_calcCustoPorGrade,
            p_cab_estabelecimento,
            p_cab_dataPrecoFinal,
            p_item_pessoaParticipante,
            p_gradProd_produto,
            p_gradProd_cor,
            p_gradProd_tamanho,
            p_locEst_indicadorPropPosseIt,
            0); --p_gerandoInventario
        -- F Formação Preço (Custo)
        ELSIF CASE WHEN p_manterPreco = 1 AND p_tipoPreco <> ' ' THEN p_tipoPreco ELSE p_modDoc_tipoPreco END = 'F' THEN
          r_precoSugestaoAPrazo := FUNC_ADD_BUSCA_PRECO_FORMACAO(
            p_config_209_filtrarGrupoEcon,
            p_config_362_calcCustoPorGrade,
            p_cab_estabelecimento,
            p_cab_dataPrecoInicial,
            p_cab_dataPrecoFinal,
            p_item_personalizacao,
            p_gradProd_produto,
            p_gradProd_cor,
            p_gradProd_tamanho,
            0); --p_gerandoInventario
        -- G Custo Médio da Venda Gerencial (CMV)
        ELSIF CASE WHEN p_manterPreco = 1 AND p_tipoPreco <> ' ' THEN p_tipoPreco ELSE p_modDoc_tipoPreco END = 'G' AND NOT(p_prod_controleEstoque IN (3,4)) THEN
          r_precoSugestaoAPrazo := FUNC_ADD_BUSCA_PRECO_MEDIO_GER(
            p_config_209_filtrarGrupoEcon,
            p_config_362_calcCustoPorGrade,
            p_cab_estabelecimento,
            p_cab_dataPrecoFinal,
            p_item_personalizacao,
            p_item_pessoaParticipante,
            p_gradProd_produto,
            p_gradProd_cor,
            p_gradProd_tamanho,
            p_locEst_indicadorPropPosseIt,
            0); --p_gerandoInventario
        -- P Preço de Custo (Último Custo)
        ELSIF CASE WHEN p_manterPreco = 1 AND p_tipoPreco <> ' ' THEN p_tipoPreco ELSE p_modDoc_tipoPreco END = 'P' THEN
          r_precoSugestaoAPrazo := FUNC_ADD_BUSCA_PRECO_ULT_CUSTO(
            p_config_209_filtrarGrupoEcon,
            p_config_362_calcCustoPorGrade,
            p_cab_estabelecimento,
            p_cab_dataPrecoInicial,
            p_cab_dataPrecoFinal,
            p_item_personalizacao,
            p_item_pessoaParticipante,
            p_gradProd_produto,
            p_gradProd_cor,
            p_gradProd_tamanho,
            p_locEst_indicadorPropPosseIt,
            0); --p_gerandoInventario
        -- T Tabela de Preço
        ELSIF CASE WHEN p_manterPreco = 1 AND p_tipoPreco <> ' ' THEN p_tipoPreco ELSE p_modDoc_tipoPreco END = 'T' THEN
          ADD_BUSCA_PRECO_INTERNO_TABELA(
            p_perfilUsuarioLogado,
            p_usuarioLogado,
            p_cab_entradaSaida,
            p_cab_devolucaoAnulacaoRetorno,
            p_cab_estabelecimento,
            p_cab_dataPrecoFinal,
            p_cab_pessoa,
            p_modDoc_capituloNaturezaFisc,
            p_endPessEst_uf,
            p_endPess_uf,
            p_item_vendedor,
            p_item_personalizacao,
            p_item_localEstoque,
            p_item_quantidade,
            p_gradProd_produto,
            p_gradProd_cor,
            p_gradProd_tamanho,
            p_manterPreco,
            p_precoSugestaoAPrazoOriginal,
            p_precoSugestaoAVistaOriginal,
            CASE WHEN p_manterPreco = 1 AND p_tipoPreco <> ' ' THEN p_tabelaPreco ELSE p_modDoc_tabelaPreco END,
            r_tabelaPreco,
            r_precoSugestaoAPrazo,
            r_precoSugestaoAVista,
            r_precoDesconto,
            r_precoMinimo,
            r_informarPrecoManualmente,
            r_precoAPrazo,
            r_precoAVista,
            r_promocao,
            r_precoPromocaoAPrazo,
            r_precoPromocaoAVista,
            r_precoIndexadoAPrazo,
            r_precoIndexadoAVista);
        -- U Última Compra
        ELSIF CASE WHEN p_manterPreco = 1 AND p_tipoPreco <> ' ' THEN p_tipoPreco ELSE p_modDoc_tipoPreco END = 'U' THEN
          r_precoSugestaoAPrazo := FUNC_ADD_BUSCA_PRECO_ULT_COMPR(
            p_config_209_filtrarGrupoEcon,
            p_config_362_calcCustoPorGrade,
            p_cab_estabelecimento,
            p_cab_dataPrecoInicial,
            p_cab_dataPrecoFinal,
            p_item_personalizacao,
            p_gradProd_produto,
            p_gradProd_cor,
            p_gradProd_tamanho,
            0, --p_retornarPrecoBruto
            0); --p_gerandoInventario
        -- 2 Última Compra Bruto
        ELSIF CASE WHEN p_manterPreco = 1 AND p_tipoPreco <> ' ' THEN p_tipoPreco ELSE p_modDoc_tipoPreco END = '2' THEN
          r_precoSugestaoAPrazo := FUNC_ADD_BUSCA_PRECO_ULT_COMPR(
            p_config_209_filtrarGrupoEcon,
            p_config_362_calcCustoPorGrade,
            p_cab_estabelecimento,
            p_cab_dataPrecoInicial,
            p_cab_dataPrecoFinal,
            p_item_personalizacao,
            p_gradProd_produto,
            p_gradProd_cor,
            p_gradProd_tamanho,
            1, --p_retornarPrecoBruto
            0); --p_gerandoInventario
        END IF;
        IF NOT(CASE WHEN p_manterPreco = 1 AND p_tipoPreco <> ' ' THEN p_tipoPreco ELSE p_modDoc_tipoPreco END IN ('A','T')) THEN
          r_tabelaPreco              := ' ';
          r_precoSugestaoAVista      := r_precoSugestaoAPrazo;
          r_precoDesconto            := 0;
          r_precoMinimo              := 0;
          r_informarPrecoManualmente := 0;
          r_precoAPrazo              := r_precoSugestaoAPrazo;
          r_precoAVista              := r_precoSugestaoAPrazo;
          r_promocao                 := 0;
          r_precoPromocaoAPrazo      := r_precoSugestaoAPrazo;
          r_precoPromocaoAVista      := r_precoSugestaoAPrazo;
          r_precoIndexadoAPrazo      := r_precoSugestaoAPrazo;
          r_precoIndexadoAVista      := r_precoSugestaoAPrazo;
        END IF;
        -- 3 = Combo / 4 = Kit
        IF r_tabelaPreco = ' ' AND r_precoSugestaoAPrazo = 0 AND p_prod_controleEstoque IN (3,4) THEN
          ADD_BUSCA_PRECO_INTERNO_KIT(
            p_config_209_filtrarGrupoEcon,
            p_config_362_calcCustoPorGrade,
            p_perfilUsuarioLogado,
            p_usuarioLogado,
            p_cab_entradaSaida,
            p_cab_devolucaoAnulacaoRetorno,
            p_cab_estabelecimento,
            p_cab_dataPrecoInicial,
            p_cab_dataPrecoFinal,
            p_cab_pessoa,
            p_modDoc_capituloNaturezaFisc,
            p_endPessEst_uf,
            p_endPess_uf,
            p_item_vendedor,
            p_item_personalizacao,
            p_item_localEstoque,
            p_item_pessoaParticipante,
            p_item_quantidade,
            p_gradProd_produto,
            p_locEst_indicadorPropPosseIt,
            p_manterPreco,
            CASE WHEN p_manterPreco = 1 AND p_tipoPreco <> ' ' THEN p_tipoPreco ELSE p_modDoc_tipoPreco END,
            CASE WHEN p_manterPreco = 1 AND p_tipoPreco <> ' ' THEN p_tabelaPreco ELSE p_modDoc_tabelaPreco END,
            r_tabelaPreco,
            r_precoSugestaoAPrazo,
            r_precoSugestaoAVista,
            r_precoDesconto,
            r_precoMinimo,
            r_informarPrecoManualmente,
            r_precoAPrazo,
            r_precoAVista,
            r_promocao,
            r_precoPromocaoAPrazo,
            r_precoPromocaoAVista,
            r_precoIndexadoAPrazo,
            r_precoIndexadoAVista);
        END IF;
      END IF;
      -- Se encontrou preço
      IF r_tabelaPreco <> ' ' OR r_precoSugestaoAPrazo <> 0 OR r_precoSugestaoAVista <> 0 OR r_precoDesconto <> 0 OR r_precoMinimo <> 0 OR r_informarPrecoManualmente <> 0 OR r_precoAPrazo <> 0 OR r_precoAVista <> 0 OR r_precoPromocaoAPrazo <> 0 OR r_precoPromocaoAVista <> 0 OR r_precoIndexadoAPrazo <> 0 OR r_precoIndexadoAVista <> 0 OR CASE WHEN p_manterPreco = 1 AND p_tipoPreco <> ' ' THEN p_tipoPreco ELSE p_modDoc_tipoPreco END = 'I' THEN
        r_tipoPreco := CASE WHEN p_manterPreco = 1 AND p_tipoPreco <> ' ' THEN p_tipoPreco ELSE p_modDoc_tipoPreco END;
        IF NOT (p_modDoc_fatorMultiplicador IN (0,1)) AND (p_manterPreco = 0 OR p_tipoPreco = p_modDoc_tipoPreco AND p_tabelaPreco = p_modDoc_tabelaPreco) THEN
          r_precoSugestaoAPrazo := r_precoSugestaoAPrazo * p_modDoc_fatorMultiplicador;
          r_precoSugestaoAVista := r_precoSugestaoAVista * p_modDoc_fatorMultiplicador;
          r_precoDesconto       := r_precoDesconto       * p_modDoc_fatorMultiplicador;
          r_precoMinimo         := r_precoMinimo         * p_modDoc_fatorMultiplicador;
          r_precoAPrazo         := r_precoAPrazo         * p_modDoc_fatorMultiplicador;
          r_precoAVista         := r_precoAVista         * p_modDoc_fatorMultiplicador;
          r_precoPromocaoAPrazo := r_precoPromocaoAPrazo * p_modDoc_fatorMultiplicador;
          r_precoPromocaoAVista := r_precoPromocaoAVista * p_modDoc_fatorMultiplicador;
          r_precoIndexadoAPrazo := r_precoIndexadoAPrazo * p_modDoc_fatorMultiplicador;
          r_precoIndexadoAVista := r_precoIndexadoAVista * p_modDoc_fatorMultiplicador;
        END IF;
      -- Se não encontrou preço, não mantém o atual e existe regra de preço B
      ELSIF p_manterPreco = 0 AND p_modDoc_tipoPrecoB <> ' ' THEN
        ADD_BUSCA_PRECO(
          p_config_64_casasDecSaidas,
          p_config_65_casasDecEntrada,
          p_config_209_filtrarGrupoEcon,
          p_config_362_calcCustoPorGrade,
          p_perfilUsuarioLogado,
          p_usuarioLogado,
          p_cab_entradaSaida,
          p_cab_devolucaoAnulacaoRetorno,
          p_cab_estabelecimento,
          p_cab_dataPrecoInicial,
          p_cab_dataPrecoFinal,
          p_cab_pessoa,
          p_modDoc_capituloNaturezaFisc,
          p_modDoc_tipoPrecoB,
          p_modDoc_tabelaPrecoB,
          p_modDoc_fatorMultiplicadorB,
          ' ', --p_modDoc_tipoPrecoB
          ' ', --p_modDoc_tabelaPrecoB
          0, --p_modDoc_fatorMultiplicadorB
          p_endPessEst_uf,
          p_endPess_uf,
          p_item_vendedor,
          p_item_idFormulaTinta,
          p_item_personalizacao,
          p_item_localEstoque,
          p_item_pessoaParticipante,
          p_item_quantidade,
          p_gradProd_produto,
          p_gradProd_cor,
          p_gradProd_tamanho,
          p_prod_controleEstoque,
          p_locEst_indicadorPropPosseIt,
          0, --p_manterPreco
          p_precoSugestaoAPrazoOriginal,
          p_precoSugestaoAVistaOriginal,
          p_modDoc_tipoPrecoB,
          p_modDoc_tabelaPrecoB,
          r_tipoPreco,
          r_tabelaPreco,
          r_precoSugestaoAPrazo,
          r_precoSugestaoAVista,
          r_precoDesconto,
          r_precoMinimo,
          r_informarPrecoManualmente,
          r_precoAPrazo,
          r_precoAVista,
          r_promocao,
          r_precoPromocaoAPrazo,
          r_precoPromocaoAVista,
          r_precoIndexadoAPrazo,
          r_precoIndexadoAVista);
        -- Se não encontrou preço B, devolve tipo preço e tabela atual
        IF r_precoSugestaoAPrazo = 0 AND r_precoSugestaoAVista = 0 AND r_precoDesconto = 0 AND r_precoMinimo = 0 AND r_informarPrecoManualmente = 0 AND r_precoAPrazo = 0 AND r_precoAVista = 0 AND r_precoPromocaoAPrazo = 0 AND r_precoPromocaoAVista = 0 AND r_precoIndexadoAPrazo = 0 AND r_precoIndexadoAVista = 0 AND p_modDoc_tipoPrecoB <> 'I' THEN
          r_tipoPreco   := CASE WHEN p_manterPreco = 1 AND p_tipoPreco <> ' ' THEN p_tipoPreco   ELSE p_modDoc_tipoPreco   END;
          r_tabelaPreco := CASE WHEN p_manterPreco = 1 AND p_tipoPreco <> ' ' THEN p_tabelaPreco ELSE p_modDoc_tabelaPreco END;
        END IF;
      -- Se não encontrou e não usa regra B, devolve tipo preço e tabela atual
      ELSE
        r_tipoPreco   := CASE WHEN p_manterPreco = 1 AND p_tipoPreco <> ' ' THEN p_tipoPreco   ELSE p_modDoc_tipoPreco   END;
        r_tabelaPreco := CASE WHEN p_manterPreco = 1 AND p_tipoPreco <> ' ' THEN p_tabelaPreco ELSE p_modDoc_tabelaPreco END;
      END IF;
      -- Efetua arredondamento de preço
      r_precoSugestaoAPrazo := ROUND (r_precoSugestaoAPrazo, TO_NUMBER(CASE WHEN p_cab_entradaSaida = CASE WHEN p_cab_devolucaoAnulacaoRetorno = 1 THEN 'E' ELSE 'S' END THEN p_config_64_casasDecSaidas ELSE p_config_65_casasDecEntrada END));
      r_precoSugestaoAVista := ROUND (r_precoSugestaoAVista, TO_NUMBER(CASE WHEN p_cab_entradaSaida = CASE WHEN p_cab_devolucaoAnulacaoRetorno = 1 THEN 'E' ELSE 'S' END THEN p_config_64_casasDecSaidas ELSE p_config_65_casasDecEntrada END));
      r_precoDesconto       := ROUND (r_precoDesconto      , TO_NUMBER(CASE WHEN p_cab_entradaSaida = CASE WHEN p_cab_devolucaoAnulacaoRetorno = 1 THEN 'E' ELSE 'S' END THEN p_config_64_casasDecSaidas ELSE p_config_65_casasDecEntrada END));
      r_precoMinimo         := ROUND (r_precoMinimo        , TO_NUMBER(CASE WHEN p_cab_entradaSaida = CASE WHEN p_cab_devolucaoAnulacaoRetorno = 1 THEN 'E' ELSE 'S' END THEN p_config_64_casasDecSaidas ELSE p_config_65_casasDecEntrada END));
      r_precoAPrazo         := ROUND (r_precoAPrazo        , TO_NUMBER(CASE WHEN p_cab_entradaSaida = CASE WHEN p_cab_devolucaoAnulacaoRetorno = 1 THEN 'E' ELSE 'S' END THEN p_config_64_casasDecSaidas ELSE p_config_65_casasDecEntrada END));
      r_precoAVista         := ROUND (r_precoAVista        , TO_NUMBER(CASE WHEN p_cab_entradaSaida = CASE WHEN p_cab_devolucaoAnulacaoRetorno = 1 THEN 'E' ELSE 'S' END THEN p_config_64_casasDecSaidas ELSE p_config_65_casasDecEntrada END));
      r_precoPromocaoAPrazo := ROUND (r_precoPromocaoAPrazo, TO_NUMBER(CASE WHEN p_cab_entradaSaida = CASE WHEN p_cab_devolucaoAnulacaoRetorno = 1 THEN 'E' ELSE 'S' END THEN p_config_64_casasDecSaidas ELSE p_config_65_casasDecEntrada END));
      r_precoPromocaoAVista := ROUND (r_precoPromocaoAVista, TO_NUMBER(CASE WHEN p_cab_entradaSaida = CASE WHEN p_cab_devolucaoAnulacaoRetorno = 1 THEN 'E' ELSE 'S' END THEN p_config_64_casasDecSaidas ELSE p_config_65_casasDecEntrada END));
      r_precoIndexadoAPrazo := ROUND (r_precoIndexadoAPrazo, TO_NUMBER(CASE WHEN p_cab_entradaSaida = CASE WHEN p_cab_devolucaoAnulacaoRetorno = 1 THEN 'E' ELSE 'S' END THEN p_config_64_casasDecSaidas ELSE p_config_65_casasDecEntrada END));
      r_precoIndexadoAVista := ROUND (r_precoIndexadoAVista, TO_NUMBER(CASE WHEN p_cab_entradaSaida = CASE WHEN p_cab_devolucaoAnulacaoRetorno = 1 THEN 'E' ELSE 'S' END THEN p_config_64_casasDecSaidas ELSE p_config_65_casasDecEntrada END));
    END IF;
  END IF;
END ADD_BUSCA_PRECO;

/

create or replace PROCEDURE ADD_CALCULA_MARGEM_CONTRIB (
    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_reduzirTarifaCartao  IN NUMBER,
    p_regMarg_taxaCapitacaoCustoFi IN NUMBER,
    p_regMarg_exibImagemMargemItem IN NUMBER,
    p_regMarg_regraImagemItem      IN NUMBER,
    p_cab_estabelecimento          IN NUMBER,
    p_cab_dataPreco                IN DATE,
    p_cab_prazoMedioPonderado      IN NUMBER,
    p_cab_valorLiquidoItem         IN NUMBER,
    p_cab_valorTarifaCartao        IN NUMBER,
    p_munEndEst_uf                 IN CHAR,
    p_item_idFormulaTinta          IN NUMBER,
    p_item_personalizacao          IN NUMBER,
    p_item_localEstoque            IN NUMBER,
    p_item_pessoaParticipante      IN NUMBER,
    p_item_quantidade              IN NUMBER,
    p_item_valorFreteTotal         IN NUMBER,
    p_item_valorSeguroTotal        IN NUMBER,
    p_item_valorAdicFreteMarTotal  IN NUMBER,
    p_item_valorDespesasAduanTotal 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_valorICMSSTAnteriorment 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,
    p_gradProd_produto             IN NUMBER,
    p_gradProd_cor                 IN NUMBER,
    p_gradProd_tamanho             IN VARCHAR,
    p_prod_controleEstoque         IN NUMBER,
    p_locEst_indicadorPropPosseIt  IN CHAR,
    /* Retornos */
    r_valorLiquidoSemFreteSeguro   OUT NUMBER,
    r_valorCaptacao                OUT NUMBER,
    r_valorTarifaCartao            OUT NUMBER,
    r_valorImpostos                OUT NUMBER,
    r_precoCusto                   OUT NUMBER,
    r_valorCusto                   OUT NUMBER,
    r_valorMargem                  OUT NUMBER,
    r_percentualMargem             OUT NUMBER)
IS
    v_auxNumber NUMBER;
    v_auxVarchar VARCHAR2(256);    
BEGIN
  r_valorLiquidoSemFreteSeguro := p_item_valorLiquidoItem - p_item_valorFreteTotal - p_item_valorSeguroTotal - p_item_valorAdicFreteMarTotal - p_item_valorDespesasAduanTotal;
  r_valorCaptacao := FUNC_ADD_CALC_VALOR_CAPTACAO(p_cab_prazoMedioPonderado,p_regMarg_taxaCapitacaoCustoFi,r_valorLiquidoSemFreteSeguro);
  IF (p_regMarg_reduzirTarifaCartao = 1 AND p_cab_valorLiquidoItem <> 0) THEN
    r_valorTarifaCartao := CASE WHEN p_cab_valorLiquidoItem = 0 THEN 0 ELSE ROUND ((p_cab_valorTarifaCartao * p_item_valorLiquidoItem / p_cab_valorLiquidoItem), 2) END;
  ELSE
    r_valorTarifaCartao := 0;
  END IF;
  IF p_regMarg_reduzirImpostos = 1 THEN
    r_valorImpostos :=
      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_valorICMSSTAnteriorment
      + p_item_valorICMSUFDestinatario
      + p_item_valorICMSUFRemetente
      + p_item_valorFCP
      + p_item_valorFCPST
      + p_item_valorFCPSTAnteriormente
      + p_item_valorFCPUFDestinatario;
  ELSE
    r_valorImpostos := 0;
  END IF;
  ADD_BUSCA_PRECO (
    p_config_65_casasDecEntrada, -- p_config_64_casasDecSaidas
    p_config_65_casasDecEntrada,
    p_config_209_filtrarGrupoEcon,
    p_config_362_calcCustoPorGrade,
    0, -- p_perfilUsuarioLogado
    0, -- p_usuarioLogado
    'E', -- p_cab_entradaSaida
    0, -- p_cab_devolucaoAnulacaoRetorno
    p_cab_estabelecimento,
    TO_DATE('01/01/1900','DD/MM/YYYY'), -- p_cab_dataPrecoInicial
    p_cab_dataPreco, -- p_cab_dataPrecoFinal
    0, -- p_cab_pessoa
    0, -- p_modDoc_capituloNaturezaFisc
    p_regMarg_tipoPreco,
    p_regMarg_tabelaPreco,
    p_regMarg_fatorMultiplicador,
    p_regMarg_tipoPrecoB,
    p_regMarg_tabelaPrecoB,
    p_regMarg_fatorMultiplicadorB,
    p_munEndEst_uf, -- p_endPessEst_uf
    p_munEndEst_uf, -- p_endPess_uf
    0, -- p_item_vendedor
    p_item_idFormulaTinta,
    p_item_personalizacao,
    p_item_localEstoque,
    p_item_pessoaParticipante,
    p_item_quantidade,
    p_gradProd_produto,
    p_gradProd_cor,
    p_gradProd_tamanho,
    p_prod_controleEstoque,
    p_locEst_indicadorPropPosseIt,
    0, -- p_manterPreco
    0, -- p_precoSugestaoAPrazoOriginal
    0, -- p_precoSugestaoAVistaOriginal
    ' ', -- p_tipoPreco
    ' ', -- p_tabelaPreco
    /* Retornos */
    v_auxVarchar, -- r_tipoPreco
    v_auxVarchar, -- r_tabelaPreco
    r_precoCusto,
    v_auxNumber,
    v_auxNumber,
    v_auxNumber,
    v_auxNumber,
    v_auxNumber,
    v_auxNumber,
    v_auxNumber,
    v_auxNumber,
    v_auxNumber,
    v_auxNumber,
    v_auxNumber);
  -- CUSTOMIZAÇÃO CENTERLUZ
  -- r_valorImpostos      := ROUND ((r_valorLiquidoSemFreteSeguro * 0.3),2);
  -- r_valorTarifaCartao  := ROUND ((p_cab_valorLiquidoItem * 0.005),2);
  r_valorCusto         := ROUND ((p_item_quantidade * r_precoCusto),2);
  r_valorMargem        := r_valorLiquidoSemFreteSeguro - r_valorCaptacao - r_valorImpostos - r_valorTarifaCartao - r_valorCusto;
  r_percentualMargem   := CASE WHEN r_valorLiquidoSemFreteSeguro = 0 THEN 0 ELSE ROUND ((100 * r_valorMargem / r_valorLiquidoSemFreteSeguro), 8) END;
END ADD_CALCULA_MARGEM_CONTRIB;

/

UPDATE SIMENUS SET tipoMenu = 'MO' WHERE menu = 773;

COMMIT;

UPDATE MODOCFISCALXLOTESNFE SET situacaoDocumentoFiscal = 53 WHERE situacaoDocumentoFiscal <> 53 AND mensagemProtocoloNfe = 205;

COMMIT;

UPDATE MODOCUMENTOSFISCAIS a SET a.situacaoDocumentoFiscal = 53 WHERE a.situacaoDocumentoFiscal <23 AND EXISTS(SELECT 1 FROM MODOCFISCALXLOTESNFE b WHERE b.idDocumentoFiscal = a.idDocumentoFiscal AND b.mensagemProtocoloNfe = 205);

COMMIT;

INSERT INTO SITIPOSRESUMOSAPURACAOICM (tipoResumoApuracaoIcms, descricao, ativo, observacoes) VALUES (2, 'Outros Débitos (Discriminar abaixo)', 1, ' ');
INSERT INTO SITIPOSRESUMOSAPURACAOICM (tipoResumoApuracaoIcms, descricao, ativo, observacoes) VALUES (3, 'Estornos de Créditos (Discriminar abaixo)', 1, ' ');
INSERT INTO SITIPOSRESUMOSAPURACAOICM (tipoResumoApuracaoIcms, descricao, ativo, observacoes) VALUES (6, 'Outros Créditos (Discriminar abaixo)', 1, ' ');
INSERT INTO SITIPOSRESUMOSAPURACAOICM (tipoResumoApuracaoIcms, descricao, ativo, observacoes) VALUES (7, 'Estornos de Débitos (Discriminar abaixo)', 1, ' ');

COMMIT;

create or replace FUNCTION FUNC_ADD_BUSCA_PRECO_MEDIO_FIS(
    p_config_209_filtrarGrupoEcon  IN NUMBER,
    p_config_362_calcCustoPorGrade IN NUMBER,
    p_cab_estabelecimento          IN NUMBER,
    p_cab_dataPrecoFinal           IN DATE,
    p_item_pessoaParticipante      IN NUMBER,
    p_gradProd_produto             IN NUMBER,
    p_gradProd_cor                 IN NUMBER,
    p_gradProd_tamanho             IN VARCHAR,
    p_locEst_indicadorPropPosseIt  IN CHAR,
    p_gerandoInventario            IN NUMBER)
  RETURN NUMBER
IS
  v_quebra             CHAR(9);
  v_quantidade         NUMBER;
  v_preco              NUMBER;
  v_total              NUMBER;
  v_dataInventario     DATE;
  v_dataEstoqueInicial DATE;
BEGIN
  v_quebra     := '000000000';
  v_quantidade := 0;
  v_preco      := 0;
  v_total      := 0;
  SELECT MAX(TRUNC(invEst.data))
  INTO v_dataInventario
  FROM MOINVENTARIOSESTOQUE invEst
  WHERE invEst.data < TRUNC(p_cab_dataPrecoFinal)
    + CASE
        WHEN p_gerandoInventario = 0
        THEN 1
        ELSE 0
      END
  AND (invEst.estabelecimento = p_cab_estabelecimento
    OR EXISTS (
      SELECT 1
      FROM PAESTABELECIMENTOS est
      JOIN PAESTABELECIMENTOS est2
      ON est2.pessoaEstabelecimento = est.pessoaEstabelecimento
      WHERE est.estabelecimento = invEst.estabelecimento
      AND est.ativo = 1
      AND est.pessoaEstabelecimento > 0
      AND est2.estabelecimento = p_cab_estabelecimento)
    OR EXISTS (
      SELECT 1
      FROM PAESTABELECIMENTOS est
      JOIN CAPESSOAS pessEst
      ON pessEst.pessoa = est.pessoaEstabelecimento
      JOIN CAPESSOAS pessEst2
      ON pessEst2.grupoEconomico = pessEst.grupoEconomico
      JOIN PAESTABELECIMENTOS est2
      ON est2.pessoaEstabelecimento = pessEst2.pessoa
      WHERE p_config_209_filtrarGrupoEcon = 1
      AND est.estabelecimento = invEst.estabelecimento
      AND est.ativo = 1
      AND est.pessoaEstabelecimento > 0
      AND pessEst.grupoEconomico > 0
      AND est2.estabelecimento = p_cab_estabelecimento))
  AND (invEst.motivoInventarioEstoque = '01'
    OR invEst.data < TRUNC(p_cab_dataPrecoFinal)
    AND EXISTS(
      SELECT 1
      FROM MOINVENTARIOESTOQUEXFISC itemInv
      JOIN CAGRADESPRODUTO gradProd
      ON gradProd.gradeProduto = itemInv.gradeProduto
      JOIN CAPRODUTOS prod
      ON prod.produto = gradProd.produto
      WHERE itemInv.inventarioEstoque = invEst.inventarioEstoque
      AND gradProd.produto = p_gradProd_produto
      AND (p_config_362_calcCustoPorGrade = 0
        OR p_gerandoInventario = 0
        AND p_gradProd_cor = 0
        OR gradProd.cor = p_gradProd_cor)
      AND (p_config_362_calcCustoPorGrade = 0
        OR p_gerandoInventario = 0
        AND (p_gradProd_tamanho = ''
          OR p_gradProd_tamanho = ' ')
        OR gradProd.tamanho = p_gradProd_tamanho)
      AND prod.controleEstoque NOT IN (2,3,4,21,99)
      AND prod.tipoProduto IN ('00','01','02','03','04','05','06','10','99')));
  SELECT MAX(TRUNC(mov.data))
  INTO v_dataEstoqueInicial
  FROM MOESTOQUES mov
  JOIN CAGRADESPRODUTO gradProd
  ON gradProd.gradeProduto = mov.gradeProduto
  JOIN CAPRODUTOS prod
  ON prod.produto = gradProd.produto
  WHERE mov.operacaoInternaEstoque = 1
  AND mov.data >= CASE WHEN v_dataInventario IS NULL THEN TO_DATE ('01/01/1900','DD/MM/YYYY') ELSE v_dataInventario + 1 END
  AND mov.data < TO_DATE('' || TO_CHAR(p_cab_dataPrecoFinal, 'DD/MM/YYYY') || '', 'DD/MM/YYYY') + 1
  AND (mov.estabelecimento = p_cab_estabelecimento
    OR EXISTS (
      SELECT 1
      FROM PAESTABELECIMENTOS est
      JOIN PAESTABELECIMENTOS est2
      ON est2.pessoaEstabelecimento = est.pessoaEstabelecimento
      WHERE est.estabelecimento = mov.estabelecimento
      AND est.ativo = 1
      AND est.pessoaEstabelecimento > 0
      AND est2.estabelecimento = p_cab_estabelecimento)
    OR EXISTS (
      SELECT 1
      FROM PAESTABELECIMENTOS est
      JOIN CAPESSOAS pessEst
      ON pessEst.pessoa = est.pessoaEstabelecimento
      JOIN CAPESSOAS pessEst2
      ON pessEst2.grupoEconomico = pessEst.grupoEconomico
      JOIN PAESTABELECIMENTOS est2
      ON est2.pessoaEstabelecimento = pessEst2.pessoa
      WHERE p_config_209_filtrarGrupoEcon = 1
      AND est.estabelecimento = mov.estabelecimento
      AND est.ativo = 1
      AND est.pessoaEstabelecimento > 0
      AND pessEst.grupoEconomico > 0
      AND est2.estabelecimento = p_cab_estabelecimento))
  AND gradProd.produto = p_gradProd_produto
  AND (p_config_362_calcCustoPorGrade = 0
    OR p_gerandoInventario = 0
    AND p_gradProd_cor = 0
    OR gradProd.cor = p_gradProd_cor)
  AND (p_config_362_calcCustoPorGrade = 0
    OR p_gerandoInventario = 0
    AND (p_gradProd_tamanho = ''
      OR p_gradProd_tamanho = ' ')
    OR gradProd.tamanho = p_gradProd_tamanho)
  AND prod.controleEstoque NOT IN (2,3,4,21,99)
  AND prod.tipoProduto IN ('00','01','02','03','04','05','06','10','99');
  FOR a IN (
    SELECT
      TRUNC(a.data) data,
      a.operacao,
      TO_CHAR (a.data,'HH24MISS') tora,
      a.tabelaSistema,
      a.id,
      a.entradaSaida,
      a.quantidade,
      a.total
    FROM (
      SELECT
        invEst.data,
        4 operacao,
        'MOINVENTARIOESTOQUEXFISC' tabelaSistema,
        itemInv.id,
        'E' entradaSaida,
        itemInv.quantidade,
        ROUND(itemInv.quantidade * itemInv.precoUnitarioCMV,2) total
      FROM MOINVENTARIOESTOQUEXFISC itemInv
      JOIN MOINVENTARIOSESTOQUE invEst
      ON invEst.inventarioEstoque = itemInv.inventarioEstoque
      JOIN CAGRADESPRODUTO gradProd
      ON gradProd.gradeProduto = itemInv.gradeProduto
      JOIN CAPRODUTOS prod
      ON prod.produto = gradProd.produto
      WHERE v_dataEstoqueInicial IS NULL
      AND invEst.data >= v_dataInventario
      AND invEst.data < v_dataInventario + 1
      AND (invEst.estabelecimento = p_cab_estabelecimento
        OR EXISTS (
          SELECT 1
          FROM PAESTABELECIMENTOS est
          JOIN PAESTABELECIMENTOS est2
          ON est2.pessoaEstabelecimento = est.pessoaEstabelecimento
          WHERE est.estabelecimento = invEst.estabelecimento
          AND est.ativo = 1
          AND est.pessoaEstabelecimento > 0
          AND est2.estabelecimento = p_cab_estabelecimento)
        OR EXISTS (
          SELECT 1
          FROM PAESTABELECIMENTOS est
          JOIN CAPESSOAS pessEst
          ON pessEst.pessoa = est.pessoaEstabelecimento
          JOIN CAPESSOAS pessEst2
          ON pessEst2.grupoEconomico = pessEst.grupoEconomico
          JOIN PAESTABELECIMENTOS est2
          ON est2.pessoaEstabelecimento = pessEst2.pessoa
          WHERE p_config_209_filtrarGrupoEcon = 1
          AND est.estabelecimento = invEst.estabelecimento
          AND est.ativo = 1
          AND est.pessoaEstabelecimento > 0
          AND pessEst.grupoEconomico > 0
          AND est2.estabelecimento = p_cab_estabelecimento))
      AND gradProd.produto = p_gradProd_produto
      AND (p_config_362_calcCustoPorGrade = 0
        OR p_gerandoInventario = 0
        AND p_gradProd_cor = 0
        OR gradProd.cor = p_gradProd_cor)
      AND (p_config_362_calcCustoPorGrade = 0
        OR p_gerandoInventario = 0
        AND (p_gradProd_tamanho = ''
          OR p_gradProd_tamanho = ' ')
        OR gradProd.tamanho = p_gradProd_tamanho)
      AND prod.controleEstoque NOT IN (2,3,4,21,99)
      AND prod.tipoProduto IN ('00','01','02','03','04','05','06','10','99')
      AND invEst.inventarioEstoque = (
        SELECT MAX(invEst2.inventarioEstoque)
        FROM MOINVENTARIOSESTOQUE invEst2
        WHERE invEst2.estabelecimento = invEst.estabelecimento
        AND invEst2.data >= v_dataInventario
        AND invEst2.data < v_dataInventario + 1
        AND (invEst2.motivoInventarioEstoque = '01'
          OR invEst2.data < TRUNC(p_cab_dataPrecoFinal)
          AND EXISTS(
            SELECT 1
            FROM MOINVENTARIOESTOQUEXFISC itemInv2
            JOIN CAGRADESPRODUTO gradProd2
            ON gradProd2.gradeProduto = itemInv2.gradeProduto
            JOIN CAPRODUTOS prod2
            ON prod2.produto = gradProd2.produto
            WHERE itemInv2.inventarioEstoque = invEst2.inventarioEstoque
            AND gradProd2.produto = p_gradProd_produto
            AND (p_config_362_calcCustoPorGrade = 0
              OR p_gerandoInventario = 0
              AND p_gradProd_cor = 0
              OR gradProd2.cor = p_gradProd_cor)
            AND (p_config_362_calcCustoPorGrade = 0
              OR p_gerandoInventario = 0
              AND (p_gradProd_tamanho = ''
                OR p_gradProd_tamanho = ' ')
              OR gradProd2.tamanho = p_gradProd_tamanho)
            AND prod2.controleEstoque NOT IN (2,3,4,21,99)
            AND prod2.tipoProduto IN ('00','01','02','03','04','05','06','10','99'))))
      UNION ALL
      SELECT
        mov.data,
        CASE
          WHEN mov.operacaoInternaEstoque = 1
          THEN 1
          WHEN mov.atualizaCustoMedio = 1
          THEN 2
          ELSE 3
        END operacao,
        'MOESTOQUES' tabelaSistema,
        mov.idEstoque id,
        mov.entradaSaida,
        mov.quantidade,
        mov.totalCustoOperacao total
      FROM MOESTOQUES mov
      JOIN CAGRADESPRODUTO gradProd
      ON gradProd.gradeProduto = mov.gradeProduto
      JOIN CAPRODUTOS prod
      ON prod.produto = gradProd.produto
      WHERE mov.operacaoInternaEstoque IN (101,900)
      AND mov.indicadorPropriedadePosseItem = p_locEst_indicadorPropPosseIt
      AND mov.pessoaParticipante = p_item_pessoaParticipante
      AND mov.data >=
        CASE
          WHEN NOT(v_dataEstoqueInicial IS NULL)
          THEN v_dataEstoqueInicial
          WHEN NOT(v_dataInventario IS NULL)
          THEN v_dataInventario + 1
          ELSE TO_DATE ('01/01/1900','DD/MM/YYYY')
        END
      AND mov.data < TRUNC(p_cab_dataPrecoFinal) + 1
      AND (mov.estabelecimento = p_cab_estabelecimento
        OR EXISTS (
          SELECT 1
          FROM PAESTABELECIMENTOS est
          JOIN PAESTABELECIMENTOS est2
          ON est2.pessoaEstabelecimento = est.pessoaEstabelecimento
          WHERE est.estabelecimento = mov.estabelecimento
          AND est.ativo = 1
          AND est.pessoaEstabelecimento > 0
          AND est2.estabelecimento = p_cab_estabelecimento)
        OR EXISTS (
          SELECT 1
          FROM PAESTABELECIMENTOS est
          JOIN CAPESSOAS pessEst
          ON pessEst.pessoa = est.pessoaEstabelecimento
          JOIN CAPESSOAS pessEst2
          ON pessEst2.grupoEconomico = pessEst.grupoEconomico
          JOIN PAESTABELECIMENTOS est2
          ON est2.pessoaEstabelecimento = pessEst2.pessoa
          WHERE p_config_209_filtrarGrupoEcon = 1
          AND est.estabelecimento = mov.estabelecimento
          AND est.ativo = 1
          AND est.pessoaEstabelecimento > 0
          AND pessEst.grupoEconomico > 0
          AND est2.estabelecimento = p_cab_estabelecimento))
      AND gradProd.produto = p_gradProd_produto
      AND (p_config_362_calcCustoPorGrade = 0
        OR p_gerandoInventario = 0
        AND p_gradProd_cor = 0
        OR gradProd.cor = p_gradProd_cor)
      AND (p_config_362_calcCustoPorGrade = 0
        OR p_gerandoInventario = 0
        AND (p_gradProd_tamanho = ''
          OR p_gradProd_tamanho = ' ')
        OR gradProd.tamanho = p_gradProd_tamanho)
      AND prod.controleEstoque NOT IN (2,3,4,21,99)
      AND prod.tipoProduto IN ('00','01','02','03','04','05','06','10','99')
      UNION ALL
      SELECT
        cabDoc.dataEntradaSaida data,
        CASE
          WHEN modDoc.operacaoInternaEstoque = 1
          THEN 1
          WHEN cabDoc.atualizaCustoMedio = 1
          THEN 2
          ELSE 3
        END operacao,
        'MODOCFISCALXITENS' tabelaSistema,
        itemDoc.idItemDocFiscal id,
        cabDoc.entradaSaida,
        itemDoc.quantidade,
        itemDoc.valorCustoOperacao total
      FROM MODOCFISCALXITENS itemDoc
      JOIN MODOCUMENTOSFISCAIS cabDoc
      ON cabDoc.idDocumentoFiscal = itemDoc.idDocumentoFiscal
      JOIN PAMODELOSDOCUMENTO modDoc
      ON modDoc.modeloDocumento = itemDoc.modeloDocumento
      JOIN PALOCAISESTOQUE locEst
      ON locEst.localEstoque = itemDoc.localEstoque
      JOIN CAGRADESPRODUTO gradProd
      ON gradProd.gradeProduto = itemDoc.gradeProduto
      JOIN CAPRODUTOS prod
      ON prod.produto = gradProd.produto
      WHERE itemDoc.cancelado = 0
      AND itemDoc.movimentaEstoqueFiscal = 1
      AND itemDoc.pessoaParticipante = p_item_pessoaParticipante
      AND cabDoc.situacaoDocumentoFiscal BETWEEN 21 AND 23
      AND cabDoc.dataEntradaSaida >= 
        CASE
          WHEN NOT(v_dataEstoqueInicial IS NULL)
          THEN v_dataEstoqueInicial
          WHEN NOT(v_dataInventario IS NULL)
          THEN v_dataInventario + 1
          ELSE TO_DATE ('01/01/1900','DD/MM/YYYY')
        END
      AND cabDoc.dataEntradaSaida < TRUNC(p_cab_dataPrecoFinal) + 1
      AND (cabDoc.estabelecimento = p_cab_estabelecimento
        OR EXISTS (
          SELECT 1
          FROM PAESTABELECIMENTOS est
          JOIN PAESTABELECIMENTOS est2
          ON est2.pessoaEstabelecimento = est.pessoaEstabelecimento
          WHERE est.estabelecimento = cabDoc.estabelecimento
          AND est.ativo = 1
          AND est.pessoaEstabelecimento > 0
          AND est2.estabelecimento = p_cab_estabelecimento)
        OR EXISTS (
          SELECT 1
          FROM PAESTABELECIMENTOS est
          JOIN CAPESSOAS pessEst
          ON pessEst.pessoa = est.pessoaEstabelecimento
          JOIN CAPESSOAS pessEst2
          ON pessEst2.grupoEconomico = pessEst.grupoEconomico
          JOIN PAESTABELECIMENTOS est2
          ON est2.pessoaEstabelecimento = pessEst2.pessoa
          WHERE p_config_209_filtrarGrupoEcon = 1
          AND est.estabelecimento = cabDoc.estabelecimento
          AND est.ativo = 1
          AND est.pessoaEstabelecimento > 0
          AND pessEst.grupoEconomico > 0
          AND est2.estabelecimento = p_cab_estabelecimento))
      AND locEst.indicadorPropriedadePosseItem = p_locEst_indicadorPropPosseIt
      AND gradProd.produto = p_gradProd_produto
      AND (p_config_362_calcCustoPorGrade = 0
        OR p_gerandoInventario = 0
        AND p_gradProd_cor = 0
        OR gradProd.cor = p_gradProd_cor)
      AND (p_config_362_calcCustoPorGrade = 0
        OR p_gerandoInventario = 0
        AND (p_gradProd_tamanho = ''
          OR p_gradProd_tamanho = ' ')
        OR gradProd.tamanho = p_gradProd_tamanho)
      AND prod.controleEstoque NOT IN (2,3,4,21,99)
      AND prod.tipoProduto IN ('00','01','02','03','04','05','06','10','99')
      AND NOT(EXISTS(
        SELECT 1
        FROM MODOCFISCALXPRODUTOFILHO filhoDoc
        WHERE filhoDoc.idItemDocFiscal = itemDoc.idItemDocFiscal))
      UNION ALL
      SELECT
        cabDoc.dataEntradaSaida data,
        CASE
          WHEN modDoc.operacaoInternaEstoque = 1
          THEN 1
          WHEN cabDoc.atualizaCustoMedio = 1
          THEN 2
          ELSE 3
        END operacao,
        'MODOCFISCALXPRODUTOFILHO' tabelaSistema,
        filhoDoc.id,
        cabDoc.entradaSaida,
        filhoDoc.quantidade,
        filhoDoc.totalCustoOperacao total
      FROM MODOCFISCALXPRODUTOFILHO filhoDoc
      JOIN MODOCFISCALXITENS itemDoc
      ON itemDoc.idItemDocFiscal = filhoDoc.idItemDocFiscal
      JOIN MODOCUMENTOSFISCAIS cabDoc
      ON cabDoc.idDocumentoFiscal = itemDoc.idDocumentoFiscal
      JOIN PAMODELOSDOCUMENTO modDoc
      ON modDoc.modeloDocumento = itemDoc.modeloDocumento
      JOIN PALOCAISESTOQUE locEst
      ON locEst.localEstoque = itemDoc.localEstoque
      JOIN CAGRADESPRODUTO gradProd
      ON gradProd.gradeProduto = filhoDoc.gradeProduto
      JOIN CAPRODUTOS prod
      ON prod.produto = gradProd.produto
      WHERE itemDoc.cancelado = 0
      AND itemDoc.movimentaEstoqueFiscal = 1
      AND itemDoc.pessoaParticipante = p_item_pessoaParticipante
      AND cabDoc.situacaoDocumentoFiscal BETWEEN 21 AND 23
      AND cabDoc.dataEntradaSaida >= 
        CASE
          WHEN NOT(v_dataEstoqueInicial IS NULL)
          THEN v_dataEstoqueInicial
          WHEN NOT(v_dataInventario IS NULL)
          THEN v_dataInventario + 1
          ELSE TO_DATE ('01/01/1900','DD/MM/YYYY')
        END
      AND cabDoc.dataEntradaSaida < TRUNC(p_cab_dataPrecoFinal) + 1
      AND (cabDoc.estabelecimento = p_cab_estabelecimento
        OR EXISTS (
          SELECT 1
          FROM PAESTABELECIMENTOS est
          JOIN PAESTABELECIMENTOS est2
          ON est2.pessoaEstabelecimento = est.pessoaEstabelecimento
          WHERE est.estabelecimento = cabDoc.estabelecimento
          AND est.ativo = 1
          AND est.pessoaEstabelecimento > 0
          AND est2.estabelecimento = p_cab_estabelecimento)
        OR EXISTS (
          SELECT 1
          FROM PAESTABELECIMENTOS est
          JOIN CAPESSOAS pessEst
          ON pessEst.pessoa = est.pessoaEstabelecimento
          JOIN CAPESSOAS pessEst2
          ON pessEst2.grupoEconomico = pessEst.grupoEconomico
          JOIN PAESTABELECIMENTOS est2
          ON est2.pessoaEstabelecimento = pessEst2.pessoa
          WHERE p_config_209_filtrarGrupoEcon = 1
          AND est.estabelecimento = cabDoc.estabelecimento
          AND est.ativo = 1
          AND est.pessoaEstabelecimento > 0
          AND pessEst.grupoEconomico > 0
          AND est2.estabelecimento = p_cab_estabelecimento))
      AND locEst.indicadorPropriedadePosseItem = p_locEst_indicadorPropPosseIt
      AND gradProd.produto = p_gradProd_produto
      AND (p_config_362_calcCustoPorGrade = 0
        OR p_gerandoInventario = 0
        AND p_gradProd_cor = 0
        OR gradProd.cor = p_gradProd_cor)
      AND (p_config_362_calcCustoPorGrade = 0
        OR p_gerandoInventario = 0
        AND (p_gradProd_tamanho = ''
          OR p_gradProd_tamanho = ' ')
        OR gradProd.tamanho = p_gradProd_tamanho)
      AND prod.controleEstoque NOT IN (2,3,4,21,99)
      AND prod.tipoProduto IN ('00','01','02','03','04','05','06','10','99')) a
    ORDER BY
      TRUNC(a.data),
      a.operacao,
      TO_CHAR (a.data,'HH24MISS'),
      a.tabelaSistema,
      a.id)
  LOOP
    IF v_quebra < TO_CHAR(a.data,'YYYYMMDD') || TO_CHAR(a.operacao) THEN
      v_quebra := TO_CHAR(a.data,'YYYYMMDD') || TO_CHAR(a.operacao);
      -- 1 = Saldo Inicial / 4 = Inventário Estoque
      IF a.operacao IN (1,4) THEN
        v_quantidade := 0;
        v_preco := 0;
        v_total := 0;
      END IF;
    END IF;
    -- 1 = Saldo Inicial / 2 = Atualiza Custo Médio / 4 = Inventário Estoque
    IF a.operacao IN (1,2,4) THEN
      IF a.entradaSaida = 'E' THEN
        v_quantidade := v_quantidade + a.quantidade;
        IF v_quantidade <= 0 THEN
          v_total := 0;
        ELSIF v_quantidade > a.quantidade THEN
          IF v_total + a.total > 9999999999999.99 THEN
             v_total := 9999999999999.99;
          ELSE
             v_total := v_total + a.total;
          END IF;
        ELSIF ROUND ((a.total * v_quantidade / a.quantidade),2) > 9999999999999.99 THEN
           v_total := 9999999999999.99;
        ELSE
           v_total := ROUND ((a.total * v_quantidade / a.quantidade),2);
        END IF;
     ELSE
        v_quantidade := v_quantidade - a.quantidade;
        v_total := v_total - a.total;
        IF v_total < 0 OR v_quantidade <= 0 THEN
          v_total := 0;
        END IF;
      END IF;
      IF v_total > 0 AND v_quantidade >= 0 AND ROUND(v_total / CASE WHEN v_quantidade = 0 THEN 1 ELSE v_quantidade END, 7) > 99999999.9999999 THEN
        v_preco := 99999999.9999999;
      ELSIF v_total > 0 AND v_quantidade >= 0 THEN
        v_preco := ROUND(v_total / CASE WHEN v_quantidade = 0 THEN 1 ELSE v_quantidade END, 7);
      END IF;
    -- Operação = 3 Não atualiza custo médio
    ELSIF a.entradaSaida = 'E' THEN
      v_quantidade := v_quantidade + a.quantidade;
      IF v_quantidade <= 0 THEN
        v_total := 0;
      ELSIF v_quantidade > a.quantidade THEN
        IF v_total + ROUND((a.quantidade * v_preco),2) > 9999999999999.99 THEN
           v_total := 9999999999999.99;
        ELSE
           v_total := v_total + a.total;
        END IF;
      ELSIF ROUND((v_quantidade * v_preco),2) > 9999999999999.99 THEN
         v_total := 9999999999999.99;
      ELSE
         v_total := ROUND((v_quantidade * v_preco),2);
      END IF;
    ELSE
      v_quantidade := v_quantidade - a.quantidade;
      v_total := v_total - a.quantidade * v_preco;
      IF v_total < 0 OR v_quantidade <= 0 THEN
        v_total := 0;
      END IF;
    END IF;
  END LOOP;
  IF v_preco = 0 THEN
    v_preco := FUNC_ADD_BUSCA_PRECO_PRODXEST(
      p_config_209_filtrarGrupoEcon,
      p_cab_estabelecimento,
      p_gradProd_produto,
      'C');
  END IF;
  RETURN v_preco;  
END;

/

create or replace FUNCTION FUNC_ADD_BUSCA_PRECO_MEDIO_GER(
    p_config_209_filtrarGrupoEcon  IN NUMBER,
    p_config_362_calcCustoPorGrade IN NUMBER,
    p_cab_estabelecimento          IN NUMBER,
    p_cab_dataPrecoFinal           IN DATE,
    p_item_personalizacao          IN NUMBER,
    p_item_pessoaParticipante      IN NUMBER,
    p_gradProd_produto             IN NUMBER,
    p_gradProd_cor                 IN NUMBER,
    p_gradProd_tamanho             IN VARCHAR,
    p_locEst_indicadorPropPosseIt  IN CHAR,
    p_gerandoInventario            IN NUMBER)
  RETURN NUMBER
IS
  v_quebra             CHAR(9);
  v_quantidade         NUMBER;
  v_preco              NUMBER;
  v_total              NUMBER;
  v_dataInventario     DATE;
  v_dataEstoqueInicial DATE;
BEGIN
  v_quebra     := '000000000';
  v_quantidade := 0;
  v_preco      := 0;
  v_total      := 0;
  SELECT MAX(TRUNC(invEst.data))
  INTO v_dataInventario
  FROM MOINVENTARIOSESTOQUE invEst
  WHERE invEst.data < TRUNC(p_cab_dataPrecoFinal)
    + CASE
        WHEN p_gerandoInventario = 0
        THEN 1
        ELSE 0
      END
  AND (invEst.estabelecimento = p_cab_estabelecimento
    OR EXISTS (
      SELECT 1
      FROM PAESTABELECIMENTOS est
      JOIN PAESTABELECIMENTOS est2
      ON est2.pessoaEstabelecimento = est.pessoaEstabelecimento
      WHERE est.estabelecimento = invEst.estabelecimento
      AND est.ativo = 1
      AND est.pessoaEstabelecimento > 0
      AND est2.estabelecimento = p_cab_estabelecimento)
    OR EXISTS (
      SELECT 1
      FROM PAESTABELECIMENTOS est
      JOIN CAPESSOAS pessEst
      ON pessEst.pessoa = est.pessoaEstabelecimento
      JOIN CAPESSOAS pessEst2
      ON pessEst2.grupoEconomico = pessEst.grupoEconomico
      JOIN PAESTABELECIMENTOS est2
      ON est2.pessoaEstabelecimento = pessEst2.pessoa
      WHERE p_config_209_filtrarGrupoEcon = 1
      AND est.estabelecimento = invEst.estabelecimento
      AND est.ativo = 1
      AND est.pessoaEstabelecimento > 0
      AND pessEst.grupoEconomico > 0
      AND est2.estabelecimento = p_cab_estabelecimento))
  AND (invEst.motivoInventarioEstoque = '01'
    OR invEst.data < TRUNC(p_cab_dataPrecoFinal)
    AND EXISTS(
      SELECT 1
      FROM MOINVENTARIOESTOQUEXITENS itemInv
      JOIN CAGRADESPRODUTO gradProd
      ON gradProd.gradeProduto = itemInv.gradeProduto
      JOIN CAPRODUTOS prod
      ON prod.produto = gradProd.produto
      WHERE itemInv.inventarioEstoque = invEst.inventarioEstoque
      AND (p_config_362_calcCustoPorGrade = 0
        OR p_gerandoInventario = 0
        AND p_item_personalizacao = 0
        OR itemInv.personalizacao = p_item_personalizacao)
      AND gradProd.produto = p_gradProd_produto
      AND (p_config_362_calcCustoPorGrade = 0
        OR p_gerandoInventario = 0
        AND p_gradProd_cor = 0
        OR gradProd.cor = p_gradProd_cor)
      AND (p_config_362_calcCustoPorGrade = 0
        OR p_gerandoInventario = 0
        AND (p_gradProd_tamanho = ''
          OR p_gradProd_tamanho = ' ')
        OR gradProd.tamanho = p_gradProd_tamanho)
      AND prod.controleEstoque NOT IN (2,3,4,21,99)
      AND prod.tipoProduto IN ('00','01','02','03','04','05','06','10','99')));
  SELECT MAX(TRUNC(mov.data))
  INTO v_dataEstoqueInicial
  FROM MOESTOQUES mov
  JOIN CAGRADESPRODUTO gradProd
  ON gradProd.gradeProduto = mov.gradeProduto
  JOIN CAPRODUTOS prod
  ON prod.produto = gradProd.produto
  WHERE mov.operacaoInternaEstoque = 1
  AND (p_config_362_calcCustoPorGrade = 0
    OR p_gerandoInventario = 0
    AND p_item_personalizacao = 0
    OR mov.personalizacao = p_item_personalizacao)
  AND mov.data >= CASE WHEN v_dataInventario IS NULL THEN TO_DATE ('01/01/1900','DD/MM/YYYY') ELSE v_dataInventario + 1 END
  AND mov.data < TO_DATE('' || TO_CHAR(p_cab_dataPrecoFinal, 'DD/MM/YYYY') || '', 'DD/MM/YYYY') + 1
AND (mov.estabelecimento = p_cab_estabelecimento
  OR EXISTS (
    SELECT 1
    FROM PAESTABELECIMENTOS est
    JOIN PAESTABELECIMENTOS est2
    ON est2.pessoaEstabelecimento = est.pessoaEstabelecimento
    WHERE est.estabelecimento = mov.estabelecimento
    AND est.ativo = 1
    AND est.pessoaEstabelecimento > 0
    AND est2.estabelecimento = p_cab_estabelecimento)
  OR EXISTS (
    SELECT 1
    FROM PAESTABELECIMENTOS est
    JOIN CAPESSOAS pessEst
    ON pessEst.pessoa = est.pessoaEstabelecimento
    JOIN CAPESSOAS pessEst2
    ON pessEst2.grupoEconomico = pessEst.grupoEconomico
    JOIN PAESTABELECIMENTOS est2
    ON est2.pessoaEstabelecimento = pessEst2.pessoa
    WHERE p_config_209_filtrarGrupoEcon = 1
    AND est.estabelecimento = mov.estabelecimento
    AND est.ativo = 1
    AND est.pessoaEstabelecimento > 0
    AND pessEst.grupoEconomico > 0
    AND est2.estabelecimento = p_cab_estabelecimento))
  AND gradProd.produto = p_gradProd_produto
  AND (p_config_362_calcCustoPorGrade = 0
    OR p_gerandoInventario = 0
    AND p_gradProd_cor = 0
    OR gradProd.cor = p_gradProd_cor)
  AND (p_config_362_calcCustoPorGrade = 0
    OR p_gerandoInventario = 0
    AND (p_gradProd_tamanho = ''
      OR p_gradProd_tamanho = ' ')
    OR gradProd.tamanho = p_gradProd_tamanho)
  AND prod.controleEstoque NOT IN (2,3,4,21,99)
  AND prod.tipoProduto IN ('00','01','02','03','04','05','06','10','99');
  FOR a IN (
    SELECT
      TRUNC(a.data) data,
      a.operacao,
      TO_CHAR (a.data,'HH24MISS') tora,
      a.tabelaSistema,
      a.id,
      a.entradaSaida,
      a.quantidade,
      a.total
    FROM (
      SELECT
        invEst.data,
        4 operacao,
        'MOINVENTARIOESTOQUEXITENS' tabelaSistema,
        itemInv.idItemInventarioEstoque id,
        'E' entradaSaida,
        itemInv.quantidade,
        ROUND(itemInv.quantidade * itemInv.precoUnitarioCMV,2) total
      FROM MOINVENTARIOESTOQUEXITENS itemInv
      JOIN MOINVENTARIOSESTOQUE invEst
      ON invEst.inventarioEstoque = itemInv.inventarioEstoque
      JOIN CAGRADESPRODUTO gradProd
      ON gradProd.gradeProduto = itemInv.gradeProduto
      JOIN CAPRODUTOS prod
      ON prod.produto = gradProd.produto
      WHERE v_dataEstoqueInicial IS NULL
      AND (p_config_362_calcCustoPorGrade = 0
        OR p_gerandoInventario = 0
        AND p_item_personalizacao = 0
        OR itemInv.personalizacao = p_item_personalizacao)
      AND invEst.data >= v_dataInventario
      AND invEst.data < v_dataInventario + 1
      AND (invEst.estabelecimento = p_cab_estabelecimento
        OR EXISTS (
          SELECT 1
          FROM PAESTABELECIMENTOS est
          JOIN PAESTABELECIMENTOS est2
          ON est2.pessoaEstabelecimento = est.pessoaEstabelecimento
          WHERE est.estabelecimento = invEst.estabelecimento
          AND est.ativo = 1
          AND est.pessoaEstabelecimento > 0
          AND est2.estabelecimento = p_cab_estabelecimento)
        OR EXISTS (
          SELECT 1
          FROM PAESTABELECIMENTOS est
          JOIN CAPESSOAS pessEst
          ON pessEst.pessoa = est.pessoaEstabelecimento
          JOIN CAPESSOAS pessEst2
          ON pessEst2.grupoEconomico = pessEst.grupoEconomico
          JOIN PAESTABELECIMENTOS est2
          ON est2.pessoaEstabelecimento = pessEst2.pessoa
          WHERE p_config_209_filtrarGrupoEcon = 1
          AND est.estabelecimento = invEst.estabelecimento
          AND est.ativo = 1
          AND est.pessoaEstabelecimento > 0
          AND pessEst.grupoEconomico > 0
          AND est2.estabelecimento = p_cab_estabelecimento))
      AND gradProd.produto = p_gradProd_produto
      AND (p_config_362_calcCustoPorGrade = 0
        OR p_gerandoInventario = 0
        AND p_gradProd_cor = 0
        OR gradProd.cor = p_gradProd_cor)
      AND (p_config_362_calcCustoPorGrade = 0
        OR p_gerandoInventario = 0
        AND (p_gradProd_tamanho = ''
          OR p_gradProd_tamanho = ' ')
        OR gradProd.tamanho = p_gradProd_tamanho)
      AND prod.controleEstoque NOT IN (2,3,4,21,99)
      AND prod.tipoProduto IN ('00','01','02','03','04','05','06','10','99')
      AND invEst.inventarioEstoque = (
        SELECT MAX(invEst2.inventarioEstoque)
        FROM MOINVENTARIOSESTOQUE invEst2
        WHERE invEst2.estabelecimento = invEst.estabelecimento
        AND invEst2.data >= v_dataInventario
        AND invEst2.data < v_dataInventario + 1
        AND (invEst2.motivoInventarioEstoque = '01'
          OR invEst2.data < TRUNC(p_cab_dataPrecoFinal)
          AND EXISTS(
            SELECT 1
            FROM MOINVENTARIOESTOQUEXITENS itemInv2
            JOIN CAGRADESPRODUTO gradProd2
            ON gradProd2.gradeProduto = itemInv2.gradeProduto
            JOIN CAPRODUTOS prod2
            ON prod2.produto = gradProd2.produto
            WHERE itemInv2.inventarioEstoque = invEst2.inventarioEstoque
            AND (p_config_362_calcCustoPorGrade = 0
              OR p_gerandoInventario = 0
              AND p_item_personalizacao = 0
              OR itemInv2.personalizacao = p_item_personalizacao)
            AND gradProd2.produto = p_gradProd_produto
            AND (p_config_362_calcCustoPorGrade = 0
              OR p_gerandoInventario = 0
              AND p_gradProd_cor = 0
              OR gradProd2.cor = p_gradProd_cor)
            AND (p_config_362_calcCustoPorGrade = 0
              OR p_gerandoInventario = 0
              AND (p_gradProd_tamanho = ''
                OR p_gradProd_tamanho = ' ')
              OR gradProd2.tamanho = p_gradProd_tamanho)
            AND prod2.controleEstoque NOT IN (2,3,4,21,99)
            AND prod2.tipoProduto IN ('00','01','02','03','04','05','06','10','99'))))
      UNION ALL
      SELECT
        mov.data,
        CASE
          WHEN mov.operacaoInternaEstoque = 1
          THEN 1
          WHEN mov.atualizaCustoMedio = 1
          THEN 2
          ELSE 3
        END operacao,
        'MOESTOQUES' tabelaSistema,
        mov.idEstoque id,
        mov.entradaSaida,
        mov.quantidade,
        mov.totalCustoOperacao total
      FROM MOESTOQUES mov
      JOIN CAGRADESPRODUTO gradProd
      ON gradProd.gradeProduto = mov.gradeProduto
      JOIN CAPRODUTOS prod
      ON prod.produto = gradProd.produto
      WHERE mov.indicadorPropriedadePosseItem = p_locEst_indicadorPropPosseIt
      AND mov.pessoaParticipante = p_item_pessoaParticipante
      AND (p_config_362_calcCustoPorGrade = 0
        OR p_gerandoInventario = 0
        AND p_item_personalizacao = 0
        OR mov.personalizacao = p_item_personalizacao)
      AND mov.data >=
        CASE
          WHEN NOT(v_dataEstoqueInicial IS NULL)
          THEN v_dataEstoqueInicial
          WHEN NOT(v_dataInventario IS NULL)
          THEN v_dataInventario + 1
          ELSE TO_DATE ('01/01/1900','DD/MM/YYYY')
        END
      AND mov.data < TRUNC(p_cab_dataPrecoFinal) + 1
      AND (mov.estabelecimento = p_cab_estabelecimento
        OR EXISTS (
          SELECT 1
          FROM PAESTABELECIMENTOS est
          JOIN PAESTABELECIMENTOS est2
          ON est2.pessoaEstabelecimento = est.pessoaEstabelecimento
          WHERE est.estabelecimento = mov.estabelecimento
          AND est.ativo = 1
          AND est.pessoaEstabelecimento > 0
          AND est2.estabelecimento = p_cab_estabelecimento)
        OR EXISTS (
          SELECT 1
          FROM PAESTABELECIMENTOS est
          JOIN CAPESSOAS pessEst
          ON pessEst.pessoa = est.pessoaEstabelecimento
          JOIN CAPESSOAS pessEst2
          ON pessEst2.grupoEconomico = pessEst.grupoEconomico
          JOIN PAESTABELECIMENTOS est2
          ON est2.pessoaEstabelecimento = pessEst2.pessoa
          WHERE p_config_209_filtrarGrupoEcon = 1
          AND est.estabelecimento = mov.estabelecimento
          AND est.ativo = 1
          AND est.pessoaEstabelecimento > 0
          AND pessEst.grupoEconomico > 0
          AND est2.estabelecimento = p_cab_estabelecimento))
      AND gradProd.produto = p_gradProd_produto
      AND (p_config_362_calcCustoPorGrade = 0
        OR p_gerandoInventario = 0
        AND p_gradProd_cor = 0
        OR gradProd.cor = p_gradProd_cor)
      AND (p_config_362_calcCustoPorGrade = 0
        OR p_gerandoInventario = 0
        AND (p_gradProd_tamanho = ''
          OR p_gradProd_tamanho = ' ')
        OR gradProd.tamanho = p_gradProd_tamanho)
      AND prod.controleEstoque NOT IN (2,3,4,21,99)
      AND prod.tipoProduto IN ('00','01','02','03','04','05','06','10','99')) a
    ORDER BY
      TRUNC(a.data),
      a.operacao,
      TO_CHAR (a.data,'HH24MISS'),
      a.tabelaSistema,
      a.id)
  LOOP
    IF v_quebra < TO_CHAR(a.data,'YYYYMMDD') || TO_CHAR(a.operacao) THEN
      v_quebra := TO_CHAR(a.data,'YYYYMMDD') || TO_CHAR(a.operacao);
      -- 1 = Saldo Inicial / 4 = Inventário Estoque
      IF a.operacao IN (1,4) THEN
        v_quantidade := 0;
        v_preco := 0;
        v_total := 0;
      END IF;
    END IF;
    -- 1 = Saldo Inicial / 2 = Atualiza Custo Médio / 4 = Inventário Estoque
    IF a.operacao IN (1,2,4) THEN
      IF a.entradaSaida = 'E' THEN
        v_quantidade := v_quantidade + a.quantidade;
        IF v_quantidade <= 0 THEN
          v_total := 0;
        ELSIF v_quantidade > a.quantidade THEN
          IF v_total + a.total > 9999999999999.99 THEN
             v_total := 9999999999999.99;
          ELSE
             v_total := v_total + a.total;
          END IF;
        ELSIF ROUND ((a.total * v_quantidade / a.quantidade),2) > 9999999999999.99 THEN
           v_total := 9999999999999.99;
        ELSE
           v_total := ROUND ((a.total * v_quantidade / a.quantidade),2);
        END IF;
     ELSE
        v_quantidade := v_quantidade - a.quantidade;
        v_total := v_total - a.total;
        IF v_total < 0 OR v_quantidade <= 0 THEN
          v_total := 0;
        END IF;
      END IF;
      IF v_total > 0 AND v_quantidade >= 0 AND ROUND(v_total / CASE WHEN v_quantidade = 0 THEN 1 ELSE v_quantidade END, 7) > 99999999.9999999 THEN
        v_preco := 99999999.9999999;
      ELSIF v_total > 0 AND v_quantidade >= 0 THEN
        v_preco := ROUND(v_total / CASE WHEN v_quantidade = 0 THEN 1 ELSE v_quantidade END, 7);
      END IF;
    -- Operação = 3 Não atualiza custo médio
    ELSIF a.entradaSaida = 'E' THEN
      v_quantidade := v_quantidade + a.quantidade;
      IF v_quantidade <= 0 THEN
        v_total := 0;
      ELSIF v_quantidade > a.quantidade THEN
        IF v_total + ROUND((a.quantidade * v_preco),2) > 9999999999999.99 THEN
           v_total := 9999999999999.99;
        ELSE
           v_total := v_total + a.total;
        END IF;
      ELSIF ROUND((v_quantidade * v_preco),2) > 9999999999999.99 THEN
         v_total := 9999999999999.99;
      ELSE
         v_total := ROUND((v_quantidade * v_preco),2);
      END IF;
    ELSE
      v_quantidade := v_quantidade - a.quantidade;
      v_total := v_total - a.quantidade * v_preco;
      IF v_total < 0 OR v_quantidade <= 0 THEN
        v_total := 0;
      END IF;
    END IF;
  END LOOP;
  IF v_preco = 0 THEN
    v_preco := FUNC_ADD_BUSCA_PRECO_PRODXEST(
      p_config_209_filtrarGrupoEcon,
      p_cab_estabelecimento,
      p_gradProd_produto,
      'C');
  END IF;
  RETURN v_preco;  
END;

/

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_GRAVA (
    p_estabelecimentoAtivo         IN NUMBER,
    p_idNumeroSerieOrcamento       IN NUMBER,
    p_idItemOrcamento              IN NUMBER,
    p_idEnderecoEstoqueOrcamento   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_idEnderecoEstoqueOrcamento   idEnderecoEstoqueOrcamento,
      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.idEnderecoEstoqueOrcamento    = b.idEnderecoEstoqueOrcamento,
    a.gradeProduto                  = b.gradeProduto,
    a.idNumeroSerie                 = b.idNumeroSerie,
    a.efetivado                     = b.efetivado
  WHEN NOT MATCHED THEN INSERT (
    idNumeroSerieOrcamento,
    idItemOrcamento,
    idEnderecoEstoqueOrcamento,
    gradeProduto,
    idNumeroSerie,
    efetivado)
  VALUES (
    b.idNumeroSerieOrcamento,
    b.idItemOrcamento,
    b.idEnderecoEstoqueOrcamento,
    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_idEnderecoEstoquePreDocument 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_idEnderecoEstoquePreDocument idEnderecoEstoquePreDocumento,
      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.idEnderecoEstoquePreDocumento = b.idEnderecoEstoquePreDocumento,
    a.gradeProduto                  = b.gradeProduto,
    a.idNumeroSerie                 = b.idNumeroSerie,
    a.devolvidoRetornado            = b.devolvidoRetornado
  WHEN NOT MATCHED THEN INSERT (
    idNumeroSeriePreDocumento,
    idItemPreDocumento,
    idEnderecoEstoquePreDocumento,
    gradeProduto,
    idNumeroSerie,
    devolvidoRetornado)
  VALUES (
    b.idNumeroSeriePreDocumento,
    b.idItemPreDocumento,
    b.idEnderecoEstoquePreDocumento,
    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_idEnderecoEstoqueDocFiscal 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_idEnderecoEstoqueDocFiscal idEnderecoEstoqueDocFiscal,
      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.idEnderecoEstoqueDocFiscal = b.idEnderecoEstoqueDocFiscal,
    a.gradeProduto               = b.gradeProduto,
    a.idNumeroSerie              = b.idNumeroSerie,
    a.devolvidoRetornado         = b.devolvidoRetornado
  WHEN NOT MATCHED THEN INSERT (
    idNumeroSerieDocFiscal,
    idItemDocFiscal,
    idEnderecoEstoqueDocFiscal,
    gradeProduto,
    idNumeroSerie,
    devolvidoRetornado)
  VALUES (
    b.idNumeroSerieDocFiscal,
    b.idItemDocFiscal,
    b.idEnderecoEstoqueDocFiscal,
    b.gradeProduto,
    b.idNumeroSerie,
    b.devolvidoRetornado);
END ADD_DOC_FISC_ITEM_N_SER_GRAVA;

/

create or replace PROCEDURE ADD_SEPARACAO_ITEM_N_SER_GRAVA (
    p_estabelecimentoAtivo       IN NUMBER,
    p_idNumeroSerieSeparacao     IN NUMBER,
    p_idItemSeparacao            IN NUMBER,
    p_idEnderecoEstoqueSeparacao IN NUMBER,
    p_gradeProduto               IN NUMBER,
    p_idNumeroSerie              IN NUMBER,
    /* Retornos */
    r_idNumeroSerieSeparacao     OUT NUMBER)
IS
BEGIN
  r_idNumeroSerieSeparacao := p_idNumeroSerieSeparacao;
  IF r_idNumeroSerieSeparacao = 0 THEN
    SELECT COALESCE(MAX(idNumeroSerieSeparacao),0)
    INTO r_idNumeroSerieSeparacao
    FROM MOSEPARACAOXNUMEROSSERIE
    WHERE idItemSeparacao = p_idItemSeparacao
    AND idNumeroSerie = p_idNumeroSerie;
  END IF; 
  IF r_idNumeroSerieSeparacao = 0 THEN
    r_idNumeroSerieSeparacao := FUNC_ADD_BUSCA_PROXIMO_ID('MOSEPARACAOXNUMEROSSERIE', 'idNumeroSerieSeparacao', 14, p_estabelecimentoAtivo, NULL);
  END IF;
  MERGE INTO MOSEPARACAOXNUMEROSSERIE a 
  USING (
    SELECT
      r_idNumeroSerieSeparacao     idNumeroSerieSeparacao,
      p_idItemSeparacao            idItemSeparacao,
      p_idEnderecoEstoqueSeparacao idEnderecoEstoqueSeparacao,
      p_gradeProduto               gradeProduto,
      p_idNumeroSerie              idNumeroSerie
    FROM DUAL
  ) b ON (a.idNumeroSerieSeparacao = b.idNumeroSerieSeparacao)
  WHEN MATCHED THEN UPDATE SET
    a.idItemSeparacao            = b.idItemSeparacao,
    a.idEnderecoEstoqueSeparacao = b.idEnderecoEstoqueSeparacao,
    a.gradeProduto               = b.gradeProduto,
    a.idNumeroSerie              = b.idNumeroSerie
  WHEN NOT MATCHED THEN INSERT (
    idNumeroSerieSeparacao,
    idItemSeparacao,
    idEnderecoEstoqueSeparacao,
    gradeProduto,
    idNumeroSerie)
  VALUES (
    b.idNumeroSerieSeparacao,
    b.idItemSeparacao,
    b.idEnderecoEstoqueSeparacao,
    b.gradeProduto,
    b.idNumeroSerie);
END ADD_SEPARACAO_ITEM_N_SER_GRAVA;

/

create or replace PROCEDURE ADD_ORCAMENTO_ITEM_GRAVA (
    p_uniqueMachineID              IN VARCHAR2,
    p_estabelecimentoAtivo         IN NUMBER,
    p_config_198_obs_add_referenc  IN NUMBER,
    p_config_199_obs_add_caractA   IN NUMBER,
    p_config_200_obs_add_caractB   IN NUMBER,
    p_config_201_obs_add_caractC   IN NUMBER,
    p_config_202_obs_add_caractD   IN NUMBER,
    p_config_203_obs_add_caractE   IN NUMBER,
    p_tempComp_nomeTempComposicao  IN VARCHAR2,
    p_tempComp_sequencia           IN NUMBER,
    p_cab_orcamento                IN NUMBER,
    p_cab_entradaSaida             IN CHAR,
    p_cab_estabelecimento          IN NUMBER,
    p_cab_dataEmissao              IN DATE,
    p_cab_dataEntrega              IN DATE,
    p_etOrc_situacaoOrcamento      IN NUMBER,
    p_item_idItemOrcamento         IN NUMBER,
    p_item_sequencia               IN NUMBER,
    p_a_item_cancelado             IN NUMBER,
    p_item_cancelado               IN NUMBER,
    p_item_modeloDocumento         IN NUMBER,
    p_item_estabelecimentoOriginal IN NUMBER,
    p_item_vendedor                IN NUMBER,
    p_a_item_gradeProduto          IN NUMBER,
    p_item_gradeProduto            IN NUMBER,
    p_item_servico                 IN NUMBER,
    p_item_atividadeServico        IN NUMBER,
    p_item_statusAtividadeServico  IN CHAR,
    p_a_item_idFormulaTinta        IN NUMBER,
    p_item_idFormulaTinta          IN NUMBER,
    p_item_personalizacao          IN NUMBER,
    p_a_item_idLoteEstoque         IN NUMBER,
    p_item_idLoteEstoque           IN NUMBER,
    p_item_vinculoItemDocumento    IN NUMBER,
    p_item_operacaoFiscal          IN NUMBER,
    p_a_item_movimentaEstoque      IN NUMBER,
    p_item_movimentaEstoque        IN NUMBER,
    p_item_geraFinanceiro          IN NUMBER,
    p_a_item_localEstoque          IN NUMBER,
    p_item_localEstoque            IN NUMBER,
    p_a_item_pessoaParticipante    IN NUMBER,
    p_item_pessoaParticipante      IN NUMBER,
    p_item_dataEntrega             IN DATE,
    p_item_controleQuantidade      IN NUMBER,
    p_item_unidadeMedidaConversao  IN VARCHAR2,
    p_item_conversorQuantidade     IN NUMBER,
    p_item_loteMinimo              IN NUMBER,
    p_item_loteMultiplo            IN NUMBER,
    p_item_altura                  IN NUMBER,
    p_item_largura                 IN NUMBER,
    p_item_comprimento             IN NUMBER,
    p_item_pecas                   IN NUMBER,
    p_item_quantidade              IN NUMBER,
    p_item_quantidadeConvertida    IN NUMBER,
    p_a_item_quantidadeSaldo       IN NUMBER,
    p_item_quantidadeSaldo         IN NUMBER,
    p_item_controleEntrega         IN NUMBER,
    p_item_situacaoEntrega         IN NUMBER,
    p_item_pesoLiquido             IN NUMBER,
    p_item_pesoBruto               IN NUMBER,
    p_item_tipoPreco               IN CHAR,
    p_item_tabelaPreco             IN VARCHAR2,
    p_item_precoSugestaoAPrazo     IN NUMBER,
    p_item_precoSugestaoAVista     IN NUMBER,
    p_item_precoDesconto           IN NUMBER,
    p_item_precoMinimo             IN NUMBER,
    p_item_usarPrecoAVista         IN NUMBER,
    p_item_precoPautaTabelado      IN NUMBER,
    p_item_precoUnitarioBruto      IN NUMBER,
    p_item_acrescimoUnitarioCompos IN NUMBER,
    p_item_precoUnitario           IN NUMBER,
    p_item_precoUnitarioConvertido IN NUMBER,
    p_item_valorProdutoServicoBrut IN NUMBER,
    p_item_valorProdutoServico     IN NUMBER,
    p_item_percDescontoItem        IN NUMBER,
    p_item_valorDescontoItem       IN NUMBER,
    p_item_percAcrescimoItem       IN NUMBER,
    p_item_valorAcrescimoItem      IN NUMBER,
    p_item_valorFreteItem          IN NUMBER,
    p_item_valorSeguroItem         IN NUMBER,
    p_item_valorAdicFreteMarItem   IN NUMBER,
    p_item_valorDespesasAduanItem  IN NUMBER,
    p_item_valorFreteGeral         IN NUMBER,
    p_item_valorSeguroGeral        IN NUMBER,
    p_item_valorDescontoGeral      IN NUMBER,
    p_item_valorOutrasDespGeral    IN NUMBER,
    p_item_valorAdicFreteMarGeral  IN NUMBER,
    p_item_valorDespesasAduanGeral IN NUMBER,
    p_item_valorBasePagamento      IN NUMBER,
    p_item_valorDescontoPagamento  IN NUMBER,
    p_item_valorOutrasDespPag      IN NUMBER,
    p_item_valorJurosPagamento     IN NUMBER,
    p_item_valorFreteTotal         IN NUMBER,
    p_item_valorSeguroTotal        IN NUMBER,
    p_item_valorDescontoTotal      IN NUMBER,
    p_item_valorOutrasDespTotal    IN NUMBER,
    p_item_valorAdicFreteMarTotal  IN NUMBER,
    p_item_valorDespesasAduanTotal IN NUMBER,
    p_item_cfop                    IN NUMBER,
    p_item_indicadorISSQN          IN CHAR,
    p_item_aliquotaISSQN           IN NUMBER,
    p_item_baseISSQN               IN NUMBER,
    p_item_valorISSQN              IN NUMBER,
    p_item_aliquotaIRRF            IN NUMBER,
    p_item_baseIRRF                IN NUMBER,
    p_item_valorIRRF               IN NUMBER,
    p_item_aliquotaINSS            IN NUMBER,
    p_item_baseINSS                IN NUMBER,
    p_item_valorINSS               IN NUMBER,
    p_item_retencaoPIS             IN NUMBER,
    p_item_baseRetPIS              IN NUMBER,
    p_item_valorRetPIS             IN NUMBER,
    p_item_retencaoCOFINS          IN NUMBER,
    p_item_baseRetCOFINS           IN NUMBER,
    p_item_valorRetCOFINS          IN NUMBER,
    p_item_retencaoCSLL            IN NUMBER,
    p_item_baseRetCSLL             IN NUMBER,
    p_item_valorRetCSLL            IN NUMBER,
    p_item_aliquotaII              IN NUMBER,
    p_item_baseII                  IN NUMBER,
    p_item_valorII                 IN NUMBER,
    p_item_aliquotaIOF             IN NUMBER,
    p_item_baseIOF                 IN NUMBER,
    p_item_valorIOF                IN NUMBER,
    p_item_codigoEnquadramentoIPI  IN NUMBER,
    p_item_stIPI                   IN CHAR,
    p_item_aliquotaIPI             IN NUMBER,
    p_item_valorAliquotaIPI        IN NUMBER,
    p_item_baseIPI                 IN NUMBER,
    p_item_valorIPI                IN NUMBER,
    p_item_stPIS                   IN CHAR,
    p_item_aliquotaPIS             IN NUMBER,
    p_item_valorAliquotaPIS        IN NUMBER,
    p_item_basePIS                 IN NUMBER,
    p_item_valorPIS                IN NUMBER,
    p_item_aliquotaPISST           IN NUMBER,
    p_item_valorAliquotaPISST      IN NUMBER,
    p_item_basePISST               IN NUMBER,
    p_item_valorPISST              IN NUMBER,
    p_item_stCOFINS                IN CHAR,
    p_item_aliquotaCOFINS          IN NUMBER,
    p_item_valorAliquotaCOFINS     IN NUMBER,
    p_item_baseCOFINS              IN NUMBER,
    p_item_valorCOFINS             IN NUMBER,
    p_item_aliquotaCOFINSST        IN NUMBER,
    p_item_valorAliquotaCOFINSST   IN NUMBER,
    p_item_baseCOFINSST            IN NUMBER,
    p_item_valorCOFINSST           IN NUMBER,
    p_item_stSimplesNacional       IN CHAR,
    p_item_creditoSimplesNacional  IN NUMBER,
    p_item_baseCreditoSimplesNac   IN NUMBER,
    p_item_valorCreditoSimplesNac  IN NUMBER,
    p_item_stICMS                  IN CHAR,
    p_item_modalBaseCalcICMS       IN CHAR,
    p_item_reducaoBaseICMS         IN NUMBER,
    p_item_aliquotaICMS            IN NUMBER,
    p_item_diferimentoICMS         IN NUMBER,
    p_item_motivoDesoneracaoICMS   IN CHAR,
    p_item_baseICMS                IN NUMBER,
    p_item_valorICMSOperacao       IN NUMBER,
    p_item_valorICMSDiferido       IN NUMBER,
    p_item_valorICMS               IN NUMBER,
    p_item_valorICMSDesoneracao    IN NUMBER,
    p_item_modalBaseCalcICMSST     IN CHAR,
    p_item_margemValorAdicionadoST IN NUMBER,
    p_item_reducaoBaseST           IN NUMBER,
    p_item_aliquotaICMSST          IN NUMBER,
    p_item_aliquotaSTSuportConsFin IN NUMBER,
    p_item_baseICMSST              IN NUMBER,
    p_item_valorICMSST             IN NUMBER,
    p_item_baseICMSSTAnteriormente IN NUMBER,
    p_item_valorICMSSTAnteriorm    IN NUMBER,
    p_item_valorICMSProprioSubstit IN NUMBER,
    p_item_reducaoBaseICMSEfetivo  IN NUMBER,
    p_item_aliquotaICMSEfetivo     IN NUMBER,
    p_item_baseICMSEfetivo         IN NUMBER,
    p_item_valorICMSEfetivo        IN NUMBER,
    p_item_aliquotaICMSUFDestinat  IN NUMBER,
    p_item_aliquotaICMSInterestad  IN NUMBER,
    p_item_partilhaICMSInterestad  IN NUMBER,
    p_item_baseICMSUFDestinatario  IN NUMBER,
    p_item_valorICMSUFDestinatario IN NUMBER,
    p_item_baseICMSUFRemetente     IN NUMBER,
    p_item_valorICMSUFRemetente    IN NUMBER,
    p_item_aliquotaFCP             IN NUMBER,
    p_item_baseFCP                 IN NUMBER,
    p_item_valorFCP                IN NUMBER,
    p_item_aliquotaFCPST           IN NUMBER,
    p_item_baseFCPST               IN NUMBER,
    p_item_valorFCPST              IN NUMBER,
    p_item_aliquotaFCPSTAnteriorm  IN NUMBER,
    p_item_baseFCPSTAnteriormente  IN NUMBER,
    p_item_valorFCPSTAnteriormente IN NUMBER,
    p_item_aliquotaFCPUFDestinat   IN NUMBER,
    p_item_baseFCPUFDestinatario   IN NUMBER,
    p_item_valorFCPUFDestinatario  IN NUMBER,
    p_item_aliquotaEstImpFederais  IN NUMBER,
    p_item_aliquotaEstImpEstaduais IN NUMBER,
    p_item_aliquotaEstImpMunicipai IN NUMBER,
    p_item_baseEstimadaImpostos    IN NUMBER,
    p_item_valorEstImpFederais     IN NUMBER,
    p_item_valorEstImpEstaduais    IN NUMBER,
    p_item_valorEstImpMunicipais   IN NUMBER,
    p_item_valorImpostosSomaPag    IN NUMBER,
    p_item_valorImpostosDiminuiPag IN NUMBER,
    p_item_valorLiquidoItem        IN NUMBER,
    p_item_observacoesDigitadas    IN VARCHAR2,
    /* Retornos */
    r_item_idItemOrcamento         OUT NUMBER)
IS
    v_item_observacoes             VARCHAR2 (4000);
    v_auxVarchar                   VARCHAR2 (32000);
BEGIN
  r_item_idItemOrcamento := p_item_idItemOrcamento;
  IF r_item_idItemOrcamento = 0 THEN
    r_item_idItemOrcamento := FUNC_ADD_BUSCA_PROXIMO_ID ('MOORCAMENTOXITENS', 'idItemOrcamento', 14, p_estabelecimentoAtivo, NULL);
  END IF;
  v_item_observacoes := FUNC_ADD_MONTA_OBSERVACAO_ITEM (
    p_uniqueMachineID,
    p_config_198_obs_add_referenc,
    p_config_199_obs_add_caractA,
    p_config_200_obs_add_caractB,
    p_config_201_obs_add_caractC,
    p_config_202_obs_add_caractD,
    p_config_203_obs_add_caractE,
    p_tempComp_nomeTempComposicao,
    p_tempComp_sequencia,
    'O',
    r_item_idItemOrcamento,
    p_item_gradeProduto,
    p_item_idFormulaTinta,
    p_item_personalizacao,
    p_item_idLoteEstoque,
    p_item_controleQuantidade,
    p_item_loteMultiplo,
    p_item_altura,
    p_item_largura,
    p_item_comprimento,
    p_item_quantidade,
    p_item_observacoesDigitadas);
  MERGE INTO MOORCAMENTOXITENS a USING (
    SELECT
      r_item_idItemOrcamento         idItemOrcamento,
      p_cab_orcamento                orcamento,
      p_item_sequencia               sequencia,
      p_item_cancelado               cancelado,
      p_item_modeloDocumento         modeloDocumento,
      p_item_estabelecimentoOriginal estabelecimentoOriginal,
      p_item_vendedor                vendedor,
      p_item_gradeProduto            gradeProduto,
      p_item_servico                 servico,
      p_item_atividadeServico        atividadeServico,
      p_item_statusAtividadeServico  statusAtividadeServico,
      p_item_idFormulaTinta          idFormulaTinta,
      p_item_personalizacao          personalizacao,
      p_item_idLoteEstoque           idLoteEstoque,
      p_item_vinculoItemDocumento    vinculoItemDocumento,
      p_item_operacaoFiscal          operacaoFiscal,
      p_item_movimentaEstoque        movimentaEstoque,
      p_item_geraFinanceiro          geraFinanceiro,
      p_item_localEstoque            localEstoque,
      p_item_pessoaParticipante      pessoaParticipante,
      p_item_dataEntrega             dataEntrega,
      p_item_controleQuantidade      controleQuantidade,
      p_item_unidadeMedidaConversao  unidadeMedidaConversao,
      p_item_conversorQuantidade     conversorQuantidade,
      p_item_loteMinimo              loteMinimo,
      p_item_loteMultiplo            loteMultiplo,
      p_item_altura                  altura,
      p_item_largura                 largura,
      p_item_comprimento             comprimento,
      p_item_pecas                   pecas,
      p_item_quantidade              quantidade,
      p_item_quantidadeConvertida    quantidadeConvertida,
      p_item_quantidadeSaldo         quantidadeSaldo,
      p_item_controleEntrega         controleEntrega,
      p_item_situacaoEntrega         situacaoEntrega,
      p_item_pesoLiquido             pesoLiquido,
      p_item_pesoBruto               pesoBruto,
      p_item_tipoPreco               tipoPreco,
      p_item_tabelaPreco             tabelaPreco,
      p_item_precoSugestaoAPrazo     precoSugestaoAPrazo,
      p_item_precoSugestaoAVista     precoSugestaoAVista,
      p_item_precoDesconto           precoDesconto,
      p_item_precoMinimo             precoMinimo,
      p_item_usarPrecoAVista         usarPrecoAVista,
      p_item_precoPautaTabelado      precoPautaTabelado,
      p_item_precoUnitarioBruto      precoUnitarioBruto,
      p_item_acrescimoUnitarioCompos acrescimoUnitarioComposicao,
      p_item_precoUnitario           precoUnitario,
      p_item_precoUnitarioConvertido precoUnitarioConvertido,
      p_item_valorProdutoServicoBrut valorProdutoServicoBruto,
      p_item_valorProdutoServico     valorProdutoServico,
      p_item_percDescontoItem        percDescontoItem,
      p_item_valorDescontoItem       valorDescontoItem,
      p_item_percAcrescimoItem       percAcrescimoItem,
      p_item_valorAcrescimoItem      valorAcrescimoItem,
      p_item_valorFreteItem          valorFreteItem,
      p_item_valorSeguroItem         valorSeguroItem,
      p_item_valorAdicFreteMarItem   valorAdicFreteMarinhaMerItem,
      p_item_valorDespesasAduanItem  valorDespesasAduaneirasItem,
      p_item_valorFreteGeral         valorFreteGeral,
      p_item_valorSeguroGeral        valorSeguroGeral,
      p_item_valorDescontoGeral      valorDescontoGeral,
      p_item_valorOutrasDespGeral    valorOutrasDespesasGeral,
      p_item_valorAdicFreteMarGeral  valorAdicFreteMarinhaMerGeral,
      p_item_valorDespesasAduanGeral valorDespesasAduaneirasGeral,
      p_item_valorBasePagamento      valorBasePagamento,
      p_item_valorDescontoPagamento  valorDescontoPagamento,
      p_item_valorOutrasDespPag      valorOutrasDespesasPagamento,
      p_item_valorJurosPagamento     valorJurosPagamento,
      p_item_valorFreteTotal         valorFreteTotal,
      p_item_valorSeguroTotal        valorSeguroTotal,
      p_item_valorDescontoTotal      valorDescontoTotal,
      p_item_valorOutrasDespTotal    valorOutrasDespesasTotal,
      p_item_valorAdicFreteMarTotal  valorAdicFreteMarinhaMerTotal,
      p_item_valorDespesasAduanTotal valorDespesasAduaneirasTotal,
      p_item_cfop                    cfop,
      p_item_indicadorISSQN          indicadorISSQN,
      p_item_aliquotaISSQN           aliquotaISSQN,
      p_item_baseISSQN               baseISSQN,
      p_item_valorISSQN              valorISSQN,
      p_item_aliquotaIRRF            aliquotaIRRF,
      p_item_baseIRRF                baseIRRF,
      p_item_valorIRRF               valorIRRF,
      p_item_aliquotaINSS            aliquotaINSS,
      p_item_baseINSS                baseINSS,
      p_item_valorINSS               valorINSS,
      p_item_retencaoPIS             retencaoPIS,
      p_item_baseRetPIS              baseRetPIS,
      p_item_valorRetPIS             valorRetPIS,
      p_item_retencaoCOFINS          retencaoCOFINS,
      p_item_baseRetCOFINS           baseRetCOFINS,
      p_item_valorRetCOFINS          valorRetCOFINS,
      p_item_retencaoCSLL            retencaoCSLL,
      p_item_baseRetCSLL             baseRetCSLL,
      p_item_valorRetCSLL            valorRetCSLL,
      p_item_aliquotaII              aliquotaII,
      p_item_baseII                  baseII,
      p_item_valorII                 valorII,
      p_item_aliquotaIOF             aliquotaIOF,
      p_item_baseIOF                 baseIOF,
      p_item_valorIOF                valorIOF,
      p_item_codigoEnquadramentoIPI  codigoEnquadramentoIPI,
      p_item_stIPI                   stIPI,
      p_item_aliquotaIPI             aliquotaIPI,
      p_item_valorAliquotaIPI        valorAliquotaIPI,
      p_item_baseIPI                 baseIPI,
      p_item_valorIPI                valorIPI,
      p_item_stPIS                   stPIS,
      p_item_aliquotaPIS             aliquotaPIS,
      p_item_valorAliquotaPIS        valorAliquotaPIS,
      p_item_basePIS                 basePIS,
      p_item_valorPIS                valorPIS,
      p_item_aliquotaPISST           aliquotaPISST,
      p_item_valorAliquotaPISST      valorAliquotaPISST,
      p_item_basePISST               basePISST,
      p_item_valorPISST              valorPISST,
      p_item_stCOFINS                stCOFINS,
      p_item_aliquotaCOFINS          aliquotaCOFINS,
      p_item_valorAliquotaCOFINS     valorAliquotaCOFINS,
      p_item_baseCOFINS              baseCOFINS,
      p_item_valorCOFINS             valorCOFINS,
      p_item_aliquotaCOFINSST        aliquotaCOFINSST,
      p_item_valorAliquotaCOFINSST   valorAliquotaCOFINSST,
      p_item_baseCOFINSST            baseCOFINSST,
      p_item_valorCOFINSST           valorCOFINSST,
      p_item_stSimplesNacional       stSimplesNacional,
      p_item_creditoSimplesNacional  creditoSimplesNacional,
      p_item_baseCreditoSimplesNac   baseCreditoSimplesNacional,
      p_item_valorCreditoSimplesNac  valorCreditoSimplesNacional,
      p_item_stICMS                  stICMS,
      p_item_modalBaseCalcICMS       modalidadeBaseCalcICMS,
      p_item_reducaoBaseICMS         reducaoBaseICMS,
      p_item_aliquotaICMS            aliquotaICMS,
      p_item_diferimentoICMS         diferimentoICMS,
      p_item_motivoDesoneracaoICMS   motivoDesoneracaoICMS,
      p_item_baseICMS                baseICMS,
      p_item_valorICMSOperacao       valorICMSOperacao,
      p_item_valorICMSDiferido       valorICMSDiferido,
      p_item_valorICMS               valorICMS,
      p_item_valorICMSDesoneracao    valorICMSDesoneracao,
      p_item_modalBaseCalcICMSST     modalidadeBaseCalcICMSST,
      p_item_margemValorAdicionadoST margemValorAdicionadoST,
      p_item_reducaoBaseST           reducaoBaseST,
      p_item_aliquotaICMSST          aliquotaICMSST,
      p_item_aliquotaSTSuportConsFin aliquotaSTSuportConsFinal,
      p_item_baseICMSST              baseICMSST,
      p_item_valorICMSST             valorICMSST,
      p_item_baseICMSSTAnteriormente baseICMSSTAnteriormente,
      p_item_valorICMSSTAnteriorm    valorICMSSTAnteriormente,
      p_item_valorICMSProprioSubstit valorICMSProprioSubstituto,
      p_item_reducaoBaseICMSEfetivo  reducaoBaseICMSEfetivo,
      p_item_aliquotaICMSEfetivo     aliquotaICMSEfetivo,
      p_item_baseICMSEfetivo         baseICMSEfetivo,
      p_item_valorICMSEfetivo        valorICMSEfetivo,
      p_item_aliquotaICMSUFDestinat  aliquotaICMSUFDestinatario,
      p_item_aliquotaICMSInterestad  aliquotaICMSInterestadual,
      p_item_partilhaICMSInterestad  partilhaICMSInterestadual,
      p_item_baseICMSUFDestinatario  baseICMSUFDestinatario,
      p_item_valorICMSUFDestinatario valorICMSUFDestinatario,
      p_item_baseICMSUFRemetente     baseICMSUFRemetente,
      p_item_valorICMSUFRemetente    valorICMSUFRemetente,
      p_item_aliquotaFCP             aliquotaFCP,
      p_item_baseFCP                 baseFCP,
      p_item_valorFCP                valorFCP,
      p_item_aliquotaFCPST           aliquotaFCPST,
      p_item_baseFCPST               baseFCPST,
      p_item_valorFCPST              valorFCPST,
      p_item_aliquotaFCPSTAnteriorm  aliquotaFCPSTAnteriormente,
      p_item_baseFCPSTAnteriormente  baseFCPSTAnteriormente,
      p_item_valorFCPSTAnteriormente valorFCPSTAnteriormente,
      p_item_aliquotaFCPUFDestinat   aliquotaFCPUFDestinatario,
      p_item_baseFCPUFDestinatario   baseFCPUFDestinatario,
      p_item_valorFCPUFDestinatario  valorFCPUFDestinatario,
      p_item_aliquotaEstImpFederais  aliquotaEstimadaImpFederais,
      p_item_aliquotaEstImpEstaduais aliquotaEstimadaImpEstaduais,
      p_item_aliquotaEstImpMunicipai aliquotaEstimadaImpMunicipais,
      p_item_baseEstimadaImpostos    baseEstimadaImpostos,
      p_item_valorEstImpFederais     valorEstimadoImpFederais,
      p_item_valorEstImpEstaduais    valorEstimadoImpEstaduais,
      p_item_valorEstImpMunicipais   valorEstimadoImpMunicipais,
      p_item_valorImpostosSomaPag    valorImpostosSomaPagamento,
      p_item_valorImpostosDiminuiPag valorImpostosDiminuiPagamento,
      p_item_valorLiquidoItem        valorLiquidoItem,
      p_item_observacoesDigitadas    observacoesDigitadas,
      v_item_observacoes             observacoes
    FROM DUAL) b ON (a.idItemOrcamento = b.idItemOrcamento)
  WHEN MATCHED THEN UPDATE SET
    a.orcamento                     = b.orcamento,
    a.sequencia                     = b.sequencia,
    a.cancelado                     = b.cancelado,
    a.vendedor                      = b.vendedor,
    a.modeloDocumento               = b.modeloDocumento,
    a.estabelecimentoOriginal       = b.estabelecimentoOriginal,
    a.gradeProduto                  = b.gradeProduto,
    a.servico                       = b.servico,
    a.atividadeServico              = b.atividadeServico,
    a.statusAtividadeServico        = b.statusAtividadeServico,
    a.idFormulaTinta                = b.idFormulaTinta,
    a.personalizacao                = b.personalizacao,
    a.idLoteEstoque                 = b.idLoteEstoque,
    a.vinculoItemDocumento          = b.vinculoItemDocumento,
    a.operacaoFiscal                = b.operacaoFiscal,
    a.movimentaEstoque              = b.movimentaEstoque,
    a.geraFinanceiro                = b.geraFinanceiro,
    a.localEstoque                  = b.localEstoque,
    a.pessoaParticipante            = b.pessoaParticipante,
    a.dataEntrega                   = b.dataEntrega,
    a.controleQuantidade            = b.controleQuantidade,
    a.unidadeMedidaConversao        = b.unidadeMedidaConversao,
    a.conversorQuantidade           = b.conversorQuantidade,
    a.loteMinimo                    = b.loteMinimo,
    a.loteMultiplo                  = b.loteMultiplo,
    a.altura                        = b.altura,
    a.largura                       = b.largura,
    a.comprimento                   = b.comprimento,
    a.pecas                         = b.pecas,
    a.quantidade                    = b.quantidade,
    a.quantidadeConvertida          = b.quantidadeConvertida,
    a.quantidadeSaldo               = b.quantidadeSaldo,
    a.controleEntrega               = b.controleEntrega,
    a.situacaoEntrega               = b.situacaoEntrega,
    a.pesoLiquido                   = b.pesoLiquido,
    a.pesoBruto                     = b.pesoBruto,
    a.tipoPreco                     = b.tipoPreco,
    a.tabelaPreco                   = b.tabelaPreco,
    a.precoSugestaoAPrazo           = b.precoSugestaoAPrazo,
    a.precoSugestaoAVista           = b.precoSugestaoAVista,
    a.precoDesconto                 = b.precoDesconto,
    a.precoMinimo                   = b.precoMinimo,
    a.usarPrecoAVista               = b.usarPrecoAVista,
    a.precoPautaTabelado            = b.precoPautaTabelado,
    a.precoUnitarioBruto            = b.precoUnitarioBruto,
    a.acrescimoUnitarioComposicao   = b.acrescimoUnitarioComposicao,
    a.precoUnitario                 = b.precoUnitario,
    a.precoUnitarioConvertido       = b.precounitarioConvertido,
    a.valorProdutoServicoBruto      = b.valorProdutoServicoBruto,
    a.valorProdutoServico           = b.valorProdutoServico,
    a.percDescontoItem              = b.percDescontoItem,
    a.valorDescontoItem             = b.valorDescontoItem,
    a.percAcrescimoItem             = b.percAcrescimoItem,
    a.valorAcrescimoItem            = b.valorAcrescimoItem,
    a.valorFreteItem                = b.valorFreteItem,
    a.valorSeguroItem               = b.valorSeguroItem,
    a.valorAdicFreteMarinhaMerItem  = b.valorAdicFreteMarinhaMerItem,
    a.valorDespesasAduaneirasItem   = b.valorDespesasAduaneirasItem,
    a.valorFreteGeral               = b.valorFreteGeral,
    a.valorSeguroGeral              = b.valorSeguroGeral,
    a.valorDescontoGeral            = b.valorDescontoGeral,
    a.valorOutrasDespesasGeral      = b.valorOutrasDespesasGeral,
    a.valorAdicFreteMarinhaMerGeral = b.valorAdicFreteMarinhaMerGeral,
    a.valorDespesasAduaneirasGeral  = b.valorDespesasAduaneirasGeral,
    a.valorBasePagamento            = b.valorBasePagamento,
    a.valorDescontoPagamento        = b.valorDescontoPagamento,
    a.valorOutrasDespesasPagamento  = b.valorOutrasDespesasPagamento,
    a.valorJurosPagamento           = b.valorJurosPagamento,
    a.valorFreteTotal               = b.valorFreteTotal,
    a.valorSeguroTotal              = b.valorSeguroTotal,
    a.valorDescontoTotal            = b.valorDescontoTotal,
    a.valorOutrasDespesasTotal      = b.valorOutrasDespesasTotal,
    a.valorAdicFreteMarinhaMerTotal = b.valorAdicFreteMarinhaMerTotal,
    a.valorDespesasAduaneirasTotal  = b.valorDespesasAduaneirasTotal,
    a.cfop                          = b.cfop,
    a.indicadorISSQN                = b.indicadorISSQN,
    a.aliquotaISSQN                 = b.aliquotaISSQN,
    a.baseISSQN                     = b.baseISSQN,
    a.valorISSQN                    = b.valorISSQN,
    a.aliquotaIRRF                  = b.aliquotaIRRF,
    a.baseIRRF                      = b.baseIRRF,
    a.valorIRRF                     = b.valorIRRF,
    a.aliquotaINSS                  = b.aliquotaINSS,
    a.baseINSS                      = b.baseINSS,
    a.valorINSS                     = b.valorINSS,
    a.retencaoPIS                   = b.retencaoPIS,
    a.baseRetPIS                    = b.baseRetPIS,
    a.valorRetPIS                   = b.valorRetPIS,
    a.retencaoCOFINS                = b.retencaoCOFINS,
    a.baseRetCOFINS                 = b.baseRetCOFINS,
    a.valorRetCOFINS                = b.valorRetCOFINS,
    a.retencaoCSLL                  = b.retencaoCSLL,
    a.baseRetCSLL                   = b.baseRetCSLL,
    a.valorRetCSLL                  = b.valorRetCSLL,
    a.aliquotaII                    = b.aliquotaII,
    a.baseII                        = b.baseII,
    a.valorII                       = b.valorII,
    a.aliquotaIOF                   = b.aliquotaIOF,
    a.baseIOF                       = b.baseIOF,
    a.valorIOF                      = b.valorIOF,
    a.codigoEnquadramentoIPI        = b.codigoEnquadramentoIPI,
    a.stIPI                         = b.stIPI,
    a.aliquotaIPI                   = b.aliquotaIPI,
    a.valorAliquotaIPI              = b.valorAliquotaIPI,
    a.baseIPI                       = b.baseIPI,
    a.valorIPI                      = b.valorIPI,
    a.stPIS                         = b.stPIS,
    a.aliquotaPIS                   = b.aliquotaPIS,
    a.valorAliquotaPIS              = b.valorAliquotaPIS,
    a.basePIS                       = b.basePIS,
    a.valorPIS                      = b.valorPIS,
    a.aliquotaPISST                 = b.aliquotaPISST,
    a.valorAliquotaPISST            = b.valorAliquotaPISST,
    a.basePISST                     = b.basePISST,
    a.valorPISST                    = b.valorPISST,
    a.stCOFINS                      = b.stCOFINS,
    a.aliquotaCOFINS                = b.aliquotaCOFINS,
    a.valorAliquotaCOFINS           = b.valorAliquotaCOFINS,
    a.baseCOFINS                    = b.baseCOFINS,
    a.valorCOFINS                   = b.valorCOFINS,
    a.aliquotaCOFINSST              = b.aliquotaCOFINSST,
    a.valorAliquotaCOFINSST         = b.valorAliquotaCOFINSST,
    a.baseCOFINSST                  = b.baseCOFINSST,
    a.valorCOFINSST                 = b.valorCOFINSST,
    a.stSimplesNacional             = b.stSimplesNacional,
    a.creditoSimplesNacional        = b.creditoSimplesNacional,
    a.baseCreditoSimplesNacional    = b.baseCreditoSimplesNacional,
    a.valorCreditoSimplesNacional   = b.valorCreditoSimplesNacional,
    a.stICMS                        = b.stICMS,
    a.modalidadeBaseCalcICMS        = b.modalidadeBaseCalcICMS,
    a.reducaoBaseICMS               = b.reducaoBaseICMS,
    a.aliquotaICMS                  = b.aliquotaICMS,
    a.diferimentoICMS               = b.diferimentoICMS,
    a.motivoDesoneracaoICMS         = b.motivoDesoneracaoICMS,
    a.baseICMS                      = b.baseICMS,
    a.valorICMSoperacao             = b.valorICMSoperacao,
    a.valorICMSdiferido             = b.valorICMSdiferido,
    a.valorICMS                     = b.valorICMS,
    a.valorICMSdesoneracao          = b.valorICMSdesoneracao,
    a.modalidadeBaseCalcICMSST      = b.modalidadeBaseCalcICMSST,
    a.margemValorAdicionadoST       = b.margemValorAdicionadoST,
    a.reducaoBaseST                 = b.reducaoBaseST,
    a.aliquotaICMSST                = b.aliquotaICMSST,
    a.aliquotaSTSuportConsFinal     = b.aliquotaSTSuportConsFinal,
    a.baseICMSST                    = b.baseICMSST,
    a.valorICMSST                   = b.valorICMSST,
    a.baseICMSSTAnteriormente       = b.baseICMSSTAnteriormente,
    a.valorICMSSTAnteriormente      = b.valorICMSSTAnteriormente,
    a.valorICMSProprioSubstituto    = b.valorICMSProprioSubstituto,
    a.reducaoBaseICMSEfetivo        = b.reducaoBaseICMSEfetivo,
    a.aliquotaICMSEfetivo           = b.aliquotaICMSEfetivo,
    a.baseICMSEfetivo               = b.baseICMSEfetivo,
    a.valorICMSEfetivo              = b.valorICMSEfetivo,
    a.aliquotaICMSUFDestinatario    = b.aliquotaICMSUFDestinatario,
    a.aliquotaICMSInterestadual     = b.aliquotaICMSInterestadual,
    a.partilhaICMSInterestadual     = b.partilhaICMSInterestadual,
    a.baseICMSUFDestinatario        = b.baseICMSUFDestinatario,
    a.valorICMSUFDestinatario       = b.valorICMSUFDestinatario,
    a.baseICMSUFRemetente           = b.baseICMSUFRemetente,
    a.valorICMSUFRemetente          = b.valorICMSUFRemetente,
    a.aliquotaFCP                   = b.aliquotaFCP,
    a.baseFCP                       = b.baseFCP,
    a.valorFCP                      = b.valorFCP,
    a.aliquotaFCPST                 = b.aliquotaFCPST,
    a.baseFCPST                     = b.baseFCPST,
    a.valorFCPST                    = b.valorFCPST,
    a.aliquotaFCPSTAnteriormente    = b.aliquotaFCPSTAnteriormente,
    a.baseFCPSTAnteriormente        = b.baseFCPSTAnteriormente,
    a.valorFCPSTAnteriormente       = b.valorFCPSTAnteriormente,
    a.aliquotaFCPUFDestinatario     = b.aliquotaFCPUFDestinatario,
    a.baseFCPUFDestinatario         = b.baseFCPUFDestinatario,
    a.valorFCPUFDestinatario        = b.valorFCPUFDestinatario,
    a.aliquotaestimadaimpfederais   = b.aliquotaestimadaimpfederais,
    a.aliquotaestimadaimpestaduais  = b.aliquotaestimadaimpestaduais,
    a.aliquotaestimadaimpmunicipais = b.aliquotaestimadaimpmunicipais,
    a.baseestimadaimpostos          = b.baseestimadaimpostos,
    a.valorestimadoimpfederais      = b.valorestimadoimpfederais,
    a.valorEstimadoImpEstaduais     = b.valorEstimadoImpEstaduais,
    a.valorEstimadoImpMunicipais    = b.valorEstimadoImpMunicipais,
    a.valorImpostosSomaPagamento    = b.valorImpostosSomaPagamento,
    a.valorImpostosDiminuiPagamento = b.valorImpostosDiminuiPagamento,
    a.valorLiquidoItem              = b.valorLiquidoItem,
    a.observacoesDigitadas          = b.observacoesDigitadas,
    a.observacoes                   = b.observacoes
  WHEN NOT MATCHED THEN INSERT (
    idItemOrcamento,
    orcamento,
    sequencia,
    cancelado,
    modeloDocumento,
    estabelecimentoOriginal,
    vendedor,
    gradeProduto,
    servico,
    atividadeServico,
    statusAtividadeServico,
    idFormulaTinta,
    personalizacao,
    idLoteEstoque,
    vinculoItemDocumento,
    operacaoFiscal,
    movimentaEstoque,
    geraFinanceiro,
    localEstoque,
    pessoaParticipante,
    dataEntrega,
    controleQuantidade,
    unidadeMedidaConversao,
    conversorQuantidade,
    loteMinimo,
    loteMultiplo,
    altura,
    largura,
    comprimento,
    pecas,
    quantidade,
    quantidadeConvertida,
    quantidadeSaldo,
    controleEntrega,
    situacaoEntrega,
    pesoLiquido,
    pesoBruto,
    tipoPreco,
    tabelaPreco,
    precoSugestaoAPrazo,
    precoSugestaoAVista,
    precoDesconto,
    precoMinimo,
    usarPrecoAVista,
    precoPautaTabelado,
    precoUnitarioBruto,
    acrescimoUnitarioComposicao,
    precoUnitario,
    precoUnitarioConvertido,
    valorProdutoServicoBruto,
    valorProdutoServico,
    percDescontoItem,
    valorDescontoItem,
    percAcrescimoItem,
    valorAcrescimoItem,
    valorFreteItem,
    valorSeguroItem,
    valorAdicFreteMarinhaMerItem,
    valorDespesasAduaneirasItem,
    valorFreteGeral,
    valorSeguroGeral,
    valorDescontoGeral,
    valorOutrasDespesasGeral,
    valorAdicFreteMarinhaMerGeral,
    valorDespesasAduaneirasGeral,
    valorBasePagamento,
    valorDescontoPagamento,
    valorOutrasDespesasPagamento,
    valorJurosPagamento,
    valorFreteTotal,
    valorSeguroTotal,
    valorDescontoTotal,
    valorOutrasDespesasTotal,
    valorAdicFreteMarinhaMerTotal,
    valorDespesasAduaneirasTotal,
    cfop,
    indicadorISSQN,
    aliquotaISSQN,
    baseISSQN,
    valorISSQN,
    aliquotaIRRF,
    baseIRRF,
    valorIRRF,
    aliquotaINSS,
    baseINSS,
    valorINSS,
    retencaoPIS,
    baseRetPIS,
    valorRetPIS,
    retencaoCOFINS,
    baseRetCOFINS,
    valorRetCOFINS,
    retencaoCSLL,
    baseRetCSLL,
    valorRetCSLL,
    aliquotaII,
    baseII,
    valorII,
    aliquotaIOF,
    baseIOF,
    valorIOF,
    codigoEnquadramentoIPI,
    stIPI,
    aliquotaIPI,
    valorAliquotaIPI,
    baseIPI,
    valorIPI,
    stPIS,
    aliquotaPIS,
    valorAliquotaPIS,
    basePIS,
    valorPIS,
    aliquotaPISST,
    valorAliquotaPISST,
    basePISST,
    valorPISST,
    stCOFINS,
    aliquotaCOFINS,
    valorAliquotaCOFINS,
    baseCOFINS,
    valorCOFINS,
    aliquotaCOFINSST,
    valorAliquotaCOFINSST,
    baseCOFINSST,
    valorCOFINSST,
    stSimplesNacional,
    creditoSimplesNacional,
    baseCreditoSimplesNacional,
    valorCreditoSimplesNacional,
    stICMS,
    modalidadeBaseCalcICMS,
    reducaoBaseICMS,
    aliquotaICMS,
    diferimentoICMS,
    motivoDesoneracaoICMS,
    baseICMS,
    valorICMSOperacao,
    valorICMSDiferido,
    valorICMS,
    valorICMSDesoneracao,
    modalidadeBaseCalcICMSST,
    margemValorAdicionadoST,
    reducaoBaseST,
    aliquotaICMSST,
    aliquotaSTSuportConsFinal,
    baseICMSST,
    valorICMSST,
    baseICMSSTAnteriormente,
    valorICMSSTAnteriormente,
    valorICMSProprioSubstituto,
    reducaoBaseICMSEfetivo,
    aliquotaICMSEfetivo,
    baseICMSEfetivo,
    valorICMSEfetivo,
    aliquotaICMSUFDestinatario,
    aliquotaICMSInterestadual,
    partilhaICMSInterestadual,
    baseICMSUFDestinatario,
    valorICMSUFDestinatario,
    baseICMSUFRemetente,
    valorICMSUFRemetente,
    aliquotaFCP,
    baseFCP,
    valorFCP,
    aliquotaFCPST,
    baseFCPST,
    valorFCPST,
    aliquotaFCPSTAnteriormente,
    baseFCPSTAnteriormente,
    valorFCPSTAnteriormente,
    aliquotaFCPUFDestinatario,
    baseFCPUFDestinatario,
    valorFCPUFDestinatario,
    aliquotaEstimadaImpFederais,
    aliquotaEstimadaImpEstaduais,
    aliquotaEstimadaImpMunicipais,
    baseEstimadaImpostos,
    valorEstimadoImpFederais,
    valorEstimadoImpEstaduais,
    valorEstimadoImpMunicipais,
    valorImpostosSomaPagamento,
    valorImpostosDiminuiPagamento,
    valorLiquidoItem,
    observacoesDigitadas,
    observacoes)
  VALUES (
    b.idItemOrcamento,
    b.orcamento,
    b.sequencia,
    b.cancelado,
    b.modeloDocumento,
    b.estabelecimentoOriginal,
    b.vendedor,
    b.gradeProduto,
    b.servico,
    b.atividadeServico,
    b.statusAtividadeServico,
    b.idFormulaTinta,
    b.personalizacao,
    b.idLoteEstoque,
    b.vinculoItemDocumento,
    b.operacaoFiscal,
    b.movimentaEstoque,
    b.geraFinanceiro,
    b.localEstoque,
    b.pessoaParticipante,
    b.dataEntrega,
    b.controleQuantidade,
    b.unidadeMedidaConversao,
    b.conversorQuantidade,
    b.loteMinimo,
    b.loteMultiplo,
    b.altura,
    b.largura,
    b.comprimento,
    b.pecas,
    b.quantidade,
    b.quantidadeConvertida,
    b.quantidadeSaldo,
    b.controleEntrega,
    b.situacaoEntrega,
    b.pesoLiquido,
    b.pesoBruto,
    b.tipoPreco,
    b.tabelaPreco,
    b.precoSugestaoAPrazo,
    b.precoSugestaoAVista,
    b.precoDesconto,
    b.precoMinimo,
    b.usarPrecoAVista,
    b.precoPautaTabelado,
    b.precoUnitarioBruto,
    b.acrescimoUnitarioComposicao,
    b.precoUnitario,
    b.precoUnitarioConvertido,
    b.valorProdutoServicoBruto,
    b.valorProdutoServico,
    b.percDescontoItem,
    b.valorDescontoItem,
    b.percAcrescimoItem,
    b.valorAcrescimoItem,
    b.valorFreteItem,
    b.valorSeguroItem,
    b.valorAdicFreteMarinhaMerItem,
    b.valorDespesasAduaneirasItem,
    b.valorFreteGeral,
    b.valorSeguroGeral,
    b.valorDescontoGeral,
    b.valorOutrasDespesasGeral,
    b.valorAdicFreteMarinhaMerGeral,
    b.valorDespesasAduaneirasGeral,
    b.valorBasePagamento,
    b.valorDescontoPagamento,
    b.valorOutrasDespesasPagamento,
    b.valorJurosPagamento,
    b.valorFreteTotal,
    b.valorSeguroTotal,
    b.valorDescontoTotal,
    b.valorOutrasDespesasTotal,
    b.valorAdicFreteMarinhaMerTotal,
    b.valorDespesasAduaneirasTotal,
    b.cfop,
    b.indicadorISSQN,
    b.aliquotaISSQN,
    b.baseISSQN,
    b.valorISSQN,
    b.aliquotaIRRF,
    b.baseIRRF,
    b.valorIRRF,
    b.aliquotaINSS,
    b.baseINSS,
    b.valorINSS,
    b.retencaoPIS,
    b.baseRetPIS,
    b.valorRetPIS,
    b.retencaoCOFINS,
    b.baseRetCOFINS,
    b.valorRetCOFINS,
    b.retencaoCSLL,
    b.baseRetCSLL,
    b.valorRetCSLL,
    b.aliquotaII,
    b.baseII,
    b.valorII,
    b.aliquotaIOF,
    b.baseIOF,
    b.valorIOF,
    b.codigoEnquadramentoIPI,
    b.stIPI,
    b.aliquotaIPI,
    b.valorAliquotaIPI,
    b.baseIPI,
    b.valorIPI,
    b.stPIS,
    b.aliquotaPIS,
    b.valorAliquotaPIS,
    b.basePIS,
    b.valorPIS,
    b.aliquotaPISST,
    b.valorAliquotaPISST,
    b.basePISST,
    b.valorPISST,
    b.stCOFINS,
    b.aliquotaCOFINS,
    b.valorAliquotaCOFINS,
    b.baseCOFINS,
    b.valorCOFINS,
    b.aliquotaCOFINSST,
    b.valorAliquotaCOFINSST,
    b.baseCOFINSST,
    b.valorCOFINSST,
    b.stSimplesNacional,
    b.creditoSimplesNacional,
    b.baseCreditoSimplesNacional,
    b.valorCreditoSimplesNacional,
    b.stICMS,
    b.modalidadeBaseCalcICMS,
    b.reducaoBaseICMS,
    b.aliquotaICMS,
    b.diferimentoICMS,
    b.motivoDesoneracaoICMS,
    b.baseICMS,
    b.valorICMSOperacao,
    b.valorICMSDiferido,
    b.valorICMS,
    b.valorICMSDesoneracao,
    b.modalidadeBaseCalcICMSST,
    b.margemValorAdicionadoST,
    b.reducaoBaseST,
    b.aliquotaICMSST,
    b.aliquotaSTSuportConsFinal,
    b.baseICMSST,
    b.valorICMSST,
    b.baseICMSSTAnteriormente,
    b.valorICMSSTAnteriormente,
    b.valorICMSProprioSubstituto,
    b.reducaoBaseICMSEfetivo,
    b.aliquotaICMSEfetivo,
    b.baseICMSEfetivo,
    b.valorICMSEfetivo,
    b.aliquotaICMSUFDestinatario,
    b.aliquotaICMSInterestadual,
    b.partilhaICMSInterestadual,
    b.baseICMSUFDestinatario,
    b.valorICMSUFDestinatario,
    b.baseICMSUFRemetente,
    b.valorICMSUFRemetente,
    b.aliquotaFCP,
    b.baseFCP,
    b.valorFCP,
    b.aliquotaFCPST,
    b.baseFCPST,
    b.valorFCPST,
    b.aliquotaFCPSTAnteriormente,
    b.baseFCPSTAnteriormente,
    b.valorFCPSTAnteriormente,
    b.aliquotaFCPUFDestinatario,
    b.baseFCPUFDestinatario,
    b.valorFCPUFDestinatario,
    b.aliquotaEstimadaImpFederais,
    b.aliquotaEstimadaImpEstaduais,
    b.aliquotaEstimadaImpMunicipais,
    b.baseEstimadaImpostos,
    b.valorEstimadoImpFederais,
    b.valorEstimadoImpEstaduais,
    b.valorEstimadoImpMunicipais,
    b.valorImpostosSomaPagamento,
    b.valorImpostosDiminuiPagamento,
    b.valorLiquidoItem,
    b.observacoesDigitadas,
    b.observacoes);
  IF p_item_idItemOrcamento <> 0
    AND p_a_item_cancelado = 0
    AND p_item_cancelado = 1
  THEN
    ADD_ORCAMENTO_ITEM_PREV_CANC (p_item_idItemOrcamento);
  END IF;
  IF (p_item_idItemOrcamento <> 0
      OR p_item_movimentaEstoque = 1
      AND p_item_cancelado = 0)
    AND (p_etOrc_situacaoOrcamento BETWEEN 41 AND 63
      OR p_etOrc_situacaoOrcamento BETWEEN 64 AND 89
      AND p_item_controleEntrega > 0)
    AND (p_item_idItemOrcamento = 0
      OR p_a_item_movimentaEstoque   <> p_item_movimentaEstoque
      OR p_a_item_cancelado          <> p_item_cancelado
      OR p_a_item_gradeProduto       <> p_item_gradeProduto
      OR p_a_item_idFormulaTinta     <> p_item_idFormulaTinta
      OR p_a_item_idLoteEstoque      <> p_item_idLoteEstoque
      OR p_a_item_localEstoque       <> p_item_localEstoque
      OR p_a_item_pessoaParticipante <> p_item_pessoaParticipante
      OR p_a_item_quantidadeSaldo    <> p_item_quantidadeSaldo)
    OR p_item_movimentaEstoque = 0
    OR p_item_cancelado = 1
  THEN
    ADD_ORCAMENTO_ITEM_RES_ITEM (
      r_item_idItemOrcamento,
      p_estabelecimentoAtivo,
      ' ',
      /* Retornos */
      v_auxVarchar);
  END IF;
END ADD_ORCAMENTO_ITEM_GRAVA;

/

create or replace PROCEDURE ADD_ORCAMENTO_ITEM_COMP_GRAVA (
    p_estabelecimentoAtivo IN NUMBER,
    p_id                   IN NUMBER,
    p_idItemOrcamento      IN NUMBER,
    p_composicaoPreco      IN NUMBER,
    p_selecionado          IN NUMBER,
    p_quantidade           IN NUMBER,
    p_observacoes          IN VARCHAR2,
    /* Retornos */
    r_id                   OUT NUMBER)
IS
BEGIN
  r_id := p_id;
  IF r_id = 0 THEN
    r_id := FUNC_ADD_BUSCA_PROXIMO_ID ('MOORCAMENTOXCOMPOSICOESPR', 'id', 14, p_estabelecimentoAtivo, NULL);
  END IF;
  MERGE INTO MOORCAMENTOXCOMPOSICOESPR a 
  USING (
    SELECT
      r_id              id,
      p_idItemOrcamento idItemOrcamento,
      p_composicaoPreco composicaoPreco,
      p_selecionado     selecionado,
      p_quantidade      quantidade,
      p_observacoes     observacoes
    FROM DUAL) b
  ON (a.id = b.id)
  WHEN MATCHED THEN UPDATE SET
    a.idItemOrcamento = b.idItemOrcamento,
    a.composicaoPreco = b.composicaoPreco,
    a.selecionado     = b.selecionado,
    a.quantidade      = b.quantidade,
    a.observacoes     = b.observacoes
  WHEN NOT MATCHED THEN INSERT (
    id,
    idItemOrcamento,
    composicaoPreco,
    selecionado,
    quantidade,
    observacoes)
  VALUES (
    b.id,
    b.idItemOrcamento,
    b.composicaoPreco,
    b.selecionado,
    b.quantidade,
    b.observacoes);
END ADD_ORCAMENTO_ITEM_COMP_GRAVA;

/

create or replace PROCEDURE ADD_ORCAMENTO_ITEM_COMP_ORC (
  p_estabelecimentoAtivo IN NUMBER,
  p_idItemOrcamentoDe    IN NUMBER,
  p_idItemOrcamentoPara  IN NUMBER)
IS
  v_auxNumber NUMBER;
BEGIN
  ADD_ORCAMENTO_COMPPRECO_EXCLUI (p_idItemOrcamentoPara);
  FOR comp IN (
    SELECT
      composicaoPreco,
      selecionado,
      quantidade,
      observacoes
    FROM MOORCAMENTOXCOMPOSICOESPR
    WHERE idItemOrcamento = p_idItemOrcamentoDe
    AND selecionado = 1)
  LOOP
    ADD_ORCAMENTO_ITEM_COMP_GRAVA (
      p_estabelecimentoAtivo,
      0,
      p_idItemOrcamentoPara,
      comp.composicaoPreco,
      comp.selecionado,
      comp.quantidade,
      comp.observacoes,
      v_auxNumber);
  END LOOP;
END ADD_ORCAMENTO_ITEM_COMP_ORC;

/

create or replace PROCEDURE ADD_ORCAMENTO_ITEM_ORC_GRAVA (
  p_estabelecimentoAtivo        IN NUMBER,
  p_idItemOrcamento             IN NUMBER,
  p_idItemOrcamentoReferenciado IN NUMBER,
  p_quantidade                  IN NUMBER)
IS
  v_existeOrcamentoReferenciado NUMBER;
  v_id                          NUMBER;
BEGIN
  SELECT COALESCE (MAX (1),0)
  INTO v_existeOrcamentoReferenciado
  FROM MOORCAMENTOXORCAMENTO
  WHERE idItemOrcamento = p_idItemOrcamento
  AND idItemOrcamentoReferenc = p_idItemOrcamentoReferenciado;
  IF v_existeOrcamentoReferenciado = 0 THEN
    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_quantidade);
  END IF;
  ADD_ORCAMENTO_ITEM_COMP_ORC (
    p_estabelecimentoAtivo,
    p_idItemOrcamentoReferenciado,
    p_idItemOrcamento);
END ADD_ORCAMENTO_ITEM_ORC_GRAVA;

/

create or replace PROCEDURE ADD_ORCAMENTO_ITEM_TRANS_GRAVA (
  p_estabelecimentoAtivo   IN NUMBER,
  p_entradaSaidaOriginal   IN CHAR,
  p_idItemDocTransferencia IN NUMBER,
  p_idItemOrcamento        IN NUMBER,
  p_quantidade             IN NUMBER)
IS
  v_existeDocTransfXOrcItem NUMBER;
  v_id                      NUMBER;
BEGIN
  SELECT COALESCE (MAX (1),0)
  INTO v_existeDocTransfXOrcItem
  FROM MODOCTRANSFXORCAMENTOITEM
  WHERE idItemDocTransferencia = p_idItemDocTransferencia
  AND idItemOrcamento = p_idItemOrcamento;
  IF v_existeDocTransfXOrcItem = 0 THEN
    v_id := FUNC_ADD_BUSCA_PROXIMO_ID ('MODOCTRANSFXORCAMENTOITEM', 'id', 14, p_estabelecimentoAtivo, NULL);
    INSERT INTO MODOCTRANSFXORCAMENTOITEM (
      id,
      entradaSaidaOriginal,
      idItemDocTransferencia,
      idItemOrcamento,
      quantidade)
    VALUES (
      v_id,
      p_entradaSaidaOriginal,
      p_idItemDocTransferencia,
      p_idItemOrcamento,
      p_quantidade);
  END IF;
END ADD_ORCAMENTO_ITEM_TRANS_GRAVA;

/

create or replace PROCEDURE ADD_ORCAMENTO_ITEM_ENDER_GRAVA (
  p_estabelecimentoAtivo       IN NUMBER,
  p_idEnderecoEstoqueOrcamento IN NUMBER,
  p_idItemOrcamento            IN NUMBER,
  p_idEnderecoEstoque          IN NUMBER,
  p_quantidade                 IN NUMBER,
  p_quantidadeSaldo            IN NUMBER,
  p_observacoes                IN VARCHAR2,
  /* Retornos */
  r_idEnderecoEstoqueOrcamento OUT NUMBER)
IS
BEGIN
  r_idEnderecoEstoqueOrcamento := p_idEnderecoEstoqueOrcamento;
  IF r_idEnderecoEstoqueOrcamento = 0 THEN
    r_idEnderecoEstoqueOrcamento := FUNC_ADD_BUSCA_PROXIMO_ID ('MOORCAMENTOXENDERECOESTOQ', 'idEnderecoEstoqueOrcamento', 14, p_estabelecimentoAtivo, NULL);
  END IF;
  MERGE INTO MOORCAMENTOXENDERECOESTOQ a 
  USING (
    SELECT
      r_idEnderecoEstoqueOrcamento idEnderecoEstoqueOrcamento,
      p_idItemOrcamento            idItemOrcamento,
      p_idEnderecoEstoque          idEnderecoEstoque,
      p_quantidade                 quantidade,
      p_quantidadeSaldo            quantidadeSaldo,
      p_observacoes                observacoes
    FROM DUAL) b
  ON (a.idEnderecoEstoqueOrcamento = b.idEnderecoEstoqueOrcamento)
  WHEN MATCHED THEN UPDATE SET
    a.idItemOrcamento   = b.idItemOrcamento,
    a.idEnderecoEstoque = b.idEnderecoEstoque,
    a.quantidade        = b.quantidade,
    a.quantidadeSaldo   = b.quantidadeSaldo,
    a.observacoes       = b.observacoes
  WHEN NOT MATCHED THEN INSERT (
    idEnderecoEstoqueOrcamento,
    idItemOrcamento,
    idEnderecoEstoque,
    quantidade,
    quantidadeSaldo,
    observacoes)
  VALUES (
    b.idEnderecoEstoqueOrcamento,
    b.idItemOrcamento,
    b.idEnderecoEstoque,
    b.quantidade,
    b.quantidadeSaldo,
    b.observacoes);
END ADD_ORCAMENTO_ITEM_ENDER_GRAVA;

/

create or replace PROCEDURE ADD_ORCAMENTO_ITEM_REAL_GRAVA (
  p_estabelecimentoAtivo     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_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_BUSCA_PROXIMO_ID ('MOORCAMENTOXATIVIDADEREAL', 'idAtividadeRealOrcamento', 14, p_estabelecimentoAtivo, NULL);
  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_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.quantidade               = b.quantidade,
    a.observacoes              = b.observacoes
  WHEN NOT MATCHED THEN INSERT (
    idAtividadeRealOrcamento,
    idAtividadePrevOrcamento,
    sequencia,
    atividadeServico,
    descricao,
    tecnico,
    statusAtividadeServico,
    dataInicio,
    dataTermino,
    quantidade,
    observacoes)
  VALUES (
    b.idAtividadeRealOrcamento,
    b.idAtividadePrevOrcamento,
    b.sequencia,
    b.atividadeServico,
    b.descricao,
    b.tecnico,
    b.statusAtividadeServico,
    b.dataInicio,
    b.dataTermino,
    b.quantidade,
    b.observacoes);
END ADD_ORCAMENTO_ITEM_REAL_GRAVA;

/

create or replace PROCEDURE ADD_ORCAMENTO_ITEM_PREV_GRAVA (
  p_estabelecimentoAtivo     IN NUMBER,
  p_idAtividadePrevOrcamento IN NUMBER,
  p_idItemOrcamento          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_quantidade               IN NUMBER,
  p_observacoes              IN VARCHAR2,
  p_gravarAtividadeRealizada IN NUMBER,
  p_idAtividadeRealOrcamento IN NUMBER,
  p_atReal_dataInicio        IN DATE,
  p_atReal_dataTermino       IN DATE,
  p_atReal_quantidade        IN NUMBER,
  /* Retornos */
  r_idAtividadePrevOrcamento OUT NUMBER,
  r_idAtividadeRealOrcamento OUT NUMBER)
IS
BEGIN
  r_idAtividadePrevOrcamento := p_idAtividadePrevOrcamento;
  IF r_idAtividadePrevOrcamento = 0 THEN
    r_idAtividadePrevOrcamento := FUNC_ADD_BUSCA_PROXIMO_ID ('MOORCAMENTOXATIVIDADEPREV', 'idAtividadePrevOrcamento', 14, p_estabelecimentoAtivo, NULL);
  END IF;
  r_idAtividadeRealOrcamento := p_idAtividadeRealOrcamento;
  MERGE INTO MOORCAMENTOXATIVIDADEPREV a USING (
    SELECT
      r_idAtividadePrevOrcamento idAtividadePrevOrcamento,
      p_idItemOrcamento          idItemOrcamento,
      p_sequencia                sequencia,
      p_atividadeServico         atividadeServico,
      p_descricao                descricao,
      p_tecnico                  tecnico,
      p_statusAtividadeServico   statusAtividadeServico,
      p_dataInicio               dataInicio,
      p_dataTermino              dataTermino,
      p_quantidade               quantidade,
      p_observacoes              observacoes
    FROM DUAL) b
  ON (a.idAtividadePrevOrcamento = b.idAtividadePrevOrcamento)
  WHEN MATCHED THEN UPDATE SET
    a.idItemOrcamento        = b.idItemOrcamento,
    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.quantidade             = b.quantidade,
    a.observacoes            = b.observacoes
  WHEN NOT MATCHED THEN INSERT (
    idAtividadePrevOrcamento,
    idItemOrcamento,
    sequencia,
    atividadeServico,
    descricao,
    tecnico,
    statusAtividadeServico,
    dataInicio,
    dataTermino,
    quantidade,
    observacoes)
  VALUES (
    b.idAtividadePrevOrcamento,
    b.idItemOrcamento,
    b.sequencia,
    b.atividadeServico,
    b.descricao,
    b.tecnico,
    b.statusAtividadeServico,
    b.dataInicio,
    b.dataTermino,
    b.quantidade,
    b.observacoes);
  IF p_gravarAtividadeRealizada = 1 THEN
    ADD_ORCAMENTO_ITEM_REAL_GRAVA (
      p_estabelecimentoAtivo,
      p_idAtividadeRealOrcamento,
      r_idAtividadePrevOrcamento,
      1,
      p_atividadeServico,
      p_descricao,
      p_tecnico,
      p_statusAtividadeServico,
      p_atReal_dataInicio,
      p_atReal_dataTermino,
      p_atReal_quantidade,
      p_observacoes,
      /* Retornos */
      r_idAtividadeRealOrcamento);
  END IF;
  IF NOT(p_statusAtividadeServico IN ('A','I','P')) THEN
    UPDATE MOORCAMENTOXATIVIDADEPREV prev
    SET prev.tecnico = CASE WHEN prev.tecnico = 0 THEN p_tecnico ELSE prev.tecnico END,
      prev.statusAtividadeServico = 'P',
      prev.dataInicio = CASE WHEN prev.dataInicio IS NULL THEN SYSDATE ELSE prev.dataInicio END,
      prev.dataTermino = CASE WHEN prev.dataTermino IS NULL THEN SYSDATE ELSE prev.dataTermino END
    WHERE prev.idItemOrcamento = p_idItemOrcamento
    AND prev.statusAtividadeServico = 'A'
    AND prev.sequencia =
      ( SELECT MIN (prev2.sequencia)
        FROM MOORCAMENTOXATIVIDADEPREV prev2
        WHERE prev2.idItemOrcamento = prev.idItemOrcamento
        AND prev2.statusAtividadeServico IN ('A','I','P'));
  END IF;
  UPDATE MOORCAMENTOXITENS a
  SET a.statusAtividadeServico =
    CASE
      WHEN EXISTS (
        SELECT 1
        FROM MOORCAMENTOXATIVIDADEPREV prev
        WHERE prev.idItemOrcamento = a.idItemOrcamento
        AND prev.statusAtividadeServico = 'I')
      THEN 'I'
      WHEN EXISTS (
        SELECT 1
        FROM MOORCAMENTOXATIVIDADEPREV prev
        WHERE prev.idItemOrcamento = a.idItemOrcamento
        AND prev.statusAtividadeServico = 'P')
      THEN
        CASE
          WHEN
            EXISTS (
              SELECT 1
              FROM MOORCAMENTOXATIVIDADEPREV prev
              WHERE prev.idItemOrcamento = a.idItemOrcamento
              AND prev.statusAtividadeServico = 'E')
          THEN 'I'
          ELSE 'P'
        END
      WHEN EXISTS (
        SELECT 1
        FROM MOORCAMENTOXATIVIDADEPREV prev
        WHERE prev.idItemOrcamento = a.idItemOrcamento
        AND prev.statusAtividadeServico = 'A')
      THEN 'A'
      WHEN EXISTS (
        SELECT 1
        FROM MOORCAMENTOXATIVIDADEPREV prev
        WHERE prev.idItemOrcamento = a.idItemOrcamento
        AND prev.statusAtividadeServico = 'C')
      THEN 'C'
      WHEN EXISTS (
        SELECT 1
        FROM MOORCAMENTOXATIVIDADEPREV prev
        WHERE prev.idItemOrcamento = a.idItemOrcamento
        AND prev.statusAtividadeServico = 'E')
      THEN 'E'
      ELSE 'A'
    END
  WHERE a.idItemOrcamento = p_idItemOrcamento
  AND a.statusAtividadeServico <>
    CASE
      WHEN EXISTS (
        SELECT 1
        FROM MOORCAMENTOXATIVIDADEPREV prev
        WHERE prev.idItemOrcamento = a.idItemOrcamento
        AND prev.statusAtividadeServico = 'I')
      THEN 'I'
      WHEN EXISTS (
        SELECT 1
        FROM MOORCAMENTOXATIVIDADEPREV prev
        WHERE prev.idItemOrcamento = a.idItemOrcamento
        AND prev.statusAtividadeServico = 'P')
      THEN
        CASE
          WHEN
            EXISTS (
              SELECT 1
              FROM MOORCAMENTOXATIVIDADEPREV prev
              WHERE prev.idItemOrcamento = a.idItemOrcamento
              AND prev.statusAtividadeServico = 'E')
          THEN 'I'
          ELSE 'P'
        END
      WHEN EXISTS (
        SELECT 1
        FROM MOORCAMENTOXATIVIDADEPREV prev
        WHERE prev.idItemOrcamento = a.idItemOrcamento
        AND prev.statusAtividadeServico = 'A')
      THEN 'A'
      WHEN EXISTS (
        SELECT 1
        FROM MOORCAMENTOXATIVIDADEPREV prev
        WHERE prev.idItemOrcamento = a.idItemOrcamento
        AND prev.statusAtividadeServico = 'C')
      THEN 'C'
      WHEN EXISTS (
        SELECT 1
        FROM MOORCAMENTOXATIVIDADEPREV prev
        WHERE prev.idItemOrcamento = a.idItemOrcamento
        AND prev.statusAtividadeServico = 'E')
      THEN 'E'
      ELSE 'A'
    END;
END ADD_ORCAMENTO_ITEM_PREV_GRAVA;

/

create or replace PROCEDURE ADD_PRE_DOC_ROT_EFET_ORCAMENTO(
    p_exclusivo               IN VARCHAR2,
    p_orcamento               IN NUMBER,
    p_usuarioLogado           IN NUMBER,
    p_estabelecimentoAtivo    IN NUMBER,
    p_sessao                  IN NUMBER,
    p_sessaoCaixa             IN NUMBER,
    p_idTerminalSiTef         IN VARCHAR2,
    p_serieFiscal             IN VARCHAR2,
    p_subSerieFiscal          IN NUMBER,
    p_documentoFiscal         IN NUMBER,
    p_dataEmissao             IN DATE,
    p_timezone                IN VARCHAR2,
    p_dataEntradaSaida        IN DATE,
    p_comissionadoB           IN NUMBER,
    p_comissionadoC           IN NUMBER,
    p_novaEtapaOrcamento      IN NUMBER,
    p_versaoAplicativo        IN VARCHAR2,
    r_preDocumento            OUT NUMBER)
IS
  v_tipoDocumento          NUMBER;
  v_fatoContabil           NUMBER;
  v_preDocumento           NUMBER;
  v_estabelecimento        NUMBER;
  v_pessoa                 NUMBER;
  v_colaboradorResponsavel NUMBER;
  CURSOR c_itens
  IS SELECT idItemOrcamento, CASE WHEN cancelado = 0 THEN FUNC_ADD_BUSCA_PROXIMO_ID('MOPREDOCUMXITENS', 'idItemPreDocumento', 0, p_estabelecimentoAtivo, NULL) ELSE 0 END idItemPreDocumento, sequencia, cancelado, modeloDocumento, vendedor, gradeProduto, servico, idFormulaTinta, personalizacao, idLoteEstoque, operacaoFiscal, movimentaEstoque, geraFinanceiro, localEstoque, pessoaParticipante, controleQuantidade, unidadeMedidaConversao, conversorQuantidade, loteMinimo, loteMultiplo, altura, largura, comprimento, pecas, quantidade, quantidadeConvertida, quantidadeConferida, pesoLiquido, pesoBruto, tipoPreco, tabelaPreco, precoSugestaoAPrazo, precoSugestaoAVista, precoDesconto, precoMinimo, usarPrecoAVista, precoPautaTabelado, precoUnitarioBruto, acrescimoUnitarioComposicao, precoUnitario, precoUnitarioConvertido, valorProdutoServicoBruto, valorProdutoServico, percDescontoItem, valorDescontoItem, percAcrescimoItem, valorAcrescimoItem, valorFreteItem, valorSeguroItem, valorAdicFreteMarinhaMerItem, valorDespesasAduaneirasItem, valorFreteGeral, valorSeguroGeral, valorDescontoGeral, valorOutrasDespesasGeral, valorAdicFreteMarinhaMerGeral, valorDespesasAduaneirasGeral, valorBasePagamento, valorDescontoPagamento, valorOutrasDespesasPagamento, valorJurosPagamento, valorFreteTotal, valorSeguroTotal, valorDescontoTotal, valorOutrasDespesasTotal, valorAdicFreteMarinhaMerTotal, valorDespesasAduaneirasTotal, cfop, indicadorISSQN, aliquotaISSQN, baseISSQN, valorISSQN, aliquotaIRRF, baseIRRF, valorIRRF, aliquotaINSS, baseINSS, valorINSS, retencaoPIS, baseRetPIS, valorRetPIS, retencaoCOFINS, baseRetCOFINS, valorRetCOFINS, retencaoCSLL, baseRetCSLL, valorRetCSLL, aliquotaII, baseII, valorII, aliquotaIOF, baseIOF, valorIOF, codigoEnquadramentoIPI, stIPI, aliquotaIPI, valorAliquotaIPI, baseIPI, valorIPI, stPIS, aliquotaPIS, valorAliquotaPIS, basePIS, valorPIS, aliquotaPISST, valorAliquotaPISST, basePISST, valorPISST, stCOFINS, aliquotaCOFINS, valorAliquotaCOFINS, baseCOFINS, valorCOFINS, aliquotaCOFINSST, valorAliquotaCOFINSST, baseCOFINSST, valorCOFINSST, stSimplesNacional, creditoSimplesNacional, baseCreditoSimplesNacional, valorCreditoSimplesNacional, stICMS, modalidadeBaseCalcICMS, reducaoBaseICMS, aliquotaICMS, diferimentoICMS, motivoDesoneracaoICMS, baseICMS, valorICMSOperacao, valorICMSDiferido, valorICMS, valorICMSDesoneracao, modalidadeBaseCalcICMSST, margemValorAdicionadoST, reducaoBaseST, aliquotaICMSST, aliquotaSTSuportConsFinal, baseICMSST, valorICMSST, baseICMSSTAnteriormente, valorICMSSTAnteriormente, valorICMSProprioSubstituto, reducaoBaseICMSEfetivo, aliquotaICMSEfetivo, baseICMSEfetivo, valorICMSEfetivo, aliquotaICMSUFDestinatario, aliquotaICMSInterestadual, partilhaICMSInterestadual, baseICMSUFDestinatario, valorICMSUFDestinatario, baseICMSUFRemetente, valorICMSUFRemetente, aliquotaFCP, baseFCP, valorFCP, aliquotaFCPST, baseFCPST, valorFCPST, aliquotaFCPSTAnteriormente, baseFCPSTAnteriormente, valorFCPSTAnteriormente, aliquotaFCPUFDestinatario, baseFCPUFDestinatario, valorFCPUFDestinatario, aliquotaEstimadaImpFederais, aliquotaEstimadaImpEstaduais, aliquotaEstimadaImpMunicipais, baseEstimadaImpostos, valorEstimadoImpFederais, valorEstimadoImpEstaduais, valorEstimadoImpMunicipais, valorImpostosSomaPagamento, valorImpostosDiminuiPagamento, valorLiquidoItem, observacoesDigitadas, observacoes
     FROM MOORCAMENTOXITENS
     WHERE orcamento = p_orcamento
     ORDER BY sequencia;
  CURSOR c_endEst
  IS SELECT a.idEnderecoEstoqueOrcamento, a.idItemOrcamento, FUNC_ADD_BUSCA_PROXIMO_ID('MOPREDOCUMXENDERECOESTOQ', 'idEnderecoEstoquePreDocumento', 0, p_estabelecimentoAtivo, NULL) idEnderecoEstoquePreDocumento, a.idEnderecoEstoque, a.posicaoCaixaEstoque, a.quantidade, 0 quantidadeDevolvidaRetornada, a.quantidadeConferida, a.observacoes
     FROM MOORCAMENTOXENDERECOESTOQ a
     JOIN MOORCAMENTOXITENS b ON b.idItemOrcamento = a.idItemOrcamento
     WHERE b.orcamento = p_orcamento
     AND b.cancelado = 0;
  CURSOR c_mot_cab IS
    SELECT idMotivoBloqueioDocumento, FUNC_ADD_BUSCA_PROXIMO_ID('MOMOTIVOSBLOQUEIOS', 'idMotivoBloqueioDocumento', 0, p_estabelecimentoAtivo, NULL) idMotivoBloqueioNovo
    FROM MOMOTBLOQXORCAMENTOS
    WHERE orcamento = p_orcamento;
  CURSOR c_mot_item IS
    SELECT a.idMotivoBloqueioDocumento, a.idItemOrcamento, FUNC_ADD_BUSCA_PROXIMO_ID('MOMOTIVOSBLOQUEIOS', 'idMotivoBloqueioDocumento', 0, p_estabelecimentoAtivo, NULL) idMotivoBloqueioNovo
    FROM MOMOTBLOQXORCAMENTOITENS a
    JOIN MOORCAMENTOXITENS b ON b.idItemOrcamento = a.idItemOrcamento
    WHERE b.orcamento = p_orcamento
    AND b.cancelado = 0;
  CURSOR c_mot_pag IS
    SELECT
      FUNC_ADD_BUSCA_PROXIMO_ID('MOMOTIVOSBLOQUEIOS', 'idMotivoBloqueioDocumento', 0, p_estabelecimentoAtivo, NULL) idMotivoBloqueioNovo,
      a.idMotivoBloqueioDocumento
      FROM MOMOTIVOSBLOQUEIOS a
      WHERE a.origem = 'O'
      AND a.idCabecalho = p_orcamento
      AND a.cabecalhoItemPagamento = 'P'
      AND NOT (EXISTS(
        SELECT 1
        FROM MOMOTBLOQXORCAMENTOPAGAM b
        WHERE b.idMotivoBloqueioDocumento = a.idMotivoBloqueioDocumento));
BEGIN
  SELECT
    CASE
      WHEN orc.entradaSaida='E'
      THEN 401
      ELSE 301
    END,
    orc.estabelecimento,
    orc.pessoa,
    CASE
      WHEN orc.tipoDocumento = 102
        AND orc.colaboradorResponsavel <> 0
        AND EXISTS (
          SELECT 1
          FROM CAVENDEDORES vend
          WHERE vend.vendedor = orc.colaboradorResponsavel
          AND vend.ativo = 1)
      THEN orc.colaboradorResponsavel
      ELSE 0
    END
  INTO
    v_tipoDocumento,
    v_estabelecimento,
    v_pessoa,
    v_colaboradorResponsavel
  FROM MOORCAMENTOS orc
  WHERE orcamento = p_orcamento;
  v_fatoContabil := FUNC_ADD_BUSCA_PROXIMO_ID('MOFATOSCONTABEIS', 'fatoContabil', 0, p_estabelecimentoAtivo, NULL);
  INSERT INTO MOFATOSCONTABEIS (fatoContabil, estabelecimento, data, ordenacao, situacaoTransacao, situacaoContabilizacao, sessao, observacoes) VALUES (v_fatoContabil, v_estabelecimento, p_dataEmissao, 0, 'A', 'N', p_sessao, ' ');
  v_preDocumento := FUNC_ADD_BUSCA_PROXIMO_ID('MOPREDOCUMENTOS', 'preDocumento', 0, p_estabelecimentoAtivo, NULL);
  INSERT INTO MOPREDOCUMENTOS (preDocumento, origemDocumento, tipoDocumento, tipoVenda, modeloDocumento, entradaSaida, devolucaoAnulacaoRetorno, finalidadeNota, atualizaCustoMedio, atualizaUltimaCompra, validoFaturamento, usarPrecoAVista, sessao, sessaoCaixa, fatoContabil, idTerminalSiTef, estabelecimentoOriginal, estabelecimento, enderecoRetiradaEstabeleciment, indicadorPresencaComprador, controlaSeparacaoConferencia, serieFiscal, subserieFiscal, documentoFiscal, dataEmissao, timezoneEmissao, dataEntradaSaida, pessoa, indicadorPessoa, indicadorDocumentoPessoa, cnpjCpfIdEstrangeiro, nomeRazaoSocial, fone, indicadorFone, operadoraTelefonia, autorizadoPessoa, enderecoEntregaPessoa, municipioFatoGerador, localDestinoOperacao, indicadorConsumidorFinal, projeto, contratoCompra, comissionadoB, comissionadoC, modalidadeFrete, tipoPagamentoFrete, transportadora, enderecoTransportadora, motorista, placa, vagao, balsa, quantidadeVolume, especieVolume, descricaoMarca, numeracaoVolume, codigoIntegracao, atendimento, statusPreDocumento, ultimoVendedorItem, quantidade, pesoLiquido, pesoBruto, valorProdutosBruto, valorProdutos, valorDescontoProdutos, valorAcrescimoProdutos, valorServicosBruto, valorServicos, valorDescontoServicos, valorAcrescimoServicos, valorFreteItem, valorSeguroItem, valorAdicFreteMarinhaMerItem, valorDespesasAduaneirasItem, valorFreteGeral, valorSeguroGeral, valorDescontoGeral, valorOutrasDespesasGeral, valorAdicFreteMarinhaMerGeral, valorDespesasAduaneirasGeral, condicaoPagamento, contaFinanceira, numeroParcelas, somaPrazoParcelas, valorXPrazoParcelas, prazoMedio, prazoMedioPonderado, valorBasePagamento, valorAVistaMinimo, valorEntradaMinima, valorAVistaEntrada, valorPagamentoBruto, valorDescontoPagamento, valorOutrasDespesasPagamento, valorJurosPagamento, valorPagamentoLiquido, valorTroco, valorFreteTotal, valorSeguroTotal, valorDescontoTotal, valorOutrasDespesasTotal, valorAdicFreteMarinhaMerTotal, valorDespesasAduaneirasTotal, impostosEditados, valorImpostosSomaPagamento, valorImpostosDiminuiPagamento, valorLiquidoItem, valorDescontoCustoOpItem, valorDescontoCustoOpGeral, valorDescontoCustoOpTotal, valorAcrescimoCustoOpItem, valorAcrescimoCustoOpGeral, valorAcrescimoCustoOpTotal, valorCustoOperacao, valorCMV, versaoAplicativo)
  SELECT v_preDocumento,
    2,
    v_tipoDocumento,
    orc.tipoVenda,
    orc.modeloDocumento,
    orc.entradaSaida,
    0 devolucaoAnulacaoRetorno,
    orc.finalidadeNota,
    orc.atualizaCustoMedio,
    orc.atualizaUltimaCompra,
    orc.validoFaturamento,
    orc.usarPrecoAVista,
    p_sessao,
    p_sessaoCaixa,
    v_fatoContabil,
    p_idTerminalSiTef,
    orc.estabelecimento,
    orc.estabelecimento,
    orc.enderecoRetiradaEstabeleciment,
    orc.indicadorPresencaComprador,
    orc.controlaSeparacaoConferencia,
    p_serieFiscal,
    p_subserieFiscal,
    p_documentoFiscal,
    p_dataEmissao dataEmissao,
    p_timezone timezoneEmissao,
    p_dataEntradaSaida dataEntradaSaida,
    orc.pessoa,
    'F' indicadorPessoa,
    'C' indicadorDocumentoPessoa,
    ' ' cnpjCpfIdEstrangeiro,
    ' ' nomeRazaoSocial,
    ' ' fone,
    0 indicadorFone,
    0 operadoraTelefonia,
    orc.autorizadoPessoa,
    orc.enderecoEntregaPessoa,
    orc.municipioFatoGerador,
    orc.localDestinoOperacao,
    orc.indicadorConsumidorFinal,
    orc.projeto,
    orc.contratoCompra,
    p_comissionadoB comissionadoB,
    p_comissionadoC comissionadoC,
    CASE WHEN orc.modalidadeFrete = ' ' THEN '9' ELSE orc.modalidadeFrete END,
    CASE WHEN orc.tipoPagamentoFrete = ' ' THEN 'N' ELSE orc.tipoPagamentoFrete END,
    orc.transportadora,
    orc.enderecoTransportadora,
    orc.motorista,
    orc.placa,
    orc.vagao,
    orc.balsa,
    orc.quantidadeVolume,
    orc.especieVolume,
    orc.descricaoMarca,
    orc.numeracaoVolume,
    orc.codigoIntegracao,
    orc.atendimento,
    'E' statusPreDocumento,
    CASE WHEN orc.ultimoVendedorItem = 0 THEN v_colaboradorResponsavel ELSE orc.ultimoVendedorItem END,
    orc.quantidade,
    orc.pesoLiquido,
    orc.pesoBruto,
    orc.valorProdutosBruto,
    orc.valorProdutos,
    orc.valorDescontoProdutos,
    orc.valorAcrescimoProdutos,
    orc.valorServicosBruto,
    orc.valorServicos,
    orc.valorDescontoServicos,
    orc.valorAcrescimoServicos,
    orc.valorFreteItem,
    orc.valorSeguroItem,
    orc.valorAdicFreteMarinhaMerItem,
    orc.valorDespesasAduaneirasItem,
    orc.valorFreteGeral,
    orc.valorSeguroGeral,
    orc.valorDescontoGeral,
    orc.valorOutrasDespesasGeral,
    orc.valorAdicFreteMarinhaMerGeral,
    orc.valorDespesasAduaneirasGeral,
    orc.condicaoPagamento,
    orc.contaFinanceira,
    0 numeroParcelas,
    0 somaPrazoParcelas,
    0 valorXPrazoParcelas,
    0 prazoMedio,
    0 prazoMedioPonderado,
    orc.valorBasePagamento,
    orc.valorAVistaMinimo,
    0 valorEntradaMinima,
    0 valorAVistaEntrada,
    0 valorPagamentoBruto,
    0 valorDescontoPagamento,
    0 valorOutrasDespesasPagamento,
    0 valorJurosPagamento,
    0 valorPagamentoLiquido,
    0 valorTroco,
    orc.valorFreteTotal,
    orc.valorSeguroTotal,
    orc.valorDescontoTotal - CASE WHEN orc.valorDescontoTotal >= orc.valorDescontoPagamento THEN orc.valorDescontoPagamento ELSE 0 END,
    orc.valorOutrasDespesasTotal - CASE WHEN orc.valorOutrasDespesasTotal > orc.valorOutrasDespesasPagamento + orc.valorJurosPagamento THEN orc.valorOutrasDespesasPagamento + orc.valorJurosPagamento ELSE 0 END,
    orc.valorAdicFreteMarinhaMerTotal,
    orc.valorDespesasAduaneirasTotal,
    orc.impostosEditados,
    orc.valorImpostosSomaPagamento,
    orc.valorImpostosDiminuiPagamento,
    orc.valorLiquidoItem + CASE WHEN orc.valorDescontoTotal >= orc.valorDescontoPagamento THEN orc.valorDescontoPagamento ELSE 0 END - CASE WHEN orc.valorOutrasDespesasTotal > orc.valorOutrasDespesasPagamento + orc.valorJurosPagamento THEN orc.valorOutrasDespesasPagamento + orc.valorJurosPagamento ELSE 0 END,
    0,
    0,
    0,
    0,
    0,
    0,
    0,
    0,
    p_versaoAplicativo
  FROM MOORCAMENTOS orc
  JOIN PAESTABELECIMENTOS est ON est.estabelecimento = orc.estabelecimento
  WHERE orcamento = p_orcamento;
  UPDATE MOORCAMENTOS SET etapaOrcamento = p_novaEtapaOrcamento WHERE orcamento = p_orcamento;
  INSERT INTO MOORCAMENTOXETAPAS (id, orcamento, data, usuario, etapaOrcamento, observacoes) VALUES (FUNC_ADD_BUSCA_PROXIMO_ID('MOORCAMENTOXETAPAS', 'id', 0, p_estabelecimentoAtivo, NULL), p_orcamento, sysdate, p_usuarioLogado, p_novaEtapaOrcamento, ' ');
  INSERT INTO MOPREDOCUMXPERSPROJETO (idPersonProjetoPreDocumento, preDocumento, personalizacaoProjeto, conteudo) SELECT FUNC_ADD_BUSCA_PROXIMO_ID('MOPREDOCUMXPERSPROJETO', 'idPersonProjetoPreDocumento', 0, p_estabelecimentoAtivo, NULL), v_preDocumento, x.personalizacaoProjeto, x.conteudo FROM MOORCAMENTOXPERSPROJETO x WHERE x.orcamento = p_orcamento;
  INSERT INTO MOPREDOCUMXINFOCOMPLENT (id, preDocumento, sequencia, geradoPeloSistema, imprimir, destaque, informacaoComplementar, descInformacaoComplementar) SELECT FUNC_ADD_BUSCA_PROXIMO_ID('MOPREDOCUMXINFOCOMPLENT', 'id', 0, p_estabelecimentoAtivo, NULL), v_preDocumento, x.sequencia, x.geradoPeloSistema, x.imprimir, x.destaque, x.informacaoComplementar, x.descInformacaoComplementar FROM MOORCAMENTOXINFOCOMPLENT x WHERE x.orcamento = p_orcamento;
  INSERT INTO MOPREDOCUMXPROMOCOES (id, preDocumento, cabecalhoItemPagamento, sequencia, idItemPreDocumento, idPagamentoPreDocumento, regraPromocao, tipoBeneficio, multiplicador, precoUnitarioDe, precoUnitarioPor, precoDesconto, precoMinimo, percentualDesconto, valorDesconto, pontuacao, gerarPontuacao, observacoes) SELECT FUNC_ADD_BUSCA_PROXIMO_ID('MOPREDOCUMXPROMOCOES', 'id', 0, p_estabelecimentoAtivo, NULL), v_preDocumento, x.cabecalhoItemPagamento, x.sequencia, 0, 0, x.regraPromocao, x.tipoBeneficio, x.multiplicador, x.precoUnitarioDe, x.precoUnitarioPor, x.precoDesconto, x.precoMinimo, x.percentualDesconto, x.valorDesconto, x.pontuacao, x.gerarPontuacao, x.observacoes FROM MOORCAMENTOXPROMOCOES x WHERE x.orcamento = p_orcamento AND x.idItemOrcamento = 0 AND x.idPagamentoOrcamento = 0;
  FOR itens IN c_itens
  LOOP
    IF itens.cancelado = 0
    THEN
      INSERT INTO MOPREDOCUMXITENS (idItemPreDocumento, preDocumento, sequencia, cancelado, modeloDocumento, estabelecimentoOriginal, vendedor, gradeProduto, servico, idFormulaTinta, personalizacao, idLoteEstoque, operacaoFiscal, movimentaEstoque, geraFinanceiro, localEstoque, pessoaParticipante, controleQuantidade, unidadeMedidaConversao, conversorQuantidade, loteMinimo, loteMultiplo, altura, largura, comprimento, pecas, quantidade, quantidadeConvertida, quantidadeDevolvidaRetornada, quantidadeConferida, percentualDevolucao, pesoLiquido, pesoBruto, tipoPreco, tabelaPreco, precoSugestaoAPrazo, precoSugestaoAVista, precoDesconto, precoMinimo, usarPrecoAVista, precoPautaTabelado, precoUnitarioBruto, acrescimoUnitarioComposicao, precoUnitario, precoUnitarioConvertido, valorProdutoServicoBruto, valorProdutoServico, percDescontoItem, valorDescontoItem, percAcrescimoItem, valorAcrescimoItem, valorFreteItem, valorSeguroItem, valorAdicFreteMarinhaMerItem, valorDespesasAduaneirasItem, valorFreteGeral, valorSeguroGeral, valorDescontoGeral, valorOutrasDespesasGeral, valorAdicFreteMarinhaMerGeral, valorDespesasAduaneirasGeral, valorBasePagamento, valorDescontoPagamento, valorOutrasDespesasPagamento, valorJurosPagamento, valorFreteTotal, valorSeguroTotal, valorDescontoTotal, valorOutrasDespesasTotal, valorAdicFreteMarinhaMerTotal, valorDespesasAduaneirasTotal, cfop, indicadorISSQN, aliquotaISSQN, baseISSQN, valorISSQN, aliquotaIRRF, baseIRRF, valorIRRF, aliquotaINSS, baseINSS, valorINSS, retencaoPIS, baseRetPIS, valorRetPIS, retencaoCOFINS, baseRetCOFINS, valorRetCOFINS, retencaoCSLL, baseRetCSLL, valorRetCSLL, aliquotaII, baseII, valorII, aliquotaIOF, baseIOF, valorIOF, codigoEnquadramentoIPI, stIPI, aliquotaIPI, valorAliquotaIPI, baseIPI, valorIPI, valorIPIDevolucao, stPIS, aliquotaPIS, valorAliquotaPIS, basePIS, valorPIS, aliquotaPISST, valorAliquotaPISST, basePISST, valorPISST, stCOFINS, aliquotaCOFINS, valorAliquotaCOFINS, baseCOFINS, valorCOFINS, aliquotaCOFINSST, valorAliquotaCOFINSST, baseCOFINSST, valorCOFINSST, stSimplesNacional, creditoSimplesNacional, baseCreditoSimplesNacional, valorCreditoSimplesNacional, stICMS, modalidadeBaseCalcICMS, reducaoBaseICMS, aliquotaICMS, diferimentoICMS, motivoDesoneracaoICMS, baseICMS, valorICMSOperacao, valorICMSDiferido, valorICMS, valorICMSDesoneracao, modalidadeBaseCalcICMSST, margemValorAdicionadoST, reducaoBaseST, aliquotaICMSST, aliquotaSTSuportConsFinal, baseICMSST, valorICMSST, baseICMSSTAnteriormente, valorICMSSTAnteriormente, valorICMSProprioSubstituto, reducaoBaseICMSEfetivo, aliquotaICMSEfetivo, baseICMSEfetivo, valorICMSEfetivo, aliquotaICMSUFDestinatario, aliquotaICMSInterestadual, partilhaICMSInterestadual, baseICMSUFDestinatario, valorICMSUFDestinatario, baseICMSUFRemetente, valorICMSUFRemetente, aliquotaFCP, baseFCP, valorFCP, aliquotaFCPST, baseFCPST, valorFCPST, aliquotaFCPSTAnteriormente, baseFCPSTAnteriormente, valorFCPSTAnteriormente, aliquotaFCPUFDestinatario, baseFCPUFDestinatario, valorFCPUFDestinatario, aliquotaEstimadaImpFederais, aliquotaEstimadaImpEstaduais, aliquotaEstimadaImpMunicipais, baseEstimadaImpostos, valorEstimadoImpFederais, valorEstimadoImpEstaduais, valorEstimadoImpMunicipais, valorImpostosSomaPagamento, valorImpostosDiminuiPagamento, valorLiquidoItem, valorDescontoCustoOpItem, valorDescontoCustoOpGeral, valorDescontoCustoOpTotal, valorAcrescimoCustoOpItem, valorAcrescimoCustoOpGeral, valorAcrescimoCustoOpTotal, precoCustoOperacao, valorCustoOperacao, precoCMV, valorCMV, observacoesDigitadas, observacoes) VALUES (itens.idItemPreDocumento, v_preDocumento, itens.sequencia, itens.cancelado, itens.modeloDocumento, v_estabelecimento, CASE WHEN itens.vendedor = 0 THEN v_colaboradorResponsavel ELSE itens.vendedor END, itens.gradeProduto, itens.servico, itens.idFormulaTinta, itens.personalizacao, itens.idLoteEstoque, itens.operacaoFiscal, itens.movimentaEstoque, itens.geraFinanceiro, itens.localEstoque, itens.pessoaParticipante, itens.controleQuantidade, itens.unidadeMedidaConversao, itens.conversorQuantidade, itens.loteMinimo, itens.loteMultiplo, itens.altura, itens.largura, itens.comprimento, itens.pecas, itens.quantidade, itens.quantidadeConvertida, 0, itens.quantidadeConferida, 0, itens.pesoLiquido, itens.pesoBruto, itens.tipoPreco, itens.tabelaPreco, itens.precoSugestaoAPrazo, itens.precoSugestaoAVista, itens.precoDesconto, itens.precoMinimo, itens.usarPrecoAVista, itens.precoPautaTabelado, itens.precoUnitarioBruto, itens.acrescimoUnitarioComposicao, itens.precoUnitario, itens.precoUnitarioConvertido, itens.valorProdutoServicoBruto, itens.valorProdutoServico, itens.percDescontoItem, itens.valorDescontoItem, itens.percAcrescimoItem, itens.valorAcrescimoItem, itens.valorFreteItem, itens.valorSeguroItem, itens.valorAdicFreteMarinhaMerItem, itens.valorDespesasAduaneirasItem, itens.valorFreteGeral, itens.valorSeguroGeral, itens.valorDescontoGeral, itens.valorOutrasDespesasGeral, itens.valorAdicFreteMarinhaMerGeral, itens.valorDespesasAduaneirasGeral, itens.valorBasePagamento, itens.valorDescontoPagamento, itens.valorOutrasDespesasPagamento, itens.valorJurosPagamento, itens.valorFreteTotal, itens.valorSeguroTotal, itens.valorDescontoTotal, itens.valorOutrasDespesasTotal, itens.valorAdicFreteMarinhaMerTotal, itens.valorDespesasAduaneirasTotal, itens.cfop, itens.indicadorISSQN, itens.aliquotaISSQN, itens.baseISSQN, itens.valorISSQN, itens.aliquotaIRRF, itens.baseIRRF, itens.valorIRRF, itens.aliquotaINSS, itens.baseINSS, itens.valorINSS, itens.retencaoPIS, itens.baseRetPIS, itens.valorRetPIS, itens.retencaoCOFINS, itens.baseRetCOFINS, itens.valorRetCOFINS, itens.retencaoCSLL, itens.baseRetCSLL, itens.valorRetCSLL, itens.aliquotaII, itens.baseII, itens.valorII, itens.aliquotaIOF, itens.baseIOF, itens.valorIOF, itens.codigoEnquadramentoIPI, itens.stIPI, itens.aliquotaIPI, itens.valorAliquotaIPI, itens.baseIPI, itens.valorIPI, 0, itens.stPIS, itens.aliquotaPIS, itens.valorAliquotaPIS, itens.basePIS, itens.valorPIS, itens.aliquotaPISST, itens.valorAliquotaPISST, itens.basePISST, itens.valorPISST, itens.stCOFINS, itens.aliquotaCOFINS, itens.valorAliquotaCOFINS, itens.baseCOFINS, itens.valorCOFINS, itens.aliquotaCOFINSST, itens.valorAliquotaCOFINSST, itens.baseCOFINSST, itens.valorCOFINSST, itens.stSimplesNacional, itens.creditoSimplesNacional, itens.baseCreditoSimplesNacional, itens.valorCreditoSimplesNacional, itens.stICMS, itens.modalidadeBaseCalcICMS, itens.reducaoBaseICMS, itens.aliquotaICMS, itens.diferimentoICMS, itens.motivoDesoneracaoICMS, itens.baseICMS, itens.valorICMSOperacao, itens.valorICMSDiferido, itens.valorICMS, itens.valorICMSDesoneracao, itens.modalidadeBaseCalcICMSST, itens.margemValorAdicionadoST, itens.reducaoBaseST, itens.aliquotaICMSST, itens.aliquotaSTSuportConsFinal, itens.baseICMSST, itens.valorICMSST, itens.baseICMSSTAnteriormente, itens.valorICMSSTAnteriormente, itens.valorICMSProprioSubstituto, itens.reducaoBaseICMSEfetivo, itens.aliquotaICMSEfetivo, itens.baseICMSEfetivo, itens.valorICMSEfetivo, itens.aliquotaICMSUFDestinatario, itens.aliquotaICMSInterestadual, itens.partilhaICMSInterestadual, itens.baseICMSUFDestinatario, itens.valorICMSUFDestinatario, itens.baseICMSUFRemetente, itens.valorICMSUFRemetente, itens.aliquotaFCP, itens.baseFCP, itens.valorFCP, itens.aliquotaFCPST, itens.baseFCPST, itens.valorFCPST, itens.aliquotaFCPSTAnteriormente, itens.baseFCPSTAnteriormente, itens.valorFCPSTAnteriormente, itens.aliquotaFCPUFDestinatario, itens.baseFCPUFDestinatario, itens.valorFCPUFDestinatario, itens.aliquotaEstimadaImpFederais, itens.aliquotaEstimadaImpEstaduais, itens.aliquotaEstimadaImpMunicipais, itens.baseEstimadaImpostos, itens.valorEstimadoImpFederais, itens.valorEstimadoImpEstaduais, itens.valorEstimadoImpMunicipais, itens.valorImpostosSomaPagamento, itens.valorImpostosDiminuiPagamento, itens.valorLiquidoItem, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, itens.observacoesDigitadas, itens.observacoes);
      INSERT INTO MOPREDOCUMXPEDIDOCOMPRA (idItemPreDocumento, pedidoCompraFornecedor, sequenciaPedidoCompraFornec) SELECT itens.idItemPreDocumento, x.pedidoCompraFornecedor, x.sequenciaPedidoCompraFornec FROM MOORCAMENTOXPEDIDOCOMPRA x WHERE x.idItemOrcamento = itens.idItemOrcamento;
      INSERT INTO MOPREDOCUMXCOMPOSICOESPR (id, idItemPreDocumento, composicaoPreco, selecionado, quantidade, observacoes) SELECT FUNC_ADD_BUSCA_PROXIMO_ID('MOPREDOCUMXCOMPOSICOESPR', 'id', 0, p_estabelecimentoAtivo, NULL), itens.idItemPreDocumento, x.composicaoPreco, x.selecionado, x.quantidade, x.observacoes FROM MOORCAMENTOXCOMPOSICOESPR x WHERE x.idItemOrcamento = itens.idItemOrcamento;
      INSERT INTO MOPREDOCUMXEMBALAGENSTIN (idEmbalagemTintaPreDocumento, idItemPreDocumento, embalagemTinta, quantidade, quantidadeSaldo, quantidadeConferida, observacoes) SELECT FUNC_ADD_BUSCA_PROXIMO_ID('MOPREDOCUMXEMBALAGENSTIN', 'idEmbalagemTintaPreDocumento', 0, p_estabelecimentoAtivo, NULL), itens.idItemPreDocumento, x.embalagemTinta, x.quantidade, x.quantidadeSaldo, x.quantidadeConferida, x.observacoes FROM MOORCAMENTOXEMBALAGENSTIN x WHERE x.idItemOrcamento = itens.idItemOrcamento;
      INSERT INTO MOPREDOCUMXNUMEROSSERIE (idNumeroSeriePreDocumento, idItemPreDocumento, idEnderecoEstoquePreDocumento, gradeProduto, idNumeroSerie, devolvidoRetornado) SELECT FUNC_ADD_BUSCA_PROXIMO_ID('MOPREDOCUMXNUMEROSSERIE', 'idNumeroSeriePreDocumento', 0, p_estabelecimentoAtivo, NULL), itens.idItemPreDocumento, 0, x.gradeProduto, x.idNumeroSerie, 0 FROM MOORCAMENTOXNUMEROSSERIE x WHERE x.idItemOrcamento = itens.idItemOrcamento AND x.idEnderecoEstoqueOrcamento = 0;
      INSERT INTO MOPREDOCUMXCENTROSCUSTOS (idCentroCustoPreDocumento, idItemPreDocumento, centroCusto, percentualRateio) SELECT FUNC_ADD_BUSCA_PROXIMO_ID('MOPREDOCUMXCENTROSCUSTOS', 'idCentroCustoPreDocumento', 0, p_estabelecimentoAtivo, NULL), itens.idItemPreDocumento, x.centroCusto, x.percentualRateio FROM MOORCAMENTOXCENTROSCUSTOS x WHERE x.idItemOrcamento = itens.idItemOrcamento;
      INSERT INTO MOPREDOCUMXORCAMENTOITEM (id, idItemPreDocumento, idItemOrcamento, quantidade, efetivacao) VALUES (FUNC_ADD_BUSCA_PROXIMO_ID('MOPREDOCUMXORCAMENTOITEM', 'id', 0, p_estabelecimentoAtivo, NULL), itens.idItemPreDocumento, itens.idItemOrcamento, itens.quantidade, 1);
      INSERT INTO MOPREDOCUMXPROMOCOES (id, preDocumento, cabecalhoItemPagamento, sequencia, idItemPreDocumento, idPagamentoPreDocumento, regraPromocao, tipoBeneficio, multiplicador, precoUnitarioDe, precoUnitarioPor, precoDesconto, precoMinimo, percentualDesconto, valorDesconto, pontuacao, gerarPontuacao, observacoes) SELECT FUNC_ADD_BUSCA_PROXIMO_ID('MOPREDOCUMXPROMOCOES', 'id', 0, p_estabelecimentoAtivo, NULL), v_preDocumento, x.cabecalhoItemPagamento, itens.sequencia, itens.idItemPreDocumento, 0, x.regraPromocao, x.tipoBeneficio, x.multiplicador, x.precoUnitarioDe, x.precoUnitarioPor, x.precoDesconto, x.precoMinimo, x.percentualDesconto, x.valorDesconto, x.pontuacao, x.gerarPontuacao, x.observacoes FROM MOORCAMENTOXPROMOCOES x WHERE x.idItemOrcamento = itens.idItemOrcamento;
      UPDATE MOCONSERTOS cons SET cons.situacaoConserto = 'R' WHERE cons.documentoTransferenciaFornec > 0 AND cons.situacaoConserto = 'E' AND EXISTS (SELECT 1 FROM MODOCUMENTOTRANSFXITENS itemTransf JOIN MODOCTRANSFXORCAMENTOITEM transfXDoc ON transfXDoc.idItemDocTransferencia = itemTransf.idItemDocTransferencia WHERE itemTransf.documentoTransferencia = cons.documentoTransferenciaFornec AND transfXDoc.entradaSaidaOriginal = 'E' AND transfXDoc.idItemOrcamento = itens.idItemOrcamento);
      FOR endEst IN c_endEst
      LOOP
        IF endEst.idItemOrcamento = itens.idItemOrcamento
        THEN
          INSERT INTO MOPREDOCUMXENDERECOESTOQ (idEnderecoEstoquePreDocumento, idItemPreDocumento, idEnderecoEstoque, posicaoCaixaEstoque, quantidade, quantidadeDevolvidaRetornada, quantidadeConferida, observacoes) VALUES (endEst.idEnderecoEstoquePreDocumento, itens.idItemPreDocumento, endEst.idEnderecoEstoque, endEst.posicaoCaixaEstoque, endEst.quantidade, endEst.quantidadeDevolvidaRetornada, endEst.quantidadeConferida, endEst.observacoes);
          INSERT INTO MOPREDOCUMXNUMEROSSERIE (idNumeroSeriePreDocumento, idItemPreDocumento, idEnderecoEstoquePreDocumento, gradeProduto, idNumeroSerie, devolvidoRetornado) SELECT FUNC_ADD_BUSCA_PROXIMO_ID('MOPREDOCUMXNUMEROSSERIE', 'idNumeroSeriePreDocumento', 0, p_estabelecimentoAtivo, NULL), itens.idItemPreDocumento, endEst.idEnderecoEstoquePreDocumento, x.gradeProduto, x.idNumeroSerie, 0 FROM MOORCAMENTOXNUMEROSSERIE x WHERE x.idItemOrcamento = itens.idItemOrcamento AND x.idEnderecoEstoqueOrcamento = endEst.idEnderecoEstoqueOrcamento;
        END IF;
      END LOOP;
      FOR mot IN c_mot_item
      LOOP
        IF mot.idItemOrcamento = itens.idItemOrcamento THEN
          INSERT INTO MOMOTIVOSBLOQUEIOS (idMotivoBloqueioDocumento, origem, idCabecalho, tipoDocumento, idDocumento, estabelecimento, pessoa, cabecalhoItemPagamento, sequencia, condicaoPagamento, vendedor, gradeProduto, unidadeMedidaConversao, quantidadeConvertida, valorLiquido, motivoBloqueioDocumento, dataBloqueio, baseBloqueado, valorBloqueado, percentualBloqueado, situacaoLiberacao, observacoes) SELECT mot.idMotivoBloqueioNovo, 'P', v_preDocumento, v_tipoDocumento, v_preDocumento, v_estabelecimento, v_pessoa, a.cabecalhoItemPagamento, itens.sequencia, a.condicaoPagamento, a.vendedor, a.gradeProduto, a.unidadeMedidaConversao, a.quantidadeConvertida, a.valorLiquido, a.motivoBloqueioDocumento, a.dataBloqueio, a.baseBloqueado, a.valorBloqueado, a.percentualBloqueado, a.situacaoLiberacao, a.observacoes FROM MOMOTIVOSBLOQUEIOS a WHERE a.idMotivoBloqueioDocumento = mot.idMotivoBloqueioDocumento;
          INSERT INTO MOMOTBLOQXPREDOCUMITENS (id, idMotivoBloqueioDocumento, idItemPreDocumento) VALUES (FUNC_ADD_BUSCA_PROXIMO_ID('MOMOTBLOQXPREDOCUMITENS', 'id', 0, p_estabelecimentoAtivo, NULL), mot.idMotivoBloqueioNovo, itens.idItemPreDocumento);
          INSERT INTO MOMOTBLOQXLIBERACOES (id, idMotivoBloqueioDocumento, usuario, dataLiberacao, valorLiberado, percentualLiberado, percentualAlcada, situacaoLiberacao, observacoes) SELECT FUNC_ADD_BUSCA_PROXIMO_ID('MOMOTBLOQXLIBERACOES', 'id', 0, p_estabelecimentoAtivo, NULL), mot.idMotivoBloqueioNovo, a.usuario, a.dataLiberacao, a.valorLiberado, a.percentualLiberado, a.percentualAlcada, a.situacaoLiberacao, a.observacoes FROM MOMOTBLOQXLIBERACOES a WHERE a.idMotivoBloqueioDocumento = mot.idMotivoBloqueioDocumento;
        END IF;
      END LOOP;
    END IF;
  END LOOP;
  UPDATE MOORCAMENTOXITENS SET quantidadeSaldo = 0 WHERE orcamento = p_orcamento AND cancelado = 0;
  FOR mot IN c_mot_cab
  LOOP
    INSERT INTO MOMOTIVOSBLOQUEIOS (idMotivoBloqueioDocumento, origem, idCabecalho, tipoDocumento, idDocumento, estabelecimento, pessoa, cabecalhoItemPagamento, sequencia, condicaoPagamento, vendedor, gradeProduto, unidadeMedidaConversao, quantidadeConvertida, valorLiquido, motivoBloqueioDocumento, dataBloqueio, baseBloqueado, valorBloqueado, percentualBloqueado, situacaoLiberacao, observacoes) SELECT mot.idMotivoBloqueioNovo, 'P', v_preDocumento, v_tipoDocumento, v_preDocumento, v_estabelecimento, v_pessoa, a.cabecalhoItemPagamento, 0, a.condicaoPagamento, a.vendedor, a.gradeProduto, a.unidadeMedidaConversao, a.quantidadeConvertida, a.valorLiquido, a.motivoBloqueioDocumento, a.dataBloqueio, a.baseBloqueado, a.valorBloqueado, a.percentualBloqueado, a.situacaoLiberacao, a.observacoes FROM MOMOTIVOSBLOQUEIOS a WHERE a.idMotivoBloqueioDocumento = mot.idMotivoBloqueioDocumento;
    INSERT INTO MOMOTBLOQXPREDOCUMENTOS (id, idMotivoBloqueioDocumento, preDocumento) VALUES (FUNC_ADD_BUSCA_PROXIMO_ID('MOMOTBLOQXPREDOCUMENTOS', 'id', 0, p_estabelecimentoAtivo, NULL), mot.idMotivoBloqueioNovo, v_preDocumento);
    INSERT INTO MOMOTBLOQXLIBERACOES (id, idMotivoBloqueioDocumento, usuario, dataLiberacao, valorLiberado, percentualLiberado, percentualAlcada, situacaoLiberacao, observacoes) SELECT FUNC_ADD_BUSCA_PROXIMO_ID('MOMOTBLOQXLIBERACOES', 'id', 0, p_estabelecimentoAtivo, NULL), mot.idMotivoBloqueioNovo, a.usuario, a.dataLiberacao, a.valorLiberado, a.percentualLiberado, a.percentualAlcada, a.situacaoLiberacao, a.observacoes FROM MOMOTBLOQXLIBERACOES a WHERE a.idMotivoBloqueioDocumento = mot.idMotivoBloqueioDocumento;
  END LOOP;
  FOR mot IN c_mot_pag
  LOOP
    INSERT INTO MOMOTIVOSBLOQUEIOS (idMotivoBloqueioDocumento, origem, idCabecalho, tipoDocumento, idDocumento, estabelecimento, pessoa, cabecalhoItemPagamento, sequencia, condicaoPagamento, vendedor, gradeProduto, unidadeMedidaConversao, quantidadeConvertida, valorLiquido, motivoBloqueioDocumento, dataBloqueio, baseBloqueado, valorBloqueado, percentualBloqueado, situacaoLiberacao, observacoes) SELECT mot.idMotivoBloqueioNovo, 'P', v_preDocumento, v_tipoDocumento, v_preDocumento, v_estabelecimento, v_pessoa, a.cabecalhoItemPagamento, a.sequencia, a.condicaoPagamento, a.vendedor, a.gradeProduto, a.unidadeMedidaConversao, a.quantidadeConvertida, a.valorLiquido, a.motivoBloqueioDocumento, a.dataBloqueio, a.baseBloqueado, a.valorBloqueado, a.percentualBloqueado, a.situacaoLiberacao, a.observacoes FROM MOMOTIVOSBLOQUEIOS a WHERE a.idMotivoBloqueioDocumento = mot.idMotivoBloqueioDocumento;
    INSERT INTO MOMOTBLOQXLIBERACOES (id, idMotivoBloqueioDocumento, usuario, dataLiberacao, valorLiberado, percentualLiberado, percentualAlcada, situacaoLiberacao, observacoes) SELECT FUNC_ADD_BUSCA_PROXIMO_ID('MOMOTBLOQXLIBERACOES', 'id', 0, p_estabelecimentoAtivo, NULL), mot.idMotivoBloqueioNovo, a.usuario, a.dataLiberacao, a.valorLiberado, a.percentualLiberado, a.percentualAlcada, a.situacaoLiberacao, a.observacoes FROM MOMOTBLOQXLIBERACOES a WHERE a.idMotivoBloqueioDocumento = mot.idMotivoBloqueioDocumento;
  END LOOP;
  ADD_ORCAMENTO_CAB_RESERVA_GRAV (p_orcamento, p_estabelecimentoAtivo);
  r_preDocumento := v_preDocumento;
END ADD_PRE_DOC_ROT_EFET_ORCAMENTO;

/

create or replace PROCEDURE ADD_DOC_FISC_ROT_EFET_ORCAMENT(
    p_exclusivo               IN VARCHAR2,
    p_1_NFCe_2_ConsFinal_3_NF IN VARCHAR2,
    p_orcamento               IN NUMBER,
    p_usuarioLogado           IN NUMBER,
    p_estabelecimentoAtivo    IN NUMBER,
    p_sessao                  IN NUMBER,
    p_sessaoCaixa             IN NUMBER,
    p_idTerminalSiTef         IN VARCHAR2,
    p_nfFornecedor            IN NUMBER,
    p_idSerieFiscal           IN NUMBER,
    p_serieFiscal             IN VARCHAR2,
    p_subSerieFiscal          IN NUMBER,
    p_modeloDocumentoFiscal   IN VARCHAR2,
    p_documentoFiscal         IN NUMBER,
    p_dataEmissao             IN DATE,
    p_timezone                IN VARCHAR2,
    p_dataEntradaSaida        IN DATE,
    p_comissionadoB           IN NUMBER,
    p_comissionadoC           IN NUMBER,
    p_chaveNfe                IN VARCHAR2,
    p_novaEtapaOrcamento      IN NUMBER,
    p_versaoAplicativo        IN VARCHAR2,
    r_idDocumentoFiscal       OUT NUMBER)
IS
  v_tipoDocumento          NUMBER;
  v_fatoContabil           NUMBER;
  v_idDocumentoFiscal      NUMBER;
  v_estabelecimento        NUMBER;
  v_pessoa                 NUMBER;
  v_colaboradorResponsavel NUMBER;
  v_documentoFiscal        NUMBER;
  CURSOR c_itens IS
    SELECT item.idItemOrcamento,
      CASE
        WHEN cancelado = 0
        THEN FUNC_ADD_BUSCA_PROXIMO_ID('MODOCFISCALXITENS', 'idItemDocFiscal', 0, p_estabelecimentoAtivo, NULL)
        ELSE 0
      END idItemDocFiscal,
      item.sequencia,
      item.cancelado,
      item.modeloDocumento,
      item.vendedor,
      item.gradeProduto,
      item.servico,
      item.idFormulaTinta,
      item.personalizacao,
      item.idLoteEstoque,
      item.operacaoFiscal,
      item.movimentaEstoque,
      item.geraFinanceiro,
      item.localEstoque,
      item.pessoaParticipante,
      item.controleQuantidade,
      item.unidadeMedidaConversao,
      item.conversorQuantidade,
      item.loteMinimo,
      item.loteMultiplo,
      item.altura,
      item.largura,
      item.comprimento,
      item.pecas,
      item.quantidade,
      item.quantidadeConvertida,
      item.quantidadeConferida,
      item.pesoLiquido,
      item.pesoBruto,
      item.tipoPreco,
      item.tabelaPreco,
      item.precoSugestaoAPrazo,
      item.precoSugestaoAVista,
      item.precoDesconto,
      item.precoMinimo,
      item.usarPrecoAVista,
      item.precoPautaTabelado,
      item.precoUnitarioBruto,
      item.acrescimoUnitarioComposicao,
      item.precoUnitario,
      item.precoUnitarioConvertido,
      item.valorProdutoServicoBruto,
      item.valorProdutoServico,
      item.percDescontoItem,
      item.valorDescontoItem,
      item.percAcrescimoItem,
      item.valorAcrescimoItem,
      item.valorFreteItem,
      item.valorSeguroItem,
      item.valorAdicFreteMarinhaMerItem,
      item.valorDespesasAduaneirasItem,
      item.valorFreteGeral,
      item.valorSeguroGeral,
      item.valorDescontoGeral,
      item.valorOutrasDespesasGeral,
      item.valorAdicFreteMarinhaMerGeral,
      item.valorDespesasAduaneirasGeral,
      item.valorBasePagamento,
      item.valorDescontoPagamento,
      item.valorOutrasDespesasPagamento,
      item.valorJurosPagamento,
      item.valorFreteTotal,
      item.valorSeguroTotal,
      item.valorDescontoTotal,
      item.valorOutrasDespesasTotal,
      item.valorAdicFreteMarinhaMerTotal,
      item.valorDespesasAduaneirasTotal,
      item.cfop,
      item.indicadorISSQN,
      item.aliquotaISSQN,
      item.baseISSQN,
      item.valorISSQN,
      item.aliquotaIRRF,
      item.baseIRRF,
      item.valorIRRF,
      item.aliquotaINSS,
      item.baseINSS,
      item.valorINSS,
      item.retencaoPIS,
      item.baseRetPIS,
      item.valorRetPIS,
      item.retencaoCOFINS,
      item.baseRetCOFINS,
      item.valorRetCOFINS,
      item.retencaoCSLL,
      item.baseRetCSLL,
      item.valorRetCSLL,
      item.aliquotaII,
      item.baseII,
      item.valorII,
      item.aliquotaIOF,
      item.baseIOF,
      item.valorIOF,
      item.codigoEnquadramentoIPI,
      item.stIPI,
      item.aliquotaIPI,
      item.valorAliquotaIPI,
      item.baseIPI,
      item.valorIPI,
      item.stPIS,
      item.aliquotaPIS,
      item.valorAliquotaPIS,
      item.basePIS,
      item.valorPIS,
      item.aliquotaPISST,
      item.valorAliquotaPISST,
      item.basePISST,
      item.valorPISST,
      item.stCOFINS,
      item.aliquotaCOFINS,
      item.valorAliquotaCOFINS,
      item.baseCOFINS,
      item.valorCOFINS,
      item.aliquotaCOFINSST,
      item.valorAliquotaCOFINSST,
      item.baseCOFINSST,
      item.valorCOFINSST,
      item.stSimplesNacional,
      item.creditoSimplesNacional,
      item.baseCreditoSimplesNacional,
      item.valorCreditoSimplesNacional,
      item.stICMS,
      item.modalidadeBaseCalcICMS,
      item.reducaoBaseICMS,
      item.aliquotaICMS,
      item.diferimentoICMS,
      item.motivoDesoneracaoICMS,
      item.baseICMS,
      item.valorICMSOperacao,
      item.valorICMSDiferido,
      item.valorICMS,
      item.valorICMSDesoneracao,
      item.modalidadeBaseCalcICMSST,
      item.margemValorAdicionadoST,
      item.reducaoBaseST,
      item.aliquotaICMSST,
      item.aliquotaSTSuportConsFinal,
      item.baseICMSST,
      item.valorICMSST,
      item.baseICMSSTAnteriormente,
      item.valorICMSSTAnteriormente,
      item.valorICMSProprioSubstituto,
      item.reducaoBaseICMSEfetivo,
      item.aliquotaICMSEfetivo,
      item.baseICMSEfetivo,
      item.valorICMSEfetivo,
      CASE
        WHEN p_nfFornecedor = 1 AND prod.tipoProduto IN('07','08')
        THEN '90'
        WHEN p_nfFornecedor = 1 AND item.stICMS IN('10','30','70')
          OR p_nfFornecedor = 1 AND item.stICMS = ' ' AND item.stSimplesNacional IN ('201','202','203')
          OR item.stICMS = ' ' AND item.stSimplesNacional = '500'
        THEN '60'
        WHEN item.stICMS <> ' '
        THEN item.stICMS
        WHEN item.stSimplesNacional IN ('101','102') AND item.reducaoBaseICMS = 0
        THEN '00'
        WHEN item.stSimplesNacional IN ('101','102')
        THEN '20'
        WHEN item.stSimplesNacional IN ('103','300')
        THEN '40'
        WHEN item.stSimplesNacional IN ('201','202','203') AND item.reducaoBaseICMS = 0
        THEN '10' WHEN item.stSimplesNacional IN ('201','202','203')
        THEN '70' WHEN item.stSimplesNacional = '400'
        THEN '41'
        ELSE '90'
      END stICMSEscrituracao,
      CASE
        WHEN p_nfFornecedor = 1 AND (prod.tipoProduto IN('07','08')
          OR item.stICMS IN('10','30','70')
          OR item.stICMS = ' ' AND item.stSimplesNacional IN ('201','202','203'))
          OR item.stICMS = ' ' AND item.stSimplesNacional = '500' THEN 0 WHEN item.stICMS <> ' '
        THEN item.reducaoBaseICMS
        ELSE 0
      END reducaoBaseICMSEscrituracao,
      CASE
        WHEN p_nfFornecedor = 1 AND (prod.tipoProduto IN('07','08')
          OR item.stICMS IN('10','30','70')
          OR item.stICMS = ' ' AND item.stSimplesNacional IN ('201','202','203'))
          OR item.stICMS = ' ' AND item.stSimplesNacional = '500' THEN 0 WHEN item.stICMS <> ' '
        THEN item.aliquotaICMS
        WHEN item.stSimplesNacional IN ('101','201')
        THEN item.creditoSimplesNacional
        ELSE 0
      END aliquotaICMSEscrituracao,
      CASE
        WHEN p_nfFornecedor = 1 AND (prod.tipoProduto IN('07','08')
          OR item.stICMS IN('10','30','70')
          OR item.stICMS = ' ' AND item.stSimplesNacional IN ('201','202','203'))
          OR item.stICMS = ' ' AND item.stSimplesNacional = '500'
        THEN 0
        WHEN item.stICMS <> ' ' AND p_nfFornecedor = 1
        THEN ROUND(item.baseICMS *(1-item.diferimentoICMS/100),2)
        WHEN item.stICMS <> ' '
        THEN item.baseICMS
        WHEN item.stSimplesNacional IN ('101','201') AND item.baseCreditoSimplesNacional = 0
        THEN item.valorProdutoServico
          - item.valorDescontoTotal
          + item.valorOutrasDespesasTotal
          + item.valorAdicFreteMarinhaMerTotal
          + item.valorDespesasAduaneirasTotal
          + item.valorII
          + item.valorIOF
        WHEN item.stSimplesNacional IN ('101','201')
        THEN item.baseCreditoSimplesNacional
        ELSE 0
      END baseICMSEscrituracao,
      CASE
        WHEN p_nfFornecedor = 1 AND (prod.tipoProduto IN('07','08')
          OR item.stICMS IN('10','30','70')
          OR item.stICMS = ' ' AND item.stSimplesNacional IN ('201','202','203'))
          OR item.stICMS = ' ' AND item.stSimplesNacional = '500'
        THEN 0
        WHEN item.stICMS <> ' '
        THEN item.valorICMS
        WHEN item.stSimplesNacional IN ('101','201')
        THEN item.valorCreditoSimplesNacional
        ELSE 0
      END valorICMSEscrituracao,
      CASE
        WHEN p_nfFornecedor = 1 AND (prod.tipoProduto IN('07','08')
          OR item.stICMS IN('10','30','70')
          OR item.stICMS = ' ' AND item.stSimplesNacional IN ('201','202','203'))
          OR item.stICMS = ' ' AND item.stSimplesNacional = '500'
        THEN 0
        WHEN item.stICMS <> ' '
        THEN item.valorICMSDesoneracao
        ELSE 0
      END valorICMSDesonEscrituracao,
      CASE
        WHEN item.stICMS = ' '
          OR p_nfFornecedor = 1 AND (prod.tipoProduto IN('07','08')
          OR item.stICMS IN('10','30','60','70'))
        THEN 0
        ELSE item.margemValorAdicionadoST
      END margemValorAdicSTEscrituracao,
      CASE
        WHEN item.stICMS = ' '
          OR p_nfFornecedor = 1 AND (prod.tipoProduto IN('07','08')
          OR item.stICMS IN('10','30','60','70'))
        THEN 0
        ELSE item.reducaoBaseST
      END reducaoBaseSTEscrituracao,
      CASE
        WHEN item.stICMS = ' '
          OR p_nfFornecedor = 1 AND (prod.tipoProduto IN('07','08')
          OR item.stICMS IN('10','30','60','70'))
        THEN 0
        ELSE item.aliquotaICMSST
      END aliquotaICMSSTEscrituracao,
      CASE
        WHEN item.stICMS = ' '
          OR p_nfFornecedor = 1 AND (prod.tipoProduto IN('07','08')
          OR item.stICMS IN('10','30','60','70'))
        THEN 0
        ELSE item.baseICMSST
      END baseICMSSTEscrituracao,
      CASE
        WHEN item.stICMS = ' '
          OR p_nfFornecedor = 1 AND (prod.tipoProduto IN('07','08')
          OR item.stICMS IN('10','30','60','70'))
        THEN 0
        ELSE item.valorICMSST
      END valorICMSSTEscrituracao,
      1 somarICMSST,
      item.aliquotaICMSUFDestinatario,
      item.aliquotaICMSInterestadual,
      item.partilhaICMSInterestadual,
      item.baseICMSUFDestinatario,
      item.valorICMSUFDestinatario,
      item.baseICMSUFRemetente,
      item.valorICMSUFRemetente,
      item.aliquotaFCP,
      item.baseFCP,
      item.valorFCP,
      item.aliquotaFCPST,
      item.baseFCPST,
      item.valorFCPST,
      item.aliquotaFCPSTAnteriormente,
      item.baseFCPSTAnteriormente,
      item.valorFCPSTAnteriormente,
      item.aliquotaFCPUFDestinatario,
      item.baseFCPUFDestinatario,
      item.valorFCPUFDestinatario,
      item.aliquotaEstimadaImpFederais,
      item.aliquotaEstimadaImpEstaduais,
      item.aliquotaEstimadaImpMunicipais,
      item.baseEstimadaImpostos,
      item.valorEstimadoImpFederais,
      item.valorEstimadoImpEstaduais,
      item.valorEstimadoImpMunicipais,
      item.valorImpostosSomaPagamento,
      item.valorImpostosDiminuiPagamento,
      item.valorLiquidoItem,
      item.observacoesDigitadas,
      item.observacoes
    FROM MOORCAMENTOXITENS item
    JOIN CAGRADESPRODUTO gradProd ON gradProd.gradeProduto = item.gradeProduto
    JOIN CAPRODUTOS prod ON prod.produto = gradProd.produto
    WHERE item.orcamento = p_orcamento
    ORDER BY item.sequencia;
  CURSOR c_endEst IS
    SELECT
      a.idEnderecoEstoqueOrcamento,
      a.idItemOrcamento,
      FUNC_ADD_BUSCA_PROXIMO_ID(
        'MODOCFISCALXENDERECOESTOQ',
        'idEnderecoEstoqueDocFiscal',
        0,
        p_estabelecimentoAtivo,
        NULL) idEnderecoEstoqueDocFiscal,
      a.idEnderecoEstoque,
      a.posicaoCaixaEstoque,
      a.quantidade,
      0 quantidadeDevolvidaRetornada,
      a.quantidadeConferida,
      a.observacoes
    FROM MOORCAMENTOXENDERECOESTOQ a
    JOIN MOORCAMENTOXITENS b ON b.idItemOrcamento = a.idItemOrcamento
    WHERE b.orcamento = p_orcamento
    AND b.cancelado = 0;
  CURSOR c_mot_cab IS
    SELECT idMotivoBloqueioDocumento, FUNC_ADD_BUSCA_PROXIMO_ID('MOMOTIVOSBLOQUEIOS', 'idMotivoBloqueioDocumento', 0, p_estabelecimentoAtivo, NULL) idMotivoBloqueioNovo
    FROM MOMOTBLOQXORCAMENTOS
    WHERE orcamento = p_orcamento;
  CURSOR c_mot_item IS
    SELECT a.idMotivoBloqueioDocumento, a.idItemOrcamento, FUNC_ADD_BUSCA_PROXIMO_ID('MOMOTIVOSBLOQUEIOS', 'idMotivoBloqueioDocumento', 0, p_estabelecimentoAtivo, NULL) idMotivoBloqueioNovo
    FROM MOMOTBLOQXORCAMENTOITENS a
    JOIN MOORCAMENTOXITENS b ON b.idItemOrcamento = a.idItemOrcamento
    WHERE b.orcamento = p_orcamento
    AND b.cancelado = 0;
  CURSOR c_mot_pag IS
    SELECT
      FUNC_ADD_BUSCA_PROXIMO_ID('MOMOTIVOSBLOQUEIOS', 'idMotivoBloqueioDocumento', 0, p_estabelecimentoAtivo, NULL) idMotivoBloqueioNovo,
      a.idMotivoBloqueioDocumento
      FROM MOMOTIVOSBLOQUEIOS a
      WHERE a.origem = 'O'
      AND a.idCabecalho = p_orcamento
      AND a.cabecalhoItemPagamento = 'P'
      AND NOT (EXISTS(
        SELECT 1
        FROM MOMOTBLOQXORCAMENTOPAGAM b
        WHERE b.idMotivoBloqueioDocumento = a.idMotivoBloqueioDocumento));
BEGIN
SELECT
  CASE
    WHEN orc.entradaSaida='E'
    THEN 601
    WHEN p_1_NFCe_2_ConsFinal_3_NF = '1'
    OR p_1_NFCe_2_ConsFinal_3_NF   = '2'
    THEN 503
    ELSE 501
  END,
  orc.estabelecimento,
  CASE
    WHEN p_1_NFCe_2_ConsFinal_3_NF = '2'
    THEN 0
    ELSE orc.pessoa
  END,
  CASE
    WHEN orc.tipoDocumento = 102
      AND orc.colaboradorResponsavel <> 0
      AND EXISTS (
        SELECT 1
        FROM CAVENDEDORES
        WHERE vendedor = orc.colaboradorResponsavel
        AND ativo = 1)
    THEN orc.colaboradorResponsavel
    ELSE 0
  END,
  CASE
    WHEN p_nfFornecedor = 1
    THEN p_documentoFiscal
    ELSE FUNC_ADD_BUSCA_PROXIMO_ID('MODOCUMENTOSFISCAIS|'
      || LPAD (orc.estabelecimento,4,'0')
      || '|'
      || LPAD (p_idSerieFiscal,14,'0'), ' ', 0, 0,TRUNC(p_dataEmissao))
  END
INTO v_tipoDocumento,
  v_estabelecimento,
  v_pessoa,
  v_colaboradorResponsavel,
  v_documentoFiscal
FROM MOORCAMENTOS orc
WHERE orcamento = p_orcamento;
  v_fatoContabil := FUNC_ADD_BUSCA_PROXIMO_ID('MOFATOSCONTABEIS', 'fatoContabil', 0, p_estabelecimentoAtivo, NULL);
  INSERT INTO MOFATOSCONTABEIS (
    fatoContabil,
    estabelecimento,
    data,
    ordenacao,
    situacaoTransacao,
    situacaoContabilizacao,
    sessao,
    observacoes)
  VALUES (
    v_fatoContabil,
    v_estabelecimento,
    p_dataEmissao,
    0,
    'A',
    'A',
    p_sessao,
    ' ');
  v_idDocumentoFiscal := FUNC_ADD_BUSCA_PROXIMO_ID('MODOCUMENTOSFISCAIS', 'idDocumentoFiscal', 0, p_estabelecimentoAtivo, NULL);
  INSERT INTO MODOCUMENTOSFISCAIS (
    idDocumentoFiscal,
    origemDocumento,
    tipoDocumento,
    tipoVenda,
    modeloDocumento,
    entradaSaida,
    devolucaoAnulacaoRetorno,
    finalidadeNota,
    atualizaCustoMedio,
    atualizaUltimaCompra,
    validoFaturamento,
    usarPrecoAVista,
    sessao,
    sessaoCaixa,
    fatoContabil,
    idTerminalSiTef,
    estabelecimentoOriginal,
    estabelecimento,
    enderecoRetiradaEstabeleciment,
    indicadorPresencaComprador,
    controlaSeparacaoConferencia,
    nfFornecedor,
    idSerieFiscal,
    serieFiscal,
    subserieFiscal,
    modeloDocumentoFiscal,
    documentoFiscal,
    dataEmissao,
    timezoneEmissao,
    dataEntradaSaida,
    pessoa,
    vendaConsumidor,
    indicadorPessoa,
    indicadorDocumentoPessoa,
    cnpjCpfIdEstrangeiro,
    nomeRazaoSocial,
    fone,
    indicadorFone,
    operadoraTelefonia,
    autorizadoPessoa,
    enderecoEntregaPessoa,
    municipioFatoGerador,
    localDestinoOperacao,
    indicadorConsumidorFinal,
    projeto,
    contratoCompra,
    comissionadoB,
    comissionadoC,
    modalidadeFrete,
    tipoPagamentoFrete,
    transportadora,
    enderecoTransportadora,
    motorista,
    placa,
    vagao,
    balsa,
    quantidadeVolume,
    especieVolume,
    descricaoMarca,
    numeracaoVolume,
    codigoIntegracao,
    atendimento,
    tipoCTe,
    idContingenciaNfe,
    codigoNumericoNfe,
    digitoVerificadorNfe,
    formaEmissaoNfe,
    indicadorAmbienteNfe,
    qrCode,
    chaveNfe,
    situacaoDocumentoFiscal,
    ultimoVendedorItem,
    quantidade,
    pesoLiquido,
    pesoBruto,
    valorProdutosBruto,
    valorProdutos,
    valorDescontoProdutos,
    valorAcrescimoProdutos,
    valorServicosBruto,
    valorServicos,
    valorDescontoServicos,
    valorAcrescimoServicos,
    valorFreteItem,
    valorSeguroItem,
    valorAdicFreteMarinhaMerItem,
    valorDespesasAduaneirasItem,
    valorFreteGeral,
    valorSeguroGeral,
    valorDescontoGeral,
    valorOutrasDespesasGeral,
    valorAdicFreteMarinhaMerGeral,
    valorDespesasAduaneirasGeral,
    condicaoPagamento,
    contaFinanceira,
    numeroParcelas,
    somaPrazoParcelas,
    valorXPrazoParcelas,
    prazoMedio,
    prazoMedioPonderado,
    valorBasePagamento,
    valorAVistaMinimo,
    valorEntradaMinima,
    valorAVistaEntrada,
    valorPagamentoBruto,
    valorDescontoPagamento,
    valorOutrasDespesasPagamento,
    valorJurosPagamento,
    valorPagamentoLiquido,
    valorTroco,
    valorFreteTotal,
    valorSeguroTotal,
    valorDescontoTotal,
    valorOutrasDespesasTotal,
    valorAdicFreteMarinhaMerTotal,
    valorDespesasAduaneirasTotal,
    impostosEditados,
    valorImpostosSomaPagamento,
    valorImpostosDiminuiPagamento,
    valorLiquidoItem,
    valorDescontoCustoOpItem,
    valorDescontoCustoOpGeral,
    valorDescontoCustoOpTotal,
    valorAcrescimoCustoOpItem,
    valorAcrescimoCustoOpGeral,
    valorAcrescimoCustoOpTotal,
    valorCustoOperacao,
    valorCMV,
    versaoAplicativo)
  SELECT
    v_idDocumentoFiscal,
    2,
    v_tipoDocumento,
    orc.tipoVenda,
    orc.modeloDocumento,
    orc.entradaSaida,
    0 devolucaoAnulacaoRetorno,
    orc.finalidadeNota,
    orc.atualizaCustoMedio,
    orc.atualizaUltimaCompra,
    orc.validoFaturamento,
    orc.usarPrecoAVista,
    p_sessao,
    p_sessaoCaixa,
    v_fatoContabil,
    p_idTerminalSiTef,
    orc.estabelecimento,
    orc.estabelecimento,
    orc.enderecoRetiradaEstabeleciment,
    orc.indicadorPresencaComprador,
    orc.controlaSeparacaoConferencia,
    p_nfFornecedor,
    p_idSerieFiscal,
    p_serieFiscal,
    p_subserieFiscal,
    p_modeloDocumentoFiscal,
    v_documentoFiscal,
    p_dataEmissao dataEmissao,
    p_timezone timezoneEmissao,
    p_dataEntradaSaida dataEntradaSaida,
    CASE WHEN p_1_NFCe_2_ConsFinal_3_NF = '2' THEN 0 ELSE orc.pessoa END pessoa,
    CASE WHEN p_1_NFCe_2_ConsFinal_3_NF = '2' THEN 1 ELSE 0 END vendaConsumidor,
    'F' indicadorPessoa,
    'C' indicadorDocumentoPessoa,
    ' ' cnpjCpfIdEstrangeiro,
    ' ' nomeRazaoSocial,
    ' ' fone,
    0 indicadorFone,
    0 operadoraTelefonia,
    CASE WHEN p_1_NFCe_2_ConsFinal_3_NF = '2' THEN 0 ELSE orc.autorizadoPessoa END autorizadoPessoa,
    CASE WHEN p_1_NFCe_2_ConsFinal_3_NF = '2' THEN 0 ELSE orc.enderecoEntregaPessoa END enderecoEntregaPessoa,
    CASE
      WHEN p_1_NFCe_2_ConsFinal_3_NF = '2'
      THEN COALESCE ((SELECT MAX(endEst.municipio) FROM CAENDERECOSPESSOA endEst WHERE endEst.pessoa = est.pessoaEstabelecimento AND endEst.ativo = 1 AND endEst.principal = 1),0)
      ELSE orc.municipioFatoGerador
    END municipioFatoGerador,
    CASE WHEN p_1_NFCe_2_ConsFinal_3_NF = '2' THEN '1' ELSE orc.localDestinoOperacao END localDestinoOperacao,
    CASE WHEN p_1_NFCe_2_ConsFinal_3_NF = '2' THEN '1' ELSE orc.indicadorConsumidorFinal END indicadorConsumidorFinal,
    orc.projeto,
    orc.contratoCompra,
    p_comissionadoB comissionadoB,
    p_comissionadoC comissionadoC,
    CASE WHEN orc.modalidadeFrete = ' ' THEN '9' ELSE orc.modalidadeFrete END,
    CASE WHEN orc.tipoPagamentoFrete = ' ' THEN 'N' ELSE orc.tipoPagamentoFrete END,
    orc.transportadora,
    orc.enderecoTransportadora,
    orc.motorista,
    orc.placa,
    orc.vagao,
    orc.balsa,
    orc.quantidadeVolume,
    orc.especieVolume,
    orc.descricaoMarca,
    orc.numeracaoVolume,
    orc.codigoIntegracao,
    orc.atendimento,
    '0' tipoCTe,
    0 idContingenciaNfe,
    0 codigoNumericoNfe,
    0 digitoVerificadorNfe,
    ' ' formaEmissaoNfe,
    est.indicadorAmbienteNfe,
    ' ' qrCode,
    p_chaveNfe chaveNfe,
    11 situacaoDocumentoFiscal,
    CASE WHEN orc.ultimoVendedorItem = 0 THEN v_colaboradorResponsavel ELSE orc.ultimoVendedorItem END,
    orc.quantidade,
    orc.pesoLiquido,
    orc.pesoBruto,
    orc.valorProdutosBruto,
    orc.valorProdutos,
    orc.valorDescontoProdutos,
    orc.valorAcrescimoProdutos,
    orc.valorServicosBruto,
    orc.valorServicos,
    orc.valorDescontoServicos,
    orc.valorAcrescimoServicos,
    orc.valorFreteItem,
    orc.valorSeguroItem,
    orc.valorAdicFreteMarinhaMerItem,
    orc.valorDespesasAduaneirasItem,
    orc.valorFreteGeral,
    orc.valorSeguroGeral,
    orc.valorDescontoGeral,
    orc.valorOutrasDespesasGeral,
    orc.valorAdicFreteMarinhaMerGeral,
    orc.valorDespesasAduaneirasGeral,
    orc.condicaoPagamento,
    orc.contaFinanceira,
    0 numeroParcelas,
    0 somaPrazoParcelas,
    0 valorXPrazoParcelas,
    0 prazoMedio,
    0 prazoMedioPonderado,
    orc.valorBasePagamento,
    orc.valorAVistaMinimo,
    0 valorEntradaMinima,
    0 valorAVistaEntrada,
    0 valorPagamentoBruto,
    0 valorDescontoPagamento,
    0 valorOutrasDespesasPagamento,
    0 valorJurosPagamento,
    0 valorPagamentoLiquido,
    0 valorTroco,
    orc.valorFreteTotal,
    orc.valorSeguroTotal,
    orc.valorDescontoTotal - CASE WHEN orc.valorDescontoTotal >= orc.valorDescontoPagamento THEN orc.valorDescontoPagamento ELSE 0 END,
    orc.valorOutrasDespesasTotal - CASE WHEN orc.valorOutrasDespesasTotal > orc.valorOutrasDespesasPagamento + orc.valorJurosPagamento THEN orc.valorOutrasDespesasPagamento + orc.valorJurosPagamento ELSE 0 END,
    orc.valorAdicFreteMarinhaMerTotal,
    orc.valorDespesasAduaneirasTotal,
    orc.impostosEditados,
    orc.valorImpostosSomaPagamento,
    orc.valorImpostosDiminuiPagamento,
    orc.valorLiquidoItem + CASE WHEN orc.valorDescontoTotal >= orc.valorDescontoPagamento THEN orc.valorDescontoPagamento ELSE 0 END - CASE WHEN orc.valorOutrasDespesasTotal > orc.valorOutrasDespesasPagamento + orc.valorJurosPagamento THEN orc.valorOutrasDespesasPagamento + orc.valorJurosPagamento ELSE 0 END,
    0,
    0,
    0,
    0,
    0,
    0,
    0,
    0,
    p_versaoAplicativo
  FROM MOORCAMENTOS orc
  JOIN PAESTABELECIMENTOS est ON est.estabelecimento = orc.estabelecimento
  WHERE orcamento = p_orcamento;
  UPDATE MOORCAMENTOS SET etapaOrcamento = p_novaEtapaOrcamento WHERE orcamento = p_orcamento;
  INSERT INTO MOORCAMENTOXETAPAS (id, orcamento, data, usuario, etapaOrcamento, observacoes) VALUES (FUNC_ADD_BUSCA_PROXIMO_ID('MOORCAMENTOXETAPAS', 'id', 0, p_estabelecimentoAtivo, NULL), p_orcamento, sysdate, p_usuarioLogado, p_novaEtapaOrcamento, ' ');
  INSERT INTO MODOCFISCALXPERSPROJETO (idPersonProjetoDocFiscal, idDocumentoFiscal, personalizacaoProjeto, conteudo) SELECT FUNC_ADD_BUSCA_PROXIMO_ID('MODOCFISCALXPERSPROJETO', 'idPersonProjetoDocFiscal', 0, p_estabelecimentoAtivo, NULL), v_idDocumentoFiscal, x.personalizacaoProjeto, x.conteudo FROM MOORCAMENTOXPERSPROJETO x WHERE x.orcamento = p_orcamento;
  INSERT INTO MODOCFISCALXINFOCOMPLEMEN (id, idDocumentoFiscal, sequencia, geradoPeloSistema, imprimir, destaque, informacaoComplementar, descInformacaoComplementar) SELECT FUNC_ADD_BUSCA_PROXIMO_ID('MODOCFISCALXINFOCOMPLEMEN', 'id', 0, p_estabelecimentoAtivo, NULL), v_idDocumentoFiscal, x.sequencia, x.geradoPeloSistema, x.imprimir, x.destaque, x.informacaoComplementar, x.descInformacaoComplementar FROM MOORCAMENTOXINFOCOMPLENT x WHERE x.orcamento = p_orcamento;
  INSERT INTO MODOCFISCALXPROMOCOES (id, idDocumentoFiscal, cabecalhoItemPagamento, sequencia, idItemDocFiscal, idPagamentoDocFiscal, regraPromocao, tipoBeneficio, multiplicador, precoUnitarioDe, precoUnitarioPor, precoDesconto, precoMinimo, percentualDesconto, valorDesconto, pontuacao, gerarPontuacao, observacoes) SELECT FUNC_ADD_BUSCA_PROXIMO_ID('MODOCFISCALXPROMOCOES', 'id', 0, p_estabelecimentoAtivo, NULL), v_idDocumentoFiscal, x.cabecalhoItemPagamento, x.sequencia, 0, 0, x.regraPromocao, x.tipoBeneficio, x.multiplicador, x.precoUnitarioDe, x.precoUnitarioPor, x.precoDesconto, x.precoMinimo, x.percentualDesconto, x.valorDesconto, x.pontuacao, x.gerarPontuacao, x.observacoes
  FROM MOORCAMENTOXPROMOCOES x WHERE x.orcamento = p_orcamento AND x.idItemOrcamento = 0 AND x.idPagamentoOrcamento = 0;
  FOR itens IN c_itens
  LOOP
    IF itens.cancelado = 0
    THEN
      INSERT INTO MODOCFISCALXITENS (idItemDocFiscal, idDocumentoFiscal, sequencia, cancelado, modeloDocumento, estabelecimentoOriginal, vendedor, gradeProduto, servico, idFormulaTinta, personalizacao, idLoteEstoque, operacaoFiscal, movimentaEstoque, movimentaEstoqueFiscal, geraFinanceiro, localEstoque, pessoaParticipante, controleQuantidade, unidadeMedidaConversao, conversorQuantidade, loteMinimo, loteMultiplo, altura, largura, comprimento, pecas, quantidade, quantidadeConvertida, quantidadeDevolvidaRetornada, quantidadeConferida, percentualDevolucao, pesoLiquido, pesoBruto, tipoPreco, tabelaPreco, precoSugestaoAPrazo, precoSugestaoAVista, precoDesconto, precoMinimo, usarPrecoAVista, precoPautaTabelado, precoUnitarioBruto, acrescimoUnitarioComposicao, precoUnitario, precoUnitarioConvertido, valorProdutoServicoBruto, valorProdutoServico, percDescontoItem, valorDescontoItem, percAcrescimoItem, valorAcrescimoItem, valorFreteItem, valorSeguroItem, valorAdicFreteMarinhaMerItem, valorDespesasAduaneirasItem, valorFreteGeral, valorSeguroGeral, valorDescontoGeral, valorOutrasDespesasGeral, valorAdicFreteMarinhaMerGeral, valorDespesasAduaneirasGeral, valorBasePagamento, valorDescontoPagamento, valorOutrasDespesasPagamento, valorJurosPagamento, valorFreteTotal, valorSeguroTotal, valorDescontoTotal, valorOutrasDespesasTotal, valorAdicFreteMarinhaMerTotal, valorDespesasAduaneirasTotal, cfop, indicadorISSQN, aliquotaISSQN, baseISSQN, valorISSQN, aliquotaIRRF, baseIRRF, valorIRRF, aliquotaINSS, baseINSS, valorINSS, retencaoPIS, baseRetPIS, valorRetPIS, retencaoCOFINS, baseRetCOFINS, valorRetCOFINS, retencaoCSLL, baseRetCSLL, valorRetCSLL, aliquotaII, baseII, valorII, aliquotaIOF, baseIOF, valorIOF, codigoEnquadramentoIPI, stIPI, aliquotaIPI, valorAliquotaIPI, baseIPI, valorIPI, valorIPIDevolucao, stPIS, aliquotaPIS, valorAliquotaPIS, basePIS, valorPIS, aliquotaPISST, valorAliquotaPISST, basePISST, valorPISST, stCOFINS, aliquotaCOFINS, valorAliquotaCOFINS, baseCOFINS, valorCOFINS, aliquotaCOFINSST, valorAliquotaCOFINSST, baseCOFINSST, valorCOFINSST, stSimplesNacional, creditoSimplesNacional, baseCreditoSimplesNacional, valorCreditoSimplesNacional, stICMS, modalidadeBaseCalcICMS, reducaoBaseICMS, aliquotaICMS, diferimentoICMS, motivoDesoneracaoICMS, baseICMS, valorICMSOperacao, valorICMSDiferido, valorICMS, valorICMSDesoneracao, modalidadeBaseCalcICMSST, margemValorAdicionadoST, reducaoBaseST, aliquotaICMSST, aliquotaSTSuportConsFinal, baseICMSST, valorICMSST, baseICMSSTAnteriormente, valorICMSSTAnteriormente, valorICMSProprioSubstituto, reducaoBaseICMSEfetivo, aliquotaICMSEfetivo, baseICMSEfetivo, valorICMSEfetivo, stICMSEscrituracao, reducaoBaseICMSEscrituracao, aliquotaICMSEscrituracao, baseICMSEscrituracao, valorICMSEscrituracao, valorICMSDesonEscrituracao, margemValorAdicSTEscrituracao, reducaoBaseSTEscrituracao, aliquotaICMSSTEscrituracao, baseICMSSTEscrituracao, valorICMSSTEscrituracao, somarICMSST, aliquotaICMSUFDestinatario, aliquotaICMSInterestadual, partilhaICMSInterestadual, baseICMSUFDestinatario, valorICMSUFDestinatario, baseICMSUFRemetente, valorICMSUFRemetente, aliquotaFCP, baseFCP, valorFCP, aliquotaFCPST, baseFCPST, valorFCPST, aliquotaFCPSTAnteriormente, baseFCPSTAnteriormente, valorFCPSTAnteriormente, aliquotaFCPUFDestinatario, baseFCPUFDestinatario, valorFCPUFDestinatario, aliquotaEstimadaImpFederais, aliquotaEstimadaImpEstaduais, aliquotaEstimadaImpMunicipais, baseEstimadaImpostos, valorEstimadoImpFederais, valorEstimadoImpEstaduais, valorEstimadoImpMunicipais, valorImpostosSomaPagamento, valorImpostosDiminuiPagamento, valorLiquidoItem, valorDescontoCustoOpItem, valorDescontoCustoOpGeral, valorDescontoCustoOpTotal, valorAcrescimoCustoOpItem, valorAcrescimoCustoOpGeral, valorAcrescimoCustoOpTotal, precoCustoOperacao, valorCustoOperacao, precoCMV, valorCMV, observacoesDigitadas, observacoes) VALUES (itens.idItemDocFiscal, v_idDocumentoFiscal, itens.sequencia, itens.cancelado, itens.modeloDocumento, v_estabelecimento, CASE WHEN itens.vendedor = 0 THEN v_colaboradorResponsavel ELSE itens.vendedor END, itens.gradeProduto, itens.servico, itens.idFormulaTinta, itens.personalizacao, itens.idLoteEstoque, itens.operacaoFiscal, itens.movimentaEstoque, itens.movimentaEstoque, itens.geraFinanceiro, itens.localEstoque, itens.pessoaParticipante, itens.controleQuantidade, itens.unidadeMedidaConversao, itens.conversorQuantidade, itens.loteMinimo, itens.loteMultiplo, itens.altura, itens.largura, itens.comprimento, itens.pecas, itens.quantidade, itens.quantidadeConvertida, 0, itens.quantidadeConferida, 0, itens.pesoLiquido, itens.pesoBruto, itens.tipoPreco, itens.tabelaPreco, itens.precoSugestaoAPrazo, itens.precoSugestaoAVista, itens.precoDesconto, itens.precoMinimo, itens.usarPrecoAVista, itens.precoPautaTabelado, itens.precoUnitarioBruto, itens.acrescimoUnitarioComposicao, itens.precoUnitario, itens.precoUnitarioConvertido, itens.valorProdutoServicoBruto, itens.valorProdutoServico, itens.percDescontoItem, itens.valorDescontoItem, itens.percAcrescimoItem, itens.valorAcrescimoItem, itens.valorFreteItem, itens.valorSeguroItem, itens.valorAdicFreteMarinhaMerItem, itens.valorDespesasAduaneirasItem, itens.valorFreteGeral, itens.valorSeguroGeral, itens.valorDescontoGeral, itens.valorOutrasDespesasGeral, itens.valorAdicFreteMarinhaMerGeral, itens.valorDespesasAduaneirasGeral, itens.valorBasePagamento, itens.valorDescontoPagamento, itens.valorOutrasDespesasPagamento, itens.valorJurosPagamento, itens.valorFreteTotal, itens.valorSeguroTotal, itens.valorDescontoTotal, itens.valorOutrasDespesasTotal, itens.valorAdicFreteMarinhaMerTotal, itens.valorDespesasAduaneirasTotal, itens.cfop, itens.indicadorISSQN, itens.aliquotaISSQN, itens.baseISSQN, itens.valorISSQN, itens.aliquotaIRRF, itens.baseIRRF, itens.valorIRRF, itens.aliquotaINSS, itens.baseINSS, itens.valorINSS, itens.retencaoPIS, itens.baseRetPIS, itens.valorRetPIS, itens.retencaoCOFINS, itens.baseRetCOFINS, itens.valorRetCOFINS, itens.retencaoCSLL, itens.baseRetCSLL, itens.valorRetCSLL, itens.aliquotaII, itens.baseII, itens.valorII, itens.aliquotaIOF, itens.baseIOF, itens.valorIOF, itens.codigoEnquadramentoIPI, itens.stIPI, itens.aliquotaIPI, itens.valorAliquotaIPI, itens.baseIPI, itens.valorIPI, 0, itens.stPIS, itens.aliquotaPIS, itens.valorAliquotaPIS, itens.basePIS, itens.valorPIS, itens.aliquotaPISST, itens.valorAliquotaPISST, itens.basePISST, itens.valorPISST, itens.stCOFINS, itens.aliquotaCOFINS, itens.valorAliquotaCOFINS, itens.baseCOFINS, itens.valorCOFINS, itens.aliquotaCOFINSST, itens.valorAliquotaCOFINSST, itens.baseCOFINSST, itens.valorCOFINSST, itens.stSimplesNacional, itens.creditoSimplesNacional, itens.baseCreditoSimplesNacional, itens.valorCreditoSimplesNacional, itens.stICMS, itens.modalidadeBaseCalcICMS, itens.reducaoBaseICMS, itens.aliquotaICMS, itens.diferimentoICMS, itens.motivoDesoneracaoICMS, itens.baseICMS, itens.valorICMSOperacao, itens.valorICMSDiferido, itens.valorICMS, itens.valorICMSDesoneracao, itens.modalidadeBaseCalcICMSST, itens.margemValorAdicionadoST, itens.reducaoBaseST, itens.aliquotaICMSST, itens.aliquotaSTSuportConsFinal, itens.baseICMSST, itens.valorICMSST, itens.baseICMSSTAnteriormente, itens.valorICMSSTAnteriormente, itens.valorICMSProprioSubstituto, itens.reducaoBaseICMSEfetivo, itens.aliquotaICMSEfetivo, itens.baseICMSEfetivo, itens.valorICMSEfetivo, itens.stICMSEscrituracao, itens.reducaoBaseICMSEscrituracao, itens.aliquotaICMSEscrituracao, itens.baseICMSEscrituracao, itens.valorICMSEscrituracao, itens.valorICMSDesonEscrituracao, itens.margemValorAdicSTEscrituracao, itens.reducaoBaseSTEscrituracao, itens.aliquotaICMSSTEscrituracao, itens.baseICMSSTEscrituracao, itens.valorICMSSTEscrituracao, itens.somarICMSST, itens.aliquotaICMSUFDestinatario, itens.aliquotaICMSInterestadual, itens.partilhaICMSInterestadual, itens.baseICMSUFDestinatario, itens.valorICMSUFDestinatario, itens.baseICMSUFRemetente, itens.valorICMSUFRemetente, itens.aliquotaFCP, itens.baseFCP, itens.valorFCP, itens.aliquotaFCPST, itens.baseFCPST, itens.valorFCPST, itens.aliquotaFCPSTAnteriormente, itens.baseFCPSTAnteriormente, itens.valorFCPSTAnteriormente, itens.aliquotaFCPUFDestinatario, itens.baseFCPUFDestinatario, itens.valorFCPUFDestinatario, itens.aliquotaEstimadaImpFederais, itens.aliquotaEstimadaImpEstaduais, itens.aliquotaEstimadaImpMunicipais, itens.baseEstimadaImpostos, itens.valorEstimadoImpFederais, itens.valorEstimadoImpEstaduais, itens.valorEstimadoImpMunicipais, itens.valorImpostosSomaPagamento, itens.valorImpostosDiminuiPagamento, itens.valorLiquidoItem, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, itens.observacoesDigitadas, itens.observacoes);
      INSERT INTO MODOCFISCALXPEDIDOCOMPRA (idItemDocFiscal, pedidoCompraFornecedor, sequenciaPedidoCompraFornec) SELECT itens.idItemDocFiscal, x.pedidoCompraFornecedor, x.sequenciaPedidoCompraFornec FROM MOORCAMENTOXPEDIDOCOMPRA x WHERE x.idItemOrcamento = itens.idItemOrcamento;
      INSERT INTO MODOCFISCALXCOMPOSICOESPR (id, idItemDocFiscal, composicaoPreco, selecionado, quantidade, observacoes) SELECT FUNC_ADD_BUSCA_PROXIMO_ID('MODOCFISCALXCOMPOSICOESPR', 'id', 0, p_estabelecimentoAtivo, NULL), itens.idItemDocFiscal, x.composicaoPreco, x.selecionado, x.quantidade, x.observacoes FROM MOORCAMENTOXCOMPOSICOESPR x WHERE x.idItemOrcamento = itens.idItemOrcamento;
      INSERT INTO MODOCFISCALXEMBALAGENSTIN (idEmbalagemTintaDocFiscal, idItemDocFiscal, embalagemTinta, quantidade, quantidadeSaldo, quantidadeConferida, observacoes) SELECT FUNC_ADD_BUSCA_PROXIMO_ID('MODOCFISCALXEMBALAGENSTIN', 'idEmbalagemTintaDocFiscal', 0, p_estabelecimentoAtivo, NULL), itens.idItemDocFiscal, x.embalagemTinta, x.quantidade, x.quantidadeSaldo, x.quantidadeConferida, x.observacoes FROM MOORCAMENTOXEMBALAGENSTIN x WHERE x.idItemOrcamento = itens.idItemOrcamento;
      INSERT INTO MODOCFISCALXNUMEROSSERIE (idNumeroSerieDocFiscal, idItemDocFiscal, idEnderecoEstoqueDocFiscal, gradeProduto, idNumeroSerie, devolvidoRetornado) SELECT FUNC_ADD_BUSCA_PROXIMO_ID('MODOCFISCALXNUMEROSSERIE', 'idNumeroSerieDocFiscal', 0, p_estabelecimentoAtivo, NULL), itens.idItemDocFiscal, 0, x.gradeProduto, x.idNumeroSerie, 0 FROM MOORCAMENTOXNUMEROSSERIE x WHERE x.idItemOrcamento = itens.idItemOrcamento AND x.idEnderecoEstoqueOrcamento = 0;
      INSERT INTO MODOCFISCALXCENTROSCUSTOS (idCentroCustoDocFiscal, idItemDocFiscal, centroCusto, percentualRateio) SELECT FUNC_ADD_BUSCA_PROXIMO_ID('MODOCFISCALXCENTROSCUSTOS', 'idCentroCustoDocFiscal', 0, p_estabelecimentoAtivo, NULL), itens.idItemDocFiscal, x.centroCusto, x.percentualRateio FROM MOORCAMENTOXCENTROSCUSTOS x WHERE x.idItemOrcamento = itens.idItemOrcamento;
      INSERT INTO MODOCFISCALXORCAMENTOITEM (id, idItemDocFiscal, idItemOrcamento, quantidade, efetivacao) VALUES (FUNC_ADD_BUSCA_PROXIMO_ID('MODOCFISCALXORCAMENTOITEM', 'id', 0, p_estabelecimentoAtivo, NULL), itens.idItemDocFiscal, itens.idItemOrcamento, itens.quantidade, 1);
      INSERT INTO MODOCFISCALXPROMOCOES (id, idDocumentoFiscal, cabecalhoItemPagamento, sequencia, idItemDocFiscal, idPagamentoDocFiscal, regraPromocao, tipoBeneficio, multiplicador, precoUnitarioDe, precoUnitarioPor, precoDesconto, precoMinimo, percentualDesconto, valorDesconto, pontuacao, gerarPontuacao, observacoes) SELECT FUNC_ADD_BUSCA_PROXIMO_ID('MODOCFISCALXPROMOCOES', 'id', 0, p_estabelecimentoAtivo, NULL), v_idDocumentoFiscal, x.cabecalhoItemPagamento, itens.sequencia, itens.idItemDocFiscal, 0, x.regraPromocao, x.tipoBeneficio, x.multiplicador, x.precoUnitarioDe, x.precoUnitarioPor, x.precoDesconto, x.precoMinimo, x.percentualDesconto, x.valorDesconto, x.pontuacao, x.gerarPontuacao, x.observacoes FROM MOORCAMENTOXPROMOCOES x WHERE x.idItemOrcamento = itens.idItemOrcamento;
      UPDATE MOCONSERTOS cons SET cons.situacaoConserto = 'R' WHERE cons.documentoTransferenciaFornec > 0 AND cons.situacaoConserto = 'E' AND EXISTS (SELECT 1 FROM MODOCUMENTOTRANSFXITENS itemTransf JOIN MODOCTRANSFXORCAMENTOITEM transfXDoc ON transfXDoc.idItemDocTransferencia = itemTransf.idItemDocTransferencia WHERE itemTransf.documentoTransferencia = cons.documentoTransferenciaFornec AND transfXDoc.entradaSaidaOriginal = 'E' AND transfXDoc.idItemOrcamento = itens.idItemOrcamento);
      FOR endEst IN c_endEst
      LOOP
        IF endEst.idItemOrcamento = itens.idItemOrcamento
        THEN
          INSERT INTO MODOCFISCALXENDERECOESTOQ (idEnderecoEstoqueDocFiscal, idItemDocFiscal, idEnderecoEstoque, posicaoCaixaEstoque, quantidade, quantidadeDevolvidaRetornada, quantidadeConferida, observacoes) VALUES (endEst.idEnderecoEstoqueDocFiscal, itens.idItemDocFiscal, endEst.idEnderecoEstoque, endEst.posicaoCaixaEstoque, endEst.quantidade, endEst.quantidadeDevolvidaRetornada, endEst.quantidadeConferida, endEst.observacoes);
          INSERT INTO MODOCFISCALXNUMEROSSERIE (idNumeroSerieDocFiscal, idItemDocFiscal, idEnderecoEstoqueDocFiscal, gradeProduto, idNumeroSerie, devolvidoRetornado) SELECT FUNC_ADD_BUSCA_PROXIMO_ID('MODOCFISCALXNUMEROSSERIE', 'idNumeroSerieDocFiscal', 0, p_estabelecimentoAtivo, NULL), itens.idItemDocFiscal, endEst.idEnderecoEstoqueDocFiscal, x.gradeProduto, x.idNumeroSerie, 0 FROM MOORCAMENTOXNUMEROSSERIE x WHERE x.idItemOrcamento = itens.idItemOrcamento AND x.idEnderecoEstoqueOrcamento = endEst.idEnderecoEstoqueOrcamento;
        END IF;
      END LOOP;
    FOR mot IN c_mot_item
      LOOP
        IF mot.idItemOrcamento = itens.idItemOrcamento THEN
          INSERT INTO MOMOTIVOSBLOQUEIOS (idMotivoBloqueioDocumento, origem, idCabecalho, tipoDocumento, idDocumento, estabelecimento, pessoa, cabecalhoItemPagamento, sequencia, condicaoPagamento, vendedor, gradeProduto, unidadeMedidaConversao, quantidadeConvertida, valorLiquido, motivoBloqueioDocumento, dataBloqueio, baseBloqueado, valorBloqueado, percentualBloqueado, situacaoLiberacao, observacoes) SELECT mot.idMotivoBloqueioNovo, 'D', v_idDocumentoFiscal, v_tipoDocumento, v_documentoFiscal, v_estabelecimento, v_pessoa, a.cabecalhoItemPagamento, itens.sequencia, a.condicaoPagamento, a.vendedor, a.gradeProduto, a.unidadeMedidaConversao, a.quantidadeConvertida, a.valorLiquido, a.motivoBloqueioDocumento, a.dataBloqueio, a.baseBloqueado, a.valorBloqueado, a.percentualBloqueado, a.situacaoLiberacao, a.observacoes FROM MOMOTIVOSBLOQUEIOS a WHERE a.idMotivoBloqueioDocumento = mot.idMotivoBloqueioDocumento;
          INSERT INTO MOMOTBLOQXDOCFISCALITENS (id, idMotivoBloqueioDocumento, idItemDocFiscal) VALUES (FUNC_ADD_BUSCA_PROXIMO_ID('MOMOTBLOQXDOCFISCALITENS', 'id', 0, p_estabelecimentoAtivo, NULL), mot.idMotivoBloqueioNovo, itens.idItemDocFiscal);
          INSERT INTO MOMOTBLOQXLIBERACOES (id, idMotivoBloqueioDocumento, usuario, dataLiberacao, valorLiberado, percentualLiberado, percentualAlcada, situacaoLiberacao, observacoes) SELECT FUNC_ADD_BUSCA_PROXIMO_ID('MOMOTBLOQXLIBERACOES', 'id', 0, p_estabelecimentoAtivo, NULL), mot.idMotivoBloqueioNovo, a.usuario, a.dataLiberacao, a.valorLiberado, a.percentualLiberado, a.percentualAlcada, a.situacaoLiberacao, a.observacoes FROM MOMOTBLOQXLIBERACOES a WHERE a.idMotivoBloqueioDocumento = mot.idMotivoBloqueioDocumento;
        END IF;
      END LOOP;
    END IF;
  END LOOP;
  UPDATE MOORCAMENTOXITENS SET quantidadeSaldo = 0 WHERE orcamento = p_orcamento AND cancelado = 0;
  FOR mot IN c_mot_cab
  LOOP
    INSERT INTO MOMOTIVOSBLOQUEIOS (idMotivoBloqueioDocumento, origem, idCabecalho, tipoDocumento, idDocumento, estabelecimento, pessoa, cabecalhoItemPagamento, sequencia, condicaoPagamento, vendedor, gradeProduto, unidadeMedidaConversao, quantidadeConvertida, valorLiquido, motivoBloqueioDocumento, dataBloqueio, baseBloqueado, valorBloqueado, percentualBloqueado, situacaoLiberacao, observacoes) SELECT mot.idMotivoBloqueioNovo, 'D', v_idDocumentoFiscal, v_tipoDocumento, v_documentoFiscal, v_estabelecimento, v_pessoa, a.cabecalhoItemPagamento, 0, a.condicaoPagamento, a.vendedor, a.gradeProduto, a.unidadeMedidaConversao, a.quantidadeConvertida, a.valorLiquido, a.motivoBloqueioDocumento, a.dataBloqueio, a.baseBloqueado, a.valorBloqueado, a.percentualBloqueado, a.situacaoLiberacao, a.observacoes FROM MOMOTIVOSBLOQUEIOS a WHERE a.idMotivoBloqueioDocumento = mot.idMotivoBloqueioDocumento;
    INSERT INTO MOMOTBLOQXDOCUMENTOSFISC (id, idMotivoBloqueioDocumento, idDocumentoFiscal) VALUES (FUNC_ADD_BUSCA_PROXIMO_ID('MOMOTBLOQXDOCUMENTOSFISC', 'id', 0, p_estabelecimentoAtivo, NULL), mot.idMotivoBloqueioNovo, v_idDocumentoFiscal);
    INSERT INTO MOMOTBLOQXLIBERACOES (id, idMotivoBloqueioDocumento, usuario, dataLiberacao, valorLiberado, percentualLiberado, percentualAlcada, situacaoLiberacao, observacoes) SELECT FUNC_ADD_BUSCA_PROXIMO_ID('MOMOTBLOQXLIBERACOES', 'id', 0, p_estabelecimentoAtivo, NULL), mot.idMotivoBloqueioNovo, a.usuario, a.dataLiberacao, a.valorLiberado, a.percentualLiberado, a.percentualAlcada, a.situacaoLiberacao, a.observacoes FROM MOMOTBLOQXLIBERACOES a WHERE a.idMotivoBloqueioDocumento = mot.idMotivoBloqueioDocumento;
  END LOOP;
  FOR mot IN c_mot_pag
  LOOP
    INSERT INTO MOMOTIVOSBLOQUEIOS (idMotivoBloqueioDocumento, origem, idCabecalho, tipoDocumento, idDocumento, estabelecimento, pessoa, cabecalhoItemPagamento, sequencia, condicaoPagamento, vendedor, gradeProduto, unidadeMedidaConversao, quantidadeConvertida, valorLiquido, motivoBloqueioDocumento, dataBloqueio, baseBloqueado, valorBloqueado, percentualBloqueado, situacaoLiberacao, observacoes) SELECT mot.idMotivoBloqueioNovo, 'D', v_idDocumentoFiscal, v_tipoDocumento, v_documentoFiscal, v_estabelecimento, v_pessoa, a.cabecalhoItemPagamento, a.sequencia, a.condicaoPagamento, a.vendedor, a.gradeProduto, a.unidadeMedidaConversao, a.quantidadeConvertida, a.valorLiquido, a.motivoBloqueioDocumento, a.dataBloqueio, a.baseBloqueado, a.valorBloqueado, a.percentualBloqueado, a.situacaoLiberacao, a.observacoes FROM MOMOTIVOSBLOQUEIOS a WHERE a.idMotivoBloqueioDocumento = mot.idMotivoBloqueioDocumento;
    INSERT INTO MOMOTBLOQXLIBERACOES (id, idMotivoBloqueioDocumento, usuario, dataLiberacao, valorLiberado, percentualLiberado, percentualAlcada, situacaoLiberacao, observacoes) SELECT FUNC_ADD_BUSCA_PROXIMO_ID('MOMOTBLOQXLIBERACOES', 'id', 0, p_estabelecimentoAtivo, NULL), mot.idMotivoBloqueioNovo, a.usuario, a.dataLiberacao, a.valorLiberado, a.percentualLiberado, a.percentualAlcada, a.situacaoLiberacao, a.observacoes FROM MOMOTBLOQXLIBERACOES a WHERE a.idMotivoBloqueioDocumento = mot.idMotivoBloqueioDocumento;
  END LOOP;
  ADD_ORCAMENTO_CAB_RESERVA_GRAV (p_orcamento, p_estabelecimentoAtivo);
  r_idDocumentoFiscal := v_idDocumentoFiscal;
END ADD_DOC_FISC_ROT_EFET_ORCAMENT;

/

UPDATE MOCONSERTOS cons
SET cons.localEstoque = COALESCE((
  SELECT MAX(itemTransf.localEstoqueEntrada)
  FROM MODOCUMENTOTRANSFXITENS itemTransf
  WHERE itemTransf.idItemDocTransferencia = cons.idItemDocTransferencia
  AND cons.idItemDocTransferencia > 0
  AND itemTransf.localEstoqueEntrada > 0),
  COALESCE((
    SELECT MAX(itemTransf.localEstoqueEntrada)
    FROM MODOCUMENTOTRANSFXITENS itemTransf
    WHERE itemTransf.documentoTransferencia = cons.documentoTransferenciaLojaCd
    AND cons.documentoTransferenciaLojaCd > 0
    AND itemTransf.localEstoqueEntrada > 0),cons.localEstoque))
WHERE cons.idConserto > 0
AND cons.localEstoque <> COALESCE((
  SELECT MAX(itemTransf.localEstoqueEntrada)
  FROM MODOCUMENTOTRANSFXITENS itemTransf
  WHERE itemTransf.idItemDocTransferencia = cons.idItemDocTransferencia
  AND cons.idItemDocTransferencia > 0
  AND itemTransf.localEstoqueEntrada > 0),
  COALESCE((
    SELECT MAX(itemTransf.localEstoqueEntrada)
    FROM MODOCUMENTOTRANSFXITENS itemTransf
    WHERE itemTransf.documentoTransferencia = cons.documentoTransferenciaLojaCd
    AND cons.documentoTransferenciaLojaCd > 0
    AND itemTransf.localEstoqueEntrada > 0),cons.localEstoque));

COMMIT;

INSERT INTO SIVERSOESSISTEMA (idVersaoSistema, versaoAplicativo, dataLiberacaoVersao, possuiConversaoTabelas, atualizada, dataAtualizacaoVersao, observacoes) VALUES (2023002013, '2023.2.13', TO_DATE('15/05/2023','DD/MM/YYYY'), 1, 1, sysdate, ' ');

COMMIT;

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

/*
*/