SET DEFINE OFF;


DROP TABLE TEMPCNAB;

-- TEMPCNAB
CREATE GLOBAL TEMPORARY TABLE TEMPCNAB
  (
    uniqueMachineID                VARCHAR (18) DEFAULT ' ' NOT NULL,
    idSessao                       NUMERIC (14,0) DEFAULT 0 NOT NULL,
    ordenacao                      NUMERIC (14,0) DEFAULT 0 NOT NULL,
    idFinanceiro                   NUMERIC (14,0) DEFAULT 0 NOT NULL,
    idBaixaFinanceiro              NUMERIC (14,0) DEFAULT 0 NOT NULL,
    idRegistroSpc                  NUMERIC (14,0) DEFAULT 0 NOT NULL,
    dataRegistroSPC                DATE,
    selecionado                    NUMERIC (1,0) DEFAULT 0 NOT NULL,
    estabelecimento                NUMERIC (14,0) DEFAULT 0 NOT NULL,
    contratoCompra                 NUMERIC (14,0) DEFAULT 0 NOT NULL,
    documento                      VARCHAR (60) DEFAULT ' ' NOT NULL,
    fatura                         VARCHAR (60) DEFAULT ' ' NOT NULL,
    parcelaAtual                   NUMERIC (3,0) DEFAULT 0 NOT NULL,
    dataEmissao                    DATE,
    vencimento                     DATE,
    naoCobrarJurosMultaAte         DATE,
    saldo                          NUMERIC (15,2) DEFAULT 0 NOT NULL,
    tarifaDescontoAteVencimento    NUMERIC (15,8) DEFAULT 0 NOT NULL,
    tarifaMensalDescontoAntecipado NUMERIC (15,8) DEFAULT 0 NOT NULL,
    tarifaMensalJuroDeMora         NUMERIC (15,8) DEFAULT 0 NOT NULL,
    tarifaMulta                    NUMERIC (15,8) DEFAULT 0 NOT NULL,
    valorFixoMulta                 NUMERIC (15,2) DEFAULT 0 NOT NULL,
    nossoNumero                    VARCHAR (25) DEFAULT ' ' NOT NULL,
    linhaDigitavelBoleto           VARCHAR (47) DEFAULT ' ' NOT NULL,
    pessoa                         NUMERIC (14,0) DEFAULT 0 NOT NULL,
    nomeRazaoSocial                VARCHAR (60) DEFAULT ' ' NOT NULL,
    indicadorPessoa                CHAR (1) DEFAULT ' ' NOT NULL,
    nascimentoFundacao             DATE,
    cnpjCpfIdEstrangeiro           VARCHAR (20) DEFAULT ' ' NOT NULL,
    enderecoCep                    NUMERIC (8,0) DEFAULT 0 NOT NULL,
    enderecoLogradouro             VARCHAR (60) DEFAULT ' ' NOT NULL,
    enderecoNumero                 VARCHAR (60) DEFAULT ' ' NOT NULL,
    enderecoComplemento            VARCHAR (60) DEFAULT ' ' NOT NULL,
    enderecoBairroDistrito         VARCHAR (60) DEFAULT ' ' NOT NULL,
    enderecoMunicipio              NUMERIC (7,0) DEFAULT 0 NOT NULL,
    enderecoPais                   CHAR (4) DEFAULT ' ' NOT NULL,
    enderecoObservacoes            VARCHAR (4000) DEFAULT ' ' NOT NULL,
    enderecoDescricaoMunicipio     VARCHAR (60) DEFAULT ' ' NOT NULL,
    enderecoUf                     CHAR (2) DEFAULT '  ' NOT NULL,
    enderecoDescricaoPais          VARCHAR (60) DEFAULT ' ' NOT NULL,
    foneA                          VARCHAR (14) DEFAULT ' ' NOT NULL,
    foneB                          VARCHAR (14) DEFAULT ' ' NOT NULL,
    email                          VARCHAR (60) DEFAULT ' ' NOT NULL,
    rg                             VARCHAR (20) DEFAULT ' ' NOT NULL,
    mae                            VARCHAR (60) DEFAULT ' ' NOT NULL,
    pai                            VARCHAR (60) DEFAULT ' ' NOT NULL,
    descricaoOcupacao              VARCHAR (256) DEFAULT ' ' NOT NULL,
    empregoRazaoSocial             VARCHAR (60) DEFAULT ' ' NOT NULL,
    empregoFone                    VARCHAR (14) DEFAULT ' ' NOT NULL,
    empregoCep                     NUMERIC (8,0) DEFAULT 0 NOT NULL,
    empregoLogradouro              VARCHAR (60) DEFAULT ' ' NOT NULL,
    empregoNumero                  VARCHAR (60) DEFAULT ' ' NOT NULL,
    empregoComplemento             VARCHAR (60) DEFAULT ' ' NOT NULL,
    empregoBairroDistrito          VARCHAR (60) DEFAULT ' ' NOT NULL,
    empregoMunicipio               NUMERIC (7,0) DEFAULT 0 NOT NULL,
    empregoPais                    CHAR (4) DEFAULT ' ' NOT NULL,
    empregoObservacoes             VARCHAR (4000) DEFAULT ' ' NOT NULL,
    empregoDescricaoMunicipio      VARCHAR (60) DEFAULT ' ' NOT NULL,
    empregoUf                      CHAR (2) DEFAULT '  ' NOT NULL,
    empregoDescricaoPais           VARCHAR (60) DEFAULT ' ' NOT NULL,
    conjugeNome                    VARCHAR (60) DEFAULT ' ' NOT NULL,
    conjugeCpf                     VARCHAR (20) DEFAULT ' ' NOT NULL,
    entidadeSPC                    NUMERIC (3,0) DEFAULT 0 NOT NULL,
    codigoCDL                      VARCHAR (256) DEFAULT ' ' NOT NULL,
    codigoAssociado                VARCHAR (256) DEFAULT ' ' NOT NULL,
    codigoFilial                   VARCHAR (256) DEFAULT ' ' NOT NULL,
    senha                          VARCHAR (256) DEFAULT ' ' NOT NULL,
    mensagemErro                   VARCHAR (256) DEFAULT ' ' NOT NULL
  ) ON COMMIT PRESERVE ROWS;
CREATE UNIQUE INDEX TEMPCNAB_PK1 ON TEMPCNAB (uniqueMachineID, idSessao, ordenacao);

create or replace FUNCTION FUNC_ADD_BUSCA_PRECO_PRODXEST(
    p_config_209_filtrarGrupoEcon IN NUMBER,
    p_estabelecimento             IN NUMBER,
    p_gradProd_produto            IN NUMBER,
    p_tipoPreco                   IN CHAR) -- C precoMedioInicial, P precoCustoInicial, U precoUltimaCompraInicial
  RETURN NUMBER
IS
  v_preco NUMBER;
BEGIN
  SELECT COALESCE(MAX(
    CASE p_tipoPreco
      WHEN 'C'
      THEN preco.precoMedioInicial
      WHEN 'P'
      THEN preco.precoCustoInicial
      WHEN 'U'
      THEN preco.precoUltimaCompraInicial
      ELSE 0
    END),0)
  INTO v_preco      
  FROM CAPRODUTOXESTABELECIMENTO preco
  WHERE preco.produto = p_gradProd_produto
  AND preco.estabelecimento = p_estabelecimento
  AND preco.ativo = 1;
  IF v_preco = 0
    AND p_estabelecimento > 0
  THEN
    SELECT COALESCE(MAX(
      CASE p_tipoPreco
        WHEN 'C'
        THEN preco.precoMedioInicial
        WHEN 'P'
        THEN preco.precoCustoInicial
        WHEN 'U'
        THEN preco.precoUltimaCompraInicial
        ELSE 0
      END),0)
    INTO v_preco      
    FROM CAPRODUTOXESTABELECIMENTO preco
    JOIN PAESTABELECIMENTOS est
    ON est.estabelecimento = preco.estabelecimento
    JOIN PAESTABELECIMENTOS est2
    ON est2.pessoaEstabelecimento = est.pessoaEstabelecimento
    WHERE preco.produto = p_gradProd_produto
    AND preco.ativo = 1
    AND preco.estabelecimento <> p_estabelecimento
    AND est.pessoaEstabelecimento > 0
    AND est.ativo = 1
    AND est2.estabelecimento = p_estabelecimento;
  END IF;
  IF v_preco = 0
    AND p_estabelecimento > 0
    AND p_config_209_filtrarGrupoEcon = 1
  THEN
    SELECT COALESCE(MAX(
      CASE p_tipoPreco
        WHEN 'C'
        THEN preco.precoMedioInicial
        WHEN 'P'
        THEN preco.precoCustoInicial
        WHEN 'U'
        THEN preco.precoUltimaCompraInicial
        ELSE 0
      END),0)
    INTO v_preco      
    FROM CAPRODUTOXESTABELECIMENTO preco
    JOIN PAESTABELECIMENTOS est
    ON est.estabelecimento = preco.estabelecimento
    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 preco.produto = p_gradProd_produto
    AND preco.ativo = 1
    AND preco.estabelecimento <> p_estabelecimento
    AND est.pessoaEstabelecimento > 0
    AND est.ativo = 1
    AND pessEst.grupoEconomico > 0
    AND est2.pessoaEstabelecimento <> est.pessoaEstabelecimento
    AND est2.estabelecimento = p_estabelecimento;
  END IF;
  IF v_preco = 0
    AND p_estabelecimento > 0
  THEN
    SELECT COALESCE(MAX(
      CASE p_tipoPreco
        WHEN 'C'
        THEN preco.precoMedioInicial
        WHEN 'P'
        THEN preco.precoCustoInicial
        WHEN 'U'
        THEN preco.precoUltimaCompraInicial
        ELSE 0
      END),0)
    INTO v_preco      
    FROM CAPRODUTOXESTABELECIMENTO preco
    WHERE preco.produto = p_gradProd_produto
    AND preco.estabelecimento = 0
    AND preco.ativo = 1;
  END IF;
  RETURN v_preco;  
END;

/

create or replace FUNCTION FUNC_ADD_BUSCA_PRECO_INVENT(
    p_config_209_filtrarGrupoEcon  IN NUMBER,
    p_config_362_calcCustoPorGrade IN NUMBER,
    p_estabelecimento              IN NUMBER,
    p_dataInicial                  IN DATE,
    p_dataFinal                    IN DATE,
    p_item_personalizacao          IN NUMBER,
    p_gradProd_produto             IN NUMBER,
    p_gradProd_cor                 IN NUMBER,
    p_gradProd_tamanho             IN VARCHAR,
    p_precoSeNaoEncontrar          IN NUMBER,
    p_tipoPreco                    IN CHAR) -- F precoCustoUltimaFormacao, P precoCustoUltimaCompra, U precoUnitarioUltimaCompra
  RETURN NUMBER
IS
  v_preco NUMBER;
BEGIN
  WITH ESTABELECIMENTOS AS (
    SELECT DISTINCT a.estabelecimento
    FROM (
      SELECT est.estabelecimento
      FROM PAESTABELECIMENTOS est
      WHERE est.estabelecimento = p_estabelecimento
      UNION ALL
      SELECT est2.estabelecimento
      FROM PAESTABELECIMENTOS est
      JOIN PAESTABELECIMENTOS est2
      ON est2.pessoaEstabelecimento = est.pessoaEstabelecimento
      WHERE est.estabelecimento = p_estabelecimento
      AND est.pessoaEstabelecimento > 0
      AND est2.ativo = 1
      UNION ALL
      SELECT est2.estabelecimento
      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 = p_estabelecimento
      AND est.pessoaEstabelecimento > 0
      AND pessEst.grupoEconomico > 0
      AND est2.ativo = 1) a)
  SELECT
    COALESCE(MAX(a.preco),0)
  INTO
    v_preco
  FROM (
    SELECT 
      ROW_NUMBER() OVER (
        ORDER BY
          invEst.data Desc,
          invEst.inventarioEstoque Desc) ordenacao,
      CASE p_tipoPreco
        WHEN 'F'
        THEN itemEst.precoCustoUltimaFormacao
        WHEN 'P'
        THEN itemEst.precoCustoUltimaCompra
        WHEN 'U'
        THEN itemEst.precoUnitarioUltimaCompra
        ELSE 0
      END preco
    FROM MOINVENTARIOESTOQUEXITENS itemEst
    JOIN MOINVENTARIOSESTOQUE invEst
    ON invEst.inventarioEstoque = itemEst.inventarioEstoque
    JOIN ESTABELECIMENTOS est
    ON est.estabelecimento = invEst.estabelecimento
    JOIN CAGRADESPRODUTO gradProd
    ON gradProd.gradeProduto = itemEst.gradeProduto
    JOIN CAPRODUTOS prod
    ON prod.produto = gradProd.produto
    WHERE invEst.data >= COALESCE(TRUNC(p_dataInicial),TO_DATE ('01/01/1900','DD/MM/YYYY'))
    AND invEst.data < TRUNC(p_dataFinal)
    AND (p_config_362_calcCustoPorGrade = 0
      OR p_item_personalizacao = 0
      OR itemEst.personalizacao = p_item_personalizacao)
    AND gradProd.produto = p_gradProd_produto
    AND (p_config_362_calcCustoPorGrade = 0
      OR p_gradProd_cor = 0
      OR gradProd.cor = p_gradProd_cor)
    AND (p_config_362_calcCustoPorGrade = 0
      OR p_gradProd_tamanho = ''
      OR p_gradProd_tamanho = ' '
      OR gradProd.tamanho = p_gradProd_tamanho)) a
  WHERE a.ordenacao = 1;
  IF v_preco = 0
    OR v_preco IS NULL
  THEN
    v_preco := p_precoSeNaoEncontrar;
  END IF;
  RETURN v_preco;
END;

/

create or replace FUNCTION FUNC_ADD_BUSCA_PRECO_ULT_COMPR(
    p_config_209_filtrarGrupoEcon  IN NUMBER,
    p_config_362_calcCustoPorGrade IN NUMBER,
    p_estabelecimento              IN NUMBER,
    p_dataInicial                  IN DATE,
    p_dataFinal                    IN DATE,
    p_item_personalizacao          IN NUMBER,
    p_gradProd_produto             IN NUMBER,
    p_gradProd_cor                 IN NUMBER,
    p_gradProd_tamanho             IN VARCHAR,
    p_retornarPrecoBruto           IN NUMBER,
    p_gerandoInventario            IN NUMBER)
  RETURN NUMBER
IS 
  v_data  DATE;
  v_preco NUMBER;
BEGIN
  WITH ESTABELECIMENTOS AS (
    SELECT DISTINCT a.estabelecimento
    FROM (
      SELECT est.estabelecimento
      FROM PAESTABELECIMENTOS est
      WHERE est.estabelecimento = p_estabelecimento
      UNION ALL
      SELECT est2.estabelecimento
      FROM PAESTABELECIMENTOS est
      JOIN PAESTABELECIMENTOS est2
      ON est2.pessoaEstabelecimento = est.pessoaEstabelecimento
      WHERE est.estabelecimento = p_estabelecimento
      AND est.pessoaEstabelecimento > 0
      AND est2.ativo = 1
      UNION ALL
      SELECT est2.estabelecimento
      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 = p_estabelecimento
      AND est.pessoaEstabelecimento > 0
      AND pessEst.grupoEconomico > 0
      AND est2.ativo = 1) a)
  SELECT
    MAX(a.data),
    COALESCE(MAX(a.preco),0)
  INTO
    v_data,
    v_preco
  FROM (
    SELECT 
      ROW_NUMBER() OVER (
        ORDER BY
          TRUNC(a.dataEntradaSaida) Desc,
          a.preco Desc) ordenacao,
      TRUNC(a.dataEntradaSaida) data,
      a.preco
    FROM (
      SELECT
        doc.dataEntradaSaida,
        CASE
          WHEN COUNT (1) = 1
            OR SUM(item.quantidade) = 0
          THEN MAX(item.precoUnitario)
          ELSE ROUND((SUM(item.valorProdutoServico) / SUM(item.quantidade)),7)
        END
        - CASE
            WHEN p_retornarPrecoBruto = 1
              OR SUM(item.quantidade) = 0
            THEN 0
            ELSE ROUND(SUM(item.valorDescontoTotal) / SUM(item.quantidade),7)
          END preco       
      FROM MODOCFISCALXITENS item
      JOIN CAGRADESPRODUTO grad
      ON grad.gradeProduto = item.gradeProduto
      JOIN MODOCUMENTOSFISCAIS doc
      ON doc.idDocumentoFiscal = item.idDocumentoFiscal
      JOIN ESTABELECIMENTOS est
      ON est.estabelecimento = doc.estabelecimento
      WHERE item.cancelado = 0
      AND (item.quantidade = 0
        AND item.precoUnitario > 0
        OR item.quantidade > 0
        AND item.valorProdutoServico > CASE WHEN p_retornarPrecoBruto = 1 THEN 0 ELSE item.valorDescontoTotal END)
      AND (p_config_362_calcCustoPorGrade = 0
        OR p_item_personalizacao = 0
        OR item.personalizacao = p_item_personalizacao)
      AND doc.entradaSaida = 'E'
      AND doc.devolucaoAnulacaoRetorno = 0
      AND doc.situacaoDocumentoFiscal IN (21,22,23)
      AND doc.atualizaUltimaCompra = 1
      AND doc.dataEntradaSaida >= COALESCE(TRUNC(p_dataInicial),TO_DATE ('01/01/1900','DD/MM/YYYY'))
      AND doc.dataEntradaSaida < TRUNC(p_dataFinal) + 1
      AND grad.produto = p_gradProd_produto
      AND (p_config_362_calcCustoPorGrade = 0
        OR p_gradProd_cor = 0
        OR grad.cor = p_gradProd_cor)
      AND (p_config_362_calcCustoPorGrade = 0
        OR p_gradProd_tamanho = ''
        OR p_gradProd_tamanho = ' '
        OR grad.tamanho = p_gradProd_tamanho)
      GROUP BY
        doc.dataEntradaSaida,
        item.idDocumentoFiscal
      UNION ALL
      SELECT
        doc.dataEntradaSaida,
        CASE
          WHEN COUNT (1) = 1
            OR SUM(item.quantidade) = 0
          THEN MAX(item.precoUnitario)
          ELSE ROUND((SUM(item.valorProdutoServico) / SUM(item.quantidade)),7)
        END
        - CASE
            WHEN p_retornarPrecoBruto = 1
              OR SUM(item.quantidade) = 0
            THEN 0
            ELSE ROUND(SUM(item.valorDescontoTotal) / SUM(item.quantidade),7)
          END preco       
      FROM MOPREDOCUMXITENS item
      JOIN CAGRADESPRODUTO grad
      ON grad.gradeProduto = item.gradeProduto
      JOIN MOPREDOCUMENTOS doc
      ON doc.preDocumento = item.preDocumento
      JOIN ESTABELECIMENTOS est
      ON est.estabelecimento = doc.estabelecimento
      WHERE item.cancelado = 0
      AND (item.quantidade = 0
        AND item.precoUnitario > 0
        OR item.quantidade > 0
        AND item.valorProdutoServico > CASE WHEN p_retornarPrecoBruto = 1 THEN 0 ELSE item.valorDescontoTotal END)
      AND (p_config_362_calcCustoPorGrade = 0
        OR p_item_personalizacao = 0
        OR item.personalizacao = p_item_personalizacao)
      AND doc.entradaSaida = 'E'
      AND doc.devolucaoAnulacaoRetorno = 0
      AND doc.statusPreDocumento IN ('A','F')
      AND doc.atualizaUltimaCompra = 1
      AND doc.dataEntradaSaida >= COALESCE(TRUNC(p_dataInicial),TO_DATE ('01/01/1900','DD/MM/YYYY'))
      AND doc.dataEntradaSaida < TRUNC(p_dataFinal) + 1
      AND grad.produto = p_gradProd_produto
      AND (p_config_362_calcCustoPorGrade = 0
        OR p_gradProd_cor = 0
        OR grad.cor = p_gradProd_cor)
      AND (p_config_362_calcCustoPorGrade = 0
        OR p_gradProd_tamanho = ''
        OR p_gradProd_tamanho = ' '
        OR grad.tamanho = p_gradProd_tamanho)
      GROUP BY
        doc.dataEntradaSaida,
        item.preDocumento) a) a
  WHERE a.ordenacao = 1;
  v_preco := FUNC_ADD_BUSCA_PRECO_INVENT(
    p_config_209_filtrarGrupoEcon,
    p_config_362_calcCustoPorGrade,
    p_estabelecimento,
    COALESCE(v_data,COALESCE(TRUNC(p_dataInicial),TO_DATE ('01/01/1900','DD/MM/YYYY'))),
    TRUNC(p_dataFinal) + CASE WHEN p_gerandoInventario = 1 THEN 0 ELSE 1 END,
    p_item_personalizacao,
    p_gradProd_produto,
    p_gradProd_cor,
    p_gradProd_tamanho,
    v_preco,
    'U');
  IF v_preco = 0
    AND (p_dataInicial IS NULL
      OR p_dataInicial = TO_DATE ('01/01/1900','DD/MM/YYYY'))
  THEN
    v_preco := FUNC_ADD_BUSCA_PRECO_PRODXEST(
      p_config_209_filtrarGrupoEcon,
      p_estabelecimento,
      p_gradProd_produto,
      'U');
  END IF;
  RETURN v_preco;
END;

/

create or replace FUNCTION FUNC_ADD_BUSCA_PRECO_ULT_CUSTO(
    p_config_209_filtrarGrupoEcon  IN NUMBER,
    p_config_362_calcCustoPorGrade IN NUMBER,
    p_estabelecimento              IN NUMBER,
    p_dataInicial                  IN DATE,
    p_dataFinal                    IN DATE,
    p_item_personalizacao          IN NUMBER,
    p_gradProd_produto             IN NUMBER,
    p_gradProd_cor                 IN NUMBER,
    p_gradProd_tamanho             IN VARCHAR,
    p_indicadorPropriedadePosseIt  IN CHAR,
    p_pessoaParticipante           IN NUMBER,
    p_gerandoInventario            IN NUMBER)
  RETURN NUMBER
IS 
  v_data  DATE;
  v_preco NUMBER;
BEGIN
  WITH ESTABELECIMENTOS AS (
    SELECT DISTINCT a.estabelecimento
    FROM (
      SELECT est.estabelecimento
      FROM PAESTABELECIMENTOS est
      WHERE est.estabelecimento = p_estabelecimento
      UNION ALL
      SELECT est2.estabelecimento
      FROM PAESTABELECIMENTOS est
      JOIN PAESTABELECIMENTOS est2
      ON est2.pessoaEstabelecimento = est.pessoaEstabelecimento
      WHERE est.estabelecimento = p_estabelecimento
      AND est.pessoaEstabelecimento > 0
      AND est2.ativo = 1
      UNION ALL
      SELECT est2.estabelecimento
      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 = p_estabelecimento
      AND est.pessoaEstabelecimento > 0
      AND pessEst.grupoEconomico > 0
      AND est2.ativo = 1) a)
  SELECT
    MAX(a.data),
    COALESCE(MAX(a.preco),0)
  INTO
    v_data,
    v_preco
  FROM (
    SELECT 
      ROW_NUMBER() OVER (
        ORDER BY
          TRUNC(a.data) Desc,
          a.preco Desc) ordenacao,
      TRUNC(a.data) data,
      a.preco
    FROM (
      SELECT 
        itemEst.data,
        CASE
          WHEN COUNT (1) = 1
            OR SUM(itemEst.quantidade) = 0
          THEN MAX(itemEst.precoCustoOperacao)
          ELSE ROUND((SUM (itemEst.totalCustoOperacao) / SUM(itemEst.quantidade)),7)
        END preco
      FROM MOESTOQUES itemEst
      JOIN ESTABELECIMENTOS est
      ON est.estabelecimento = itemEst.estabelecimento
      JOIN CAGRADESPRODUTO grad
      ON grad.gradeProduto = itemEst.gradeProduto
      LEFT JOIN MOPREDOCUMXESTOQUE preXEst
      ON preXEst.idEstoque = itemEst.idEstoque
      LEFT JOIN MOPREDOCUMXITENS itemPre
      ON itemPre.idItemPreDocumento = preXEst.idItemPreDocumento
      LEFT JOIN MODOCFISCALXESTOQUE docXEst
      ON docXEst.idEstoque = itemEst.idEstoque
      LEFT JOIN MODOCFISCALXITENS itemDoc
      ON itemDoc.idItemDocFiscal = docXEst.idItemDocFiscal
      WHERE itemEst.entradaSaida = 'E'
      AND itemEst.atualizaUltimaCompra = 1
      AND itemEst.indicadorPropriedadePosseItem = p_indicadorPropriedadePosseIt
      AND itemEst.pessoaParticipante = p_pessoaParticipante
      AND (p_config_362_calcCustoPorGrade = 0
        OR p_item_personalizacao = 0
        OR itemEst.personalizacao = p_item_personalizacao)
      AND itemEst.data >= COALESCE(TRUNC(p_dataInicial),TO_DATE ('01/01/1900','DD/MM/YYYY'))
      AND itemEst.data < TRUNC(p_dataFinal) + 1
      AND grad.produto = p_gradProd_produto
      AND (p_config_362_calcCustoPorGrade = 0
        OR p_gradProd_cor = 0
        OR grad.cor = p_gradProd_cor)
      AND (p_config_362_calcCustoPorGrade = 0
        OR p_gradProd_tamanho = ''
        OR p_gradProd_tamanho = ' '
        OR grad.tamanho = p_gradProd_tamanho)
      GROUP BY
        itemEst.data,
        CASE
          WHEN NOT (docXEst.id IS NULL)
          THEN 'D' || LPAD(itemDoc.idDocumentoFiscal,14,'0')
          WHEN NOT (preXEst.id IS NULL)
          THEN 'P' || LPAD(itemPre.preDocumento,14,'0')
          ELSE 'M' || LPAD(itemEst.idEstoque,14,'0')
        END) a) a
  WHERE a.ordenacao = 1;
  v_preco := FUNC_ADD_BUSCA_PRECO_INVENT(
    p_config_209_filtrarGrupoEcon,
    p_config_362_calcCustoPorGrade,
    p_estabelecimento,
    COALESCE(v_data,COALESCE(TRUNC(p_dataInicial),TO_DATE ('01/01/1900','DD/MM/YYYY'))),
    TRUNC(p_dataFinal) + CASE WHEN p_gerandoInventario = 1 THEN 0 ELSE 1 END,
    p_item_personalizacao,
    p_gradProd_produto,
    p_gradProd_cor,
    p_gradProd_tamanho,
    v_preco,
    'P');
  IF v_preco = 0
    AND (p_dataInicial IS NULL
      OR p_dataInicial = TO_DATE ('01/01/1900','DD/MM/YYYY'))
  THEN
    v_preco := FUNC_ADD_BUSCA_PRECO_PRODXEST(
      p_config_209_filtrarGrupoEcon,
      p_estabelecimento,
      p_gradProd_produto,
      'P');
  END IF;
  RETURN v_preco;
END;

/

create or replace FUNCTION FUNC_ADD_BUSCA_PRECO_FORMACAO(
    p_config_209_filtrarGrupoEcon  IN NUMBER,
    p_config_362_calcCustoPorGrade IN NUMBER,
    p_estabelecimento              IN NUMBER,
    p_dataInicial                  IN DATE,
    p_dataFinal                    IN DATE,
    p_item_personalizacao          IN NUMBER,
    p_gradProd_produto             IN NUMBER,
    p_gradProd_cor                 IN NUMBER,
    p_gradProd_tamanho             IN VARCHAR,
    p_gerandoInventario            IN NUMBER)
  RETURN NUMBER
IS
  v_data  DATE;
  v_preco NUMBER;
BEGIN
  SELECT
    MAX(a.data),
    COALESCE(MAX(a.novoPrecoCusto),0)
  INTO
    v_data,
    v_preco
  FROM (
    SELECT 
      ROW_NUMBER() OVER (
        ORDER BY
          data Desc,
          novoPrecoCusto Desc) ordenacao,
      data,
      novoPrecoCusto
    FROM CAPRODUTOXCUSTOS
    WHERE produto = p_gradProd_produto
    AND ativo = 1
    AND (p_config_362_calcCustoPorGrade = 0
      OR p_gradProd_cor = 0
      OR cor = p_gradProd_cor)
    AND (p_config_362_calcCustoPorGrade = 0
      OR p_gradProd_tamanho = ''
      OR p_gradProd_tamanho = ' '
      OR tamanho = p_gradProd_tamanho)
    AND (p_config_362_calcCustoPorGrade = 0
      OR p_item_personalizacao = 0
      OR personalizacao = p_item_personalizacao)
    AND data >= COALESCE(TRUNC(p_dataInicial),TO_DATE ('01/01/1900','DD/MM/YYYY'))
    AND data < TRUNC(p_dataFinal) + 1) a
  WHERE a.ordenacao = 1;
  v_preco := FUNC_ADD_BUSCA_PRECO_INVENT(
    p_config_209_filtrarGrupoEcon,
    p_config_362_calcCustoPorGrade,
    p_estabelecimento,
    COALESCE(v_data,COALESCE(TRUNC(p_dataInicial),TO_DATE ('01/01/1900','DD/MM/YYYY'))),
    TRUNC(p_dataFinal) + CASE WHEN p_gerandoInventario = 1 THEN 0 ELSE 1 END,
    p_item_personalizacao,
    p_gradProd_produto,
    p_gradProd_cor,
    p_gradProd_tamanho,
    v_preco,
    'F');
  IF v_preco = 0
    AND (p_dataInicial IS NULL
      OR p_dataInicial = TO_DATE ('01/01/1900','DD/MM/YYYY'))
  THEN
    v_preco := FUNC_ADD_BUSCA_PRECO_PRODXEST(
      p_config_209_filtrarGrupoEcon,
      p_estabelecimento,
      p_gradProd_produto,
      'P');
  END IF;
  IF v_preco = 0 THEN
    v_preco := FUNC_ADD_BUSCA_PRECO_ULT_COMPR(
      p_config_209_filtrarGrupoEcon,
      p_config_362_calcCustoPorGrade,
      p_estabelecimento,
      p_dataInicial,
      p_dataFinal,
      p_item_personalizacao,
      p_gradProd_produto,
      p_gradProd_cor,
      p_gradProd_tamanho,
      0, --p_retornarPrecoBruto
      p_gerandoInventario);
  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_estabelecimento              IN NUMBER,
    p_dataPosicaoEstoque           IN DATE,
    p_item_personalizacao          IN NUMBER,
    p_gradProd_produto             IN NUMBER,
    p_gradProd_cor                 IN NUMBER,
    p_gradProd_tamanho             IN VARCHAR,
    p_indicadorPropriedadePosseIt  IN CHAR,
    p_pessoaParticipante           IN NUMBER,
    p_dataInventarioEstoque        IN DATE)
  RETURN NUMBER
IS
  v_dataAtual         DATE;
  v_quantidadeEstoque NUMBER;
  v_precoCustoMedio   NUMBER;
  v_totalCustoMedio   NUMBER;
CURSOR c_estoque IS
  WITH ESTABELECIMENTOS AS (
    SELECT DISTINCT a.estabelecimento
    FROM (
      SELECT est.estabelecimento
      FROM PAESTABELECIMENTOS est
      WHERE est.estabelecimento = p_estabelecimento
      UNION ALL
      SELECT est2.estabelecimento
      FROM PAESTABELECIMENTOS est
      JOIN PAESTABELECIMENTOS est2
      ON est2.pessoaEstabelecimento = est.pessoaEstabelecimento
      WHERE est.estabelecimento = p_estabelecimento
      AND est.pessoaEstabelecimento > 0
      AND est2.ativo = 1
      UNION ALL
      SELECT est2.estabelecimento
      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 = p_estabelecimento
      AND est.pessoaEstabelecimento > 0
      AND pessEst.grupoEconomico > 0
      AND est2.ativo = 1) a)
  SELECT
    itemEst.data,
    itemEst.entradaSaida,
    itemEst.atualizaCustoMedio,
    itemEst.operacaoInternaEstoque,
    itemEst.quantidade,
    itemEst.totalCustoOperacao
  FROM MOESTOQUES itemEst
  JOIN ESTABELECIMENTOS est
  ON est.estabelecimento = itemEst.estabelecimento
  JOIN CAGRADESPRODUTO gradProd
  ON gradProd.gradeProduto = itemEst.gradeProduto
  WHERE itemEst.indicadorPropriedadePosseItem = p_indicadorPropriedadePosseIt
  AND itemEst.pessoaParticipante = p_pessoaParticipante
  AND itemEst.data >= COALESCE(TRUNC(p_dataInventarioEstoque) + 1,TO_DATE('01/01/1900','DD/MM/YYYY'))
  AND itemEst.data < TRUNC(p_dataPosicaoEstoque) + 1
  AND (p_config_362_calcCustoPorGrade = 0
    OR p_item_personalizacao = 0
    OR itemEst.personalizacao = p_item_personalizacao)
  AND gradProd.produto = p_gradProd_produto
  AND (p_config_362_calcCustoPorGrade = 0
    OR p_gradProd_cor = 0
    OR gradProd.cor = p_gradProd_cor)
  AND (p_config_362_calcCustoPorGrade = 0
    OR p_gradProd_tamanho = ''
    OR p_gradProd_tamanho = ' '
    OR gradProd.tamanho = p_gradProd_tamanho)
  ORDER BY
    TRUNC(itemEst.data) Asc,
    itemEst.operacaoInternaEstoque Desc,
    itemEst.atualizaCustoMedio Desc,
    itemEst.data Asc,
    itemEst.idEstoque Asc;
BEGIN
  v_dataAtual         := COALESCE(TRUNC(p_dataInventarioEstoque) + 1,TO_DATE('01/01/1900','DD/MM/YYYY'));
  v_quantidadeEstoque := 0;
  v_precoCustoMedio   := 0;
  v_totalCustoMedio   := 0;
  -- Saldo Inicial Inventário
  IF NOT(p_dataInventarioEstoque IS NULL) THEN
    WITH ESTABELECIMENTOS AS (
      SELECT DISTINCT a.estabelecimento
      FROM (
        SELECT est.estabelecimento
        FROM PAESTABELECIMENTOS est
        WHERE est.estabelecimento = p_estabelecimento
        UNION ALL
        SELECT est2.estabelecimento
        FROM PAESTABELECIMENTOS est
        JOIN PAESTABELECIMENTOS est2
        ON est2.pessoaEstabelecimento = est.pessoaEstabelecimento
        WHERE est.estabelecimento = p_estabelecimento
        AND est.pessoaEstabelecimento > 0
        AND est2.ativo = 1
        UNION ALL
        SELECT est2.estabelecimento
        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 = p_estabelecimento
        AND est.pessoaEstabelecimento > 0
        AND pessEst.grupoEconomico > 0
        AND est2.ativo = 1) a)
    SELECT
      COALESCE(SUM(itemEst.quantidade),0),
      COALESCE((
        CASE
          WHEN SUM(itemEst.quantidade) = 0
            OR SUM(ROUND(itemEst.quantidade * itemEst.precoUnitarioCMV,2)) = 0
            OR SUM(itemEst.quantidade) = MAX(itemEst.quantidade)
            AND SUM(ROUND(itemEst.quantidade * itemEst.precoUnitarioCMV,2))
             =  MAX(ROUND(itemEst.quantidade *itemEst.precoUnitarioCMV,2))
          THEN MAX(itemEst.precoUnitarioCMV)
          ELSE ROUND(SUM(ROUND(itemEst.quantidade * itemEst.precoUnitarioCMV,2))
            / SUM(itemEst.quantidade),7)
        END),0),
      COALESCE(SUM(ROUND(itemEst.quantidade * itemEst.precoUnitarioCMV,2)),0)
    INTO
      v_quantidadeEstoque,
      v_precoCustoMedio,
      v_totalCustoMedio
    FROM MOINVENTARIOESTOQUEXITENS itemEst
    JOIN MOINVENTARIOSESTOQUE invEst
    ON invEst.inventarioEstoque = itemEst.inventarioEstoque
    JOIN ESTABELECIMENTOS est
    ON est.estabelecimento = invEst.estabelecimento
    JOIN CAGRADESPRODUTO gradProd
    ON gradProd.gradeProduto = itemEst.gradeProduto
    WHERE itemEst.indicadorPropriedadePosseItem = p_indicadorPropriedadePosseIt
    AND itemEst.pessoaParticipante = p_pessoaParticipante
    AND invEst.data >= TRUNC(p_dataInventarioEstoque)
    AND invEst.data < TRUNC(p_dataInventarioEstoque) + 1
    AND (p_config_362_calcCustoPorGrade = 0
      OR p_item_personalizacao = 0
      OR itemEst.personalizacao = p_item_personalizacao)
    AND gradProd.produto = p_gradProd_produto
    AND (p_config_362_calcCustoPorGrade = 0
      OR p_gradProd_cor = 0
      OR gradProd.cor = p_gradProd_cor)
    AND (p_config_362_calcCustoPorGrade = 0
      OR p_gradProd_tamanho = ''
      OR p_gradProd_tamanho = ' '
      OR gradProd.tamanho = p_gradProd_tamanho);
  END IF;
  FOR dados IN c_estoque
  LOOP
    IF dados.operacaoInternaEstoque = 1 AND dados.data > v_dataAtual
    THEN
      v_quantidadeEstoque := 0;
      v_precoCustoMedio := 0;
      v_totalCustoMedio := 0;
    END IF;
    v_dataAtual := dados.data;
    -- Se atualiza custo médio
    IF dados.atualizaCustoMedio = 1 THEN
      IF dados.entradaSaida = 'E' THEN
        v_quantidadeEstoque := v_quantidadeEstoque + dados.quantidade;
        IF v_quantidadeEstoque <= 0 THEN
          v_totalCustoMedio := 0;
        ELSE
          IF v_quantidadeEstoque > dados.quantidade THEN
            IF v_totalCustoMedio + dados.totalCustoOperacao > 9999999999999.99 THEN
               v_totalCustoMedio := 9999999999999.99;
            ELSE
               v_totalCustoMedio := v_totalCustoMedio + dados.totalCustoOperacao;
            END IF;
          ELSE
            IF ROUND ((dados.totalCustoOperacao * v_quantidadeEstoque / dados.quantidade),2) > 9999999999999.99 THEN
               v_totalCustoMedio := 9999999999999.99;
            ELSE
               v_totalCustoMedio := ROUND ((dados.totalCustoOperacao * v_quantidadeEstoque / dados.quantidade),2);
            END IF;
          END IF;
        END IF;
     ELSE
        v_quantidadeEstoque := v_quantidadeEstoque - dados.quantidade;
        v_totalCustoMedio := v_totalCustoMedio - dados.totalCustoOperacao;
        IF v_totalCustoMedio < 0 OR v_quantidadeEstoque <= 0 THEN
          v_totalCustoMedio := 0;
        END IF;
      END IF;
      IF v_totalCustoMedio > 0 AND v_quantidadeEstoque >= 0 AND ROUND(v_totalCustoMedio / CASE WHEN v_quantidadeEstoque = 0 THEN 1 ELSE v_quantidadeEstoque END, 7) > 99999999.9999999 THEN
        v_precoCustoMedio := 99999999.9999999;
      ELSE
        IF v_totalCustoMedio > 0 AND v_quantidadeEstoque >= 0 THEN
          v_precoCustoMedio := ROUND(v_totalCustoMedio / CASE WHEN v_quantidadeEstoque = 0 THEN 1 ELSE v_quantidadeEstoque END, 7);
        END IF;
      END IF;
    -- Se não atualiza custo médio
    ELSE
      IF dados.entradaSaida = 'E' THEN
        v_quantidadeEstoque := v_quantidadeEstoque + dados.quantidade;
        IF v_quantidadeEstoque <= 0 THEN
          v_totalCustoMedio := 0;
        ELSE
          IF v_quantidadeEstoque > dados.quantidade THEN
            IF v_totalCustoMedio + ROUND((dados.quantidade * v_precoCustoMedio),2) > 9999999999999.99 THEN
               v_totalCustoMedio := 9999999999999.99;
            ELSE
               v_totalCustoMedio := v_totalCustoMedio + dados.totalCustoOperacao;
            END IF;
          ELSE
            IF ROUND((v_quantidadeEstoque * v_precoCustoMedio),2) > 9999999999999.99 THEN
               v_totalCustoMedio := 9999999999999.99;
            ELSE
               v_totalCustoMedio := ROUND((v_quantidadeEstoque * v_precoCustoMedio),2);
            END IF;
          END IF;
        END IF;
      ELSE
        v_quantidadeEstoque := v_quantidadeEstoque - dados.quantidade;
        v_totalCustoMedio := v_totalCustoMedio - dados.quantidade * v_precoCustoMedio;
        IF v_totalCustoMedio < 0 OR v_quantidadeEstoque <= 0 THEN
          v_totalCustoMedio := 0;
        END IF;
      END IF;
    END IF;
  END LOOP;
  IF v_precoCustoMedio = 0 THEN
    v_precoCustoMedio := FUNC_ADD_BUSCA_PRECO_PRODXEST(
      p_config_209_filtrarGrupoEcon,
      p_estabelecimento,
      p_gradProd_produto,
      'C');
  END IF;
  RETURN v_precoCustoMedio;  
END;

/

create or replace FUNCTION FUNC_ADD_BUSCA_PRECO_MEDIO_FIS(
    p_config_209_filtrarGrupoEcon  IN NUMBER,
    p_estabelecimento              IN NUMBER,
    p_dataPosicaoEstoque           IN DATE,
    p_gradProd_produto             IN NUMBER,
    p_gradProd_cor                 IN NUMBER,
    p_gradProd_tamanho             IN VARCHAR,
    p_indicadorPropriedadePosseIt  IN CHAR,
    p_pessoaParticipante           IN NUMBER,
    p_dataInventarioEstoque        IN DATE)
  RETURN NUMBER
IS
  v_dataAtual         DATE;
  v_quantidadeEstoque NUMBER;
  v_precoCustoMedio   NUMBER;
  v_totalCustoMedio   NUMBER;
CURSOR c_estoque IS
  WITH ESTABELECIMENTOS AS (
    SELECT DISTINCT a.estabelecimento
    FROM (
      SELECT est.estabelecimento
      FROM PAESTABELECIMENTOS est
      WHERE est.estabelecimento = p_estabelecimento
      UNION ALL
      SELECT est2.estabelecimento
      FROM PAESTABELECIMENTOS est
      JOIN PAESTABELECIMENTOS est2
      ON est2.pessoaEstabelecimento = est.pessoaEstabelecimento
      WHERE est.estabelecimento = p_estabelecimento
      AND est.pessoaEstabelecimento > 0
      AND est2.ativo = 1
      UNION ALL
      SELECT est2.estabelecimento
      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 = p_estabelecimento
      AND est.pessoaEstabelecimento > 0
      AND pessEst.grupoEconomico > 0
      AND est2.ativo = 1) a)
  SELECT
    a.data,
    a.entradaSaida,
    a.atualizaCustoMedio,
    a.operacaoInternaEstoque,
    a.quantidade,
    a.totalCustoOperacao
  FROM (
    SELECT
      itemEst.data,
      'E' tipo,
      itemEst.idEstoque id,
      itemEst.entradaSaida,
      itemEst.atualizaCustoMedio,
      itemEst.operacaoInternaEstoque,
      itemEst.quantidade,
      itemEst.totalCustoOperacao
    FROM MOESTOQUES itemEst
    JOIN ESTABELECIMENTOS est
    ON est.estabelecimento = itemEst.estabelecimento
    JOIN CAGRADESPRODUTO gradProd
    ON gradProd.gradeProduto = itemEst.gradeProduto
    WHERE itemEst.indicadorPropriedadePosseItem = p_indicadorPropriedadePosseIt
    AND itemEst.pessoaParticipante = p_pessoaParticipante
    AND itemEst.operacaoInternaEstoque IN (101,900)
    AND itemEst.data >= COALESCE(TRUNC(p_dataInventarioEstoque) + 1,TO_DATE('01/01/1900','DD/MM/YYYY'))
    AND itemEst.data < TRUNC(p_dataPosicaoEstoque) + 1
    AND gradProd.produto = p_gradProd_produto
    AND (p_gradProd_cor = 0
      OR gradProd.cor = p_gradProd_cor)
    AND (p_gradProd_tamanho = ''
      OR p_gradProd_tamanho = ' '
      OR gradProd.tamanho = p_gradProd_tamanho)
    UNION ALL
    SELECT
      cabDoc.dataEntradaSaida data,
      'F' tipo,
      itemDoc.idItemDocFiscal id,
      cabDoc.entradaSaida,
      cabDoc.atualizaCustoMedio,
      modDoc.operacaoInternaEstoque,
      itemDoc.quantidade,
      itemDoc.valorCustoOperacao totalCustoOperacao
    FROM MODOCFISCALXITENS itemDoc
    JOIN MODOCUMENTOSFISCAIS cabDoc
    ON cabDoc.idDocumentoFiscal = itemDoc.idDocumentoFiscal
    JOIN ESTABELECIMENTOS est
    ON est.estabelecimento = cabDoc.estabelecimento
    JOIN PAMODELOSDOCUMENTO modDoc
    ON modDoc.modeloDocumento = itemDoc.modeloDocumento
    JOIN PALOCAISESTOQUE locEst
    ON locEst.localEstoque = itemDoc.localEstoque
    JOIN CAGRADESPRODUTO gradProd
    ON gradProd.gradeProduto = itemDoc.gradeProduto
    WHERE itemDoc.pessoaParticipante = p_pessoaParticipante
    AND itemDoc.movimentaEstoqueFiscal = 1
    AND cabDoc.dataEntradaSaida >= COALESCE(TRUNC(p_dataInventarioEstoque) + 1,TO_DATE('01/01/1900','DD/MM/YYYY'))
    AND cabDoc.dataEntradaSaida < TRUNC(p_dataPosicaoEstoque) + 1
    AND locEst.indicadorPropriedadePosseItem = p_indicadorPropriedadePosseIt
    AND gradProd.produto = p_gradProd_produto
    AND (p_gradProd_cor = 0
      OR gradProd.cor = p_gradProd_cor)
    AND (p_gradProd_tamanho = ''
      OR p_gradProd_tamanho = ' '
      OR gradProd.tamanho = p_gradProd_tamanho)
    AND NOT(EXISTS(
      SELECT 1
      FROM MODOCFISCALXPRODUTOFILHO filhoDoc
      WHERE filhoDoc.idItemDocFiscal = itemDoc.idItemDocFiscal))
    UNION ALL
    SELECT
      cabDoc.dataEntradaSaida data,
      'G' tipo,
      filhoDoc.id,
      cabDoc.entradaSaida,
      cabDoc.atualizaCustoMedio,
      modDoc.operacaoInternaEstoque,
      filhoDoc.quantidade,
      filhoDoc.totalCustoOperacao
    FROM MODOCFISCALXPRODUTOFILHO filhoDoc
    JOIN MODOCFISCALXITENS itemDoc
    ON itemDoc.idItemDocFiscal = filhoDoc.idItemDocFiscal
    JOIN MODOCUMENTOSFISCAIS cabDoc
    ON cabDoc.idDocumentoFiscal = itemDoc.idDocumentoFiscal
    JOIN ESTABELECIMENTOS est
    ON est.estabelecimento = cabDoc.estabelecimento
    JOIN PAMODELOSDOCUMENTO modDoc
    ON modDoc.modeloDocumento = itemDoc.modeloDocumento
    JOIN PALOCAISESTOQUE locEst
    ON locEst.localEstoque = itemDoc.localEstoque
    JOIN CAGRADESPRODUTO gradProd
    ON gradProd.gradeProduto = filhoDoc.gradeProduto
    WHERE itemDoc.pessoaParticipante = p_pessoaParticipante
    AND itemDoc.movimentaEstoqueFiscal = 1
    AND cabDoc.dataEntradaSaida >= COALESCE(TRUNC(p_dataInventarioEstoque) + 1,TO_DATE('01/01/1900','DD/MM/YYYY'))
    AND cabDoc.dataEntradaSaida < TRUNC(p_dataPosicaoEstoque) + 1
    AND locEst.indicadorPropriedadePosseItem = p_indicadorPropriedadePosseIt
    AND gradProd.produto = p_gradProd_produto
    AND (p_gradProd_cor = 0
      OR gradProd.cor = p_gradProd_cor)
    AND (p_gradProd_tamanho = ''
      OR p_gradProd_tamanho = ' '
      OR gradProd.tamanho = p_gradProd_tamanho)) a
  ORDER BY TRUNC(a.data),
    a.operacaoInternaEstoque DESC,
    a.atualizaCustoMedio DESC,
    a.data,
    a.tipo,
    a.id;
BEGIN
  v_dataAtual         := COALESCE(TRUNC(p_dataInventarioEstoque)+1,TO_DATE('01/01/1900','DD/MM/YYYY'));
  v_quantidadeEstoque := 0;
  v_precoCustoMedio   := 0;
  v_totalCustoMedio   := 0;
  -- Saldo Inicial Inventário
  IF NOT(p_dataInventarioEstoque IS NULL) THEN
    WITH ESTABELECIMENTOS AS (
      SELECT DISTINCT a.estabelecimento
      FROM (
        SELECT est.estabelecimento
        FROM PAESTABELECIMENTOS est
        WHERE est.estabelecimento = p_estabelecimento
        UNION ALL
        SELECT est2.estabelecimento
        FROM PAESTABELECIMENTOS est
        JOIN PAESTABELECIMENTOS est2
        ON est2.pessoaEstabelecimento = est.pessoaEstabelecimento
        WHERE est.estabelecimento = p_estabelecimento
        AND est.pessoaEstabelecimento > 0
        AND est2.ativo = 1
        UNION ALL
        SELECT est2.estabelecimento
        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 = p_estabelecimento
        AND est.pessoaEstabelecimento > 0
        AND pessEst.grupoEconomico > 0
        AND est2.ativo = 1) a)
    SELECT
      COALESCE(SUM(itemEst.quantidade),0),
      COALESCE((
        CASE
          WHEN SUM(itemEst.quantidade) = 0
            OR SUM(ROUND(itemEst.quantidade * itemEst.precoUnitarioCMV,2)) = 0
            OR SUM(itemEst.quantidade) = MAX(itemEst.quantidade)
            AND SUM(ROUND(itemEst.quantidade * itemEst.precoUnitarioCMV,2))
             =  MAX(ROUND(itemEst.quantidade * itemEst.precoUnitarioCMV,2))
          THEN MAX(itemEst.precoUnitarioCMV)
          ELSE ROUND(SUM(ROUND(itemEst.quantidade * itemEst.precoUnitarioCMV,2))
            / SUM(itemEst.quantidade),7)
        END),0),
      COALESCE(SUM(ROUND(itemEst.quantidade * itemEst.precoUnitarioCMV,2)),0)
    INTO
      v_quantidadeEstoque,
      v_precoCustoMedio,
      v_totalCustoMedio
    FROM MOINVENTARIOESTOQUEXFISC itemEst
    JOIN MOINVENTARIOSESTOQUE invEst
    ON invEst.inventarioEstoque = itemEst.inventarioEstoque
    JOIN ESTABELECIMENTOS est
    ON est.estabelecimento = invEst.estabelecimento
    JOIN CAGRADESPRODUTO gradProd
    ON gradProd.gradeProduto = itemEst.gradeProduto
    WHERE itemEst.indicadorPropriedadePosseItem = p_indicadorPropriedadePosseIt
    AND itemEst.pessoaParticipante = p_pessoaParticipante
    AND invEst.data >= TRUNC(p_dataInventarioEstoque)
    AND invEst.data < TRUNC(p_dataInventarioEstoque) + 1
    AND gradProd.produto = p_gradProd_produto
    AND (p_gradProd_cor = 0
      OR gradProd.cor = p_gradProd_cor)
    AND (p_gradProd_tamanho = ''
      OR p_gradProd_tamanho = ' '
      OR gradProd.tamanho = p_gradProd_tamanho);
  END IF;
  FOR dados IN c_estoque
  LOOP
    IF dados.operacaoInternaEstoque = 1 AND dados.data > v_dataAtual
    THEN
      v_quantidadeEstoque := 0;
      v_precoCustoMedio   := 0;
      v_totalCustoMedio   := 0;
    END IF;
    v_dataAtual := dados.data;
    -- Se atualiza custo médio
    IF dados.atualizaCustoMedio = 1 THEN
      IF dados.entradaSaida = 'E' THEN
        v_quantidadeEstoque := v_quantidadeEstoque + dados.quantidade;
        IF v_quantidadeEstoque <= 0 THEN
          v_totalCustoMedio := 0;
        ELSE
          IF v_quantidadeEstoque > dados.quantidade THEN
            IF v_totalCustoMedio + dados.totalCustoOperacao > 9999999999999.99 THEN
               v_totalCustoMedio := 9999999999999.99;
            ELSE
               v_totalCustoMedio := v_totalCustoMedio + dados.totalCustoOperacao;
            END IF;
          ELSE
            IF ROUND ((dados.totalCustoOperacao * v_quantidadeEstoque / dados.quantidade),2) > 9999999999999.99 THEN
               v_totalCustoMedio := 9999999999999.99;
            ELSE
               v_totalCustoMedio := ROUND ((dados.totalCustoOperacao * v_quantidadeEstoque / dados.quantidade),2);
            END IF;
          END IF;
        END IF;
     ELSE
        v_quantidadeEstoque := v_quantidadeEstoque - dados.quantidade;
        v_totalCustoMedio := v_totalCustoMedio - dados.totalCustoOperacao;
        IF v_totalCustoMedio < 0 OR v_quantidadeEstoque <= 0 THEN
          v_totalCustoMedio := 0;
        END IF;
      END IF;
      IF v_totalCustoMedio > 0 AND v_quantidadeEstoque >= 0 AND ROUND(v_totalCustoMedio / CASE WHEN v_quantidadeEstoque = 0 THEN 1 ELSE v_quantidadeEstoque END, 7) > 99999999.9999999 THEN
        v_precoCustoMedio := 99999999.9999999;
      ELSE
        IF v_totalCustoMedio > 0 AND v_quantidadeEstoque >= 0 THEN
          v_precoCustoMedio := ROUND(v_totalCustoMedio / CASE WHEN v_quantidadeEstoque = 0 THEN 1 ELSE v_quantidadeEstoque END, 7);
        END IF;
      END IF;
    -- Se não atualiza custo médio
    ELSE
      IF dados.entradaSaida = 'E' THEN
        v_quantidadeEstoque := v_quantidadeEstoque + dados.quantidade;
        IF v_quantidadeEstoque <= 0 THEN
          v_totalCustoMedio := 0;
        ELSE
          IF v_quantidadeEstoque > dados.quantidade THEN
            IF v_totalCustoMedio + ROUND((dados.quantidade * v_precoCustoMedio),2) > 9999999999999.99 THEN
               v_totalCustoMedio := 9999999999999.99;
            ELSE
               v_totalCustoMedio := v_totalCustoMedio + dados.totalCustoOperacao;
            END IF;
          ELSE
            IF ROUND((v_quantidadeEstoque * v_precoCustoMedio),2) > 9999999999999.99 THEN
               v_totalCustoMedio := 9999999999999.99;
            ELSE
               v_totalCustoMedio := ROUND((v_quantidadeEstoque * v_precoCustoMedio),2);
            END IF;
          END IF;
        END IF;
      ELSE
        v_quantidadeEstoque := v_quantidadeEstoque - dados.quantidade;
        v_totalCustoMedio := v_totalCustoMedio - dados.quantidade * v_precoCustoMedio;
        IF v_totalCustoMedio < 0 OR v_quantidadeEstoque <= 0 THEN
          v_totalCustoMedio := 0;
        END IF;
      END IF;
    END IF;
  END LOOP;
  IF v_precoCustoMedio = 0 THEN
    v_precoCustoMedio := FUNC_ADD_BUSCA_PRECO_PRODXEST(
      p_config_209_filtrarGrupoEcon,
      p_estabelecimento,
      p_gradProd_produto,
      'C');
  END IF;
  RETURN v_precoCustoMedio;  
END;

/

create or replace FUNCTION FUNC_ADD_BUSCA_PRECO_MEDIO(
    p_config_209_filtrarGrupoEcon  IN NUMBER,
    p_config_362_calcCustoPorGrade IN NUMBER,
    p_estabelecimento              IN NUMBER,
    p_dataPosicaoEstoque           IN DATE,
    p_item_personalizacao          IN NUMBER,
    p_gradProd_produto             IN NUMBER,
    p_gradProd_cor                 IN NUMBER,
    p_gradProd_tamanho             IN VARCHAR,
    p_indicadorPropriedadePosseIt  IN CHAR,
    p_pessoaParticipante           IN NUMBER,
    p_buscarPrecoGerencial         IN NUMBER,
    p_gerandoInventario            IN NUMBER)
  RETURN NUMBER
IS 
  v_dataInventarioEstoque DATE;
  v_precoCustoMedio       NUMBER;
BEGIN
  -- v_dataInventarioEstoque
  WITH ESTABELECIMENTOS AS (
    SELECT DISTINCT a.estabelecimento
    FROM (
      SELECT est.estabelecimento
      FROM PAESTABELECIMENTOS est
      WHERE est.estabelecimento = p_estabelecimento
      UNION ALL
      SELECT est2.estabelecimento
      FROM PAESTABELECIMENTOS est
      JOIN PAESTABELECIMENTOS est2
      ON est2.pessoaEstabelecimento = est.pessoaEstabelecimento
      WHERE est.estabelecimento = p_estabelecimento
      AND est.pessoaEstabelecimento > 0
      AND est2.ativo = 1
      UNION ALL
      SELECT est2.estabelecimento
      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 = p_estabelecimento
      AND est.pessoaEstabelecimento > 0
      AND pessEst.grupoEconomico > 0
      AND est2.ativo = 1) a)
  SELECT MAX(TRUNC(invEst.data))
  INTO v_dataInventarioEstoque
  FROM MOINVENTARIOSESTOQUE invEst
  JOIN ESTABELECIMENTOS est
  ON est.estabelecimento = invEst.estabelecimento
  WHERE invEst.inventarioEstoque > 0
  AND invEst.data < TRUNC(p_dataPosicaoEstoque)
    + CASE WHEN invEst.motivoInventarioEstoque = '01' THEN 1 ELSE 0 END
    - CASE WHEN p_gerandoInventario = 1 THEN 1 ELSE 0 END
  AND (invEst.motivoInventarioEstoque = '01'
    OR p_buscarPrecoGerencial = 0
    AND EXISTS(
      SELECT 1
      FROM MOINVENTARIOESTOQUEXFISC itemInv
      JOIN CAGRADESPRODUTO gradProd
      ON gradProd.gradeProduto = itemInv.gradeProduto
      WHERE itemInv.inventarioEstoque = invEst.inventarioEstoque
      AND gradProd.produto = p_gradProd_produto)
    OR p_buscarPrecoGerencial = 1
    AND EXISTS(
      SELECT 1
      FROM MOINVENTARIOESTOQUEXITENS itemInv
      JOIN CAGRADESPRODUTO gradProd
      ON gradProd.gradeProduto = itemInv.gradeProduto
      WHERE itemInv.inventarioEstoque = invEst.inventarioEstoque
      AND gradProd.produto = p_gradProd_produto));
  IF p_buscarPrecoGerencial = 1 THEN
    v_precoCustoMedio := FUNC_ADD_BUSCA_PRECO_MEDIO_GER(
      p_config_209_filtrarGrupoEcon,
      p_config_362_calcCustoPorGrade,
      p_estabelecimento,
      p_dataPosicaoEstoque,
      p_item_personalizacao,
      p_gradProd_produto,
      p_gradProd_cor,
      p_gradProd_tamanho,
      p_indicadorPropriedadePosseIt,
      p_pessoaParticipante,
      v_dataInventarioEstoque);
  ELSE
    v_precoCustoMedio := FUNC_ADD_BUSCA_PRECO_MEDIO_FIS(
      p_config_209_filtrarGrupoEcon,
      p_estabelecimento,
      p_dataPosicaoEstoque,
      p_gradProd_produto,
      p_gradProd_cor,
      p_gradProd_tamanho,
      p_indicadorPropriedadePosseIt,
      p_pessoaParticipante,
      v_dataInventarioEstoque);
  END IF;
  RETURN v_precoCustoMedio;
END;

/

create or replace FUNCTION FUNC_ADD_BUSCA_PROXIMO_ID(
    p_nomeId             IN VARCHAR2,
    p_nomeCampoIdValidar IN VARCHAR2,
    p_caracteresMaximo   IN NUMBER,
    p_estabelecimento    IN NUMBER,
    p_data               IN DATE)
  RETURN NUMBER
IS

  v_estabelecimento NUMBER;
  v_proximoId NUMBER;
  CURSOR c_ultimoId
  IS
    SELECT ultimoId
    FROM PAULTIMOSIDS
    WHERE nomeId = RTRIM (p_nomeId) || CASE WHEN p_estabelecimento = 0 THEN '' ELSE '|' || LPAD (CASE WHEN FUNC_ADD_BUSCA_CONFIG_N (354,0,0,0) = 0 THEN p_estabelecimento ELSE FUNC_ADD_BUSCA_CONFIG_N (354,0,0,0) END, 4, '0') END
    FOR UPDATE;
  CURSOR c_idsLivres
  IS
    SELECT MIN (idLivre)
    FROM PAIDSLIVRES
    WHERE nomeId = RTRIM (p_nomeId) || CASE WHEN p_estabelecimento = 0 THEN '' ELSE '|' || LPAD (CASE WHEN FUNC_ADD_BUSCA_CONFIG_N (354,0,0,0) = 0 THEN p_estabelecimento ELSE FUNC_ADD_BUSCA_CONFIG_N (354,0,0,0) END, 4, '0') END
    AND idLivre > 0
    AND NOT(data IS NULL)
    AND TRUNC (data) = TRUNC (p_data);
PRAGMA AUTONOMOUS_TRANSACTION;
BEGIN
  v_proximoId := 0;
  WHILE v_proximoId = 0
  LOOP
    IF p_data IS NULL THEN
      OPEN c_ultimoId;
      FETCH c_ultimoId INTO v_proximoId;
      IF c_ultimoId%notfound THEN
        v_proximoId :=(CASE WHEN p_estabelecimento = 0 THEN 0 WHEN FUNC_ADD_BUSCA_CONFIG_N (354,0,0,0) = 0 THEN p_estabelecimento ELSE FUNC_ADD_BUSCA_CONFIG_N (354,0,0,0) END)*10000000000+1;
        INSERT INTO PAULTIMOSIDS (nomeId, ultimoId)
        VALUES (RTRIM (p_nomeId) || CASE WHEN p_estabelecimento = 0 THEN '' ELSE '|' || LPAD (CASE WHEN FUNC_ADD_BUSCA_CONFIG_N (354,0,0,0) = 0 THEN p_estabelecimento ELSE FUNC_ADD_BUSCA_CONFIG_N (354,0,0,0) END, 4, '0') END, v_proximoId);
      ELSE
        v_proximoId := v_proximoId + 1;
        UPDATE PAULTIMOSIDS
        SET ultimoId = v_proximoId
        WHERE nomeId = RTRIM (p_nomeId) || CASE WHEN p_estabelecimento = 0 THEN '' ELSE '|' || LPAD (CASE WHEN FUNC_ADD_BUSCA_CONFIG_N (354,0,0,0) = 0 THEN p_estabelecimento ELSE FUNC_ADD_BUSCA_CONFIG_N (354,0,0,0) END, 4, '0') END;
      END IF;
      CLOSE c_ultimoId;
    ELSE
      OPEN c_idsLivres;
      FETCH c_idsLivres INTO v_proximoId;
      IF c_idsLivres%notfound OR v_proximoId IS NULL OR v_proximoId <= 0 THEN
        OPEN c_ultimoId;
        FETCH c_ultimoId INTO v_proximoId;
        IF c_ultimoId%notfound THEN
          v_proximoId :=(p_estabelecimento)*10000000000+1;
          INSERT INTO PAULTIMOSIDS (nomeId, ultimoId)
          VALUES (RTRIM (p_nomeId) || CASE WHEN p_estabelecimento = 0 THEN '' ELSE '|' || LPAD (CASE WHEN FUNC_ADD_BUSCA_CONFIG_N (354,0,0,0) = 0 THEN p_estabelecimento ELSE FUNC_ADD_BUSCA_CONFIG_N (354,0,0,0) END, 4, '0') END, v_proximoId);
        ELSE
          v_proximoId := v_proximoId + 1;
          UPDATE PAULTIMOSIDS
          SET ultimoId = v_proximoId
          WHERE nomeId = RTRIM (p_nomeId) || CASE WHEN p_estabelecimento = 0 THEN '' ELSE '|' || LPAD (CASE WHEN FUNC_ADD_BUSCA_CONFIG_N (354,0,0,0) = 0 THEN p_estabelecimento ELSE FUNC_ADD_BUSCA_CONFIG_N (354,0,0,0) END, 4, '0') END;
        END IF;
        CLOSE c_ultimoId;
      ELSE
        DELETE PAIDSLIVRES
        WHERE nomeId = RTRIM (p_nomeId) || CASE WHEN p_estabelecimento = 0 THEN '' ELSE '|' || LPAD (CASE WHEN FUNC_ADD_BUSCA_CONFIG_N (354,0,0,0) = 0 THEN p_estabelecimento ELSE FUNC_ADD_BUSCA_CONFIG_N (354,0,0,0) END, 4, '0') END
        AND TRUNC (data) = TRUNC (p_data)
        AND idLivre = v_proximoId;
      END IF;
      CLOSE c_idsLivres;
    END IF;
    COMMIT;
    IF NOT(p_nomeCampoIdValidar IS NULL) AND p_nomeCampoIdValidar > ' ' THEN
      v_proximoId := FUNC_ADD_EXECUTE_IMMEDIATE_N(
'SELECT
  CASE
    WHEN EXISTS (
      SELECT 1
      FROM ' || RTRIM(p_nomeId) || '
      WHERE ' || RTRIM(p_nomeCampoIdValidar) || ' = ' || TO_CHAR(v_proximoId) || ')
    THEN 0
    ELSE ' || TO_CHAR(v_proximoId) || '
  END
FROM DUAL');
    END IF;
  END LOOP;
  IF p_caracteresMaximo > 0 AND v_proximoId > TO_NUMBER(LPAD('9',p_caracteresMaximo,'9')) THEN
    v_proximoId := 0; 
  END IF;
  RETURN v_proximoId;
END FUNC_ADD_BUSCA_PROXIMO_ID;

/

create or replace PROCEDURE ADD_GERA_TEMP_ESTOQUE (
  p_uniqueMachineID     IN VARCHAR2,
  p_contadorSessao      IN NUMBER,
  p_dataPosicaoEstoque  IN DATE,
  p_inEstabelecimentos  IN VARCHAR2,
  p_inLocaisEstoque     IN VARCHAR2,
  p_joinProdutos        IN VARCHAR2,
  p_andWhereProdutos    IN VARCHAR2,
  p_joinInventarios     IN VARCHAR2,
  p_andWhereInventarios IN VARCHAR2,
  p_joinMovimentos      IN VARCHAR2,
  p_andWhereMovimentos  IN VARCHAR2)
IS
BEGIN
  DELETE TEMPESTOQUE
  WHERE  uniqueMachineID = p_uniqueMachineID
  AND contadorSessao = p_contadorSessao;
  EXECUTE IMMEDIATE
'INSERT INTO TEMPESTOQUE (
  uniqueMachineID,
  contadorSessao,
  gradeProduto,
  estabelecimento,
  localEstoque,
  indicadorPropriedadePosseItem,
  pessoaParticipante,
  personalizacao,
  idLoteEstoque,
  idEnderecoEstoque,
  idNumeroSerie,
  quantidade)
WITH
DATAINVENTARIOSESTOQUE AS (
  SELECT
    a.inventarioEstoque,
    a.estabelecimento,
    TRUNC(a.data) data
  FROM (
  SELECT
    inventarioEstoque,
    estabelecimento,
    data,
    ROW_NUMBER() OVER (
      PARTITION BY estabelecimento
      ORDER BY
        estabelecimento ASC,
        data DESC,
        inventarioEstoque DESC
      ) ordenacao
  FROM MOINVENTARIOSESTOQUE
  WHERE inventarioEstoque > 0
  AND motivoInventarioEstoque = ''01'''
|| CASE
     WHEN p_inEstabelecimentos IS NULL OR p_inEstabelecimentos = ' ' OR p_inEstabelecimentos = '0'
     THEN ''
     WHEN INSTR(p_inEstabelecimentos,',') = 0
     THEN '
  AND estabelecimento = ' || TRIM(TO_CHAR(p_inEstabelecimentos))
     ELSE '
  AND INSTR('',' || RTRIM(p_inEstabelecimentos) || ','','','' || TRIM(TO_CHAR(estabelecimento)) || '','') > 0'
   END
|| '
  AND data < '
|| CASE
     WHEN  p_dataPosicaoEstoque IS NULL
     THEN 'TRUNC (SYSDATE) + 1'
     ELSE 'TO_DATE(''' || TO_CHAR(p_dataPosicaoEstoque, 'DD/MM/YYYY') || ''', ''DD/MM/YYYY'') + 1'
   END
|| ') a
  WHERE a.ordenacao = 1),
DATAINVENTARIOESTOQUEXITENS AS (
  SELECT
    a.inventarioEstoque,
    a.estabelecimento,
    a.produto,
    TRUNC(a.data) data
  FROM (
    SELECT
      invEst.inventarioEstoque,
      invEst.estabelecimento,
      gradProd.produto,
      invEst.data,
      ROW_NUMBER() OVER (
        PARTITION BY
          invEst.estabelecimento,
          gradProd.produto
        ORDER BY
          invEst.estabelecimento ASC,
          gradProd.produto ASC,
          invEst.data DESC,
          itemInv.inventarioEstoque DESC
        ) ordenacao
    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'
|| CASE
     WHEN p_joinProdutos IS NULL OR p_joinProdutos = ' '
     THEN ''
     ELSE '
    ' || RTRIM(p_joinProdutos)
   END
|| CASE
     WHEN p_joinInventarios IS NULL OR p_joinInventarios = ' '
     THEN ''
     ELSE '
    ' || RTRIM(p_joinInventarios)
   END
|| '
    WHERE itemInv.inventarioEstoque > 0
    AND itemInv.gradeProduto > 0
    AND invEst.motivoInventarioEstoque <> ''01'''
|| CASE
     WHEN p_inEstabelecimentos IS NULL OR p_inEstabelecimentos = ' ' OR p_inEstabelecimentos = '0'
     THEN ''
     WHEN INSTR(p_inEstabelecimentos,',') = 0
     THEN '
    AND invEst.estabelecimento = ' || TRIM(TO_CHAR(p_inEstabelecimentos))
     ELSE '
    AND INSTR('',' || RTRIM(p_inEstabelecimentos) || ','','','' || TRIM(TO_CHAR(invEst.estabelecimento)) || '','') > 0'
   END
|| CASE
     WHEN p_inLocaisEstoque IS NULL OR p_inLocaisEstoque = ' ' OR p_inLocaisEstoque = '0'
     THEN ''
     WHEN INSTR(p_inLocaisEstoque,',') = 0
     THEN '
    AND itemInv.localEstoque = ' || TRIM(TO_CHAR(p_inLocaisEstoque))
     ELSE '
    AND INSTR('',' || RTRIM(p_inLocaisEstoque) || ','','','' || TRIM(TO_CHAR(itemInv.localEstoque)) || '','') > 0'
   END
|| '
    AND invEst.data < '
|| CASE
     WHEN  p_dataPosicaoEstoque IS NULL
     THEN 'TRUNC (SYSDATE) + 1'
     ELSE 'TO_DATE(''' || TO_CHAR(p_dataPosicaoEstoque, 'DD/MM/YYYY') || ''', ''DD/MM/YYYY'') + 1'
   END
|| '
    AND invEst.data >= COALESCE((
      SELECT MAX (temp.data) + 1
      FROM DATAINVENTARIOSESTOQUE temp
      WHERE temp.estabelecimento = invEst.estabelecimento),
      TO_DATE (''01/01/1900'',''DD/MM/YYYY''))'
|| CASE
     WHEN p_andWhereProdutos IS NULL OR p_andWhereProdutos = ' '
     THEN ''
     ELSE '
    ' || RTRIM(p_andWhereProdutos)
   END
|| CASE
     WHEN p_andWhereInventarios IS NULL OR p_andWhereInventarios = ' '
     THEN ''
     ELSE '
    ' || RTRIM(p_andWhereInventarios)
   END
|| ') a
  WHERE a.ordenacao = 1),
DATAESTOQUEINICIAL AS (
  SELECT
    a.estabelecimento,
    TRUNC(a.data) data,
    a.produto
  FROM (
    SELECT
      mov.estabelecimento,
      mov.data,
      gradProd.produto,
      ROW_NUMBER() OVER (
        PARTITION BY
          mov.estabelecimento,
          gradProd.produto
        ORDER BY
          mov.estabelecimento ASC,
          gradProd.produto ASC,
          mov.data DESC,
          mov.idEstoque DESC
        ) ordenacao
    FROM MOESTOQUES mov
    JOIN CAGRADESPRODUTO gradProd
    ON gradProd.gradeProduto = mov.gradeProduto
    JOIN CAPRODUTOS prod
    ON prod.produto = gradProd.produto'
|| CASE
     WHEN p_joinProdutos IS NULL OR p_joinProdutos = ' '
     THEN ''
     ELSE '
    ' || RTRIM(p_joinProdutos)
   END
|| CASE
     WHEN p_joinMovimentos IS NULL OR p_joinMovimentos = ' '
     THEN ''
     ELSE '
    ' || RTRIM(p_joinMovimentos)
   END
|| '
    WHERE mov.idEstoque > 0
    AND mov.gradeProduto > 0
    AND mov.operacaoInternaEstoque = 1'
|| CASE
     WHEN p_inEstabelecimentos IS NULL OR p_inEstabelecimentos = ' ' OR p_inEstabelecimentos = '0'
     THEN ''
     WHEN INSTR(p_inEstabelecimentos,',') = 0
     THEN '
    AND mov.estabelecimento = ' || TRIM(TO_CHAR(p_inEstabelecimentos))
     ELSE '
    AND INSTR('',' || RTRIM(p_inEstabelecimentos) || ','','','' || TRIM(TO_CHAR(mov.estabelecimento)) || '','') > 0'
   END
|| CASE
     WHEN p_inLocaisEstoque IS NULL OR p_inLocaisEstoque = ' ' OR p_inLocaisEstoque = '0'
     THEN ''
     WHEN INSTR(p_inLocaisEstoque,',') = 0
     THEN '
    AND mov.localEstoque = ' || TRIM(TO_CHAR(p_inLocaisEstoque))
     ELSE '
    AND INSTR('',' || RTRIM(p_inLocaisEstoque) || ','','','' || TRIM(TO_CHAR(mov.localEstoque)) || '','') > 0'
   END
|| '
    AND mov.data < '
|| CASE
     WHEN  p_dataPosicaoEstoque IS NULL
     THEN 'TRUNC (SYSDATE) + 1'
     ELSE 'TO_DATE(''' || TO_CHAR(p_dataPosicaoEstoque, 'DD/MM/YYYY') || ''', ''DD/MM/YYYY'') + 1'
   END
|| '
    AND mov.data >= COALESCE((
      SELECT MAX (temp.data) + 1
      FROM DATAINVENTARIOESTOQUEXITENS temp
      WHERE temp.estabelecimento = mov.estabelecimento
      AND temp.produto = gradProd.produto),
      COALESCE((
      SELECT MAX (temp.data) + 1
      FROM DATAINVENTARIOSESTOQUE temp
      WHERE temp.estabelecimento = mov.estabelecimento),
      TO_DATE (''01/01/1900'',''DD/MM/YYYY'')))'
|| CASE
     WHEN p_andWhereProdutos IS NULL OR p_andWhereProdutos = ' '
     THEN ''
     ELSE '
    ' || RTRIM(p_andWhereProdutos)
   END
|| CASE
     WHEN p_andWhereMovimentos IS NULL OR p_andWhereMovimentos = ' '
     THEN ''
     ELSE '
   ' || RTRIM(p_andWhereMovimentos)
   END
|| ') a
  WHERE a.ordenacao = 1)
SELECT
  ''' || CASE WHEN p_uniqueMachineID IS NULL OR p_uniqueMachineID = ' ' THEN ' ' ELSE RTRIM(p_uniqueMachineID) END || ''',
  ' || TO_CHAR(p_contadorSessao) || ',
  a.gradeProduto,
  a.estabelecimento,
  a.localEstoque,
  a.indicadorPropriedadePosseItem,
  a.pessoaParticipante,
  a.personalizacao,
  a.idLoteEstoque,
  a.idEnderecoEstoque,
  a.idNumeroSerie,
  SUM (a.quantidade)
FROM (
  SELECT DISTINCT
    itemInv.idItemInventarioEstoque id,
    temp.estabelecimento,
    itemInv.localEstoque,
    itemInv.indicadorPropriedadePosseItem,
    itemInv.pessoaParticipante,
    itemInv.gradeProduto,
    itemInv.personalizacao,
    itemInv.idLoteEstoque,
    itemInv.idEnderecoEstoque,
    CASE WHEN prod.controlaNumeroSerie = 1 THEN itemInv.idNumeroSerie ELSE 0 END idNumeroSerie,
    itemInv.quantidade
  FROM MOINVENTARIOESTOQUEXITENS itemInv
  JOIN MOINVENTARIOSESTOQUE invEst
  ON invEst.inventarioEstoque = itemInv.inventarioEstoque
  JOIN DATAINVENTARIOSESTOQUE temp
  ON temp.inventarioEstoque = itemInv.inventarioEstoque
  JOIN CAGRADESPRODUTO gradProd
  ON gradProd.gradeProduto = itemInv.gradeProduto
  JOIN CAPRODUTOS prod
  ON prod.produto = gradProd.produto'
|| CASE
     WHEN p_joinProdutos IS NULL OR p_joinProdutos = ' '
     THEN ''
     ELSE '
  ' || RTRIM(p_joinProdutos)
   END
|| CASE
     WHEN p_joinInventarios IS NULL OR p_joinInventarios = ' '
     THEN ''
     ELSE '
  ' || RTRIM(p_joinInventarios)
   END
|| '
  WHERE itemInv.inventarioEstoque > 0
  AND itemInv.gradeProduto > 0
  AND NOT (EXISTS(
    SELECT 1
    FROM DATAINVENTARIOESTOQUEXITENS temp2
    WHERE temp2.estabelecimento = temp.estabelecimento
    AND temp2.produto = gradProd.produto))
  AND NOT (EXISTS(
    SELECT 1
    FROM DATAESTOQUEINICIAL temp2
    WHERE temp2.estabelecimento = temp.estabelecimento
    AND temp2.produto = gradProd.produto))'
|| CASE
     WHEN p_andWhereProdutos IS NULL OR p_andWhereProdutos = ' '
     THEN ''
     ELSE '
  ' || RTRIM(p_andWhereProdutos)
   END
|| CASE
     WHEN p_andWhereInventarios IS NULL OR p_andWhereInventarios = ' '
     THEN ''
     ELSE '
  ' || RTRIM(p_andWhereInventarios)
   END
|| '
  UNION ALL
  SELECT DISTINCT
    itemInv.idItemInventarioEstoque id,
    temp.estabelecimento,
    itemInv.localEstoque,
    itemInv.indicadorPropriedadePosseItem,
    itemInv.pessoaParticipante,
    itemInv.gradeProduto,
    itemInv.personalizacao,
    itemInv.idLoteEstoque,
    itemInv.idEnderecoEstoque,
    CASE WHEN prod.controlaNumeroSerie = 1 THEN itemInv.idNumeroSerie ELSE 0 END idNumeroSerie,
    itemInv.quantidade
  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
  JOIN DATAINVENTARIOESTOQUEXITENS temp
  ON temp.inventarioEstoque = itemInv.inventarioEstoque
  AND temp.produto = gradProd.produto'
|| CASE
     WHEN p_joinProdutos IS NULL OR p_joinProdutos = ' '
     THEN ''
     ELSE '
  ' || RTRIM(p_joinProdutos)
   END
|| CASE
     WHEN p_joinInventarios IS NULL OR p_joinInventarios = ' '
     THEN ''
     ELSE '
  ' || RTRIM(p_joinInventarios)
   END
|| '
  WHERE itemInv.inventarioEstoque > 0
  AND itemInv.gradeProduto > 0
  AND NOT (EXISTS(
    SELECT 1
    FROM DATAESTOQUEINICIAL temp2
    WHERE temp2.estabelecimento = temp.estabelecimento
    AND temp2.produto = gradProd.produto))'
|| CASE
     WHEN p_andWhereProdutos IS NULL OR p_andWhereProdutos = ' '
     THEN ''
     ELSE '
  ' || RTRIM(p_andWhereProdutos)
   END
|| CASE
     WHEN p_andWhereInventarios IS NULL OR p_andWhereInventarios = ' '
     THEN ''
     ELSE '
  ' || RTRIM(p_andWhereInventarios)
   END
|| '
  UNION ALL
  SELECT DISTINCT
    mov.idEstoque id,
    mov.estabelecimento,
    mov.localEstoque,
    mov.indicadorPropriedadePosseItem,
    mov.pessoaParticipante,
    mov.gradeProduto,
    mov.personalizacao,
    mov.idLoteEstoque,
    mov.idEnderecoEstoque,
    CASE WHEN prod.controlaNumeroSerie = 1 THEN mov.idNumeroSerie ELSE 0 END idNumeroSerie,
    mov.quantidade * CASE WHEN mov.entradaSaida = ''S'' THEN -1 ELSE 1 END quantidade
  FROM MOESTOQUES mov
  JOIN CAGRADESPRODUTO gradProd
  ON gradProd.gradeProduto = mov.gradeProduto
  JOIN CAPRODUTOS prod
  ON prod.produto = gradProd.produto'
|| CASE
     WHEN p_joinProdutos IS NULL OR p_joinProdutos = ' '
     THEN ''
     ELSE '
  ' || RTRIM(p_joinProdutos)
   END
|| CASE
     WHEN p_joinMovimentos IS NULL OR p_joinMovimentos = ' '
     THEN ''
     ELSE '
  ' || RTRIM(p_joinMovimentos)
   END
|| '
  WHERE mov.idEstoque > 0
  AND mov.gradeProduto > 0'
|| CASE
     WHEN p_inEstabelecimentos IS NULL OR p_inEstabelecimentos = ' ' OR p_inEstabelecimentos = '0'
     THEN ''
     WHEN INSTR(p_inEstabelecimentos,',') = 0
     THEN '
  AND mov.estabelecimento = ' || TRIM(TO_CHAR(p_inEstabelecimentos))
     ELSE '
  AND INSTR('',' || RTRIM(p_inEstabelecimentos) || ','','','' || TRIM(TO_CHAR(mov.estabelecimento)) || '','') > 0'
   END
|| CASE
     WHEN p_inLocaisEstoque IS NULL OR p_inLocaisEstoque = ' ' OR p_inLocaisEstoque = '0'
     THEN ''
     WHEN INSTR(p_inLocaisEstoque,',') = 0
     THEN '
  AND mov.localEstoque = ' || TRIM(TO_CHAR(p_inLocaisEstoque))
     ELSE '
  AND INSTR('',' || RTRIM(p_inLocaisEstoque) || ','','','' || TRIM(TO_CHAR(mov.localEstoque)) || '','') > 0'
   END
|| '
  AND mov.data < '
|| CASE
     WHEN  p_dataPosicaoEstoque IS NULL
     THEN 'TRUNC (SYSDATE) + 1'
     ELSE 'TO_DATE(''' || TO_CHAR(p_dataPosicaoEstoque, 'DD/MM/YYYY') || ''', ''DD/MM/YYYY'') + 1'
   END
|| '
  AND mov.data >= COALESCE((
    SELECT MAX (temp.data)
    FROM DATAESTOQUEINICIAL temp
    WHERE temp.estabelecimento = mov.estabelecimento
    AND temp.produto = gradProd.produto),
    COALESCE((
    SELECT MAX (temp.data) + 1
    FROM DATAINVENTARIOESTOQUEXITENS temp
    WHERE temp.estabelecimento = mov.estabelecimento
    AND temp.produto = gradProd.produto),
    COALESCE((
    SELECT MAX (temp.data) + 1
    FROM DATAINVENTARIOSESTOQUE temp
    WHERE temp.estabelecimento = mov.estabelecimento),
    TO_DATE (''01/01/1900'',''DD/MM/YYYY''))))'
|| CASE
     WHEN p_andWhereProdutos IS NULL OR p_andWhereProdutos = ' '
     THEN ''
     ELSE '
  ' || RTRIM(p_andWhereProdutos)
   END
|| CASE
     WHEN p_andWhereMovimentos IS NULL OR p_andWhereMovimentos = ' '
     THEN ''
     ELSE '
 ' || RTRIM(p_andWhereMovimentos)
   END
|| ') a
GROUP BY
  a.gradeProduto,
  a.estabelecimento,
  a.localEstoque,
  a.indicadorPropriedadePosseItem,
  a.pessoaParticipante,
  a.personalizacao,
  a.idLoteEstoque,
  a.idEnderecoEstoque,
  a.idNumeroSerie';
END ADD_GERA_TEMP_ESTOQUE;

/

create or replace PROCEDURE ADD_CALCULA_IMPOSTOS_ITEM (
    p_config_64_casasDecSaidas     IN CHAR,
    p_config_209_filtrarGrupoEcon  IN NUMBER,
    p_config_330_redIcmsBasePisCof IN NUMBER,
    p_config_362_calcCustoPorGrade IN NUMBER,
    p_cab_entradaSaida             IN CHAR,
    p_cab_devolucaoAnulacaoRetorno IN NUMBER,
    p_cab_estabelecimento          IN NUMBER,
    p_cab_nfFornecedor             IN NUMBER,
    p_cab_dataEntradaSaida         IN DATE,
    p_cab_pessoa                   IN NUMBER,
    p_cab_localDestinoOperacao     IN CHAR,
    p_cab_indicadorConsumidorFinal IN CHAR,
    p_cab_tipoPagamentoFrete       IN CHAR,
    p_pess_indicadorInscricaoEstad IN CHAR,
    p_personalizacao               IN NUMBER,
    p_quantidade                   IN NUMBER,
    p_precoPautaTabelado           IN NUMBER,
    p_valorProdutoServico          IN NUMBER,
    p_valorFreteTotal              IN NUMBER,
    p_valorSeguroTotal             IN NUMBER,
    p_valorDescontoTotal           IN NUMBER,
    p_valorOutrasDespesasTotal     IN NUMBER,
    p_valorAdicFreteMarinMerTotal  IN NUMBER,
    p_valorDespesasAduaneirasTotal IN NUMBER,
    p_cfop                         IN NUMBER,
    p_calcularISSQN                IN NUMBER,
    p_indicadorISSQN               IN CHAR,
    p_aliquotaISSQN                IN NUMBER,
    p_baseISSQN                    IN NUMBER,
    p_valorISSQN                   IN NUMBER,
    p_calcularIRRF                 IN NUMBER,
    p_aliquotaIRRF                 IN NUMBER,
    p_baseIRRF                     IN NUMBER,
    p_valorIRRF                    IN NUMBER,
    p_calcularINSS                 IN NUMBER,
    p_aliquotaINSS                 IN NUMBER,
    p_baseINSS                     IN NUMBER,
    p_valorINSS                    IN NUMBER,
    p_calcularRetencaoPIS          IN NUMBER,
    p_retencaoPIS                  IN NUMBER,
    p_baseRetPIS                   IN NUMBER,
    p_valorRetPIS                  IN NUMBER,
    p_calcularRetencaoCOFINS       IN NUMBER,
    p_retencaoCOFINS               IN NUMBER,
    p_baseRetCOFINS                IN NUMBER,
    p_valorRetCOFINS               IN NUMBER,
    p_calcularRetencaoCSLL         IN NUMBER,
    p_retencaoCSLL                 IN NUMBER,
    p_baseRetCSLL                  IN NUMBER,
    p_valorRetCSLL                 IN NUMBER,
    p_calcularII                   IN NUMBER,
    p_aliquotaII                   IN NUMBER,
    p_baseII                       IN NUMBER,
    p_valorII                      IN NUMBER,
    p_calcularIOF                  IN NUMBER,
    p_aliquotaIOF                  IN NUMBER,
    p_baseIOF                      IN NUMBER,
    p_valorIOF                     IN NUMBER,
    p_calcularIPI                  IN NUMBER,
    p_aliquotaIPI                  IN NUMBER,
    p_valorAliquotaIPI             IN NUMBER,
    p_baseIPI                      IN NUMBER,
    p_valorIPI                     IN NUMBER,
    p_valorIPIDevolucao            IN NUMBER,
    p_calcularPIS                  IN NUMBER,
    p_aliquotaPIS                  IN NUMBER,
    p_valorAliquotaPIS             IN NUMBER,
    p_basePIS                      IN NUMBER,
    p_valorPIS                     IN NUMBER,
    p_calcularPISST                IN NUMBER,
    p_aliquotaPISST                IN NUMBER,
    p_valorAliquotaPISST           IN NUMBER,
    p_basePISST                    IN NUMBER,
    p_valorPISST                   IN NUMBER,
    p_calcularCOFINS               IN NUMBER,
    p_aliquotaCOFINS               IN NUMBER,
    p_valorAliquotaCOFINS          IN NUMBER,
    p_baseCOFINS                   IN NUMBER,
    p_valorCOFINS                  IN NUMBER,
    p_calcularCOFINSST             IN NUMBER,
    p_aliquotaCOFINSST             IN NUMBER,
    p_valorAliquotaCOFINSST        IN NUMBER,
    p_baseCOFINSST                 IN NUMBER,
    p_valorCOFINSST                IN NUMBER,
    p_calcularSimplesNacional      IN NUMBER,
    p_stSimplesNacional            IN CHAR,
    p_creditoSimplesNacional       IN NUMBER,
    p_baseCreditoSimplesNacional   IN NUMBER,
    p_valorCreditoSimplesNacional  IN NUMBER,
    p_calcularICMS                 IN NUMBER,
    p_stICMS                       IN CHAR,
    p_modalidadeBaseCalcICMS       IN CHAR,
    p_reducaoBaseICMS              IN NUMBER,
    p_aliquotaICMS                 IN NUMBER,
    p_diferimentoICMS              IN NUMBER,
    p_baseICMS                     IN NUMBER,
    p_valorICMSOperacao            IN NUMBER,
    p_valorICMSDiferido            IN NUMBER,
    p_valorICMS                    IN NUMBER,
    p_valorICMSDesoneracao         IN NUMBER,
    p_calcularICMSST               IN NUMBER,
    p_modalidadeBaseCalcICMSST     IN CHAR,
    p_margemValorAdicionadoST      IN NUMBER,
    p_reducaoBaseST                IN NUMBER,
    p_aliquotaICMSST               IN NUMBER,
    p_baseICMSST                   IN NUMBER,
    p_valorICMSST                  IN NUMBER,
    p_calcularICMSSTAnterEfetivo   IN NUMBER,
    p_baseICMSSTAnteriormente      IN NUMBER,
    p_valorICMSSTAnteriormente     IN NUMBER,
    p_valorICMSProprioSubstituto   IN NUMBER,
    p_reducaoBaseICMSEfetivo       IN NUMBER,
    p_aliquotaICMSEfetivo          IN NUMBER,
    p_baseICMSEfetivo              IN NUMBER,
    p_valorICMSEfetivo             IN NUMBER,
    p_calcularICMSEscrituracao     IN NUMBER,
    p_stICMSEscrituracao           IN CHAR,
    p_reducaoBaseICMSEscrituracao  IN NUMBER,
    p_aliquotaICMSEscrituracao     IN NUMBER,
    p_baseICMSEscrituracao         IN NUMBER,
    p_valorICMSEscrituracao        IN NUMBER,
    p_valorICMSDesonEscrituracao   IN NUMBER,
    p_calcularICMSSTEscrituracao   IN NUMBER,
    p_margemValorAdicSTEscriturac  IN NUMBER,
    p_reducaoBaseSTEscrituracao    IN NUMBER,
    p_aliquotaICMSSTEscrituracao   IN NUMBER,
    p_baseICMSSTEscrituracao       IN NUMBER,
    p_valorICMSSTEscrituracao      IN NUMBER,
    p_calcularDIFAL                IN NUMBER,
    p_aliquotaICMSUFDestinatario   IN NUMBER,
    p_aliquotaICMSInterestadual    IN NUMBER,
    p_partilhaICMSInterestadual    IN NUMBER,
    p_baseICMSUFDestinatario       IN NUMBER,
    p_valorICMSUFDestinatario      IN NUMBER,
    p_baseICMSUFRemetente          IN NUMBER,
    p_valorICMSUFRemetente         IN NUMBER,
    p_calcularFCP                  IN NUMBER,
    p_aliquotaFCP                  IN NUMBER,
    p_baseFCP                      IN NUMBER,
    p_valorFCP                     IN NUMBER,
    p_aliquotaFCPST                IN NUMBER,
    p_baseFCPST                    IN NUMBER,
    p_valorFCPST                   IN NUMBER,
    p_aliquotaFCPSTAnteriormente   IN NUMBER,
    p_baseFCPSTAnteriormente       IN NUMBER,
    p_valorFCPSTAnteriormente      IN NUMBER,
    p_aliquotaFCPUFDestinatario    IN NUMBER,
    p_baseFCPUFDestinatario        IN NUMBER,
    p_valorFCPUFDestinatario       IN NUMBER,
    p_calcularImpostosEstimados    IN NUMBER,
    p_aliquotaEstImpFederais       IN NUMBER,
    p_aliquotaEstImpEstaduais      IN NUMBER,
    p_aliquotaEstImpMunicipais     IN NUMBER,
    p_baseEstimadaImpostos         IN NUMBER,
    p_valorEstimadoImpFederais     IN NUMBER,
    p_valorEstimadoImpEstaduais    IN NUMBER,
    p_valorEstimadoImpMunicipais   IN NUMBER,
    p_gradProd_produto             IN NUMBER,
    p_gradProd_cor                 IN NUMBER,
    p_gradProd_tamanho             IN VARCHAR,
    p_prod_controleEstoque         IN NUMBER,
    p_prod_tipoProduto             IN CHAR,
    /* Retornos */
    r_baseISSQN                    OUT NUMBER,
    r_valorISSQN                   OUT NUMBER,
    r_baseIRRF                     OUT NUMBER,
    r_valorIRRF                    OUT NUMBER,
    r_baseINSS                     OUT NUMBER,
    r_valorINSS                    OUT NUMBER,
    r_baseRetPIS                   OUT NUMBER,
    r_valorRetPIS                  OUT NUMBER,
    r_baseRetCOFINS                OUT NUMBER,
    r_valorRetCOFINS               OUT NUMBER,
    r_baseRetCSLL                  OUT NUMBER,
    r_valorRetCSLL                 OUT NUMBER,
    r_baseII                       OUT NUMBER,
    r_valorII                      OUT NUMBER,
    r_baseIOF                      OUT NUMBER,
    r_valorIOF                     OUT NUMBER,
    r_baseIPI                      OUT NUMBER,
    r_valorIPI                     OUT NUMBER,
    r_basePIS                      OUT NUMBER,
    r_valorPIS                     OUT NUMBER,
    r_basePISST                    OUT NUMBER,
    r_valorPISST                   OUT NUMBER,
    r_baseCOFINS                   OUT NUMBER,
    r_valorCOFINS                  OUT NUMBER,
    r_baseCOFINSST                 OUT NUMBER,
    r_valorCOFINSST                OUT NUMBER,
    r_baseCreditoSimplesNacional   OUT NUMBER,
    r_valorCreditoSimplesNacional  OUT NUMBER,
    r_baseICMS                     OUT NUMBER,
    r_valorICMSOperacao            OUT NUMBER,
    r_valorICMSDiferido            OUT NUMBER,
    r_valorICMS                    OUT NUMBER,
    r_valorICMSDesoneracao         OUT NUMBER,
    r_baseICMSST                   OUT NUMBER,
    r_valorICMSST                  OUT NUMBER,
    r_baseICMSSTAnteriormente      OUT NUMBER,
    r_valorICMSSTAnteriormente     OUT NUMBER,
    r_valorICMSProprioSubstituto   OUT NUMBER,
    r_baseICMSEfetivo              OUT NUMBER,
    r_valorICMSEfetivo             OUT NUMBER,
    r_baseICMSEscrituracao         OUT NUMBER,
    r_valorICMSEscrituracao        OUT NUMBER,
    r_valorICMSDesonEscrituracao   OUT NUMBER,
    r_baseICMSSTEscrituracao       OUT NUMBER,
    r_valorICMSSTEscrituracao      OUT NUMBER,
    r_baseICMSUFDestinatario       OUT NUMBER,
    r_valorICMSUFDestinatario      OUT NUMBER,
    r_baseICMSUFRemetente          OUT NUMBER,
    r_valorICMSUFRemetente         OUT NUMBER,
    r_baseFCP                      OUT NUMBER,
    r_valorFCP                     OUT NUMBER,
    r_baseFCPST                    OUT NUMBER,
    r_valorFCPST                   OUT NUMBER,
    r_baseFCPSTAnteriormente       OUT NUMBER,
    r_valorFCPSTAnteriormente      OUT NUMBER,
    r_baseFCPUFDestinatario        OUT NUMBER,
    r_valorFCPUFDestinatario       OUT NUMBER,
    r_baseEstimadaImpostos         OUT NUMBER,
    r_valorEstimadoImpFederais     OUT NUMBER,
    r_valorEstimadoImpEstaduais    OUT NUMBER,
    r_valorEstimadoImpMunicipais    OUT NUMBER)
IS
    v_baseICMSSTAnteriormente      NUMBER;
    v_valorICMSSTAnteriormente     NUMBER;
    v_valorICMSProprioSubstituto   NUMBER;
    v_baseFCPSTAnteriormente       NUMBER;
    v_valorFCPSTAnteriormente      NUMBER;
BEGIN
  /* Inicia retornos com paramentros */
  r_baseISSQN                   := p_baseISSQN;
  r_valorISSQN                  := p_valorISSQN;
  r_baseIRRF                    := p_baseIRRF;
  r_valorIRRF                   := p_valorIRRF;
  r_baseINSS                    := p_baseINSS;
  r_valorINSS                   := p_valorINSS;
  r_baseRetPIS                  := p_baseRetPIS;
  r_valorRetPIS                 := p_valorRetPIS;
  r_baseRetCOFINS               := p_baseRetCOFINS;
  r_valorRetCOFINS              := p_valorRetCOFINS;
  r_baseRetCSLL                 := p_baseRetCSLL;
  r_valorRetCSLL                := p_valorRetCSLL;
  r_baseII                      := p_baseII;
  r_valorII                     := p_valorII;
  r_baseIOF                     := p_baseIOF;
  r_valorIOF                    := p_valorIOF;
  r_baseIPI                     := p_baseIPI;
  r_valorIPI                    := p_valorIPI;
  r_basePIS                     := p_basePIS;
  r_valorPIS                    := p_valorPIS;
  r_basePISST                   := p_basePISST;
  r_valorPISST                  := p_valorPISST;
  r_baseCOFINS                  := p_baseCOFINS;
  r_valorCOFINS                 := p_valorCOFINS;
  r_baseCOFINSST                := p_baseCOFINSST;
  r_valorCOFINSST               := p_valorCOFINSST;
  r_baseCreditoSimplesNacional  := p_baseCreditoSimplesNacional;
  r_valorCreditoSimplesNacional := p_valorCreditoSimplesNacional;
  r_baseICMS                    := p_baseICMS;
  r_valorICMSOperacao           := p_valorICMSOperacao;
  r_valorICMSDiferido           := p_valorICMSDiferido;
  r_valorICMS                   := p_valorICMS;
  r_valorICMSDesoneracao        := p_valorICMSDesoneracao;
  r_baseICMSST                  := p_baseICMSST;
  r_valorICMSST                 := p_valorICMSST;
  r_baseICMSSTAnteriormente     := p_baseICMSSTAnteriormente;
  r_valorICMSSTAnteriormente    := p_valorICMSSTAnteriormente;
  r_valorICMSProprioSubstituto  := p_valorICMSProprioSubstituto;
  r_baseICMSEfetivo             := p_baseICMSEfetivo;
  r_valorICMSEfetivo            := p_valorICMSEfetivo;
  r_baseICMSEscrituracao        := p_baseICMSEscrituracao;
  r_valorICMSEscrituracao       := p_valorICMSEscrituracao;
  r_valorICMSDesonEscrituracao  := p_valorICMSDesonEscrituracao;
  r_baseICMSSTEscrituracao      := p_baseICMSSTEscrituracao;
  r_valorICMSSTEscrituracao     := p_valorICMSSTEscrituracao;
  r_baseICMSUFDestinatario      := p_baseICMSUFDestinatario;
  r_valorICMSUFDestinatario     := p_valorICMSUFDestinatario;
  r_baseICMSUFRemetente         := p_baseICMSUFRemetente;
  r_valorICMSUFRemetente        := p_valorICMSUFRemetente;
  r_baseFCP                     := p_baseFCP;
  r_valorFCP                    := p_valorFCP;
  r_baseFCPST                   := p_baseFCPST;
  r_valorFCPST                  := p_valorFCPST;
  r_baseFCPSTAnteriormente      := p_baseFCPSTAnteriormente;
  r_valorFCPSTAnteriormente     := p_valorFCPSTAnteriormente;
  r_baseFCPUFDestinatario       := p_baseFCPUFDestinatario;
  r_valorFCPUFDestinatario      := p_valorFCPUFDestinatario;
  r_baseEstimadaImpostos        := p_baseEstimadaImpostos;
  r_valorEstimadoImpFederais    := p_valorEstimadoImpFederais;
  r_valorEstimadoImpEstaduais   := p_valorEstimadoImpEstaduais;
  r_valorEstimadoImpMunicipais  := p_valorEstimadoImpMunicipais;
  /* ISSQN */
  IF p_calcularISSQN = 1 THEN
    IF p_indicadorISSQN = '1' THEN
      r_baseISSQN := p_valorProdutoServico - p_valorDescontoTotal + p_valorOutrasDespesasTotal;
      r_valorISSQN := ROUND ((r_baseISSQN * p_aliquotaISSQN / 100), 2);
    ELSE
      r_baseISSQN := 0;
      r_valorISSQN := 0;
    END IF;
  END IF;
  /* IRRF */
  IF p_calcularIRRF = 1 THEN
    IF p_aliquotaIRRF > 0 THEN
      r_baseIRRF := p_valorProdutoServico - p_valorDescontoTotal + p_valorOutrasDespesasTotal;
      r_valorIRRF := ROUND ((r_baseIRRF * p_aliquotaIRRF / 100), 2);
    ELSE
      r_baseIRRF := 0;
      r_valorIRRF := 0;
    END IF;
  END IF;
  /* INSS */
  IF p_calcularINSS = 1 THEN
    IF p_aliquotaINSS > 0 THEN
      r_baseINSS := p_valorProdutoServico - p_valorDescontoTotal + p_valorOutrasDespesasTotal;
      r_valorINSS := ROUND ((r_baseINSS * p_aliquotaINSS / 100), 2);
    ELSE
      r_baseINSS := 0;
      r_valorINSS := 0;
    END IF;
  END IF;
  /* Retenção PIS */
  IF p_calcularRetencaoPIS = 1 THEN
    IF p_retencaoPIS > 0 THEN
      r_baseRetPIS := p_valorProdutoServico - p_valorDescontoTotal + p_valorOutrasDespesasTotal;
      r_valorRetPIS := ROUND ((r_baseRetPIS * p_retencaoPIS / 100), 2);
    ELSE
      r_baseRetPIS := 0;
      r_valorRetPIS := 0;
    END IF;
  END IF;
  /* Retenção COFINS */
  IF p_calcularRetencaoCOFINS = 1 THEN
    IF p_retencaoCOFINS > 0 THEN
      r_baseRetCOFINS := p_valorProdutoServico - p_valorDescontoTotal + p_valorOutrasDespesasTotal;
      r_valorRetCOFINS := ROUND ((r_baseRetCOFINS * p_retencaoCOFINS / 100), 2);
    ELSE
      r_baseRetCOFINS := 0;
      r_valorRetCOFINS := 0;
    END IF;
  END IF;
  /* Retenção CSLL */
  IF p_calcularRetencaoCSLL = 1 THEN
    IF p_retencaoCSLL > 0 THEN
      r_baseRetCSLL := p_valorProdutoServico - p_valorDescontoTotal + p_valorOutrasDespesasTotal;
      r_valorRetCSLL := ROUND ((r_baseRetCSLL * p_retencaoCSLL / 100), 2);
    ELSE
      r_baseRetCSLL := 0;
      r_valorRetCSLL := 0;
    END IF;
  END IF;
  /* II */
  IF p_calcularII = 1 THEN
    IF p_aliquotaII > 0 THEN
      r_baseII :=
        p_valorProdutoServico
        + CASE WHEN p_cab_tipoPagamentoFrete = 'V' THEN 0 ELSE p_valorFreteTotal + p_valorSeguroTotal END
        - p_valorDescontoTotal
        + p_valorOutrasDespesasTotal
        + p_valorAdicFreteMarinMerTotal
        + p_valorDespesasAduaneirasTotal;
      r_valorII := ROUND ((r_baseII * p_aliquotaII / 100), 2);
    ELSE
      r_baseII := 0;
      r_valorII := 0;
    END IF;
  END IF;
  /* IOF */
  IF p_calcularIOF = 1 THEN
    IF p_aliquotaIOF > 0 THEN
      r_baseIOF := 
        p_valorProdutoServico
        + CASE WHEN p_cab_tipoPagamentoFrete = 'V' THEN 0 ELSE p_valorFreteTotal + p_valorSeguroTotal END
        - p_valorDescontoTotal
        + p_valorOutrasDespesasTotal
        + p_valorAdicFreteMarinMerTotal
        + p_valorDespesasAduaneirasTotal;
      r_valorIOF := ROUND ((r_baseIOF * p_aliquotaIOF / 100), 2);
    ELSE
      r_baseIOF := 0;
      r_valorIOF := 0;
    END IF;
  END IF;
  /* IPI */
  IF p_calcularIPI = 1 THEN
    IF p_aliquotaIPI > 0 THEN
      r_baseIPI :=
        p_valorProdutoServico
        + CASE WHEN p_cab_tipoPagamentoFrete = 'V' THEN 0 ELSE p_valorFreteTotal + p_valorSeguroTotal END
        - p_valorDescontoTotal
        + p_valorOutrasDespesasTotal
        + p_valorAdicFreteMarinMerTotal
        + p_valorDespesasAduaneirasTotal
        + r_valorII
        + r_valorIOF;
      r_valorIPI := ROUND ((r_baseIPI * p_aliquotaIPI / 100), 2);
    ELSE
      r_baseIPI := 0;
      r_valorIPI := 0;
    END IF;
    IF p_valorAliquotaIPI > 0 THEN
      r_valorIPI := ROUND ((r_valorIPI + (p_quantidade * p_valorAliquotaIPI)), 2);
    END IF;
  END IF;
  /* Simples Nacional */
  IF p_calcularSimplesNacional = 1 THEN
    IF p_stSimplesNacional IN('101','102','201','202','900') AND p_creditoSimplesNacional > 0 THEN
      r_baseCreditoSimplesNacional :=
        p_valorProdutoServico
        + CASE WHEN p_cab_tipoPagamentoFrete = 'V' THEN 0 ELSE p_valorFreteTotal + p_valorSeguroTotal END
        - p_valorDescontoTotal
        + p_valorOutrasDespesasTotal
        + p_valorAdicFreteMarinMerTotal
        + p_valorDespesasAduaneirasTotal
        + r_valorII
        + r_valorIOF
        + CASE WHEN p_cab_entradaSaida = CASE WHEN p_cab_devolucaoAnulacaoRetorno = 1 THEN 'S' ELSE 'E' END AND p_prod_tipoProduto IN ('07','08') OR p_cab_entradaSaida = CASE WHEN p_cab_devolucaoAnulacaoRetorno = 1 THEN 'E' ELSE 'S' END AND (p_cab_indicadorConsumidorFinal = '0' OR p_pess_indicadorInscricaoEstad = '9') THEN r_valorIPI + p_valorIPIDevolucao ELSE 0 END;
      r_valorCreditoSimplesNacional := ROUND ((r_baseCreditoSimplesNacional * p_creditoSimplesNacional / 100), 2);
    ELSE
      r_baseCreditoSimplesNacional := 0;
      r_valorCreditoSimplesNacional := 0;
    END IF;
  END IF;
  /* ICMS */
  IF p_calcularICMS = 1 THEN
      r_baseICMS := 0;
      r_valorICMSOperacao := 0;
      r_valorICMSDiferido := 0;
      r_valorICMS := 0;
      r_valorICMSDesoneracao := 0;
    IF p_aliquotaICMS > 0 AND (p_stSimplesNacional IS NULL OR p_stSimplesNacional = '   ') AND p_stICMS IN ('40','41','50') THEN
      r_valorICMSDesoneracao := ROUND (((
        p_valorProdutoServico
        + CASE WHEN p_cab_tipoPagamentoFrete = 'V' THEN 0 ELSE p_valorFreteTotal + p_valorSeguroTotal END
        - p_valorDescontoTotal
        + p_valorOutrasDespesasTotal
        + p_valorAdicFreteMarinMerTotal
        + p_valorDespesasAduaneirasTotal
        + r_valorII
        + r_valorIOF
        + CASE WHEN p_cab_entradaSaida = CASE WHEN p_cab_devolucaoAnulacaoRetorno = 1 THEN 'S' ELSE 'E' END AND p_prod_tipoProduto IN ('07','08') OR p_cab_entradaSaida = CASE WHEN p_cab_devolucaoAnulacaoRetorno = 1 THEN 'E' ELSE 'S' END AND (p_cab_indicadorConsumidorFinal = '0' OR p_pess_indicadorInscricaoEstad = '9') THEN r_valorIPI + p_valorIPIDevolucao ELSE 0 END
      ) * p_aliquotaICMS / 100), 2);
    ELSIF p_aliquotaICMS > 0 AND (p_stSimplesNacional IS NULL OR p_stSimplesNacional = '   ') AND (p_stICMS IN ('00','10','20','51','70') OR p_stICMS = '90' AND p_aliquotaICMS > 0) OR p_stSimplesNacional = '900' AND p_aliquotaICMS > 0 THEN
      r_baseICMS :=
        p_valorProdutoServico
        + CASE WHEN p_cab_tipoPagamentoFrete = 'V' THEN 0 ELSE p_valorFreteTotal + p_valorSeguroTotal END
        - p_valorDescontoTotal
        + p_valorOutrasDespesasTotal
        + p_valorAdicFreteMarinMerTotal
        + p_valorDespesasAduaneirasTotal
        + r_valorII
        + r_valorIOF
        + CASE WHEN p_cab_entradaSaida = CASE WHEN p_cab_devolucaoAnulacaoRetorno = 1 THEN 'S' ELSE 'E' END AND p_prod_tipoProduto IN ('07','08') OR p_cab_entradaSaida = CASE WHEN p_cab_devolucaoAnulacaoRetorno = 1 THEN 'E' ELSE 'S' END AND (p_cab_indicadorConsumidorFinal = '0' OR p_pess_indicadorInscricaoEstad = '9') THEN r_valorIPI + p_valorIPIDevolucao ELSE 0 END;
      IF p_precoPautaTabelado > 0 AND (p_modalidadeBaseCalcICMS = '1' OR p_modalidadeBaseCalcICMS = '2' AND r_baseICMS > p_quantidade * p_precoPautaTabelado) THEN
        r_baseICMS := ROUND ((p_quantidade * p_precoPautaTabelado), 2);
      END IF;
      r_valorICMS := ROUND ((r_baseICMS * p_aliquotaICMS / 100), 2);
      IF ((p_stSimplesNacional IS NULL OR p_stSimplesNacional = '   ') AND p_stICMS IN ('20','70','90') OR p_stSimplesNacional = '900') AND p_reducaoBaseICMS > 0 THEN
        r_valorICMSDesoneracao := ROUND ((r_baseICMS * p_aliquotaICMS / 100), 2);
        r_baseICMS := ROUND ((r_baseICMS * (1 - p_reducaoBaseICMS / 100)), 2);
        r_valorICMS := ROUND ((r_baseICMS * p_aliquotaICMS / 100), 2);
        r_valorICMSDesoneracao := r_valorICMSDesoneracao - r_valorICMS;
      ELSE
        IF (p_stSimplesNacional IS NULL OR p_stSimplesNacional = '   ') AND p_stICMS = '51' AND p_reducaoBaseICMS > 0 AND p_reducaoBaseICMS <> p_diferimentoICMS THEN
          r_baseICMS := ROUND ((r_baseICMS * (1 - p_reducaoBaseICMS / 100)), 2);
          r_valorICMS := ROUND ((r_baseICMS * p_aliquotaICMS / 100), 2);
        END IF;
        r_valorICMSDesoneracao := 0;
      END IF;
      IF (p_stSimplesNacional IS NULL OR p_stSimplesNacional = '   ') AND p_stICMS = '51' THEN
        r_valorICMSOperacao := r_valorICMS;
        r_valorICMSDiferido := ROUND ((r_valorICMSOperacao * p_diferimentoICMS / 100), 2);
        r_valorICMS := r_valorICMSOperacao - r_valorICMSDiferido;
        IF r_valorICMS < 0 THEN
          r_valorICMS := 0;
        END IF;
      ELSE
        r_valorICMSOperacao := 0;
        r_valorICMSDiferido := 0;
      END IF;
    END IF;
  END IF;
  /* ICMS ST */
  IF p_calcularICMSST = 1 THEN
    IF (p_stSimplesNacional IS NULL OR p_stSimplesNacional = '   ') AND (p_stICMS IN ('10','30','70') OR p_stICMS = '90' AND p_aliquotaICMSST > 0) OR p_stSimplesNacional IN ('201','202') OR p_stSimplesNacional = '900' AND p_aliquotaICMSST > 0 THEN
      r_baseICMSST :=
        p_valorProdutoServico
        + CASE WHEN p_cab_tipoPagamentoFrete = 'V' THEN 0 ELSE p_valorFreteTotal + p_valorSeguroTotal END
        - p_valorDescontoTotal
        + p_valorOutrasDespesasTotal
        + p_valorAdicFreteMarinMerTotal
        + p_valorDespesasAduaneirasTotal
        + r_valorII
        + r_valorIOF
        + r_valorIPI
        + p_valorIPIDevolucao;
      IF p_precoPautaTabelado > 0 AND (p_modalidadeBaseCalcICMSST = '5' OR p_modalidadeBaseCalcICMSST = '0' AND r_baseICMSST > p_quantidade * p_precoPautaTabelado) AND ((p_stSimplesNacional IS NULL OR p_stSimplesNacional = '   ') AND p_stICMS IN ('10','30','70','90') OR p_stSimplesNacional IN ('201','202','900')) THEN
        r_baseICMSST := ROUND ((p_quantidade * p_precoPautaTabelado), 2);
      END IF;
      IF p_modalidadeBaseCalcICMSST = '4' OR (p_stSimplesNacional IS NULL OR p_stSimplesNacional = '   ') AND p_stICMS = '60' OR p_stSimplesNacional = '500' THEN
        r_baseICMSST := ROUND ((r_baseICMSST * (1 + p_margemValorAdicionadoST / 100)), 2);
      END IF;
      r_baseICMSST := ROUND ((r_baseICMSST * (1 - p_reducaoBaseST / 100)), 2);
      r_valorICMSST := ROUND (((r_baseICMSST * p_aliquotaICMSST / 100) - r_valorICMS), 2);
      IF r_valorICMSST <= 0 THEN
        r_baseICMSST := 0;
        r_valorICMSST := 0;
      END IF;
    ELSE
      r_baseICMSST := 0;
      r_valorICMSST := 0;
    END IF;
  END IF;
  /* Busca dados apenas quando precisa. */
  v_baseICMSSTAnteriormente := 0;
  v_valorICMSSTAnteriormente := 0;
  v_valorICMSProprioSubstituto := 0;
  v_baseFCPSTAnteriormente := 0;
  v_valorFCPSTAnteriormente := 0;
  IF (p_calcularICMSSTAnterEfetivo = 1 OR p_calcularFCP = 1) 
      AND ((p_stSimplesNacional IS NULL OR p_stSimplesNacional = '   ') AND p_stICMS='60' OR p_stSimplesNacional='500') 
      AND p_cab_indicadorConsumidorFinal = '0' 
      AND (p_cab_entradaSaida = 'S'
      OR p_cfop IN (1201,1202,1203,1204,1208,1209,1410,1411,1503,1504,1505,1506,1553,1660,1661,1662,1918,1919)
      OR p_cfop IN (2201,2202,2203,2204,2208,2209,2410,2411,2503,2504,2505,2506,2553,2660,2661,2662,2918,2919)
      OR p_cfop IN (3201,3202,3211,3503,3553)) THEN
    ADD_BUSCA_ICMS_ST_ANTERIOR (
      p_config_64_casasDecSaidas,
      p_config_209_filtrarGrupoEcon,
      p_config_362_calcCustoPorGrade,
      p_cab_estabelecimento,
      p_cab_dataEntradaSaida,
      p_personalizacao,
      p_quantidade,
      p_calcularICMSSTAnterEfetivo,
      p_calcularFCP,
      p_gradProd_produto,
      p_gradProd_cor,
      p_gradProd_tamanho,
      p_prod_controleEstoque,
      v_baseICMSSTAnteriormente,
      v_valorICMSSTAnteriormente,
      v_valorICMSProprioSubstituto,
      v_baseFCPSTAnteriormente,
      v_valorFCPSTAnteriormente
    );
  END IF;
  /* ICMS ST Retido Anteriormente / Efetivo */
  IF p_calcularICMSSTAnterEfetivo = 1 THEN
    r_baseICMSSTAnteriormente := v_baseICMSSTAnteriormente;
    r_valorICMSSTAnteriormente := v_valorICMSSTAnteriormente;
    r_valorICMSProprioSubstituto := v_valorICMSProprioSubstituto;
    IF ((p_stSimplesNacional IS NULL OR p_stSimplesNacional = '   ') AND p_stICMS = '60' OR p_stSimplesNacional = '500') AND p_aliquotaICMSEfetivo <> 0 THEN
      r_baseICMSEfetivo :=
        p_valorProdutoServico
        + CASE WHEN p_cab_tipoPagamentoFrete = 'V' THEN 0 ELSE p_valorFreteTotal + p_valorSeguroTotal END
        - p_valorDescontoTotal
        + p_valorOutrasDespesasTotal
        + p_valorAdicFreteMarinMerTotal
        + p_valorDespesasAduaneirasTotal
        + r_valorII
        + r_valorIOF
        + CASE WHEN p_cab_entradaSaida = CASE WHEN p_cab_devolucaoAnulacaoRetorno = 1 THEN 'S' ELSE 'E' END AND p_prod_tipoProduto IN ('07','08') OR p_cab_entradaSaida = CASE WHEN p_cab_devolucaoAnulacaoRetorno = 1 THEN 'E' ELSE 'S' END AND (p_cab_indicadorConsumidorFinal = '0' OR p_pess_indicadorInscricaoEstad = '9') THEN r_valorIPI + p_valorIPIDevolucao ELSE 0 END;
      r_baseICMSEfetivo := ROUND ((r_baseICMSEfetivo * (1 - p_reducaoBaseICMSEfetivo / 100)), 2);
      r_valorICMSEfetivo := ROUND ((r_baseICMSEfetivo * p_aliquotaICMSEfetivo / 100), 2);
    ELSE
      r_baseICMSEfetivo := 0;
      r_valorICMSEfetivo := 0;
    END IF;
  END IF;
  /* ICMS Escrituracao */
  IF p_calcularICMSEscrituracao = 1 THEN
    IF p_stICMSEscrituracao = p_stICMS
      AND p_aliquotaICMSEscrituracao = p_aliquotaICMS
      AND p_reducaoBaseICMSEscrituracao = p_reducaoBaseICMS
    THEN
      IF p_cab_nfFornecedor = 1 AND p_stICMSEscrituracao = '51' AND p_diferimentoICMS <> 0 AND p_diferimentoICMS <> p_reducaoBaseICMS THEN
        r_baseICMSEscrituracao := ROUND ((r_baseICMS * (1 - p_diferimentoICMS / 100)), 2);
      ELSE
        r_baseICMSEscrituracao := r_baseICMS;
      END IF;
      r_valorICMSEscrituracao := r_valorICMS;
      r_valorICMSDesonEscrituracao := r_valorICMS;
    ELSE
      r_baseICMSEscrituracao := 0;
      r_valorICMSEscrituracao := 0;
      r_valorICMSDesonEscrituracao := 0;
      IF p_aliquotaICMSEscrituracao > 0 AND p_stICMSEscrituracao IN ('40','41','50') THEN
        r_valorICMSDesonEscrituracao := ROUND (((
          p_valorProdutoServico
          + CASE WHEN p_cab_tipoPagamentoFrete = 'V' THEN 0 ELSE p_valorFreteTotal + p_valorSeguroTotal END
          - p_valorDescontoTotal
          + p_valorOutrasDespesasTotal
          + p_valorAdicFreteMarinMerTotal
          + p_valorDespesasAduaneirasTotal
          + r_valorII
          + r_valorIOF
          + CASE WHEN p_cab_entradaSaida = CASE WHEN p_cab_devolucaoAnulacaoRetorno = 1 THEN 'S' ELSE 'E' END AND p_prod_tipoProduto IN ('07','08') OR p_cab_entradaSaida = CASE WHEN p_cab_devolucaoAnulacaoRetorno = 1 THEN 'E' ELSE 'S' END AND (p_cab_indicadorConsumidorFinal = '0' OR p_pess_indicadorInscricaoEstad = '9') THEN r_valorIPI + p_valorIPIDevolucao ELSE 0 END
        ) * p_aliquotaICMSEscrituracao / 100), 2);
      ELSIF p_aliquotaICMSEscrituracao > 0 AND (p_stICMSEscrituracao IN ('00','10','20','51','70') OR p_stICMSEscrituracao = '90' AND p_aliquotaICMSEscrituracao > 0) THEN
        r_baseICMSEscrituracao :=
          p_valorProdutoServico
          + CASE WHEN p_cab_tipoPagamentoFrete = 'V' THEN 0 ELSE p_valorFreteTotal + p_valorSeguroTotal END
          - p_valorDescontoTotal
          + p_valorOutrasDespesasTotal
          + p_valorAdicFreteMarinMerTotal
          + p_valorDespesasAduaneirasTotal
          + r_valorII
          + r_valorIOF
          + CASE WHEN p_cab_entradaSaida = CASE WHEN p_cab_devolucaoAnulacaoRetorno = 1 THEN 'S' ELSE 'E' END AND p_prod_tipoProduto IN ('07','08') OR p_cab_entradaSaida = CASE WHEN p_cab_devolucaoAnulacaoRetorno = 1 THEN 'E' ELSE 'S' END AND (p_cab_indicadorConsumidorFinal = '0' OR p_pess_indicadorInscricaoEstad = '9') THEN r_valorIPI + p_valorIPIDevolucao ELSE 0 END;
        r_valorICMSEscrituracao := ROUND ((r_baseICMSEscrituracao * p_aliquotaICMSEscrituracao / 100), 2);
        IF p_stICMSEscrituracao IN ('20','70','90') AND p_reducaoBaseICMSEscrituracao > 0 THEN
          r_valorICMSDesonEscrituracao := ROUND ((r_baseICMSEscrituracao * p_aliquotaICMSEscrituracao / 100), 2);
          r_baseICMSEscrituracao := ROUND ((r_baseICMSEscrituracao * (1 - p_reducaoBaseICMSEscrituracao / 100)), 2);
          r_valorICMSEscrituracao := ROUND ((r_baseICMSEscrituracao * p_aliquotaICMSEscrituracao / 100), 2);
          r_valorICMSDesonEscrituracao := r_valorICMSDesonEscrituracao - r_valorICMSEscrituracao;
        ELSIF p_stICMSEscrituracao = '51' AND p_reducaoBaseICMSEscrituracao > 0 AND p_reducaoBaseICMSEscrituracao <> p_diferimentoICMS THEN
            r_baseICMSEscrituracao := ROUND ((r_baseICMSEscrituracao * (1 - p_reducaoBaseICMSEscrituracao / 100)), 2);
            r_valorICMSEscrituracao := ROUND ((r_baseICMSEscrituracao * p_aliquotaICMSEscrituracao / 100), 2);
            r_valorICMSDesonEscrituracao := 0;
        ELSE
          r_valorICMSDesonEscrituracao := 0;
        END IF;
        IF p_stICMSEscrituracao = '51' THEN
          r_valorICMSEscrituracao := r_valorICMSEscrituracao - ROUND ((r_valorICMSEscrituracao * p_diferimentoICMS / 100), 2);
          IF p_cab_nfFornecedor = 1 THEN
            r_baseICMSEscrituracao := ROUND ((r_baseICMSEscrituracao * (1 - p_diferimentoICMS / 100)), 2);
          END IF;
          IF r_valorICMSEscrituracao < 0 THEN
            r_valorICMSEscrituracao := 0;
          END IF;
        END IF;
      END IF;
    END IF;
  END IF;
  /* ICMS ST Escrituracao */
  IF p_calcularICMSSTEscrituracao = 1 THEN
    IF p_stICMSEscrituracao = p_stICMS
      AND p_aliquotaICMSEscrituracao = p_aliquotaICMS
      AND p_reducaoBaseICMSEscrituracao = p_reducaoBaseICMS
      AND p_margemValorAdicSTEscriturac = p_margemValorAdicionadoST
      AND p_reducaoBaseSTEscrituracao = p_reducaoBaseST
      AND p_aliquotaICMSSTEscrituracao = p_aliquotaICMSST
    THEN
      r_baseICMSSTEscrituracao := r_baseICMSST;
      r_valorICMSSTEscrituracao := r_valorICMSST;
    ELSIF p_stICMSEscrituracao IN ('10','30','70') OR p_stICMSEscrituracao = '90' AND p_aliquotaICMSSTEscrituracao > 0 THEN
      r_baseICMSSTEscrituracao := ROUND ((ROUND (((
        p_valorProdutoServico
        + CASE WHEN p_cab_tipoPagamentoFrete = 'V' THEN 0 ELSE p_valorFreteTotal + p_valorSeguroTotal END
        - p_valorDescontoTotal
        + p_valorOutrasDespesasTotal
        + p_valorAdicFreteMarinMerTotal
        + p_valorDespesasAduaneirasTotal
        + r_valorII
        + r_valorIOF
        + CASE WHEN p_cab_entradaSaida = CASE WHEN p_cab_devolucaoAnulacaoRetorno = 1 THEN 'S' ELSE 'E' END AND p_prod_tipoProduto IN ('07','08') OR p_cab_entradaSaida = CASE WHEN p_cab_devolucaoAnulacaoRetorno = 1 THEN 'E' ELSE 'S' END AND (p_cab_indicadorConsumidorFinal = '0' OR p_pess_indicadorInscricaoEstad = '9') THEN r_valorIPI + p_valorIPIDevolucao ELSE 0 END
      ) * (1 + p_margemValorAdicSTEscriturac / 100)), 2) * (1 - p_reducaoBaseSTEscrituracao / 100)), 2);
      r_valorICMSSTEscrituracao := ROUND (((r_baseICMSSTEscrituracao * p_aliquotaICMSSTEscrituracao / 100) - r_valorICMSEscrituracao), 2);
      IF r_valorICMSSTEscrituracao <= 0 THEN
        r_baseICMSSTEscrituracao := 0;
        r_valorICMSSTEscrituracao := 0;
      END IF;
    ELSE
      r_baseICMSSTEscrituracao := 0;
      r_valorICMSSTEscrituracao := 0;
    END IF;
  END IF;
  /* DIFAL */
  IF p_calcularDIFAL = 1 THEN
    IF p_cab_localDestinoOperacao = '2' AND (p_cab_entradaSaida = 'E' OR p_cab_indicadorConsumidorFinal = '1' OR p_pess_indicadorInscricaoEstad = '9') AND p_aliquotaICMSUFDestinatario <> 0 AND p_aliquotaICMSInterestadual <> 0 THEN
      IF (p_stSimplesNacional IS NULL OR p_stSimplesNacional = '   ') AND r_baseICMS = 0 OR p_stSimplesNacional IS NOT NULL AND p_stSimplesNacional <> '   ' AND r_baseCreditoSimplesNacional = 0 THEN
        r_baseICMSUFDestinatario :=
          p_valorProdutoServico
          + CASE WHEN p_cab_tipoPagamentoFrete = 'V' THEN 0 ELSE p_valorFreteTotal + p_valorSeguroTotal END
          - p_valorDescontoTotal
          + p_valorOutrasDespesasTotal
          + p_valorAdicFreteMarinMerTotal
          + p_valorDespesasAduaneirasTotal
          + r_valorII
          + r_valorIOF
          + CASE WHEN p_cab_entradaSaida = CASE WHEN p_cab_devolucaoAnulacaoRetorno = 1 THEN 'S' ELSE 'E' END AND p_prod_tipoProduto IN ('07','08') OR p_cab_entradaSaida = CASE WHEN p_cab_devolucaoAnulacaoRetorno = 1 THEN 'E' ELSE 'S' END AND (p_cab_indicadorConsumidorFinal = '0' OR p_pess_indicadorInscricaoEstad = '9') THEN r_valorIPI + p_valorIPIDevolucao ELSE 0 END;
      ELSE
        r_baseICMSUFDestinatario := CASE WHEN (p_stSimplesNacional IS NULL OR p_stSimplesNacional = '   ') THEN r_baseICMS ELSE r_baseCreditoSimplesNacional END;
      END IF;
      r_baseICMSUFRemetente := r_baseICMSUFDestinatario;
      r_valorICMSUFDestinatario := ROUND ((r_baseICMSUFDestinatario * ((p_aliquotaICMSUFDestinatario - p_aliquotaICMSInterestadual) / 100) * (p_partilhaICMSInterestadual / 100)), 2);
      r_valorICMSUFRemetente := ROUND ((r_baseICMSUFRemetente * ((p_aliquotaICMSUFDestinatario - p_aliquotaICMSInterestadual) / 100) * (1 - p_partilhaICMSInterestadual / 100)), 2);
    ELSE
      r_baseICMSUFDestinatario := 0;
      r_valorICMSUFDestinatario := 0;
      r_baseICMSUFRemetente := 0;
      r_valorICMSUFRemetente := 0;
    END IF;
  END IF;
  /* Fundo de Combate a Pobreza */
  IF p_calcularFCP = 1 THEN
    IF r_baseCreditoSimplesNacional <> 0 AND p_aliquotaFCP <> 0 THEN
      r_baseFCP := r_baseCreditoSimplesNacional;
      r_valorFCP := ROUND ((r_baseFCP * p_aliquotaFCP / 100), 2);
    ELSIF (p_stSimplesNacional IS NULL OR p_stSimplesNacional = '   ') AND p_stICMS IN ('00','20','51','90') AND r_baseICMS <> 0 AND p_aliquotaFCP <> 0 THEN
      r_baseFCP := r_baseICMS;
      r_valorFCP := ROUND ((r_baseFCP * p_aliquotaFCP / 100), 2);
    ELSE
      r_baseFCP := 0;
      r_valorFCP := 0;
    END IF;
    /* Fundo de Combate a Pobreza ST */
    IF r_baseICMSST <> 0 AND p_aliquotaFCPST <> 0 THEN
      r_baseFCPST := r_baseICMSST;
      r_valorFCPST := ROUND ((r_baseFCPST * p_aliquotaFCPST / 100), 2);
    ELSE
      r_baseFCPST := 0;
      r_valorFCPST := 0;
    END IF;
    /* Fundo de Combate a Pobreza ICMS ST Retido Anteriormente */
    r_baseFCPSTAnteriormente := v_baseFCPSTAnteriormente;
    r_valorFCPSTAnteriormente := v_valorFCPSTAnteriormente;
    /* Fundo de Combate a Pobreza DIFAL */
    IF p_cab_localDestinoOperacao = '2' AND (p_cab_entradaSaida = 'E' OR p_cab_indicadorConsumidorFinal = '1' OR p_pess_indicadorInscricaoEstad = '9') AND r_baseICMSUFDestinatario <> 0 AND p_aliquotaFCPUFDestinatario <> 0 THEN
      r_baseFCPUFDestinatario := r_baseICMSUFDestinatario;
      r_valorFCPUFDestinatario := ROUND ((r_baseFCPUFDestinatario * p_aliquotaFCPUFDestinatario / 100), 2);
    ELSE
      r_baseFCPUFDestinatario := 0;
      r_valorFCPUFDestinatario := 0;
    END IF;
  END IF;
  /* PIS */
  IF p_calcularPIS = 1 THEN
    IF p_aliquotaPIS > 0 THEN
      r_basePIS :=
        p_valorProdutoServico
        + CASE WHEN p_cab_tipoPagamentoFrete = 'V' THEN 0 ELSE p_valorFreteTotal + p_valorSeguroTotal END
        - p_valorDescontoTotal
        + p_valorOutrasDespesasTotal
        + p_valorAdicFreteMarinMerTotal
        + p_valorDespesasAduaneirasTotal
        + r_valorII
        + r_valorIOF
        - CASE WHEN p_config_330_redIcmsBasePisCof = 1 AND p_cab_entradaSaida = CASE WHEN p_cab_devolucaoAnulacaoRetorno = 1 THEN 'E' ELSE 'S' END THEN r_valorICMS ELSE 0 END;
      r_valorPIS := ROUND ((r_basePIS * p_aliquotaPIS / 100), 2);
    ELSE
      r_basePIS := 0;
      r_valorPIS := 0;
    END IF;
    IF p_valorAliquotaPIS > 0 THEN
      r_valorPIS := ROUND ((r_valorPIS + (p_quantidade * p_valorAliquotaPIS)), 2);
    END IF;
  END IF;
  /* PIS ST */
  IF p_calcularPISST = 1 THEN
    IF p_aliquotaPISST > 0 THEN
      r_basePISST :=
        p_valorProdutoServico
        + CASE WHEN p_cab_tipoPagamentoFrete = 'V' THEN 0 ELSE p_valorFreteTotal + p_valorSeguroTotal END
        - p_valorDescontoTotal
        + p_valorOutrasDespesasTotal
        + p_valorAdicFreteMarinMerTotal
        + p_valorDespesasAduaneirasTotal
        + r_valorII
        + r_valorIOF
        - CASE WHEN p_config_330_redIcmsBasePisCof = 1 AND p_cab_entradaSaida = CASE WHEN p_cab_devolucaoAnulacaoRetorno = 1 THEN 'E' ELSE 'S' END THEN r_valorICMS ELSE 0 END;
      r_valorPISST := ROUND ((r_basePISST * p_aliquotaPISST / 100), 2);
    ELSE
      r_basePISST := 0;
      r_valorPISST := 0;
    END IF;
    IF p_valorAliquotaPISST > 0 THEN
      r_valorPISST := ROUND ((r_valorPISST + (p_quantidade * p_valorAliquotaPISST)), 2);
    END IF;
  END IF;
  /* COFINS */
  IF p_calcularCOFINS = 1 THEN
    IF p_aliquotaCOFINS > 0 THEN
      r_baseCOFINS :=
        p_valorProdutoServico
        + CASE WHEN p_cab_tipoPagamentoFrete = 'V' THEN 0 ELSE p_valorFreteTotal + p_valorSeguroTotal END
        - p_valorDescontoTotal
        + p_valorOutrasDespesasTotal
        + p_valorAdicFreteMarinMerTotal
        + p_valorDespesasAduaneirasTotal
        + r_valorII
        + r_valorIOF
        - CASE WHEN p_config_330_redIcmsBasePisCof = 1 AND p_cab_entradaSaida = CASE WHEN p_cab_devolucaoAnulacaoRetorno = 1 THEN 'E' ELSE 'S' END THEN r_valorICMS ELSE 0 END;
      r_valorCOFINS := ROUND ((r_baseCOFINS * p_aliquotaCOFINS / 100), 2);
    ELSE
      r_baseCOFINS := 0;
      r_valorCOFINS := 0;
    END IF;
    IF p_valorAliquotaCOFINS > 0 THEN
      r_valorCOFINS := ROUND ((r_valorCOFINS + (p_quantidade * p_valorAliquotaCOFINS)), 2);
    END IF;
  END IF;
  /* COFINS ST */
  IF p_calcularCOFINSST = 1 THEN
    IF p_aliquotaCOFINSST > 0 THEN
      r_baseCOFINSST :=
        p_valorProdutoServico
        + CASE WHEN p_cab_tipoPagamentoFrete = 'V' THEN 0 ELSE p_valorFreteTotal + p_valorSeguroTotal END
        - p_valorDescontoTotal
        + p_valorOutrasDespesasTotal
        + p_valorAdicFreteMarinMerTotal
        + p_valorDespesasAduaneirasTotal
        + r_valorII
        + r_valorIOF
        - CASE WHEN p_config_330_redIcmsBasePisCof = 1 AND p_cab_entradaSaida = CASE WHEN p_cab_devolucaoAnulacaoRetorno = 1 THEN 'E' ELSE 'S' END THEN r_valorICMS ELSE 0 END;
      r_valorCOFINSST := ROUND ((r_baseCOFINSST * p_aliquotaCOFINSST / 100), 2);
    ELSE
      r_baseCOFINSST := 0;
      r_valorCOFINSST := 0;
    END IF;
    IF p_valorAliquotaCOFINSST > 0 THEN
      r_valorCOFINSST := ROUND ((r_valorCOFINSST + (p_quantidade * p_valorAliquotaCOFINSST)), 2);
    END IF;
  END IF;
  /* Impostos Estimados */
  IF p_calcularImpostosEstimados = 1 THEN
    IF p_aliquotaEstImpFederais > 0 OR p_aliquotaEstImpEstaduais > 0 OR p_aliquotaEstImpMunicipais > 0 THEN
      r_baseEstimadaImpostos :=
        p_valorProdutoServico
        + CASE WHEN p_cab_tipoPagamentoFrete = 'V' THEN 0 ELSE p_valorFreteTotal + p_valorSeguroTotal END
        - p_valorDescontoTotal
        + p_valorOutrasDespesasTotal;
      r_valorEstimadoImpFederais := ROUND ((r_baseEstimadaImpostos * p_aliquotaEstImpFederais / 100), 2);
      r_valorEstimadoImpEstaduais := ROUND ((r_baseEstimadaImpostos * p_aliquotaEstImpEstaduais / 100), 2);
      r_valorEstimadoImpMunicipais := ROUND ((r_baseEstimadaImpostos * p_aliquotaEstImpMunicipais / 100), 2);
    ELSE
      r_baseEstimadaImpostos := 0;
      r_valorEstimadoImpFederais := 0;
      r_valorEstimadoImpEstaduais := 0;
      r_valorEstimadoImpMunicipais := 0;
    END IF;
  END IF;
END ADD_CALCULA_IMPOSTOS_ITEM;

/

create or replace PROCEDURE ADD_ORCAMENTO_PARCELAS_INSERE (
    p_uniqueMachineID              IN VARCHAR2,
    p_estabelecimentoAtivo         IN NUMBER,
    p_contadorSessaoParcelas       IN NUMBER,
    p_pag_idPagamentoOrcamento     IN NUMBER)
IS
    v_pag_orcamento                NUMBER;
    v_pag_pagamentoTroco           CHAR (1);
    v_pag_sequencia                NUMBER;
    v_pag_meioPagamento            NUMBER;
    v_pag_cobranca                 NUMBER;
    v_pag_numeroParcelas           NUMBER;    
    v_cab_idDocumento              NUMBER;
    v_cab_entradaSaida             CHAR (1);
    v_cab_estabelecimento          NUMBER;
    v_cab_dataEmissao              DATE;
    v_cab_pessoa                   NUMBER;
    v_cab_autorizadoPessoa         NUMBER;
    v_cab_contaFinanceira          VARCHAR2 (60);    
    v_cond_contaFinanceira         VARCHAR2 (60);
    v_cond_carteiraFinanceira      NUMBER;
    v_cond_tarifaDescontoAteVenc   NUMBER;
    v_cond_tipoPagamentoAntecipado CHAR (1);
    v_cond_tarifaMensalDescAntecip NUMBER;
    v_cond_tipoJuroDeMora          CHAR (1);
    v_cond_tarifaMensalJuroDeMora  NUMBER;
    v_cond_tarifaMulta             NUMBER;    
    v_cond_valorFixoMulta          NUMBER;    
    v_parcela                      NUMBER;    
    v_idPrevisaoFinanceira         NUMBER;
BEGIN
  SELECT
    pag.orcamento,
    pag.pagamentoTroco,
    pag.sequencia,
    pag.meioPagamento,
    pag.cobranca,
    pag.numeroParcelas,
    orc.idDocumento,
    orc.entradaSaida,
    orc.estabelecimento,
    orc.dataEmissao,
    orc.pessoa,
    orc.autorizadoPessoa,
    orc.contaFinanceira,
    cond.contaFinanceira,
    cond.carteiraFinanceira,
    cond.tarifaDescontoAteVencimento,
    cond.tipoPagamentoAntecipado,
    cond.tarifaMensalDescontoAntecipado,
    cond.tipoJuroDeMora,
    cond.tarifaMensalJuroDeMora,
    cond.tarifaMulta,
    cond.valorFixoMulta
  INTO
    v_pag_orcamento,
    v_pag_pagamentoTroco,
    v_pag_sequencia,
    v_pag_meioPagamento,
    v_pag_cobranca,
    v_pag_numeroParcelas,
    v_cab_idDocumento,
    v_cab_entradaSaida,
    v_cab_estabelecimento,
    v_cab_dataEmissao,
    v_cab_pessoa,
    v_cab_autorizadoPessoa,
    v_cab_contaFinanceira,
    v_cond_contaFinanceira,
    v_cond_carteiraFinanceira,
    v_cond_tarifaDescontoAteVenc,
    v_cond_tipoPagamentoAntecipado,
    v_cond_tarifaMensalDescAntecip,
    v_cond_tipoJuroDeMora,
    v_cond_tarifaMensalJuroDeMora,
    v_cond_tarifaMulta,
    v_cond_valorFixoMulta
  FROM MOORCAMENTOXPAGAMENTOS pag
  JOIN MOORCAMENTOS orc
  ON orc.orcamento = pag.orcamento
  JOIN PACONDICOESPAGAMENTO cond
  ON cond.condicaoPagamento = pag.condicaoPagamento
  WHERE pag.idPagamentoOrcamento = p_pag_idPagamentoOrcamento;
  v_parcela := 0;
  FOR temp IN (
    SELECT
      prazoPadrao,
      vencimento,
      valor,
      complementoFinanceiro,
      chequeBomPara
    FROM TEMPPARCELAS
    WHERE uniqueMachineID = p_uniqueMachineID
    AND contadorSessao = p_contadorSessaoParcelas
    AND origem = 'O'
    AND idCabecalho = v_pag_orcamento
    AND pagamentoTroco = v_pag_pagamentoTroco
    AND sequencia = v_pag_sequencia
    AND valor > 0
    ORDER BY parcela)
  LOOP
    v_parcela := v_parcela + 1;
    ADD_PREVFIN_GRAVA (
      p_estabelecimentoAtivo,
      0,
      v_cab_estabelecimento,
      v_cab_dataEmissao,
      temp.prazoPadrao,
      (TRUNC(CASE WHEN v_pag_meioPagamento IN (41,42,43) THEN temp.chequeBomPara ELSE temp.vencimento END) - TRUNC(v_cab_dataEmissao)),
      (CASE WHEN v_pag_meioPagamento IN (41,42,43) THEN temp.chequeBomPara ELSE temp.vencimento END),
      (CASE WHEN v_cab_contaFinanceira = ' ' THEN v_cond_contaFinanceira ELSE v_cab_contaFinanceira END),
      (CASE WHEN v_pag_pagamentoTroco = 'T' THEN 'P' ELSE (CASE WHEN v_cab_entradaSaida = 'E' THEN 'P' ELSE 'R' END) END),
      (CASE WHEN v_pag_pagamentoTroco = 'T' THEN 22 ELSE (CASE WHEN v_cab_entradaSaida = 'E' THEN 51 ELSE 21 END) END),
      temp.complementoFinanceiro,
      p_pag_idPagamentoOrcamento,
      TRIM (TO_CHAR (v_cab_idDocumento)),
      TRIM (TO_CHAR (v_cab_idDocumento)),
      v_parcela,
      v_pag_numeroParcelas,
      v_cab_pessoa,
      v_cab_autorizadoPessoa,
      v_pag_cobranca,
      v_pag_meioPagamento,
      v_cond_carteiraFinanceira,
      temp.valor,
      temp.valor,
      ' ',
      0,
      0,
      0,
      0,
      v_cond_tarifaDescontoAteVenc,
      v_cond_tipoPagamentoAntecipado,
      v_cond_tarifaMensalDescAntecip,
      v_cond_tipoJuroDeMora,
      v_cond_tarifaMensalJuroDeMora,
      v_cond_tarifaMulta,
      v_cond_valorFixoMulta,
      0,
      0,
      /* Retornos */
      v_idPrevisaoFinanceira);
      UPDATE TEMPPARCELAS
      SET idPrevisaoFinanceira = v_idPrevisaoFinanceira
      WHERE uniqueMachineID = p_uniqueMachineID
      AND contadorSessao = p_contadorSessaoParcelas
      AND origem = 'O'
      AND idCabecalho = v_pag_orcamento
      AND pagamentoTroco = v_pag_pagamentoTroco
      AND sequencia = v_pag_sequencia
      AND parcela = v_parcela;
  END LOOP;
END ADD_ORCAMENTO_PARCELAS_INSERE;

/

DECLARE
  CURSOR c_pag IS
    SELECT a.idPagamentoDocFiscal
    FROM MODOCFISCALXPAGAMENTOS a
    JOIN MODOCUMENTOSFISCAIS b
    ON b.idDocumentoFiscal = a.idDocumentoFiscal
    WHERE b.situacaoDocumentoFiscal IN (33,43,53)
    AND EXISTS(
      SELECT c.idFinanceiro
      FROM MOFINANCEIROS c
      WHERE c.idPagamentoDocFiscal = a.idPagamentoDocFiscal);
BEGIN
  FOR a IN c_pag
  LOOP
    ADD_MODOCFISCALXPAGAMENTOS_E_C (a.idPagamentoDocFiscal);
  END LOOP;
  COMMIT;
END;

/

DECLARE
  CURSOR c_pag IS
    SELECT a.idPagamentoPreDocumento
    FROM MOPREDOCUMXPAGAMENTOS a
    JOIN MOPREDOCUMENTOS b
    ON b.preDocumento = a.preDocumento
    WHERE b.statusPreDocumento = 'C'
    AND EXISTS(
      SELECT c.idFinanceiro
      FROM MOFINANCEIROS c
      WHERE c.idPagamentoPreDocumento = a.idPagamentoPreDocumento);
BEGIN
  FOR a IN c_pag
  LOOP
    ADD_MOPREDOCUMXPAGAMENTOS_ECOR (a.idPagamentoPreDocumento);
  END LOOP;
  COMMIT;
END;

/

UPDATE SISPCENTIDADES SET ativo = 0 WHERE entidadeSPC = 2;

COMMIT;

UPDATE SISPCENTIDADEXMODELOSCONS SET ativo = 0 WHERE entidadeXModeloConsultaSPC = 2065;

COMMIT;

INSERT INTO SISPCENTIDADEXMODELOSCONS (entidadeXModeloConsultaSPC, descricao, ativo, entidadeSPC, modeloConsultaSPC, observacoes) VALUES (1323, 'SPC BRASIL - 323 - SPC Mix Mais', 1, 1, 323, ' ');

COMMIT;

/

INSERT INTO SIVERSOESSISTEMA (idVersaoSistema, versaoAplicativo, dataLiberacaoVersao, possuiConversaoTabelas, atualizada, dataAtualizacaoVersao, observacoes) VALUES (2023002011, '2023.2.11', TO_DATE('10/04/2023','DD/MM/YYYY'), 1, 1, sysdate, ' ');

COMMIT;

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

/*
*/