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

/

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

/

create or replace PROCEDURE ADD_PRE_DOC_ITEM_REF_ORCAMEN (
  p_usuarioLogado                IN NUMBER,
  p_estabelecimentoAtivo         IN NUMBER,
  p_config_227_manterPessoaOrcam IN NUMBER,
  p_cab_preDocumento             IN NUMBER,
  p_cab_tipoDocumento            IN NUMBER,
  p_cab_documentoFiscal          IN NUMBER,
  p_cab_estabelecimento          IN NUMBER,
  p_cab_pessoa                   IN NUMBER,
  p_item_idItemPreDocumento      IN NUMBER,
  p_item_sequencia               IN NUMBER,
  p_item_vendedor                IN NUMBER,
  p_item_gradeProduto            IN NUMBER,
  p_item_unidadeMedidaConversao  IN VARCHAR,
  p_item_quantidadeConvertida    IN NUMBER,
  p_item_valorLiquidoItem        IN NUMBER,
  p_idItemOrcamento              IN NUMBER,
  p_quantidadeBaixar             IN NUMBER,
  p_atualizarObservacoes         IN NUMBER,
  /* Retornos */
  r_atualizarObservacoes         OUT NUMBER)
IS
  v_id                    NUMBER;
  v_orcamentoReferenciado NUMBER;
  v_sequenciaReferenciado NUMBER;
  v_orc_pessoa            NUMBER;
  v_auxAlpha              VARCHAR (3200);
BEGIN
  r_atualizarObservacoes := p_atualizarObservacoes;
  ADD_PRE_DOC_ITEM_N_SER_ORCAMEN (
    p_estabelecimentoAtivo,
    p_idItemOrcamento,
    p_item_idItemPreDocumento,
    CASE WHEN p_quantidadeBaixar > 0 THEN 1 ELSE 0 END,
    r_atualizarObservacoes,
    r_atualizarObservacoes);
  ADD_PRE_DOC_ITEM_CUSTO_ORCAMEN (
    p_estabelecimentoAtivo,
    p_idItemOrcamento,
    p_item_idItemPreDocumento);
  ADD_PRE_DOC_ITEM_COMP_ORCAMEN (
    p_estabelecimentoAtivo,
    p_idItemOrcamento,
    p_item_idItemPreDocumento,
    r_atualizarObservacoes,
    r_atualizarObservacoes);
  SELECT COALESCE (MAX (id),0)
  INTO v_id
  FROM MOPREDOCUMXORCAMENTOITEM
  WHERE idItemPreDocumento = p_item_idItemPreDocumento
  AND idItemOrcamento = p_idItemOrcamento;
  IF v_id > 0 THEN
    IF p_quantidadeBaixar <> 0 THEN
      UPDATE MOPREDOCUMXORCAMENTOITEM SET
        quantidade = quantidade + p_quantidadeBaixar
      WHERE id = v_id;
    END IF;
  ELSE
    v_id := FUNC_ADD_BUSCA_PROXIMO_ID ('MOPREDOCUMXORCAMENTOITEM', 'id', 14, p_estabelecimentoAtivo, NULL);
    INSERT INTO MOPREDOCUMXORCAMENTOITEM (
      id,
      idItemPreDocumento,
      idItemOrcamento,
      quantidade,
      efetivacao)
    VALUES (
      v_id,
      p_item_idItemPreDocumento,
      p_idItemOrcamento,
      p_quantidadeBaixar,
      1);
  END IF;
  IF p_quantidadeBaixar <> 0 THEN
    SELECT
      orcamento,
      sequencia
    INTO
      v_orcamentoReferenciado,
      v_sequenciaReferenciado
    FROM MOORCAMENTOXITENS
    WHERE idItemOrcamento = p_idItemOrcamento;
    ADD_PRE_DOC_ITEM_BLOEST_ORC (
      p_estabelecimentoAtivo,
      v_orcamentoReferenciado,
      v_sequenciaReferenciado,
      p_cab_preDocumento,
      p_item_sequencia);
    v_orc_pessoa := 0;
    IF p_config_227_manterPessoaOrcam = 1 THEN
      SELECT COALESCE(MAX(orc.pessoa),0)
      INTO v_orc_pessoa
      FROM MOPREDOCUMXITENS itemDoc
      JOIN MOPREDOCUMXORCAMENTOITEM docXOrc
      ON docXOrc.idItemPreDocumento = itemDoc.idItemPreDocumento
      JOIN MOORCAMENTOXITENS itemOrc
      ON itemOrc.idItemOrcamento = docXOrc.idItemOrcamento
      JOIN MOORCAMENTOS orc
      ON orc.orcamento = itemOrc.orcamento
      WHERE itemDoc.preDocumento = p_cab_preDocumento
      AND docXOrc.quantidade <> 0;
    END IF;
    ADD_PRE_DOC_ITEM_MOT_ORCAMEN (
      p_estabelecimentoAtivo,
      p_config_227_manterPessoaOrcam,
      p_cab_preDocumento,
      p_cab_tipoDocumento,
      p_cab_documentoFiscal,
      p_cab_estabelecimento,
      p_cab_pessoa,
      v_orc_pessoa,
      p_item_idItemPreDocumento,
      p_item_sequencia,
      p_item_vendedor,
      p_item_gradeProduto,
      p_item_unidadeMedidaConversao,
      p_item_quantidadeConvertida,
      p_item_valorLiquidoItem,
      p_idItemOrcamento);
    UPDATE MOORCAMENTOXITENS
    SET quantidadeSaldo = quantidadeSaldo - p_quantidadeBaixar
    WHERE idItemOrcamento = p_idItemOrcamento;
    UPDATE MOCONSERTOS cons
    SET cons.situacaoConserto = 'R'
    WHERE cons.documentoTransferenciaFornec > 0
    AND cons.situacaoConserto = 'E'
    AND EXISTS (
      SELECT 1 FROM MODOCUMENTOTRANSFXITENS itemTransf
      JOIN MODOCTRANSFXORCAMENTOITEM transfXDoc
      ON transfXDoc.idItemDocTransferencia = itemTransf.idItemDocTransferencia
      WHERE itemTransf.documentoTransferencia = cons.documentoTransferenciaFornec
      AND transfXDoc.entradaSaidaOriginal = 'E'
      AND transfXDoc.idItemOrcamento = p_idItemOrcamento);
    ADD_ENTREGA_CRIA_PENDENTE (
      p_usuarioLogado,
      p_estabelecimentoAtivo,
      p_idItemOrcamento);
    ADD_ORCAMENTO_ITEM_RES_ITEM (
      p_idItemOrcamento,
      p_estabelecimentoAtivo,
      '',
      v_auxAlpha);
  END IF;
END ADD_PRE_DOC_ITEM_REF_ORCAMEN;

/

create or replace PROCEDURE ADD_PRE_DOC_ITEM_REF_PRE_DOC (
  p_estabelecimentoAtivo         IN NUMBER,
  p_config_227_manterPessoaOrcam IN NUMBER,
  p_cab_preDocumento             IN NUMBER,
  p_cab_tipoDocumento            IN NUMBER,
  p_cab_documentoFiscal          IN NUMBER,
  p_cab_estabelecimento          IN NUMBER,
  p_cab_pessoa                   IN NUMBER,
  p_item_idItemPreDocumento      IN NUMBER,
  p_item_sequencia               IN NUMBER,
  p_item_vendedor                IN NUMBER,
  p_item_gradeProduto            IN NUMBER,
  p_item_unidadeMedidaConversao  IN VARCHAR,
  p_item_quantidadeConvertida    IN NUMBER,
  p_item_valorLiquidoItem        IN NUMBER,
  p_idItemPreDocumentoReferenc   IN NUMBER,
  p_quantidadeReferenciada       IN NUMBER,
  p_atualizarObservacoes         IN NUMBER,
  /* Retornos */
  r_atualizarObservacoes         OUT NUMBER)
IS
  v_id                       NUMBER;
  v_preDocumentoReferenciado NUMBER;
  v_sequenciaReferenciado    NUMBER;
  v_orc_pessoa               NUMBER;
  v_auxAlpha                 VARCHAR (3200);
BEGIN
  r_atualizarObservacoes := p_atualizarObservacoes;
  ADD_PRE_DOC_ITEM_N_SER_PRE_DOC (
    p_estabelecimentoAtivo,
    p_idItemPreDocumentoReferenc,
    p_item_idItemPreDocumento,
    CASE WHEN p_quantidadeReferenciada > 0 THEN 1 ELSE 0 END,
    r_atualizarObservacoes,
    r_atualizarObservacoes);
  ADD_PRE_DOC_ITEM_CUSTO_PRE_DOC (
    p_estabelecimentoAtivo,
    p_idItemPreDocumentoReferenc,
    p_item_idItemPreDocumento);
  ADD_PRE_DOC_ITEM_COMP_PRE_DOC (
    p_estabelecimentoAtivo,
    p_idItemPreDocumentoReferenc,
    p_item_idItemPreDocumento,
    r_atualizarObservacoes,
    r_atualizarObservacoes);
  IF p_quantidadeReferenciada = 0 THEN
    v_orc_pessoa := 0;
    IF p_config_227_manterPessoaOrcam = 1 THEN
      SELECT COALESCE(MAX(orc.pessoa),0)
      INTO v_orc_pessoa
      FROM MOPREDOCUMXITENS itemDoc
      JOIN MOPREDOCUMXORCAMENTOITEM docXOrc
      ON docXOrc.idItemPreDocumento = itemDoc.idItemPreDocumento
      JOIN MOORCAMENTOXITENS itemOrc
      ON itemOrc.idItemOrcamento = docXOrc.idItemOrcamento
      JOIN MOORCAMENTOS orc
      ON orc.orcamento = itemOrc.orcamento
      WHERE itemDoc.preDocumento = p_cab_preDocumento
      AND docXOrc.quantidade <> 0;
    END IF;
    ADD_PRE_DOC_ITEM_MOT_PRE_DOC (
      p_estabelecimentoAtivo,
      p_config_227_manterPessoaOrcam,
      p_cab_preDocumento,
      p_cab_tipoDocumento,
      p_cab_documentoFiscal,
      p_cab_estabelecimento,
      p_cab_pessoa,
      v_orc_pessoa,
      p_item_idItemPreDocumento,
      p_item_sequencia,
      p_item_vendedor,
      p_item_gradeProduto,
      p_item_unidadeMedidaConversao,
      p_item_quantidadeConvertida,
      p_item_valorLiquidoItem,
      p_idItemPreDocumentoReferenc);
  ELSE
    SELECT
      preDocumento,
      sequencia
    INTO
      v_preDocumentoReferenciado,
      v_sequenciaReferenciado
    FROM MOPREDOCUMXITENS
    WHERE idItemPreDocumento = p_idItemPreDocumentoReferenc;
    ADD_PRE_DOC_ITEM_BLOEST_PRE (
      p_estabelecimentoAtivo,
      v_preDocumentoReferenciado,
      v_sequenciaReferenciado,
      p_cab_preDocumento,
      p_item_sequencia);
    SELECT COALESCE (MAX (id),0)
    INTO v_id
    FROM MOPREDOCUMXPREDOCUM
    WHERE idItemPreDocumento = p_item_idItemPreDocumento
    AND idItemPreDocReferenciado = p_idItemPreDocumentoReferenc;
    IF v_id > 0 THEN
      IF p_quantidadeReferenciada <> 0 THEN
        UPDATE MOPREDOCUMXPREDOCUM SET
          quantidade = quantidade + p_quantidadeReferenciada
        WHERE id = v_id;
      END IF;
    ELSE
      v_id := FUNC_ADD_BUSCA_PROXIMO_ID ('MOPREDOCUMXPREDOCUM', 'id', 14, p_estabelecimentoAtivo, NULL);
      INSERT INTO MOPREDOCUMXPREDOCUM (
        id,
        idItemPreDocumento,
        idItemPreDocReferenciado,
        quantidade)
      VALUES (
        v_id,
        p_item_idItemPreDocumento,
        p_idItemPreDocumentoReferenc,
        p_quantidadeReferenciada);
    END IF;
  END IF;
END ADD_PRE_DOC_ITEM_REF_PRE_DOC;

/

create or replace PROCEDURE ADD_PRE_DOC_ITEM_REF_DOC_FIS (
  p_estabelecimentoAtivo         IN NUMBER,
  p_config_227_manterPessoaOrcam IN NUMBER,
  p_cab_preDocumento             IN NUMBER,
  p_cab_tipoDocumento            IN NUMBER,
  p_cab_documentoFiscal          IN NUMBER,
  p_cab_estabelecimento          IN NUMBER,
  p_cab_pessoa                   IN NUMBER,
  p_item_idItemPreDocumento      IN NUMBER,
  p_item_sequencia               IN NUMBER,
  p_item_vendedor                IN NUMBER,
  p_item_gradeProduto            IN NUMBER,
  p_item_unidadeMedidaConversao  IN VARCHAR,
  p_item_quantidadeConvertida    IN NUMBER,
  p_item_valorLiquidoItem        IN NUMBER,
  p_idItemDocFiscalReferenciado  IN NUMBER,
  p_quantidadeReferenciada       IN NUMBER,
  p_atualizarObservacoes         IN NUMBER,
  /* Retornos */
  r_atualizarObservacoes         OUT NUMBER)
IS
  v_id                           NUMBER;
  v_idDocumentoFiscalReferenciad NUMBER;
  v_sequenciaReferenciado        NUMBER;
  v_orc_pessoa                   NUMBER;
  v_auxAlpha                     VARCHAR (3200);
BEGIN
  r_atualizarObservacoes := p_atualizarObservacoes;
  ADD_PRE_DOC_ITEM_N_SER_DOC_FIS (
    p_estabelecimentoAtivo,
    p_idItemDocFiscalReferenciado,
    p_item_idItemPreDocumento,
    CASE WHEN p_quantidadeReferenciada > 0 THEN 1 ELSE 0 END,
    r_atualizarObservacoes,
    r_atualizarObservacoes);
  ADD_PRE_DOC_ITEM_CUSTO_DOC_FIS (
    p_estabelecimentoAtivo,
    p_idItemDocFiscalReferenciado,
    p_item_idItemPreDocumento);
  ADD_PRE_DOC_ITEM_COMP_DOC_FIS (
    p_estabelecimentoAtivo,
    p_idItemDocFiscalReferenciado,
    p_item_idItemPreDocumento,
    r_atualizarObservacoes,
    r_atualizarObservacoes);
  IF p_quantidadeReferenciada = 0 THEN
    v_orc_pessoa := 0;
    IF p_config_227_manterPessoaOrcam = 1 THEN
      SELECT COALESCE(MAX(orc.pessoa),0)
      INTO v_orc_pessoa
      FROM MOPREDOCUMXITENS itemDoc
      JOIN MOPREDOCUMXORCAMENTOITEM docXOrc
      ON docXOrc.idItemPreDocumento = itemDoc.idItemPreDocumento
      JOIN MOORCAMENTOXITENS itemOrc
      ON itemOrc.idItemOrcamento = docXOrc.idItemOrcamento
      JOIN MOORCAMENTOS orc
      ON orc.orcamento = itemOrc.orcamento
      WHERE itemDoc.preDocumento = p_cab_preDocumento
      AND docXOrc.quantidade <> 0;
    END IF;
    ADD_PRE_DOC_ITEM_MOT_DOC_FIS (
      p_estabelecimentoAtivo,
      p_config_227_manterPessoaOrcam,
      p_cab_preDocumento,
      p_cab_tipoDocumento,
      p_cab_documentoFiscal,
      p_cab_estabelecimento,
      p_cab_pessoa,
      v_orc_pessoa,
      p_item_idItemPreDocumento,
      p_item_sequencia,
      p_item_vendedor,
      p_item_gradeProduto,
      p_item_unidadeMedidaConversao,
      p_item_quantidadeConvertida,
      p_item_valorLiquidoItem,
      p_idItemDocFiscalReferenciado);
  ELSE
    SELECT
      idDocumentoFiscal,
      sequencia
    INTO
      v_idDocumentoFiscalReferenciad,
      v_sequenciaReferenciado
    FROM MODOCFISCALXITENS
    WHERE idItemDocFiscal = p_idItemDocFiscalReferenciado;
    ADD_PRE_DOC_ITEM_BLOEST_DOC (
      p_estabelecimentoAtivo,
      v_idDocumentoFiscalReferenciad,
      v_sequenciaReferenciado,
      p_cab_preDocumento,
      p_item_sequencia);
    SELECT COALESCE (MAX (id),0)
    INTO v_id
    FROM MOPREDOCUMXDOCFISCAL
    WHERE idItemPreDocumento = p_item_idItemPreDocumento
    AND idItemDocFiscalReferenciado = p_idItemDocFiscalReferenciado;
    IF v_id > 0 THEN
      IF p_quantidadeReferenciada <> 0 THEN
        UPDATE MOPREDOCUMXDOCFISCAL SET
          quantidade = quantidade + p_quantidadeReferenciada
        WHERE id = v_id;
      END IF;
    ELSE
      v_id := FUNC_ADD_BUSCA_PROXIMO_ID ('MOPREDOCUMXDOCFISCAL', 'id', 14, p_estabelecimentoAtivo, NULL);
      INSERT INTO MOPREDOCUMXDOCFISCAL (
        id,
        idItemPreDocumento,
        idItemDocFiscalReferenciado,
        quantidade)
      VALUES (
        v_id,
        p_item_idItemPreDocumento,
        p_idItemDocFiscalReferenciado,
        p_quantidadeReferenciada);
    END IF;
  END IF;
END ADD_PRE_DOC_ITEM_REF_DOC_FIS;

/

create or replace PROCEDURE ADD_DOC_FISC_ITEM_REF_ORCAMEN (
  p_usuarioLogado                IN NUMBER,
  p_estabelecimentoAtivo         IN NUMBER,
  p_config_227_manterPessoaOrcam IN NUMBER,
  p_cab_idDocumentoFiscal        IN NUMBER,
  p_cab_tipoDocumento            IN NUMBER,
  p_cab_documentoFiscal          IN NUMBER,
  p_cab_estabelecimento          IN NUMBER,
  p_cab_pessoa                   IN NUMBER,
  p_item_idItemDocFiscal         IN NUMBER,
  p_item_sequencia               IN NUMBER,
  p_item_vendedor                IN NUMBER,
  p_item_gradeProduto            IN NUMBER,
  p_item_unidadeMedidaConversao  IN VARCHAR,
  p_item_quantidadeConvertida    IN NUMBER,
  p_item_valorLiquidoItem        IN NUMBER,
  p_idItemOrcamento              IN NUMBER,
  p_quantidadeBaixar             IN NUMBER,
  p_atualizarObservacoes         IN NUMBER,
  /* Retornos */
  r_atualizarObservacoes         OUT NUMBER)
IS
  v_id                    NUMBER;
  v_orcamentoReferenciado NUMBER;
  v_sequenciaReferenciado NUMBER;
  v_orc_pessoa            NUMBER;
  v_auxAlpha              VARCHAR (3200);
BEGIN
  r_atualizarObservacoes := p_atualizarObservacoes;
  ADD_DOC_FISC_ITEM_N_SER_ORCAM (
    p_estabelecimentoAtivo,
    p_idItemOrcamento,
    p_item_idItemDocFiscal,
    CASE WHEN p_quantidadeBaixar > 0 THEN 1 ELSE 0 END,
    r_atualizarObservacoes,
    r_atualizarObservacoes);
  ADD_DOC_FISC_ITEM_CUSTO_ORCAM (
    p_estabelecimentoAtivo,
    p_idItemOrcamento,
    p_item_idItemDocFiscal);
  ADD_DOC_FISC_ITEM_COMP_ORCAMEN (
    p_estabelecimentoAtivo,
    p_idItemOrcamento,
    p_item_idItemDocFiscal,
    r_atualizarObservacoes,
    r_atualizarObservacoes);
  SELECT COALESCE (MAX (id),0)
  INTO v_id
  FROM MODOCFISCALXORCAMENTOITEM
  WHERE idItemDocFiscal = p_item_idItemDocFiscal
  AND idItemOrcamento = p_idItemOrcamento;
  IF v_id > 0 THEN
    IF p_quantidadeBaixar <> 0 THEN
      UPDATE MODOCFISCALXORCAMENTOITEM SET
        quantidade = quantidade + p_quantidadeBaixar
      WHERE id = v_id;
    END IF;
  ELSE
    v_id := FUNC_ADD_BUSCA_PROXIMO_ID ('MODOCFISCALXORCAMENTOITEM', 'id', 14, p_estabelecimentoAtivo, NULL);
    INSERT INTO MODOCFISCALXORCAMENTOITEM (
      id,
      idItemDocFiscal,
      idItemOrcamento,
      quantidade,
      efetivacao)
    VALUES (
      v_id,
      p_item_idItemDocFiscal,
      p_idItemOrcamento,
      p_quantidadeBaixar,
      1);
  END IF;
  IF p_quantidadeBaixar <> 0 THEN
    SELECT
      orcamento,
      sequencia
    INTO
      v_orcamentoReferenciado,
      v_sequenciaReferenciado
    FROM MOORCAMENTOXITENS
    WHERE idItemOrcamento = p_idItemOrcamento;
    ADD_DOC_FISC_ITEM_BLOEST_ORC (
      p_estabelecimentoAtivo,
      v_orcamentoReferenciado,
      v_sequenciaReferenciado,
      p_cab_idDocumentoFiscal,
      p_item_sequencia);
    v_orc_pessoa := 0;
    IF p_config_227_manterPessoaOrcam = 1 THEN
      SELECT COALESCE(MAX(orc.pessoa),0)
      INTO v_orc_pessoa
      FROM MODOCFISCALXITENS itemDoc
      JOIN MODOCFISCALXORCAMENTOITEM docXOrc
      ON docXOrc.idItemDocFiscal = itemDoc.idItemDocFiscal
      JOIN MOORCAMENTOXITENS itemOrc
      ON itemOrc.idItemOrcamento = docXOrc.idItemOrcamento
      JOIN MOORCAMENTOS orc
      ON orc.orcamento = itemOrc.orcamento
      WHERE itemDoc.idDocumentoFiscal = p_cab_idDocumentoFiscal
      AND docXOrc.quantidade <> 0;
    END IF;
    ADD_DOC_FISC_ITEM_MOT_ORCAMEN (
      p_estabelecimentoAtivo,
      p_config_227_manterPessoaOrcam,
      p_cab_idDocumentoFiscal,
      p_cab_tipoDocumento,
      p_cab_documentoFiscal,
      p_cab_estabelecimento,
      p_cab_pessoa,
      v_orc_pessoa,
      p_item_idItemDocFiscal,
      p_item_sequencia,
      p_item_vendedor,
      p_item_gradeProduto,
      p_item_unidadeMedidaConversao,
      p_item_quantidadeConvertida,
      p_item_valorLiquidoItem,
      p_idItemOrcamento);
    UPDATE MOORCAMENTOXITENS
    SET quantidadeSaldo = quantidadeSaldo - p_quantidadeBaixar
    WHERE idItemOrcamento = p_idItemOrcamento;
    UPDATE MOCONSERTOS cons
    SET cons.situacaoConserto = 'R'
    WHERE cons.documentoTransferenciaFornec > 0
    AND cons.situacaoConserto = 'E'
    AND EXISTS (
      SELECT 1 FROM MODOCUMENTOTRANSFXITENS itemTransf
      JOIN MODOCTRANSFXORCAMENTOITEM transfXDoc
      ON transfXDoc.idItemDocTransferencia = itemTransf.idItemDocTransferencia
      WHERE itemTransf.documentoTransferencia = cons.documentoTransferenciaFornec
      AND transfXDoc.entradaSaidaOriginal = 'E'
      AND transfXDoc.idItemOrcamento = p_idItemOrcamento);
    ADD_ENTREGA_CRIA_PENDENTE (
      p_usuarioLogado,
      p_estabelecimentoAtivo,
      p_idItemOrcamento);
    ADD_ORCAMENTO_ITEM_RES_ITEM (
      p_idItemOrcamento,
      p_estabelecimentoAtivo,
      '',
      v_auxAlpha);
  END IF;
END ADD_DOC_FISC_ITEM_REF_ORCAMEN;

/

create or replace PROCEDURE ADD_DOC_FISC_ITEM_REF_PRE_DOC (
  p_estabelecimentoAtivo         IN NUMBER,
  p_config_227_manterPessoaOrcam IN NUMBER,
  p_cab_idDocumentoFiscal        IN NUMBER,
  p_cab_tipoDocumento            IN NUMBER,
  p_cab_documentoFiscal          IN NUMBER,
  p_cab_estabelecimento          IN NUMBER,
  p_cab_pessoa                   IN NUMBER,
  p_item_idItemDocFiscal         IN NUMBER,
  p_item_sequencia               IN NUMBER,
  p_item_vendedor                IN NUMBER,
  p_item_gradeProduto            IN NUMBER,
  p_item_unidadeMedidaConversao  IN VARCHAR,
  p_item_quantidadeConvertida    IN NUMBER,
  p_item_valorLiquidoItem        IN NUMBER,
  p_idItemPreDocumentoReferenc   IN NUMBER,
  p_quantidadeReferenciada       IN NUMBER,
  p_atualizarObservacoes         IN NUMBER,
  /* Retornos */
  r_atualizarObservacoes         OUT NUMBER)
IS
  v_id                       NUMBER;
  v_preDocumentoReferenciado NUMBER;
  v_sequenciaReferenciado    NUMBER;
  v_orc_pessoa               NUMBER;
  v_auxAlpha                 VARCHAR (3200);
BEGIN
  r_atualizarObservacoes := p_atualizarObservacoes;
  ADD_DOC_FISC_ITEM_N_SER_PRE (
    p_estabelecimentoAtivo,
    p_idItemPreDocumentoReferenc,
    p_item_idItemDocFiscal,
    CASE WHEN p_quantidadeReferenciada > 0 THEN 1 ELSE 0 END,
    r_atualizarObservacoes,
    r_atualizarObservacoes);
  ADD_DOC_FISC_ITEM_CUSTO_PRE (
    p_estabelecimentoAtivo,
    p_idItemPreDocumentoReferenc,
    p_item_idItemDocFiscal);
  ADD_DOC_FISC_ITEM_COMP_PRE_DOC (
    p_estabelecimentoAtivo,
    p_idItemPreDocumentoReferenc,
    p_item_idItemDocFiscal,
    r_atualizarObservacoes,
    r_atualizarObservacoes);
  IF p_quantidadeReferenciada = 0 THEN
    v_orc_pessoa := 0;
    IF p_config_227_manterPessoaOrcam = 1 THEN
      SELECT COALESCE(MAX(orc.pessoa),0)
      INTO v_orc_pessoa
      FROM MODOCFISCALXITENS itemDoc
      JOIN MODOCFISCALXORCAMENTOITEM docXOrc
      ON docXOrc.idItemDocFiscal = itemDoc.idItemDocFiscal
      JOIN MOORCAMENTOXITENS itemOrc
      ON itemOrc.idItemOrcamento = docXOrc.idItemOrcamento
      JOIN MOORCAMENTOS orc
      ON orc.orcamento = itemOrc.orcamento
      WHERE itemDoc.idDocumentoFiscal = p_cab_idDocumentoFiscal
      AND docXOrc.quantidade <> 0;
    END IF;
    ADD_DOC_FISC_ITEM_MOT_PRE_DOC (
      p_estabelecimentoAtivo,
      p_config_227_manterPessoaOrcam,
      p_cab_idDocumentoFiscal,
      p_cab_tipoDocumento,
      p_cab_documentoFiscal,
      p_cab_estabelecimento,
      p_cab_pessoa,
      v_orc_pessoa,
      p_item_idItemDocFiscal,
      p_item_sequencia,
      p_item_vendedor,
      p_item_gradeProduto,
      p_item_unidadeMedidaConversao,
      p_item_quantidadeConvertida,
      p_item_valorLiquidoItem,
      p_idItemPreDocumentoReferenc);
  ELSE
    SELECT
      preDocumento,
      sequencia
    INTO
      v_preDocumentoReferenciado,
      v_sequenciaReferenciado
    FROM MOPREDOCUMXITENS
    WHERE idItemPreDocumento = p_idItemPreDocumentoReferenc;
    ADD_DOC_FISC_ITEM_BLOEST_PRE (
      p_estabelecimentoAtivo,
      v_preDocumentoReferenciado,
      v_sequenciaReferenciado,
      p_cab_idDocumentoFiscal,
      p_item_sequencia);
    SELECT COALESCE (MAX (id),0)
    INTO v_id
    FROM MODOCFISCALXPREDOCUM
    WHERE idItemDocFiscal = p_item_idItemDocFiscal
    AND idItemPreDocReferenciado = p_idItemPreDocumentoReferenc;
    IF v_id > 0 THEN
      IF p_quantidadeReferenciada <> 0 THEN
        UPDATE MODOCFISCALXPREDOCUM SET
          quantidade = quantidade + p_quantidadeReferenciada
        WHERE id = v_id;
      END IF;
    ELSE
      v_id := FUNC_ADD_BUSCA_PROXIMO_ID ('MODOCFISCALXPREDOCUM', 'id', 14, p_estabelecimentoAtivo, NULL);
      INSERT INTO MODOCFISCALXPREDOCUM (
        id,
        idItemDocFiscal,
        idItemPreDocReferenciado,
        quantidade)
      VALUES (
        v_id,
        p_item_idItemDocFiscal,
        p_idItemPreDocumentoReferenc,
        p_quantidadeReferenciada);
    END IF;
  END IF;
END ADD_DOC_FISC_ITEM_REF_PRE_DOC;

/

create or replace PROCEDURE ADD_DOC_FISC_ITEM_REF_DOC_FIS (
  p_estabelecimentoAtivo         IN NUMBER,
  p_config_227_manterPessoaOrcam IN NUMBER,
  p_cab_idDocumentoFiscal        IN NUMBER,
  p_cab_tipoDocumento            IN NUMBER,
  p_cab_documentoFiscal          IN NUMBER,
  p_cab_estabelecimento          IN NUMBER,
  p_cab_pessoa                   IN NUMBER,
  p_item_idItemDocFiscal         IN NUMBER,
  p_item_sequencia               IN NUMBER,
  p_item_vendedor                IN NUMBER,
  p_item_gradeProduto            IN NUMBER,
  p_item_unidadeMedidaConversao  IN VARCHAR,
  p_item_quantidadeConvertida    IN NUMBER,
  p_item_valorLiquidoItem        IN NUMBER,
  p_idItemDocFiscalReferenciado  IN NUMBER,
  p_quantidadeReferenciada       IN NUMBER,
  p_atualizarObservacoes         IN NUMBER,
  /* Retornos */
  r_atualizarObservacoes         OUT NUMBER)
IS
  v_id                           NUMBER;
  v_idDocumentoFiscalReferenciad NUMBER;
  v_sequenciaReferenciado        NUMBER;
  v_orc_pessoa                   NUMBER;
  v_auxAlpha                     VARCHAR (3200);
BEGIN
  r_atualizarObservacoes := p_atualizarObservacoes;
  ADD_DOC_FISC_ITEM_N_SER_PRE (
    p_estabelecimentoAtivo,
    p_idItemDocFiscalReferenciado,
    p_item_idItemDocFiscal,
    CASE WHEN p_quantidadeReferenciada > 0 THEN 1 ELSE 0 END,
    r_atualizarObservacoes,
    r_atualizarObservacoes);
  ADD_DOC_FISC_ITEM_CUSTO_DOC (
    p_estabelecimentoAtivo,
    p_idItemDocFiscalReferenciado,
    p_item_idItemDocFiscal);
  ADD_DOC_FISC_ITEM_COMP_DOC_FIS (
    p_estabelecimentoAtivo,
    p_idItemDocFiscalReferenciado,
    p_item_idItemDocFiscal,
    r_atualizarObservacoes,
    r_atualizarObservacoes);
  IF p_quantidadeReferenciada = 0 THEN
    v_orc_pessoa := 0;
    IF p_config_227_manterPessoaOrcam = 1 THEN
      SELECT COALESCE(MAX(orc.pessoa),0)
      INTO v_orc_pessoa
      FROM MODOCFISCALXITENS itemDoc
      JOIN MODOCFISCALXORCAMENTOITEM docXOrc
      ON docXOrc.idItemDocFiscal = itemDoc.idItemDocFiscal
      JOIN MOORCAMENTOXITENS itemOrc
      ON itemOrc.idItemOrcamento = docXOrc.idItemOrcamento
      JOIN MOORCAMENTOS orc
      ON orc.orcamento = itemOrc.orcamento
      WHERE itemDoc.idDocumentoFiscal = p_cab_idDocumentoFiscal
      AND docXOrc.quantidade <> 0;
    END IF;
    ADD_DOC_FISC_ITEM_MOT_DOC_FIS (
      p_estabelecimentoAtivo,
      p_config_227_manterPessoaOrcam,
      p_cab_idDocumentoFiscal,
      p_cab_tipoDocumento,
      p_cab_documentoFiscal,
      p_cab_estabelecimento,
      p_cab_pessoa,
      v_orc_pessoa,
      p_item_idItemDocFiscal,
      p_item_sequencia,
      p_item_vendedor,
      p_item_gradeProduto,
      p_item_unidadeMedidaConversao,
      p_item_quantidadeConvertida,
      p_item_valorLiquidoItem,
      p_idItemDocFiscalReferenciado);
  ELSE
    SELECT
      idDocumentoFiscal,
      sequencia
    INTO
      v_idDocumentoFiscalReferenciad,
      v_sequenciaReferenciado
    FROM MODOCFISCALXITENS
    WHERE idItemDocFiscal = p_idItemDocFiscalReferenciado;
    ADD_DOC_FISC_ITEM_BLOEST_DOC (
      p_estabelecimentoAtivo,
      v_idDocumentoFiscalReferenciad,
      v_sequenciaReferenciado,
      p_cab_idDocumentoFiscal,
      p_item_sequencia);
    SELECT COALESCE (MAX (id),0)
    INTO v_id
    FROM MODOCFISCALXDOCFISCAL
    WHERE idItemDocFiscal = p_item_idItemDocFiscal
    AND idItemDocFiscalReferenciado = p_idItemDocFiscalReferenciado;
    IF v_id > 0 THEN
      IF p_quantidadeReferenciada <> 0 THEN
        UPDATE MODOCFISCALXDOCFISCAL SET
          quantidade = quantidade + p_quantidadeReferenciada
        WHERE id = v_id;
      END IF;
    ELSE
      v_id := FUNC_ADD_BUSCA_PROXIMO_ID ('MODOCFISCALXDOCFISCAL', 'id', 14, p_estabelecimentoAtivo, NULL);
      INSERT INTO MODOCFISCALXDOCFISCAL (
        id,
        idItemDocFiscal,
        idItemDocFiscalReferenciado,
        quantidade)
      VALUES (
        v_id,
        p_item_idItemDocFiscal,
        p_idItemDocFiscalReferenciado,
        p_quantidadeReferenciada);
    END IF;
  END IF;
END ADD_DOC_FISC_ITEM_REF_DOC_FIS;

/

create or replace PROCEDURE ADD_DOC_FISC_ITEM_REF_DFE_GRAD (
  p_usuarioLogado                IN NUMBER,
  p_estabelecimentoAtivo         IN NUMBER,
  p_person_190_modeloFrete       IN CHAR,
  p_config_227_manterPessoaOrcam IN NUMBER,
  p_config_230_etapaPedComprParc IN NUMBER,
  p_config_378_calcularVolumes   IN NUMBER,
  p_cab_idDocumentoFiscal        IN NUMBER,
  p_cab_tipoDocumento            IN NUMBER,
  p_cab_documentoFiscal          IN NUMBER,
  p_cab_estabelecimento          IN NUMBER,
  p_cab_pessoa                   IN NUMBER,
  p_item_idItemDocFiscal         IN NUMBER,
  p_item_sequencia               IN NUMBER,
  p_item_vendedor                IN NUMBER,
  p_item_gradeProduto            IN NUMBER,
  p_item_unidadeMedidaConversao  IN VARCHAR,
  p_item_quantidadeConvertida    IN NUMBER,
  p_item_valorLiquidoItem        IN NUMBER,
  p_gradeDistribuicaoDFe         IN NUMBER,
  p_atualizarObservacoes         IN NUMBER,
  /* Retornos */
  r_atualizarObservacoes         OUT NUMBER)
IS
  v_novaEtapaOrcamento NUMBER;
  v_quantidadeSaldo    NUMBER;
  v_auxNumber          NUMBER;
  v_auxChar            CHAR (1);
  v_auxVarchar         VARCHAR2 (32000);
BEGIN
  FOR a IN (
    SELECT
      a.idItemOrcamento,
      a.quantidadeSaldo,
      a.quantidadeBaixar,
      a.zerarSaldo,
      b.orcamento
    FROM MODISTRIBUICAODFEXORCAM a
    JOIN MOORCAMENTOXITENS b
    ON b.idItemOrcamento = a.idItemOrcamento
    WHERE a.gradeDistribuicaoDFe = p_gradeDistribuicaoDFe
    AND a.quantidadeBaixar > 0
    ORDER BY a.sequencia)
  LOOP
    UPDATE MODISTRIBUICAODFEXGRADE
    SET idItemDocFiscal = p_item_idItemDocFiscal
    WHERE gradeDistribuicaoDFe = p_gradeDistribuicaoDFe;
    ADD_DOC_FISC_ITEM_REF_ORCAMEN (
      p_usuarioLogado,
      p_estabelecimentoAtivo,
      p_config_227_manterPessoaOrcam,
      p_cab_idDocumentoFiscal,
      p_cab_tipoDocumento,
      p_cab_documentoFiscal,
      p_cab_estabelecimento,
      p_cab_pessoa,
      p_item_idItemDocFiscal,
      p_item_sequencia,
      p_item_vendedor,
      p_item_gradeProduto,
      p_item_unidadeMedidaConversao,
      p_item_quantidadeConvertida,
      p_item_valorLiquidoItem,
      a.idItemOrcamento,
      CASE WHEN a.zerarSaldo = 1 THEN a.quantidadeSaldo ELSE a.quantidadeBaixar END,
      r_atualizarObservacoes,
      r_atualizarObservacoes);  
    SELECT COALESCE (SUM(b.quantidadeSaldo),0)
    INTO v_quantidadeSaldo
    FROM MOORCAMENTOXITENS b
    WHERE b.orcamento = a.orcamento
    AND b.cancelado = 0;
    IF v_quantidadeSaldo <= 0 THEN
      SELECT COALESCE(MAX(etapaOrcamento),0)
      INTO v_novaEtapaOrcamento
      FROM PAETAPASORCAMENTO
      WHERE etapaOrcamento > 0
      AND ativo = 1
      AND situacaoOrcamento = 80;      
      ADD_ORCAMENTO_CAB_ETAPA_TROCA (
        p_usuarioLogado,
        p_estabelecimentoAtivo,
        p_person_190_modeloFrete,
        p_config_378_calcularVolumes,
        a.orcamento,
        p_usuarioLogado,
        v_novaEtapaOrcamento,
        ' ',
        0,
        0,
        v_auxNumber,
        v_auxVarchar,
        v_auxNumber,
        v_auxChar,
        v_auxNumber);
    ELSE
      v_novaEtapaOrcamento := p_config_230_etapaPedComprParc;
    END IF;  
    IF v_novaEtapaOrcamento <> 0 THEN
      ADD_ORCAMENTO_CAB_ETAPA_TROCA (
        p_usuarioLogado,
        p_estabelecimentoAtivo,
        p_person_190_modeloFrete,
        p_config_378_calcularVolumes,
        a.orcamento,
        p_usuarioLogado,
        v_novaEtapaOrcamento,
        ' ',
        0,
        0,
        v_auxNumber,
        v_auxVarchar,
        v_auxNumber,
        v_auxChar,
        v_auxNumber);
    END IF;
  END LOOP;
END ADD_DOC_FISC_ITEM_REF_DFE_GRAD;

/

DROP PROCEDURE ADD_ORCAMENTO_ITEM_AMB_GRAVA;
DROP PROCEDURE ADD_ORCAMENTO_ITEM_COMPR_GRAVA;
DROP PROCEDURE ADD_PRE_DOC_ITEM_COMPRA_GRAVA;
DROP PROCEDURE ADD_DOC_FISC_ITEM_COMPRA_GRAVA;

create or replace PROCEDURE ADD_ITEM_ALIQUOTA_ESCRITURACAO (
  p_cab_nfFornecedor             IN NUMBER,
  p_item_stSimplesNacional       IN CHAR,
  p_item_creditoSimplesNacional  IN NUMBER,
  p_item_stICMS                  IN CHAR,
  p_item_reducaoBaseICMS         IN NUMBER,
  p_item_aliquotaICMS            IN NUMBER,
  p_item_diferimentoICMS         IN NUMBER,
  p_item_margemValorAdicST       IN NUMBER,
  p_item_reducaoBaseST           IN NUMBER,
  p_item_aliquotaICMSST          IN NUMBER,
  p_prod_tipoProduto             IN CHAR,
  /* Retornos */
  r_item_stICMSEscrit            OUT CHAR,
  r_item_reducaoBaseICMSEscrit   OUT NUMBER,
  r_item_aliquotaICMSEscrit      OUT NUMBER,
  r_item_diferimentoICMSEscrit   OUT NUMBER,
  r_item_margemValorAdicSTEscrit OUT NUMBER,
  r_item_reducaoBaseSTEscrit     OUT NUMBER,
  r_item_aliquotaICMSSTEscrit    OUT NUMBER)
IS
BEGIN
  r_item_stICMSEscrit :=
    CASE
      WHEN p_cab_nfFornecedor = 1 AND p_prod_tipoProduto IN('07','08')
      THEN '90'
      WHEN p_cab_nfFornecedor = 1 AND p_item_stICMS IN('10','30','70')
        OR p_cab_nfFornecedor = 1 AND p_item_stICMS = ' ' AND p_item_stSimplesNacional IN ('201','202','203')
        OR p_item_stICMS = ' ' AND p_item_stSimplesNacional = '500'
      THEN '60'
      WHEN p_item_stICMS <> ' '
      THEN p_item_stICMS
      WHEN p_item_stSimplesNacional IN ('101','102') AND p_item_reducaoBaseICMS = 0
      THEN '00'
      WHEN p_item_stSimplesNacional IN ('101','102')
      THEN '20'
      WHEN p_item_stSimplesNacional IN ('103','300')
      THEN '40'
      WHEN p_item_stSimplesNacional IN ('201','202','203') AND p_item_reducaoBaseICMS = 0
      THEN '10'
      WHEN p_item_stSimplesNacional IN ('201','202','203')
      THEN '70'
      WHEN p_item_stSimplesNacional = '400'
      THEN '41'
      ELSE '90'
    END;
  r_item_reducaoBaseICMSEscrit :=
    CASE
      WHEN p_cab_nfFornecedor = 1
        AND (p_prod_tipoProduto IN('07','08')
          OR p_item_stICMS IN('10','30','70')
          OR p_item_stICMS = ' ' AND p_item_stSimplesNacional IN ('201','202','203'))
        OR p_item_stICMS = ' ' AND p_item_stSimplesNacional = '500'
      THEN 0
      WHEN p_item_stICMS <> ' '
      THEN p_item_reducaoBaseICMS
      ELSE 0
    END;
  r_item_aliquotaICMSEscrit :=
    CASE
      WHEN p_cab_nfFornecedor = 1
        AND (p_prod_tipoProduto IN('07','08')
          OR p_item_stICMS IN('10','30','70')
          OR p_item_stICMS = ' ' AND p_item_stSimplesNacional IN ('201','202','203'))
        OR p_item_stICMS = ' ' AND p_item_stSimplesNacional = '500'
      THEN 0
      WHEN p_item_stICMS <> ' '
      THEN p_item_aliquotaICMS
      WHEN p_item_stSimplesNacional IN ('101','201')
      THEN p_item_creditoSimplesNacional
      ELSE 0
    END;
  r_item_diferimentoICMSEscrit :=
    CASE
      WHEN p_cab_nfFornecedor = 1
        AND (p_prod_tipoProduto IN('07','08')
          OR p_item_stICMS IN('10','30','70')
          OR p_item_stICMS = ' ' AND p_item_stSimplesNacional IN ('201','202','203'))
        OR p_item_stICMS = ' ' AND p_item_stSimplesNacional = '500'
      THEN 0
      WHEN p_item_stICMS <> ' '
      THEN p_item_diferimentoICMS
      ELSE 0
    END;
  r_item_margemValorAdicSTEscrit :=
    CASE
      WHEN p_item_stICMS = ' '
        OR p_cab_nfFornecedor = 1
        AND (p_prod_tipoProduto IN('07','08')
          OR p_item_stICMS IN('10','30','60','70'))
      THEN 0
      ELSE p_item_margemValorAdicST
    END;
  r_item_reducaoBaseSTEscrit :=
    CASE
      WHEN p_item_stICMS = ' '
        OR p_cab_nfFornecedor = 1
        AND (p_prod_tipoProduto IN('07','08')
          OR p_item_stICMS IN('10','30','60','70'))
      THEN 0
      ELSE p_item_reducaoBaseST
    END;
  r_item_aliquotaICMSSTEscrit :=
    CASE
      WHEN p_item_stICMS = ' '
      OR p_cab_nfFornecedor = 1
      AND (p_prod_tipoProduto IN('07','08')
        OR p_item_stICMS IN('10','30','60','70'))
      THEN 0
      ELSE p_item_aliquotaICMSST
    END;
END ADD_ITEM_ALIQUOTA_ESCRITURACAO;

/

create or replace PROCEDURE ADD_CALCULA_IMPOSTOS_ESCRIT (
    p_cab_entradaSaida             IN CHAR,
    p_cab_devolucaoAnulacaoRetorno IN NUMBER,
    p_cab_nfFornecedor             IN NUMBER,
    p_cab_indicadorConsumidorFinal IN CHAR,
    p_cab_tipoPagamentoFrete       IN CHAR,
    p_pess_indicadorInscricaoEstad IN CHAR,
    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_valorIPIDevolucao            IN NUMBER,
    p_valorII                      IN NUMBER,
    p_valorIOF                     IN NUMBER,
    p_valorIPI                     IN NUMBER,
    p_stICMS                       IN CHAR,
    p_reducaoBaseICMS              IN NUMBER,
    p_aliquotaICMS                 IN NUMBER,
    p_baseICMS                     IN NUMBER,
    p_valorICMS                    IN NUMBER,
    p_valorICMSDesoneracao         IN NUMBER,
    p_margemValorAdicionadoST      IN NUMBER,
    p_reducaoBaseST                IN NUMBER,
    p_aliquotaICMSST               IN NUMBER,
    p_baseICMSST                   IN NUMBER,
    p_valorICMSST                  IN NUMBER,
    p_stICMSEscrituracao           IN CHAR,
    p_reducaoBaseICMSEscrituracao  IN NUMBER,
    p_aliquotaICMSEscrituracao     IN NUMBER,
    p_diferimentoICMSEscrituracao  IN NUMBER,
    p_margemValorAdicSTEscriturac  IN NUMBER,
    p_reducaoBaseSTEscrituracao    IN NUMBER,
    p_aliquotaICMSSTEscrituracao   IN NUMBER,
    p_prod_tipoProduto             IN CHAR,
    /* Retornos */
    r_baseICMSEscrituracao         OUT NUMBER,
    r_valorICMSEscrituracao        OUT NUMBER,
    r_valorICMSDesonEscrituracao   OUT NUMBER,
    r_baseICMSSTEscrituracao       OUT NUMBER,
    r_valorICMSSTEscrituracao      OUT NUMBER)
IS      
BEGIN
  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_diferimentoICMSEscrituracao <> 0 AND p_diferimentoICMSEscrituracao <> p_reducaoBaseICMSEscrituracao THEN
      r_baseICMSEscrituracao := ROUND ((p_baseICMS * (1 - p_diferimentoICMSEscrituracao / 100)), 2);
    ELSE
      r_baseICMSEscrituracao := p_baseICMS;
    END IF;
    r_valorICMSEscrituracao := p_valorICMS;
    r_valorICMSDesonEscrituracao := p_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
        + p_valorII
        + p_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 p_valorIPI + p_valorIPIDevolucao ELSE 0 END
      ) * p_aliquotaICMSEscrituracao / 100), 2);
    ELSIF p_aliquotaICMSEscrituracao > 0 AND p_stICMSEscrituracao IN ('00','10','20','51','70','90') 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
        + p_valorII
        + p_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 p_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;
      ELSE
        IF p_stICMSEscrituracao = '51' AND p_reducaoBaseICMSEscrituracao > 0 AND p_reducaoBaseICMSEscrituracao <> p_diferimentoICMSEscrituracao THEN
          r_baseICMSEscrituracao := ROUND ((r_baseICMSEscrituracao * (1 - p_reducaoBaseICMSEscrituracao / 100)), 2);
          r_valorICMSEscrituracao := ROUND ((r_baseICMSEscrituracao * p_aliquotaICMSEscrituracao / 100), 2);
        END IF;
        r_valorICMSDesonEscrituracao := 0;
      END IF;
      IF p_stICMSEscrituracao = '51' THEN
        r_valorICMSEscrituracao := r_valorICMSEscrituracao - ROUND ((r_valorICMSEscrituracao * p_diferimentoICMSEscrituracao / 100), 2);
        IF p_cab_nfFornecedor = 1 THEN
          r_baseICMSEscrituracao := ROUND ((r_baseICMSEscrituracao * (1 - p_diferimentoICMSEscrituracao / 100)), 2);
        END IF;
        IF r_valorICMSEscrituracao <= 0 THEN
          r_baseICMSEscrituracao := 0;
          r_valorICMSEscrituracao := 0;
        END IF;
      END IF;
    END IF;
  END IF;
  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 := p_baseICMSST;
    r_valorICMSSTEscrituracao := p_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
      + p_valorII
      + p_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 p_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 ADD_CALCULA_IMPOSTOS_ESCRIT;

/

create or replace PROCEDURE ADD_CALCULA_IMPOSTOS_ITEM (
    p_config_64_casasDecSaidas     IN CHAR,
    p_config_209_filtrarGrupoEcon  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_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_calcularRetencaoIRRF         IN NUMBER,
    p_retencaoIRRF                 IN NUMBER,
    p_baseRetIRRF                  IN NUMBER,
    p_valorRetIRRF                 IN NUMBER,
    p_calcularRetencaoINSS         IN NUMBER,
    p_retencaoINSS                 IN NUMBER,
    p_baseRetINSS                  IN NUMBER,
    p_valorRetINSS                 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_calcularRetencaoOutros       IN NUMBER,
    p_retencaoOutros               IN NUMBER,
    p_baseRetOutros                IN NUMBER,
    p_valorRetOutros               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_diferimentoICMSEscrituracao  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,
    p_prod_precoPautaTabelado      IN NUMBER,
    /* Retornos */
    r_baseISSQN                    OUT NUMBER,
    r_valorISSQN                   OUT NUMBER,
    r_baseRetIRRF                  OUT NUMBER,
    r_valorRetIRRF                 OUT NUMBER,
    r_baseRetINSS                  OUT NUMBER,
    r_valorRetINSS                 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_baseRetOutros                OUT NUMBER,
    r_valorRetOutros               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_baseRetIRRF                 := p_baseRetIRRF;
  r_valorRetIRRF                := p_valorRetIRRF;
  r_baseRetINSS                 := p_baseRetINSS;
  r_valorRetINSS                := p_valorRetINSS;
  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_baseRetOutros               := p_baseRetOutros;
  r_valorRetOutros              := p_valorRetOutros;
  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_calcularRetencaoIRRF = 1 THEN
    IF p_retencaoIRRF > 0 THEN
      r_baseRetIRRF := p_valorProdutoServico - p_valorDescontoTotal + p_valorOutrasDespesasTotal;
      r_valorRetIRRF := ROUND ((r_baseRetIRRF * p_retencaoIRRF / 100), 2);
    ELSE
      r_baseRetIRRF := 0;
      r_valorRetIRRF := 0;
    END IF;
  END IF;
  /* INSS */
  IF p_calcularRetencaoINSS = 1 THEN
    IF p_retencaoINSS > 0 THEN
      r_baseRetINSS := p_valorProdutoServico - p_valorDescontoTotal + p_valorOutrasDespesasTotal;
      r_valorRetINSS := ROUND ((r_baseRetINSS * p_retencaoINSS / 100), 2);
    ELSE
      r_baseRetINSS := 0;
      r_valorRetINSS := 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;
  /* Retenção Outros */
  IF p_calcularRetencaoOutros = 1 THEN
    IF p_retencaoOutros > 0 THEN
      r_baseRetOutros := p_valorProdutoServico - p_valorDescontoTotal + p_valorOutrasDespesasTotal;
      r_valorRetOutros := ROUND ((r_baseRetOutros * p_retencaoOutros / 100), 2);
    ELSE
      r_baseRetOutros := 0;
      r_valorRetOutros := 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','90')
        OR p_stSimplesNacional = '900')
    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_prod_precoPautaTabelado > 0 AND (p_modalidadeBaseCalcICMS = '1' OR p_modalidadeBaseCalcICMS = '2' AND r_baseICMS > p_quantidade * p_prod_precoPautaTabelado) THEN
        r_baseICMS := ROUND ((p_quantidade * p_prod_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_prod_precoPautaTabelado > 0
        AND (p_modalidadeBaseCalcICMSST = '5'
          OR p_modalidadeBaseCalcICMSST = '0'
          AND r_baseICMSST > p_quantidade * p_prod_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_prod_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_diferimentoICMSEscrituracao <> 0
        AND p_diferimentoICMSEscrituracao <> p_reducaoBaseICMSEscrituracao
      THEN
        r_baseICMSEscrituracao := ROUND ((r_baseICMS * (1 - p_diferimentoICMSEscrituracao / 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','90')
      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_diferimentoICMSEscrituracao
        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_diferimentoICMSEscrituracao / 100), 2);
          IF p_cab_nfFornecedor = 1 THEN
            r_baseICMSEscrituracao := ROUND ((r_baseICMSEscrituracao * (1 - p_diferimentoICMSEscrituracao / 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'
        AND p_pess_indicadorInscricaoEstad = '9')
      AND NOT(p_stICMS IN('40','41'))
      AND (p_stSimplesNacional IS NOT NULL
        OR NOT(p_stSimplesNacional IN('103','300','400')))
      AND NOT(p_cfop IN(6552,6922,6929))
      AND p_aliquotaICMSInterestadual <> 0
      AND p_partilhaICMSInterestadual <> 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;
      IF p_cab_devolucaoAnulacaoRetorno = 1 THEN
        r_valorICMSUFDestinatario := ROUND ((r_baseICMSUFDestinatario * ((p_aliquotaICMSUFDestinatario - p_aliquotaICMSInterestadual) / 100) * (1 - p_partilhaICMSInterestadual / 100)), 2);
        r_valorICMSUFRemetente    := ROUND ((r_baseICMSUFRemetente    * ((p_aliquotaICMSUFDestinatario - p_aliquotaICMSInterestadual) / 100) * (p_partilhaICMSInterestadual / 100)), 2);
      ELSE
        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);
      END IF;
    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
        - r_valorICMS;
      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
        - r_valorICMS;
      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
        - r_valorICMS;
      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
        - r_valorICMS;
      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_CALC_IMP_RESIDUO (
    p_troca_tipoPagamentoFrete     IN NUMBER,
    p_a_cab_tipoPagamentoFrete     IN CHAR,
    p_cab_origemDocumento          IN NUMBER,
    p_cab_atualizaCustoMedio       IN NUMBER,
    p_cab_tipoPagamentoFrete       IN CHAR,
    p_cab_valorProdutos            IN NUMBER,
    p_cab_valorServicos            IN NUMBER,
    p_cab_valorBasePagamento       IN NUMBER,
    p_cab_valorAVistaMinimo        IN NUMBER,
    p_cab_valorFreteTotal          IN NUMBER,
    p_cab_valorSeguroTotal         IN NUMBER,
    p_cab_valorDescontoTotal       IN NUMBER,
    p_cab_valorOutrasDespesasTotal IN NUMBER,
    p_cab_valorAdicFreteMarinTotal IN NUMBER,
    p_cab_valorDespesasAduanTotal  IN NUMBER,
    p_cab_impostosEditados         IN NUMBER,
    p_cab_valorLiquidoItem         IN NUMBER,
    p_item_idItemOrcamento         IN NUMBER,
    p_saldoRatFreteGeral           IN NUMBER,
    p_saldoRatSeguroGeral          IN NUMBER,
    p_saldoRatDescontoGeral        IN NUMBER,
    p_saldoRatOutrasDespesasGeral  IN NUMBER,
    p_saldoRatAdicFreteMarinGeral  IN NUMBER,
    p_saldoRatDespesasAduanGeral   IN NUMBER,
    p_saldoRatDescontoPagamento    IN NUMBER,
    p_saldoRatOutrasDespPagamento  IN NUMBER,
    p_saldoRatJurosPagamento       IN NUMBER,
    p_calcularImpostosItem         IN NUMBER,
    /* Retornos */
    r_cab_valorProdutos            OUT NUMBER,
    r_cab_valorServicos            OUT NUMBER,
    r_cab_valorBasePagamento       OUT NUMBER,
    r_cab_valorAVistaMinimo        OUT NUMBER,
    r_cab_valorFreteTotal          OUT NUMBER,
    r_cab_valorSeguroTotal         OUT NUMBER,
    r_cab_valorDescontoTotal       OUT NUMBER,
    r_cab_valorOutrasDespesasTotal OUT NUMBER,
    r_cab_valorAdicFreteMarinTotal OUT NUMBER,
    r_cab_valorDespesasAduanTotal  OUT NUMBER,
    r_cab_valorLiquidoItem         OUT NUMBER,
    r_calcularImpostosItem         OUT NUMBER)
IS
    v_auxNumber                    NUMBER;
    v_precoUnitario                NUMBER;
    v_precoUnitarioConvertido      NUMBER;
    v_valorProdutoServico          NUMBER;
    v_valorFreteGeral              NUMBER;
    v_valorSeguroGeral             NUMBER;
    v_valorDescontoGeral           NUMBER;
    v_valorOutrasDespesasGeral     NUMBER;
    v_valorAdicFreteMarinMerGeral  NUMBER;
    v_valorDespesasAduaneirasGeral NUMBER;
    v_valorBasePagamento           NUMBER;
    v_valorDescontoPagamento       NUMBER;
    v_valorOutrasDespesasPagamento NUMBER;
    v_valorJurosPagamento          NUMBER;
    v_valorFreteTotal              NUMBER;
    v_valorSeguroTotal             NUMBER;
    v_valorDescontoTotal           NUMBER;
    v_valorOutrasDespesasTotal     NUMBER;
    v_valorAdicFreteMarinMerTotal  NUMBER;
    v_valorDespesasAduaneirasTotal NUMBER;
    v_valorLiquidoItem             NUMBER;
BEGIN
  r_cab_valorProdutos            := p_cab_valorProdutos;
  r_cab_valorServicos            := p_cab_valorServicos;
  r_cab_valorBasePagamento       := p_cab_valorBasePagamento;
  r_cab_valorAVistaMinimo        := p_cab_valorAVistaMinimo;
  r_cab_valorFreteTotal          := p_cab_valorFreteTotal;
  r_cab_valorSeguroTotal         := p_cab_valorSeguroTotal;
  r_cab_valorDescontoTotal       := p_cab_valorDescontoTotal;
  r_cab_valorOutrasDespesasTotal := p_cab_valorOutrasDespesasTotal;
  r_cab_valorAdicFreteMarinTotal := p_cab_valorAdicFreteMarinTotal;
  r_cab_valorDespesasAduanTotal  := p_cab_valorDespesasAduanTotal;
  r_cab_valorLiquidoItem         := p_cab_valorLiquidoItem;
  r_calcularImpostosItem         := p_calcularImpostosItem;
  FOR a IN (
    SELECT
      a.geraFinanceiro,
      a.quantidade,
      a.quantidadeConvertida,
      a.usarPrecoAVista,
      a.precoUnitarioBruto,
      a.acrescimoUnitarioComposicao,
      a.precoUnitario,
      a.precoUnitarioConvertido,
      a.valorProdutoServicoBruto,
      a.valorProdutoServico,
      a.valorDescontoItem,
      a.valorAcrescimoItem,
      a.valorFreteItem,
      a.valorSeguroItem,
      a.valorAdicFreteMarinhaMerItem,
      a.valorDespesasAduaneirasItem,
      a.valorFreteGeral,
      a.valorSeguroGeral,
      a.valorDescontoGeral,
      a.valorOutrasDespesasGeral,
      a.valorAdicFreteMarinhaMerGeral,
      a.valorDespesasAduaneirasGeral,
      a.valorBasePagamento,
      a.valorDescontoPagamento,
      a.valorOutrasDespesasPagamento,
      a.valorJurosPagamento,
      a.valorFreteTotal,
      a.valorSeguroTotal,
      a.valorDescontoTotal,
      a.valorOutrasDespesasTotal,
      a.valorAdicFreteMarinhaMerTotal,
      a.valorDespesasAduaneirasTotal,
      a.retidoISSQN,
      a.valorISSQN,
      a.valorRetIRRF,
      a.valorRetINSS,
      a.valorRetPIS,
      a.valorRetCOFINS,
      a.valorRetCSLL,
      a.valorRetOutros,
      a.valorII,
      a.valorIOF,
      a.valorIPI,
      a.valorPIS,
      a.valorPISST,
      a.valorCOFINS,
      a.valorCOFINSST,
      a.valorCreditoSimplesNacional,
      a.valorICMS,
      a.valorICMSST,
      a.valorLiquidoItem,
      modDoc.geraFinanceiro modDoc_geraFinanceiro,
      modDoc.diminuiDescontoPrUnit,
      modDoc.somaAcrescimosPrUnit,
      modDoc.somaFreteSeguroPrUnit,
      prod.tipoProduto,
      CASE
        WHEN EXISTS (
          SELECT 1
          FROM CAPRODUTOXCOMPOSICOESPREC compPrec
          WHERE compPrec.produto = gradProd.produto
          AND compPrec.ativo = 1)
        THEN 1
        ELSE 0
      END composicaoPreco
    FROM MOORCAMENTOXITENS a
    JOIN PAMODELOSDOCUMENTO modDoc
    ON modDoc.modeloDocumento = a.modeloDocumento
    JOIN CAGRADESPRODUTO gradProd
    ON gradProd.gradeProduto = a.gradeProduto
    JOIN CAPRODUTOS prod
    ON prod.produto = gradProd.produto
    WHERE a.idItemOrcamento = p_item_idItemOrcamento)
  LOOP
    v_precoUnitario                := a.precoUnitario;
    v_precoUnitarioConvertido      := a.precoUnitarioConvertido;
    v_valorProdutoServico          := a.valorProdutoServico;
    v_valorFreteGeral              := a.valorFreteGeral;
    v_valorSeguroGeral             := a.valorSeguroGeral;
    v_valorDescontoGeral           := a.valorDescontoGeral;
    v_valorOutrasDespesasGeral     := a.valorOutrasDespesasGeral;
    v_valorAdicFreteMarinMerGeral  := a.valorAdicFreteMarinhaMerGeral;
    v_valorDespesasAduaneirasGeral := a.valorDespesasAduaneirasGeral;
    v_valorBasePagamento           := a.valorBasePagamento;
    v_valorDescontoPagamento       := a.valorDescontoPagamento;
    v_valorOutrasDespesasPagamento := a.valorOutrasDespesasPagamento;
    v_valorJurosPagamento          := a.valorJurosPagamento;
    v_valorFreteTotal              := a.valorFreteTotal;
    v_valorSeguroTotal             := a.valorSeguroTotal;
    v_valorDescontoTotal           := a.valorDescontoTotal;
    v_valorOutrasDespesasTotal     := a.valorOutrasDespesasTotal;
    v_valorAdicFreteMarinMerTotal  := a.valorAdicFreteMarinhaMerTotal;
    v_valorDespesasAduaneirasTotal := a.valorDespesasAduaneirasTotal;
    v_valorLiquidoItem             := a.valorLiquidoItem;
    IF a.tipoProduto = '09' THEN
      r_cab_valorServicos          := r_cab_valorServicos - v_valorProdutoServico;
    ELSE
      r_cab_valorProdutos          := r_cab_valorProdutos - v_valorProdutoServico;
    END IF;
    r_cab_valorBasePagamento       := r_cab_valorBasePagamento - v_valorBasePagamento;
    IF a.usarPrecoAVista = 1 AND a.geraFinanceiro = 1 THEN
      r_cab_valorAVistaMinimo      := r_cab_valorAVistaMinimo - v_valorProdutoServico - v_valorDescontoPagamento + v_valorOutrasDespesasPagamento + v_valorJurosPagamento + v_valorDescontoTotal - v_valorOutrasDespesasTotal;
    END IF;
    r_cab_valorFreteTotal          := r_cab_valorFreteTotal - v_valorFreteTotal;
    r_cab_valorSeguroTotal         := r_cab_valorSeguroTotal - v_valorSeguroTotal;
    r_cab_valorDescontoTotal       := r_cab_valorDescontoTotal - v_valorDescontoTotal;
    r_cab_valorOutrasDespesasTotal := r_cab_valorOutrasDespesasTotal - v_valorOutrasDespesasTotal;
    r_cab_valorAdicFreteMarinTotal := r_cab_valorAdicFreteMarinTotal - v_valorAdicFreteMarinMerTotal;
    r_cab_valorDespesasAduanTotal  := r_cab_valorDespesasAduanTotal - v_valorDespesasAduaneirasTotal;
    r_cab_valorLiquidoItem         := r_cab_valorLiquidoItem - v_valorLiquidoItem;
    v_valorFreteGeral              := v_valorFreteGeral + p_saldoRatFreteGeral;
    v_valorSeguroGeral             := v_valorSeguroGeral + p_saldoRatSeguroGeral;
    v_valorAdicFreteMarinMerGeral  := v_valorAdicFreteMarinMerGeral + p_saldoRatAdicFreteMarinGeral;
    v_valorDespesasAduaneirasGeral := v_valorDespesasAduaneirasGeral + p_saldoRatDespesasAduanGeral;
    v_valorDescontoGeral           := v_valorDescontoGeral + p_saldoRatDescontoGeral;
    v_valorOutrasDespesasGeral     := v_valorDespesasAduaneirasGeral + p_saldoRatOutrasDespesasGeral;
    v_valorDescontoPagamento       := v_valorDescontoPagamento + p_saldoRatDescontoPagamento;
    v_valorOutrasDespesasPagamento := v_valorOutrasDespesasPagamento + p_saldoRatOutrasDespPagamento;
    v_valorJurosPagamento          := v_valorJurosPagamento + p_saldoRatJurosPagamento;
    ADD_CALCULA_TOTAIS_ITEM (
      p_cab_tipoPagamentoFrete,
      a.quantidade,
      a.quantidadeConvertida,
      a.precoUnitarioBruto,
      a.acrescimoUnitarioComposicao,
      a.precoUnitario,
      a.valorDescontoItem,
      a.valorAcrescimoItem,
      a.valorFreteItem,
      a.valorSeguroItem,
      a.valorAdicFreteMarinhaMerItem,
      a.valorDespesasAduaneirasItem,
      v_valorFreteGeral,
      v_valorSeguroGeral,
      v_valorDescontoGeral,
      v_valorOutrasDespesasGeral,
      v_valorAdicFreteMarinMerGeral,
      v_valorDespesasAduaneirasGeral,
      v_valorDescontoPagamento,
      v_valorOutrasDespesasPagamento,
      v_valorJurosPagamento,
      a.diminuiDescontoPrUnit,
      a.somaAcrescimosPrUnit,
      a.somaFreteSeguroPrUnit,
      a.composicaoPreco,
      /* Retornos */
      v_precoUnitario,
      v_precoUnitarioConvertido,
      v_valorProdutoServico,
      v_valorFreteTotal,
      v_valorSeguroTotal,
      v_valorDescontoTotal,
      v_valorOutrasDespesasTotal,
      v_valorAdicFreteMarinMerTotal,
      v_valorDespesasAduaneirasTotal);
    IF p_cab_impostosEditados = 0 
        OR v_valorProdutoServico <> a.valorProdutoServico
        OR CASE WHEN p_cab_tipoPagamentoFrete = 'V' THEN 0 ELSE v_valorFreteTotal END
          <> CASE WHEN CASE WHEN p_troca_tipoPagamentoFrete = 1 THEN p_a_cab_tipoPagamentoFrete ELSE p_cab_tipoPagamentoFrete END = 'V' THEN 0 ELSE a.valorFreteTotal END
        OR CASE WHEN p_cab_tipoPagamentoFrete   = 'V' THEN 0 ELSE v_valorSeguroTotal END
          <> CASE WHEN CASE WHEN p_troca_tipoPagamentoFrete = 1 THEN p_a_cab_tipoPagamentoFrete ELSE p_cab_tipoPagamentoFrete END = 'V' THEN 0 ELSE a.valorSeguroTotal END
        OR v_valorDescontoTotal <> a.valorDescontoTotal
        OR v_valorOutrasDespesasTotal <> a.valorOutrasDespesasTotal
        OR v_valorAdicFreteMarinMerTotal <> a.valorAdicFreteMarinhaMerTotal
        OR v_valorDespesasAduaneirasTotal <> a.valorDespesasAduaneirasTotal
        OR v_precoUnitario <> a.precoUnitario
        OR v_valorProdutoServico <> a.valorProdutoServico
    THEN
      r_calcularImpostosItem := 1;
    END IF;
    v_valorBasePagamento := FUNC_ADD_CALC_BASE_PAGAMENTO (
      p_cab_origemDocumento,
      0, -- p_cab_nfFornecedor
      p_cab_tipoPagamentoFrete,
      a.geraFinanceiro,
      v_valorProdutoServico,
      v_valorDescontoPagamento,
      v_valorOutrasDespesasPagamento,
      v_valorJurosPagamento,
      v_valorFreteTotal,
      v_valorSeguroTotal,
      v_valorDescontoTotal,
      v_valorOutrasDespesasTotal,
      0, -- p_item_valorIPIDevolucao
      a.retidoISSQN,
      a.valorISSQN,
      a.valorRetIRRF,
      a.valorRetINSS,
      a.valorRetPIS,
      a.valorRetCOFINS,
      a.valorRetCSLL,
      a.valorRetOutros,
      a.valorII,
      a.valorIOF,
      a.valorIPI,
      a.valorICMSST,
      0, -- p_item_valorICMSSTEscrit
      0, -- p_item_somarICMSST
      0, -- p_item_valorAcrescExtempTotal
      a.modDoc_geraFinanceiro);
    v_valorLiquidoItem := FUNC_ADD_CALC_VALOR_LIQUIDO (
      0, -- p_cab_nfFornecedor
      p_cab_tipoPagamentoFrete,
      v_valorProdutoServico,
      v_valorFreteTotal,
      v_valorSeguroTotal,
      v_valorDescontoTotal,
      v_valorOutrasDespesasTotal,
      0, -- p_item_valorIPIDevolucao
      a.valorII,
      a.valorIOF,
      a.valorIPI,
      a.valorICMSST,
      0, -- p_item_valorICMSSTEscrit
      0 -- p_item_somarICMSST
      );
    UPDATE MOORCAMENTOXITENS SET
      precoUnitario                 = v_precoUnitario,
      precoUnitarioConvertido       = v_precoUnitarioConvertido,
      valorProdutoServico           = v_valorProdutoServico,
      valorFreteGeral               = v_valorFreteGeral,
      valorSeguroGeral              = v_valorSeguroGeral,
      valorDescontoGeral            = v_valorDescontoGeral,
      valorOutrasDespesasGeral      = v_valorOutrasDespesasGeral,
      valorAdicFreteMarinhaMerGeral = v_valorAdicFreteMarinMerGeral,
      valorDespesasAduaneirasGeral  = v_valorDespesasAduaneirasGeral,
      valorBasePagamento            = v_valorBasePagamento,
      valorDescontoPagamento        = v_valorDescontoPagamento,
      valorOutrasDespesasPagamento  = v_valorOutrasDespesasPagamento,
      valorJurosPagamento           = v_valorJurosPagamento,
      valorFreteTotal               = v_valorFreteTotal,
      valorSeguroTotal              = v_valorSeguroTotal,
      valorDescontoTotal            = v_valorDescontoTotal,
      valorOutrasDespesasTotal      = v_valorOutrasDespesasTotal,
      valorAdicFreteMarinhaMerTotal = v_valorAdicFreteMarinMerTotal,
      valorDespesasAduaneirasTotal  = v_valorDespesasAduaneirasTotal,
      valorLiquidoItem              = v_valorLiquidoItem
    WHERE idItemOrcamento           = p_item_idItemOrcamento;
    IF a.tipoProduto = '09' THEN
      r_cab_valorServicos          := r_cab_valorServicos + v_valorProdutoServico;
    ELSE
      r_cab_valorProdutos          := r_cab_valorProdutos + v_valorProdutoServico;
    END IF;
    r_cab_valorBasePagamento       := r_cab_valorBasePagamento + v_valorBasePagamento;
    IF a.usarPrecoAVista = 1
      AND a.geraFinanceiro = 1
    THEN
      r_cab_valorAVistaMinimo      := r_cab_valorAVistaMinimo + v_valorProdutoServico + v_valorDescontoPagamento - v_valorOutrasDespesasPagamento - v_valorJurosPagamento - v_valorDescontoTotal + v_valorOutrasDespesasTotal;
    END IF;
    r_cab_valorFreteTotal          := r_cab_valorFreteTotal + v_valorFreteTotal;
    r_cab_valorSeguroTotal         := r_cab_valorSeguroTotal + v_valorSeguroTotal;
    r_cab_valorDescontoTotal       := r_cab_valorDescontoTotal + v_valorDescontoTotal;
    r_cab_valorOutrasDespesasTotal := r_cab_valorOutrasDespesasTotal + v_valorOutrasDespesasTotal;
    r_cab_valorAdicFreteMarinTotal := r_cab_valorAdicFreteMarinTotal + v_valorAdicFreteMarinMerTotal;
    r_cab_valorDespesasAduanTotal  := r_cab_valorDespesasAduanTotal + v_valorDespesasAduaneirasTotal;
    r_cab_valorLiquidoItem         := r_cab_valorLiquidoItem + v_valorLiquidoItem;
  END LOOP;
END ADD_ORCAMENTO_CALC_IMP_RESIDUO;

/

create or replace PROCEDURE ADD_PRE_DOC_CALC_IMP_RESIDUO (
    p_troca_tipoPagamentoFrete     IN NUMBER,
    p_a_cab_tipoPagamentoFrete     IN CHAR,
    p_cab_origemDocumento          IN NUMBER,
    p_cab_atualizaCustoMedio       IN NUMBER,
    p_cab_estabelecimento          IN NUMBER,
    p_cab_tipoPagamentoFrete       IN CHAR,
    p_cab_valorProdutos            IN NUMBER,
    p_cab_valorServicos            IN NUMBER,
    p_cab_valorBasePagamento       IN NUMBER,
    p_cab_valorAVistaMinimo        IN NUMBER,
    p_cab_valorFreteTotal          IN NUMBER,
    p_cab_valorSeguroTotal         IN NUMBER,
    p_cab_valorDescontoTotal       IN NUMBER,
    p_cab_valorOutrasDespesasTotal IN NUMBER,
    p_cab_valorAdicFreteMarinTotal IN NUMBER,
    p_cab_valorDespesasAduanTotal  IN NUMBER,
    p_cab_impostosEditados         IN NUMBER,
    p_cab_valorLiquidoItem         IN NUMBER,
    p_cab_valorDescCustoOpTotal    IN NUMBER,
    p_cab_valorAcrescCustoOpTotal  IN NUMBER,
    p_cab_valorCustoOperacao       IN NUMBER,
    p_cab_valorCMV                 IN NUMBER,
    p_cab_valorAcrescExtempTotal   IN NUMBER,
    p_item_idItemPreDocumento      IN NUMBER,
    p_saldoRatFreteGeral           IN NUMBER,
    p_saldoRatSeguroGeral          IN NUMBER,
    p_saldoRatDescontoGeral        IN NUMBER,
    p_saldoRatOutrasDespesasGeral  IN NUMBER,
    p_saldoRatAdicFreteMarinGeral  IN NUMBER,
    p_saldoRatDespesasAduanGeral   IN NUMBER,
    p_saldoRatDescontoPagamento    IN NUMBER,
    p_saldoRatOutrasDespPagamento  IN NUMBER,
    p_saldoRatJurosPagamento       IN NUMBER,
    p_saldoRatDescCustoOpGeral     IN NUMBER,
    p_saldoRatAcrescCustoOpGeral   IN NUMBER,
    p_saldoRatAcrescExtempGeral    IN NUMBER,
    p_calcularImpostosItem         IN NUMBER,
    /* Retornos */
    r_cab_valorProdutos            OUT NUMBER,
    r_cab_valorServicos            OUT NUMBER,
    r_cab_valorBasePagamento       OUT NUMBER,
    r_cab_valorAVistaMinimo        OUT NUMBER,
    r_cab_valorFreteTotal          OUT NUMBER,
    r_cab_valorSeguroTotal         OUT NUMBER,
    r_cab_valorDescontoTotal       OUT NUMBER,
    r_cab_valorOutrasDespesasTotal OUT NUMBER,
    r_cab_valorAdicFreteMarinTotal OUT NUMBER,
    r_cab_valorDespesasAduanTotal  OUT NUMBER,
    r_cab_valorLiquidoItem         OUT NUMBER,
    r_cab_valorDescCustoOpTotal    OUT NUMBER,
    r_cab_valorAcrescCustoOpTotal  OUT NUMBER,
    r_cab_valorCustoOperacao       OUT NUMBER,
    r_cab_valorCMV                 OUT NUMBER,
    r_cab_valorAcrescExtempTotal   OUT NUMBER,
    r_calcularImpostosItem         OUT NUMBER)
IS
    v_auxNumber                    NUMBER;
    v_valorBaseRateio              NUMBER;
    v_precoUnitario                NUMBER;
    v_precoUnitarioConvertido      NUMBER;
    v_valorProdutoServico          NUMBER;
    v_valorFreteGeral              NUMBER;
    v_valorSeguroGeral             NUMBER;
    v_valorDescontoGeral           NUMBER;
    v_valorOutrasDespesasGeral     NUMBER;
    v_valorAdicFreteMarinMerGeral  NUMBER;
    v_valorDespesasAduaneirasGeral NUMBER;
    v_valorBasePagamento           NUMBER;
    v_valorDescontoPagamento       NUMBER;
    v_valorOutrasDespesasPagamento NUMBER;
    v_valorJurosPagamento          NUMBER;
    v_valorFreteTotal              NUMBER;
    v_valorSeguroTotal             NUMBER;
    v_valorDescontoTotal           NUMBER;
    v_valorOutrasDespesasTotal     NUMBER;
    v_valorAdicFreteMarinMerTotal  NUMBER;
    v_valorDespesasAduaneirasTotal NUMBER;
    v_valorLiquidoItem             NUMBER;
    v_valorDescontoCustoOpGeral    NUMBER;
    v_valorDescontoCustoOpTotal    NUMBER;
    v_valorAcrescimoCustoOpGeral   NUMBER;
    v_valorAcrescimoCustoOpTotal   NUMBER;
    v_precoCustoOperacao           NUMBER;
    v_valorCustoOperacao           NUMBER;
    v_precoCMV                     NUMBER;
    v_valorCMV                     NUMBER;
    v_valorAcrescimoExtempSubtotal NUMBER;
    v_valorAcrescimoExtempGeral    NUMBER;
    v_valorAcrescimoExtempTotal    NUMBER;
    v_calculoImpostosPendenteItem  NUMBER;
BEGIN
  r_cab_valorProdutos            := p_cab_valorProdutos;
  r_cab_valorServicos            := p_cab_valorServicos;
  r_cab_valorBasePagamento       := p_cab_valorBasePagamento;
  r_cab_valorAVistaMinimo        := p_cab_valorAVistaMinimo;
  r_cab_valorFreteTotal          := p_cab_valorFreteTotal;
  r_cab_valorSeguroTotal         := p_cab_valorSeguroTotal;
  r_cab_valorDescontoTotal       := p_cab_valorDescontoTotal;
  r_cab_valorOutrasDespesasTotal := p_cab_valorOutrasDespesasTotal;
  r_cab_valorAdicFreteMarinTotal := p_cab_valorAdicFreteMarinTotal;
  r_cab_valorDespesasAduanTotal  := p_cab_valorDespesasAduanTotal;
  r_cab_valorLiquidoItem         := p_cab_valorLiquidoItem;
  r_cab_valorDescCustoOpTotal    := p_cab_valorDescCustoOpTotal;
  r_cab_valorAcrescCustoOpTotal  := p_cab_valorAcrescCustoOpTotal;
  r_cab_valorCustoOperacao       := p_cab_valorCustoOperacao;
  r_cab_valorCMV                 := p_cab_valorCMV;
  r_cab_valorAcrescExtempTotal   := p_cab_valorAcrescExtempTotal;
  r_calcularImpostosItem         := p_calcularImpostosItem;
  FOR a IN (
    SELECT
      a.modeloDocumento,
      a.geraFinanceiro,
      a.quantidade,
      a.quantidadeConvertida,
      a.usarPrecoAVista,
      a.precoUnitarioBruto,
      a.acrescimoUnitarioComposicao,
      a.precoUnitario,
      a.precoUnitarioConvertido,
      a.valorProdutoServicoBruto,
      a.valorProdutoServico,
      a.valorDescontoItem,
      a.valorAcrescimoItem,
      a.valorFreteItem,
      a.valorSeguroItem,
      a.valorAdicFreteMarinhaMerItem,
      a.valorDespesasAduaneirasItem,
      a.valorFreteGeral,
      a.valorSeguroGeral,
      a.valorDescontoGeral,
      a.valorOutrasDespesasGeral,
      a.valorAdicFreteMarinhaMerGeral,
      a.valorDespesasAduaneirasGeral,
      a.valorBasePagamento,
      a.valorDescontoPagamento,
      a.valorOutrasDespesasPagamento,
      a.valorJurosPagamento,
      a.valorFreteTotal,
      a.valorSeguroTotal,
      a.valorDescontoTotal,
      a.valorOutrasDespesasTotal,
      a.valorAdicFreteMarinhaMerTotal,
      a.valorDespesasAduaneirasTotal,
      a.valorIPIDevolucao,
      a.retidoISSQN,
      a.valorISSQN,
      a.valorRetIRRF,
      a.valorRetINSS,
      a.valorRetPIS,
      a.valorRetCOFINS,
      a.valorRetCSLL,
      a.valorRetOutros,
      a.valorII,
      a.valorIOF,
      a.valorIPI,
      a.valorPIS,
      a.valorPISST,
      a.valorCOFINS,
      a.valorCOFINSST,
      a.valorCreditoSimplesNacional,
      a.valorICMS,
      a.valorICMSST,
      a.valorLiquidoItem,
      a.valorDescontoCustoOpItem,
      a.valorDescontoCustoOpGeral,
      a.valorDescontoCustoOpTotal,
      a.valorAcrescimoCustoOpItem,
      a.valorAcrescimoCustoOpGeral,
      a.valorAcrescimoCustoOpTotal,
      a.precoCustoOperacao,
      a.valorCustoOperacao,
      a.precoCMV,
      a.valorCMV,
      a.quantidadeExtemporanea,
      a.acrescimoUnitarioExtemporaneo,
      a.valorAcrescimoExtempSubtotal,
      a.valorAcrescimoExtempItem,
      a.valorAcrescimoExtempGeral,
      a.valorAcrescimoExtempTotal,
      modDoc.geraFinanceiro modDoc_geraFinanceiro,
      modDoc.diminuiDescontoPrUnit,
      modDoc.somaAcrescimosPrUnit,
      modDoc.somaFreteSeguroPrUnit,
      prod.tipoProduto,
      CASE
        WHEN EXISTS (
          SELECT 1
          FROM CAPRODUTOXCOMPOSICOESPREC compPrec
          WHERE compPrec.produto = gradProd.produto
          AND compPrec.ativo = 1)
        THEN 1
        ELSE 0
      END composicaoPreco
    FROM MOPREDOCUMXITENS a
    JOIN PAMODELOSDOCUMENTO modDoc
    ON modDoc.modeloDocumento = a.modeloDocumento
    JOIN CAGRADESPRODUTO gradProd
    ON gradProd.gradeProduto = a.gradeProduto
    JOIN CAPRODUTOS prod
    ON prod.produto = gradProd.produto
    WHERE a.idItemPreDocumento = p_item_idItemPreDocumento
    ORDER BY a.sequencia)
  LOOP
    v_precoUnitario                := a.precoUnitario;
    v_precoUnitarioConvertido      := a.precoUnitarioConvertido;
    v_valorProdutoServico          := a.valorProdutoServico;
    v_valorFreteGeral              := a.valorFreteGeral;
    v_valorSeguroGeral             := a.valorSeguroGeral;
    v_valorDescontoGeral           := a.valorDescontoGeral;
    v_valorOutrasDespesasGeral     := a.valorOutrasDespesasGeral;
    v_valorAdicFreteMarinMerGeral  := a.valorAdicFreteMarinhaMerGeral;
    v_valorDespesasAduaneirasGeral := a.valorDespesasAduaneirasGeral;
    v_valorBasePagamento           := a.valorBasePagamento;
    v_valorDescontoPagamento       := a.valorDescontoPagamento;
    v_valorOutrasDespesasPagamento := a.valorOutrasDespesasPagamento;
    v_valorJurosPagamento          := a.valorJurosPagamento;
    v_valorFreteTotal              := a.valorFreteTotal;
    v_valorSeguroTotal             := a.valorSeguroTotal;
    v_valorDescontoTotal           := a.valorDescontoTotal;
    v_valorOutrasDespesasTotal     := a.valorOutrasDespesasTotal;
    v_valorAdicFreteMarinMerTotal  := a.valorAdicFreteMarinhaMerTotal;
    v_valorDespesasAduaneirasTotal := a.valorDespesasAduaneirasTotal;
    v_valorLiquidoItem             := a.valorLiquidoItem;
    v_valorDescontoCustoOpGeral    := a.valorDescontoCustoOpGeral;
    v_valorDescontoCustoOpTotal    := a.valorDescontoCustoOpTotal;
    v_valorAcrescimoCustoOpGeral   := a.valorAcrescimoCustoOpGeral;
    v_valorAcrescimoCustoOpTotal   := a.valorAcrescimoCustoOpTotal;
    v_precoCustoOperacao           := a.precoCustoOperacao;
    v_valorCustoOperacao           := a.valorCustoOperacao;
    v_precoCMV                     := a.precoCMV;
    v_valorCMV                     := a.valorCMV;
    v_valorAcrescimoExtempSubtotal := a.valorAcrescimoExtempSubtotal;
    v_valorAcrescimoExtempGeral    := a.valorAcrescimoExtempGeral;
    v_valorAcrescimoExtempTotal    := a.valorAcrescimoExtempTotal;
    IF a.tipoProduto = '09' THEN
      r_cab_valorServicos            := r_cab_valorServicos - v_valorProdutoServico;
    ELSE
      r_cab_valorProdutos            := r_cab_valorProdutos - v_valorProdutoServico;
    END IF;
    r_cab_valorBasePagamento       := r_cab_valorBasePagamento - v_valorBasePagamento;
    IF a.usarPrecoAVista = 1 AND a.geraFinanceiro = 1 THEN
      r_cab_valorAVistaMinimo        := r_cab_valorAVistaMinimo - v_valorProdutoServico - v_valorDescontoPagamento + v_valorOutrasDespesasPagamento + v_valorJurosPagamento + v_valorDescontoTotal - v_valorOutrasDespesasTotal;
    END IF;
    r_cab_valorFreteTotal          := r_cab_valorFreteTotal - v_valorFreteTotal;
    r_cab_valorSeguroTotal         := r_cab_valorSeguroTotal - v_valorSeguroTotal;
    r_cab_valorDescontoTotal       := r_cab_valorDescontoTotal - v_valorDescontoTotal;
    r_cab_valorOutrasDespesasTotal := r_cab_valorOutrasDespesasTotal - v_valorOutrasDespesasTotal;
    r_cab_valorAdicFreteMarinTotal := r_cab_valorAdicFreteMarinTotal - v_valorAdicFreteMarinMerTotal;
    r_cab_valorDespesasAduanTotal  := r_cab_valorDespesasAduanTotal - v_valorDespesasAduaneirasTotal;
    r_cab_valorLiquidoItem         := r_cab_valorLiquidoItem - v_valorLiquidoItem;
    r_cab_valorDescCustoOpTotal    := r_cab_valorDescCustoOpTotal - v_valorDescontoCustoOpTotal;
    r_cab_valorAcrescCustoOpTotal  := r_cab_valorAcrescCustoOpTotal - v_valorAcrescimoCustoOpTotal;
    r_cab_valorCustoOperacao       := r_cab_valorCustoOperacao - v_valorCustoOperacao;
    r_cab_valorCMV                 := r_cab_valorCMV - v_valorCMV;
    r_cab_valorAcrescExtempTotal   := r_cab_valorAcrescExtempTotal - v_valorAcrescimoExtempTotal;
    v_valorFreteGeral              := v_valorFreteGeral + p_saldoRatFreteGeral;
    v_valorSeguroGeral             := v_valorSeguroGeral + p_saldoRatSeguroGeral;
    v_valorAdicFreteMarinMerGeral  := v_valorAdicFreteMarinMerGeral + p_saldoRatAdicFreteMarinGeral;
    v_valorDespesasAduaneirasGeral := v_valorDespesasAduaneirasGeral + p_saldoRatDespesasAduanGeral;
    v_valorDescontoGeral           := v_valorDescontoGeral + p_saldoRatDescontoGeral;
    v_valorOutrasDespesasGeral     := v_valorDespesasAduaneirasGeral + p_saldoRatOutrasDespesasGeral;
    v_valorDescontoPagamento       := v_valorDescontoPagamento + p_saldoRatDescontoPagamento;
    v_valorOutrasDespesasPagamento := v_valorOutrasDespesasPagamento + p_saldoRatOutrasDespPagamento;
    v_valorJurosPagamento          := v_valorJurosPagamento + p_saldoRatJurosPagamento;
    v_valorDescontoCustoOpGeral    := v_valorDescontoCustoOpGeral + p_saldoRatDescCustoOpGeral;
    v_valorAcrescimoCustoOpGeral   := v_valorAcrescimoCustoOpGeral + p_saldoRatAcrescCustoOpGeral;
    v_valorAcrescimoExtempGeral    := v_valorAcrescimoExtempGeral + p_saldoRatAcrescExtempGeral;
    ADD_CALCULA_TOTAIS_ITEM(
      p_cab_tipoPagamentoFrete,
      a.quantidade,
      a.quantidadeConvertida,
      a.precoUnitarioBruto,
      a.acrescimoUnitarioComposicao,
      a.precoUnitario,
      a.valorDescontoItem,
      a.valorAcrescimoItem,
      a.valorFreteItem,
      a.valorSeguroItem,
      a.valorAdicFreteMarinhaMerItem,
      a.valorDespesasAduaneirasItem,
      v_valorFreteGeral,
      v_valorSeguroGeral,
      v_valorDescontoGeral,
      v_valorOutrasDespesasGeral,
      v_valorAdicFreteMarinMerGeral,
      v_valorDespesasAduaneirasGeral,
      v_valorDescontoPagamento,
      v_valorOutrasDespesasPagamento,
      v_valorJurosPagamento,
      a.diminuiDescontoPrUnit,
      a.somaAcrescimosPrUnit,
      a.somaFreteSeguroPrUnit,
      a.composicaoPreco,
      /* Retornos */
      v_precoUnitario,
      v_precoUnitarioConvertido,
      v_valorProdutoServico,
      v_valorFreteTotal,
      v_valorSeguroTotal,
      v_valorDescontoTotal,
      v_valorOutrasDespesasTotal,
      v_valorAdicFreteMarinMerTotal,
      v_valorDespesasAduaneirasTotal);
    v_valorAcrescimoExtempSubtotal := FUNC_ADD_CALC_EXTEMP_SUBTOTAL(
      a.quantidade,
      v_precoUnitario,
      a.quantidadeExtemporanea,
      a.acrescimoUnitarioExtemporaneo);
    v_valorAcrescimoExtempTotal := FUNC_ADD_CALC_EXTEMP_TOTAL(
      v_valorAcrescimoExtempSubtotal,
      a.valorAcrescimoExtempItem,
      v_valorAcrescimoExtempGeral);
    IF p_cab_impostosEditados = 0 
        OR v_valorProdutoServico <> a.valorProdutoServico
        OR CASE WHEN p_cab_tipoPagamentoFrete = 'V' THEN 0 ELSE v_valorFreteTotal END
        <> CASE WHEN CASE WHEN p_troca_tipoPagamentoFrete = 1 THEN p_a_cab_tipoPagamentoFrete ELSE p_cab_tipoPagamentoFrete END = 'V' THEN 0 ELSE a.valorFreteTotal END
        OR CASE WHEN p_cab_tipoPagamentoFrete = 'V' THEN 0 ELSE v_valorSeguroTotal END
        <> CASE WHEN CASE WHEN p_troca_tipoPagamentoFrete = 1 THEN p_a_cab_tipoPagamentoFrete ELSE p_cab_tipoPagamentoFrete END = 'V' THEN 0 ELSE a.valorSeguroTotal END
        OR v_valorDescontoTotal <> a.valorDescontoTotal
        OR v_valorOutrasDespesasTotal <> a.valorOutrasDespesasTotal
        OR v_valorAdicFreteMarinMerTotal <> a.valorAdicFreteMarinhaMerTotal
        OR v_valorDespesasAduaneirasTotal <> a.valorDespesasAduaneirasTotal
        OR v_precoUnitario <> a.precoUnitario
        OR v_valorProdutoServico <> a.valorProdutoServico
    THEN
      r_calcularImpostosItem := 1;
    END IF;
    v_valorBasePagamento := FUNC_ADD_CALC_BASE_PAGAMENTO (
      p_cab_origemDocumento,
      0, -- p_cab_nfFornecedor
      p_cab_tipoPagamentoFrete,
      a.geraFinanceiro,
      v_valorProdutoServico,
      v_valorDescontoPagamento,
      v_valorOutrasDespesasPagamento,
      v_valorJurosPagamento,
      v_valorFreteTotal,
      v_valorSeguroTotal,
      v_valorDescontoTotal,
      v_valorOutrasDespesasTotal,
      a.valorIPIDevolucao,
      a.retidoISSQN,
      a.valorISSQN,
      a.valorRetIRRF,
      a.valorRetINSS,
      a.valorRetPIS,
      a.valorRetCOFINS,
      a.valorRetCSLL,
      a.valorRetOutros,
      a.valorII,
      a.valorIOF,
      a.valorIPI,
      a.valorICMSST,
      0, -- p_item_valorICMSSTEscrit
      0, -- p_item_somarICMSST
      v_valorAcrescimoExtempTotal,
      a.modDoc_geraFinanceiro);
    v_valorLiquidoItem := FUNC_ADD_CALC_VALOR_LIQUIDO (
      0, -- p_cab_nfFornecedor
      p_cab_tipoPagamentoFrete,
      v_valorProdutoServico,
      v_valorFreteTotal,
      v_valorSeguroTotal,
      v_valorDescontoTotal,
      v_valorOutrasDespesasTotal,
      a.valorIPIDevolucao,
      a.valorII,
      a.valorIOF,
      a.valorIPI,
      a.valorICMSST,
      0, -- p_item_valorICMSSTEscrit
      0 -- p_item_somarICMSST
      );
    ADD_CALCULA_CUSTO_CMV (
      p_cab_atualizaCustoMedio,
      p_cab_estabelecimento,
      0,
      a.modeloDocumento,
      a.quantidade,
      a.valorII,
      a.valorIOF,
      a.valorIPI,
      a.valorIPIDevolucao,
      a.valorPIS,
      a.valorPISST,
      a.valorCOFINS,
      a.valorCOFINSST,
      a.valorCreditoSimplesNacional,
      a.valorICMS,
      a.valorICMSST,
      0,
      v_valorLiquidoItem,
      a.valorDescontoCustoOpItem,
      v_valorDescontoCustoOpGeral,
      a.valorAcrescimoCustoOpItem,
      v_valorAcrescimoCustoOpGeral,
      v_valorAcrescimoExtempTotal,
      /* Retornos */
      v_valorDescontoCustoOpTotal,
      v_valorAcrescimoCustoOpTotal,
      v_precoCustoOperacao,
      v_valorCustoOperacao,
      v_precoCMV,
      v_valorCMV);
    UPDATE MOPREDOCUMXITENS SET
      precoUnitario                 = v_precoUnitario,
      precoUnitarioConvertido       = v_precoUnitarioConvertido,
      valorProdutoServico           = v_valorProdutoServico,
      valorFreteGeral               = v_valorFreteGeral,
      valorSeguroGeral              = v_valorSeguroGeral,
      valorDescontoGeral            = v_valorDescontoGeral,
      valorOutrasDespesasGeral      = v_valorOutrasDespesasGeral,
      valorAdicFreteMarinhaMerGeral = v_valorAdicFreteMarinMerGeral,
      valorDespesasAduaneirasGeral  = v_valorDespesasAduaneirasGeral,
      valorBasePagamento            = v_valorBasePagamento,
      valorDescontoPagamento        = v_valorDescontoPagamento,
      valorOutrasDespesasPagamento  = v_valorOutrasDespesasPagamento,
      valorJurosPagamento           = v_valorJurosPagamento,
      valorFreteTotal               = v_valorFreteTotal,
      valorSeguroTotal              = v_valorSeguroTotal,
      valorDescontoTotal            = v_valorDescontoTotal,
      valorOutrasDespesasTotal      = v_valorOutrasDespesasTotal,
      valorAdicFreteMarinhaMerTotal = v_valorAdicFreteMarinMerTotal,
      valorDespesasAduaneirasTotal  = v_valorDespesasAduaneirasTotal,
      valorLiquidoItem              = v_valorLiquidoItem,
      valorDescontoCustoOpGeral     = v_valorDescontoCustoOpGeral,
      valorDescontoCustoOpTotal     = v_valorDescontoCustoOpTotal,
      valorAcrescimoCustoOpGeral    = v_valorAcrescimoCustoOpGeral,
      valorAcrescimoCustoOpTotal    = v_valorAcrescimoCustoOpTotal,
      precoCustoOperacao            = v_precoCustoOperacao,
      valorCustoOperacao            = v_valorCustoOperacao,
      precoCMV                      = v_precoCMV,
      valorCMV                      = v_valorCMV,
      valorAcrescimoExtempSubtotal  = v_valorAcrescimoExtempSubtotal,
      valorAcrescimoExtempGeral     = v_valorAcrescimoExtempGeral,
      valorAcrescimoExtempTotal     = v_valorAcrescimoExtempTotal
    WHERE idItemPreDocumento        = p_item_idItemPreDocumento;
    IF a.tipoProduto = '09' THEN
      r_cab_valorServicos          := r_cab_valorServicos + v_valorProdutoServico;
    ELSE
      r_cab_valorProdutos          := r_cab_valorProdutos + v_valorProdutoServico;
    END IF;
    r_cab_valorBasePagamento       := r_cab_valorBasePagamento + v_valorBasePagamento;
    IF a.usarPrecoAVista = 1 AND a.geraFinanceiro = 1 THEN
      r_cab_valorAVistaMinimo      := r_cab_valorAVistaMinimo + v_valorProdutoServico + v_valorDescontoPagamento - v_valorOutrasDespesasPagamento - v_valorJurosPagamento - v_valorDescontoTotal + v_valorOutrasDespesasTotal;
    END IF;
    r_cab_valorFreteTotal          := r_cab_valorFreteTotal + v_valorFreteTotal;
    r_cab_valorSeguroTotal         := r_cab_valorSeguroTotal + v_valorSeguroTotal;
    r_cab_valorDescontoTotal       := r_cab_valorDescontoTotal + v_valorDescontoTotal;
    r_cab_valorOutrasDespesasTotal := r_cab_valorOutrasDespesasTotal + v_valorOutrasDespesasTotal;
    r_cab_valorAdicFreteMarinTotal := r_cab_valorAdicFreteMarinTotal + v_valorAdicFreteMarinMerTotal;
    r_cab_valorDespesasAduanTotal  := r_cab_valorDespesasAduanTotal + v_valorDespesasAduaneirasTotal;
    r_cab_valorDescCustoOpTotal    := r_cab_valorDescCustoOpTotal + v_valorDescontoCustoOpTotal;
    r_cab_valorLiquidoItem         := r_cab_valorLiquidoItem + v_valorLiquidoItem;
    r_cab_valorAcrescCustoOpTotal  := r_cab_valorAcrescCustoOpTotal + v_valorAcrescimoCustoOpTotal;
    r_cab_valorCustoOperacao       := r_cab_valorCustoOperacao + v_valorCustoOperacao;
    r_cab_valorCMV                 := r_cab_valorCMV + v_valorCMV;
    r_cab_valorAcrescExtempTotal   := r_cab_valorAcrescExtempTotal + v_valorAcrescimoExtempTotal;
  END LOOP;
END ADD_PRE_DOC_CALC_IMP_RESIDUO;

/

create or replace PROCEDURE ADD_DOC_FISC_CALC_IMP_RESIDUO (
    p_troca_tipoPagamentoFrete     IN NUMBER,
    p_a_cab_tipoPagamentoFrete     IN CHAR,
    p_cab_origemDocumento          IN NUMBER,
    p_cab_atualizaCustoMedio       IN NUMBER,
    p_cab_estabelecimento          IN NUMBER,
    p_cab_nfFornecedor             IN NUMBER,
    p_cab_tipoPagamentoFrete       IN CHAR,
    p_cab_valorProdutos            IN NUMBER,
    p_cab_valorServicos            IN NUMBER,
    p_cab_valorBasePagamento       IN NUMBER,
    p_cab_valorAVistaMinimo        IN NUMBER,
    p_cab_valorFreteTotal          IN NUMBER,
    p_cab_valorSeguroTotal         IN NUMBER,
    p_cab_valorDescontoTotal       IN NUMBER,
    p_cab_valorOutrasDespesasTotal IN NUMBER,
    p_cab_valorAdicFreteMarinTotal IN NUMBER,
    p_cab_valorDespesasAduanTotal  IN NUMBER,
    p_cab_impostosEditados         IN NUMBER,
    p_cab_valorLiquidoItem         IN NUMBER,
    p_cab_valorDescCustoOpTotal    IN NUMBER,
    p_cab_valorAcrescCustoOpTotal  IN NUMBER,
    p_cab_valorCustoOperacao       IN NUMBER,
    p_cab_valorCMV                 IN NUMBER,
    p_cab_valorAcrescExtempTotal   IN NUMBER,
    p_item_idItemDocFiscal         IN NUMBER,
    p_saldoRatFreteGeral           IN NUMBER,
    p_saldoRatSeguroGeral          IN NUMBER,
    p_saldoRatDescontoGeral        IN NUMBER,
    p_saldoRatOutrasDespesasGeral  IN NUMBER,
    p_saldoRatAdicFreteMarinGeral  IN NUMBER,
    p_saldoRatDespesasAduanGeral   IN NUMBER,
    p_saldoRatDescontoPagamento    IN NUMBER,
    p_saldoRatOutrasDespPagamento  IN NUMBER,
    p_saldoRatJurosPagamento       IN NUMBER,
    p_saldoRatDescCustoOpGeral     IN NUMBER,
    p_saldoRatAcrescCustoOpGeral   IN NUMBER,
    p_saldoRatAcrescExtempGeral    IN NUMBER,
    p_calcularImpostosItem         IN NUMBER,
    /* Retornos */
    r_cab_valorProdutos            OUT NUMBER,
    r_cab_valorServicos            OUT NUMBER,
    r_cab_valorBasePagamento       OUT NUMBER,
    r_cab_valorAVistaMinimo        OUT NUMBER,
    r_cab_valorFreteTotal          OUT NUMBER,
    r_cab_valorSeguroTotal         OUT NUMBER,
    r_cab_valorDescontoTotal       OUT NUMBER,
    r_cab_valorOutrasDespesasTotal OUT NUMBER,
    r_cab_valorAdicFreteMarinTotal OUT NUMBER,
    r_cab_valorDespesasAduanTotal  OUT NUMBER,
    r_cab_valorLiquidoItem         OUT NUMBER,
    r_cab_valorDescCustoOpTotal    OUT NUMBER,
    r_cab_valorAcrescCustoOpTotal  OUT NUMBER,
    r_cab_valorCustoOperacao       OUT NUMBER,
    r_cab_valorCMV                 OUT NUMBER,
    r_cab_valorAcrescExtempTotal   OUT NUMBER,
    r_calcularImpostosItem         OUT NUMBER)  
IS
    v_auxNumber                    NUMBER;
    v_precoUnitario                NUMBER;
    v_precoUnitarioConvertido      NUMBER;
    v_valorProdutoServico          NUMBER;
    v_valorFreteGeral              NUMBER;
    v_valorSeguroGeral             NUMBER;
    v_valorDescontoGeral           NUMBER;
    v_valorOutrasDespesasGeral     NUMBER;
    v_valorAdicFreteMarinMerGeral  NUMBER;
    v_valorDespesasAduaneirasGeral NUMBER;
    v_valorBasePagamento           NUMBER;
    v_valorDescontoPagamento       NUMBER;
    v_valorOutrasDespesasPagamento NUMBER;
    v_valorJurosPagamento          NUMBER;
    v_valorFreteTotal              NUMBER;
    v_valorSeguroTotal             NUMBER;
    v_valorDescontoTotal           NUMBER;
    v_valorOutrasDespesasTotal     NUMBER;
    v_valorAdicFreteMarinMerTotal  NUMBER;
    v_valorDespesasAduaneirasTotal NUMBER;
    v_valorLiquidoItem             NUMBER;
    v_valorDescontoCustoOpGeral    NUMBER;
    v_valorDescontoCustoOpTotal    NUMBER;
    v_valorAcrescimoCustoOpGeral   NUMBER;
    v_valorAcrescimoCustoOpTotal   NUMBER;
    v_precoCustoOperacao           NUMBER;
    v_valorCustoOperacao           NUMBER;
    v_precoCMV                     NUMBER;
    v_valorCMV                     NUMBER;
    v_valorAcrescimoExtempSubtotal NUMBER;
    v_valorAcrescimoExtempGeral    NUMBER;
    v_valorAcrescimoExtempTotal    NUMBER;
    v_calculoImpostosPendenteItem  NUMBER;
BEGIN
  r_cab_valorProdutos            := p_cab_valorProdutos;
  r_cab_valorServicos            := p_cab_valorServicos;
  r_cab_valorBasePagamento       := p_cab_valorBasePagamento;
  r_cab_valorAVistaMinimo        := p_cab_valorAVistaMinimo;
  r_cab_valorFreteTotal          := p_cab_valorFreteTotal;
  r_cab_valorSeguroTotal         := p_cab_valorSeguroTotal;
  r_cab_valorDescontoTotal       := p_cab_valorDescontoTotal;
  r_cab_valorOutrasDespesasTotal := p_cab_valorOutrasDespesasTotal;
  r_cab_valorAdicFreteMarinTotal := p_cab_valorAdicFreteMarinTotal;
  r_cab_valorDespesasAduanTotal  := p_cab_valorDespesasAduanTotal;
  r_cab_valorLiquidoItem         := p_cab_valorLiquidoItem;
  r_cab_valorDescCustoOpTotal    := p_cab_valorDescCustoOpTotal;
  r_cab_valorAcrescCustoOpTotal  := p_cab_valorAcrescCustoOpTotal;
  r_cab_valorCustoOperacao       := p_cab_valorCustoOperacao;
  r_cab_valorCMV                 := p_cab_valorCMV;
  r_cab_valorAcrescExtempTotal   := p_cab_valorAcrescExtempTotal;
  r_calcularImpostosItem         := p_calcularImpostosItem;
  FOR a IN (
    SELECT
      a.modeloDocumento,
      a.geraFinanceiro,
      a.quantidade,
      a.quantidadeConvertida,
      a.usarPrecoAVista,
      a.precoUnitarioBruto,
      a.acrescimoUnitarioComposicao,
      a.precoUnitario,
      a.precoUnitarioConvertido,
      a.valorProdutoServicoBruto,
      a.valorProdutoServico,
      a.valorDescontoItem,
      a.valorAcrescimoItem,
      a.valorFreteItem,
      a.valorSeguroItem,
      a.valorAdicFreteMarinhaMerItem,
      a.valorDespesasAduaneirasItem,
      a.valorFreteGeral,
      a.valorSeguroGeral,
      a.valorDescontoGeral,
      a.valorOutrasDespesasGeral,
      a.valorAdicFreteMarinhaMerGeral,
      a.valorDespesasAduaneirasGeral,
      a.valorBasePagamento,
      a.valorDescontoPagamento,
      a.valorOutrasDespesasPagamento,
      a.valorJurosPagamento,
      a.valorFreteTotal,
      a.valorSeguroTotal,
      a.valorDescontoTotal,
      a.valorOutrasDespesasTotal,
      a.valorAdicFreteMarinhaMerTotal,
      a.valorDespesasAduaneirasTotal,
      a.valorIPIDevolucao,
      a.retidoISSQN,
      a.valorISSQN,
      a.valorRetIRRF,
      a.valorRetINSS,
      a.valorRetPIS,
      a.valorRetCOFINS,
      a.valorRetCSLL,
      a.valorRetOutros,
      a.valorII,
      a.valorIOF,
      a.valorIPI,
      a.valorPIS,
      a.valorPISST,
      a.valorCOFINS,
      a.valorCOFINSST,
      a.valorCreditoSimplesNacional,
      a.valorICMS,
      a.valorICMSST,
      a.valorICMSSTEscrituracao,
      a.somarICMSST,
      a.valorLiquidoItem,
      a.valorDescontoCustoOpItem,
      a.valorDescontoCustoOpGeral,
      a.valorDescontoCustoOpTotal,
      a.valorAcrescimoCustoOpItem,
      a.valorAcrescimoCustoOpGeral,
      a.valorAcrescimoCustoOpTotal,
      a.precoCustoOperacao,
      a.valorCustoOperacao,
      a.precoCMV,
      a.valorCMV,
      a.quantidadeExtemporanea,
      a.acrescimoUnitarioExtemporaneo,
      a.valorAcrescimoExtempSubtotal,
      a.valorAcrescimoExtempItem,
      a.valorAcrescimoExtempGeral,
      a.valorAcrescimoExtempTotal,
      modDoc.geraFinanceiro modDoc_geraFinanceiro,
      modDoc.diminuiDescontoPrUnit,
      modDoc.somaAcrescimosPrUnit,
      modDoc.somaFreteSeguroPrUnit,
      prod.tipoProduto,
      CASE
        WHEN EXISTS (
          SELECT 1
          FROM CAPRODUTOXCOMPOSICOESPREC compPrec
          WHERE compPrec.produto = gradProd.produto
          AND compPrec.ativo = 1)
        THEN 1
        ELSE 0
      END composicaoPreco
    FROM MODOCFISCALXITENS a
    JOIN PAMODELOSDOCUMENTO modDoc
    ON modDoc.modeloDocumento = a.modeloDocumento
    JOIN CAGRADESPRODUTO gradProd
    ON gradProd.gradeProduto = a.gradeProduto
    JOIN CAPRODUTOS prod
    ON prod.produto = gradProd.produto
    WHERE a.idItemDocFiscal = p_item_idItemDocFiscal
    ORDER BY a.sequencia)
  LOOP
    v_precoUnitario                := a.precoUnitario;
    v_precoUnitarioConvertido      := a.precoUnitarioConvertido;
    v_valorProdutoServico          := a.valorProdutoServico;
    v_valorFreteGeral              := a.valorFreteGeral;
    v_valorSeguroGeral             := a.valorSeguroGeral;
    v_valorDescontoGeral           := a.valorDescontoGeral;
    v_valorOutrasDespesasGeral     := a.valorOutrasDespesasGeral;
    v_valorAdicFreteMarinMerGeral  := a.valorAdicFreteMarinhaMerGeral;
    v_valorDespesasAduaneirasGeral := a.valorDespesasAduaneirasGeral;
    v_valorBasePagamento           := a.valorBasePagamento;
    v_valorDescontoPagamento       := a.valorDescontoPagamento;
    v_valorOutrasDespesasPagamento := a.valorOutrasDespesasPagamento;
    v_valorJurosPagamento          := a.valorJurosPagamento;
    v_valorFreteTotal              := a.valorFreteTotal;
    v_valorSeguroTotal             := a.valorSeguroTotal;
    v_valorDescontoTotal           := a.valorDescontoTotal;
    v_valorOutrasDespesasTotal     := a.valorOutrasDespesasTotal;
    v_valorAdicFreteMarinMerTotal  := a.valorAdicFreteMarinhaMerTotal;
    v_valorDespesasAduaneirasTotal := a.valorDespesasAduaneirasTotal;
    v_valorLiquidoItem             := a.valorLiquidoItem;
    v_valorDescontoCustoOpGeral    := a.valorDescontoCustoOpGeral;
    v_valorDescontoCustoOpTotal    := a.valorDescontoCustoOpTotal;
    v_valorAcrescimoCustoOpGeral   := a.valorAcrescimoCustoOpGeral;
    v_valorAcrescimoCustoOpTotal   := a.valorAcrescimoCustoOpTotal;
    v_precoCustoOperacao           := a.precoCustoOperacao;
    v_valorCustoOperacao           := a.valorCustoOperacao;
    v_precoCMV                     := a.precoCMV;
    v_valorCMV                     := a.valorCMV;
    v_valorAcrescimoExtempSubtotal := a.valorAcrescimoExtempSubtotal;
    v_valorAcrescimoExtempGeral    := a.valorAcrescimoExtempGeral;
    v_valorAcrescimoExtempTotal    := a.valorAcrescimoExtempTotal;    
    IF a.tipoProduto = '09' THEN
      r_cab_valorServicos          := r_cab_valorServicos - v_valorProdutoServico;
    ELSE
      r_cab_valorProdutos          := r_cab_valorProdutos - v_valorProdutoServico;
    END IF;
    r_cab_valorBasePagamento       := r_cab_valorBasePagamento - v_valorBasePagamento;
    IF a.usarPrecoAVista = 1 AND a.geraFinanceiro = 1 THEN
      r_cab_valorAVistaMinimo      := r_cab_valorAVistaMinimo - v_valorProdutoServico - v_valorDescontoPagamento + v_valorOutrasDespesasPagamento + v_valorJurosPagamento + v_valorDescontoTotal - v_valorOutrasDespesasTotal;
    END IF;
    r_cab_valorFreteTotal          := r_cab_valorFreteTotal - v_valorFreteTotal;
    r_cab_valorSeguroTotal         := r_cab_valorSeguroTotal - v_valorSeguroTotal;
    r_cab_valorDescontoTotal       := r_cab_valorDescontoTotal - v_valorDescontoTotal;
    r_cab_valorOutrasDespesasTotal := r_cab_valorOutrasDespesasTotal - v_valorOutrasDespesasTotal;
    r_cab_valorAdicFreteMarinTotal := r_cab_valorAdicFreteMarinTotal - v_valorAdicFreteMarinMerTotal;
    r_cab_valorDespesasAduanTotal  := r_cab_valorDespesasAduanTotal - v_valorDespesasAduaneirasTotal;
    r_cab_valorLiquidoItem         := r_cab_valorLiquidoItem - v_valorLiquidoItem;
    r_cab_valorDescCustoOpTotal    := r_cab_valorDescCustoOpTotal - v_valorDescontoCustoOpTotal;
    r_cab_valorAcrescCustoOpTotal  := r_cab_valorAcrescCustoOpTotal - v_valorAcrescimoCustoOpTotal;
    r_cab_valorCustoOperacao       := r_cab_valorCustoOperacao - v_valorCustoOperacao;
    r_cab_valorCMV                 := r_cab_valorCMV - v_valorCMV;
    r_cab_valorAcrescExtempTotal   := r_cab_valorAcrescExtempTotal - v_valorAcrescimoExtempTotal;
    v_valorFreteGeral              := v_valorFreteGeral + p_saldoRatFreteGeral;
    v_valorSeguroGeral             := v_valorSeguroGeral + p_saldoRatSeguroGeral;
    v_valorAdicFreteMarinMerGeral  := v_valorAdicFreteMarinMerGeral + p_saldoRatAdicFreteMarinGeral;
    v_valorDespesasAduaneirasGeral := v_valorDespesasAduaneirasGeral + p_saldoRatDespesasAduanGeral;
    v_valorDescontoGeral           := v_valorDescontoGeral + p_saldoRatDescontoGeral;
    v_valorOutrasDespesasGeral     := v_valorDespesasAduaneirasGeral + p_saldoRatOutrasDespesasGeral;
    v_valorDescontoPagamento       := v_valorDescontoPagamento + p_saldoRatDescontoPagamento;
    v_valorOutrasDespesasPagamento := v_valorOutrasDespesasPagamento + p_saldoRatOutrasDespPagamento;
    v_valorJurosPagamento          := v_valorJurosPagamento + p_saldoRatJurosPagamento;
    v_valorDescontoCustoOpGeral    := v_valorDescontoCustoOpGeral + p_saldoRatDescCustoOpGeral;
    v_valorAcrescimoCustoOpGeral   := v_valorAcrescimoCustoOpGeral + p_saldoRatAcrescCustoOpGeral;
    v_valorAcrescimoExtempGeral    := v_valorAcrescimoExtempGeral + p_saldoRatAcrescExtempGeral;
    ADD_CALCULA_TOTAIS_ITEM(
      p_cab_tipoPagamentoFrete,
      a.quantidade,
      a.quantidadeConvertida,
      a.precoUnitarioBruto,
      a.acrescimoUnitarioComposicao,
      a.precoUnitario,
      a.valorDescontoItem,
      a.valorAcrescimoItem,
      a.valorFreteItem,
      a.valorSeguroItem,
      a.valorAdicFreteMarinhaMerItem,
      a.valorDespesasAduaneirasItem,
      v_valorFreteGeral,
      v_valorSeguroGeral,
      v_valorDescontoGeral,
      v_valorOutrasDespesasGeral,
      v_valorAdicFreteMarinMerGeral,
      v_valorDespesasAduaneirasGeral,
      v_valorDescontoPagamento,
      v_valorOutrasDespesasPagamento,
      v_valorJurosPagamento,
      a.diminuiDescontoPrUnit,
      a.somaAcrescimosPrUnit,
      a.somaFreteSeguroPrUnit,
      a.composicaoPreco,
      /* Retornos */
      v_precoUnitario,
      v_precoUnitarioConvertido,
      v_valorProdutoServico,
      v_valorFreteTotal,
      v_valorSeguroTotal,
      v_valorDescontoTotal,
      v_valorOutrasDespesasTotal,
      v_valorAdicFreteMarinMerTotal,
      v_valorDespesasAduaneirasTotal);
    v_valorAcrescimoExtempSubtotal := FUNC_ADD_CALC_EXTEMP_SUBTOTAL(
      a.quantidade,
      v_precoUnitario,
      a.quantidadeExtemporanea,
      a.acrescimoUnitarioExtemporaneo);
    v_valorAcrescimoExtempTotal := FUNC_ADD_CALC_EXTEMP_TOTAL(
      v_valorAcrescimoExtempSubtotal,
      a.valorAcrescimoExtempItem,
      v_valorAcrescimoExtempGeral);
    IF p_cab_impostosEditados = 0 
        OR v_valorProdutoServico <> a.valorProdutoServico
        OR CASE WHEN p_cab_tipoPagamentoFrete = 'V' THEN 0 ELSE v_valorFreteTotal END
        <> CASE WHEN CASE WHEN p_troca_tipoPagamentoFrete = 1 THEN p_a_cab_tipoPagamentoFrete ELSE p_cab_tipoPagamentoFrete END = 'V' THEN 0 ELSE a.valorFreteTotal END
        OR CASE WHEN p_cab_tipoPagamentoFrete = 'V' THEN 0 ELSE v_valorSeguroTotal END
        <> CASE WHEN CASE WHEN p_troca_tipoPagamentoFrete = 1 THEN p_a_cab_tipoPagamentoFrete ELSE p_cab_tipoPagamentoFrete END = 'V' THEN 0 ELSE a.valorSeguroTotal END
        OR v_valorDescontoTotal <> a.valorDescontoTotal
        OR v_valorOutrasDespesasTotal <> a.valorOutrasDespesasTotal
        OR v_valorAdicFreteMarinMerTotal <> a.valorAdicFreteMarinhaMerTotal
        OR v_valorDespesasAduaneirasTotal <> a.valorDespesasAduaneirasTotal
        OR v_precoUnitario <> a.precoUnitario
        OR v_valorProdutoServico <> a.valorProdutoServico
    THEN
      r_calcularImpostosItem := 1;
    END IF;
    v_valorBasePagamento := FUNC_ADD_CALC_BASE_PAGAMENTO (
      p_cab_origemDocumento,
      p_cab_nfFornecedor,
      p_cab_tipoPagamentoFrete,
      a.geraFinanceiro,
      v_valorProdutoServico,
      v_valorDescontoPagamento,
      v_valorOutrasDespesasPagamento,
      v_valorJurosPagamento,
      v_valorFreteTotal,
      v_valorSeguroTotal,
      v_valorDescontoTotal,
      v_valorOutrasDespesasTotal,
      a.valorIPIDevolucao,
      a.retidoISSQN,
      a.valorISSQN,
      a.valorRetIRRF,
      a.valorRetINSS,
      a.valorRetPIS,
      a.valorRetCOFINS,
      a.valorRetCSLL,
      a.valorRetOutros,
      a.valorII,
      a.valorIOF,
      a.valorIPI,
      a.valorICMSST,
      a.valorICMSSTEscrituracao,
      a.somarICMSST,
      v_valorAcrescimoExtempTotal,
      a.modDoc_geraFinanceiro);
    v_valorLiquidoItem := FUNC_ADD_CALC_VALOR_LIQUIDO (
      p_cab_nfFornecedor,
      p_cab_tipoPagamentoFrete,
      v_valorProdutoServico,
      v_valorFreteTotal,
      v_valorSeguroTotal,
      v_valorDescontoTotal,
      v_valorOutrasDespesasTotal,
      a.valorIPIDevolucao,
      a.valorII,
      a.valorIOF,
      a.valorIPI,
      a.valorICMSST,
      a.valorICMSSTEscrituracao,
      a.somarICMSST);
    ADD_CALCULA_CUSTO_CMV (
      p_cab_atualizaCustoMedio,
      p_cab_estabelecimento,
      p_cab_nfFornecedor,
      a.modeloDocumento,
      a.quantidade,
      a.valorII,
      a.valorIOF,
      a.valorIPI,
      a.valorIPIDevolucao,
      a.valorPIS,
      a.valorPISST,
      a.valorCOFINS,
      a.valorCOFINSST,
      a.valorCreditoSimplesNacional,
      a.valorICMS,
      a.valorICMSST,
      a.valorICMSSTEscrituracao,
      v_valorLiquidoItem,
      a.valorDescontoCustoOpItem,
      v_valorDescontoCustoOpGeral,
      a.valorAcrescimoCustoOpItem,
      v_valorAcrescimoCustoOpGeral,
      v_valorAcrescimoExtempTotal,
      /* Retornos */
      v_valorDescontoCustoOpTotal,
      v_valorAcrescimoCustoOpTotal,
      v_precoCustoOperacao,
      v_valorCustoOperacao,
      v_precoCMV,
      v_valorCMV);
    UPDATE MODOCFISCALXITENS SET
      precoUnitario                 = v_precoUnitario,
      precoUnitarioConvertido       = v_precoUnitarioConvertido,
      valorProdutoServico           = v_valorProdutoServico,
      valorFreteGeral               = v_valorFreteGeral,
      valorSeguroGeral              = v_valorSeguroGeral,
      valorDescontoGeral            = v_valorDescontoGeral,
      valorOutrasDespesasGeral      = v_valorOutrasDespesasGeral,
      valorAdicFreteMarinhaMerGeral = v_valorAdicFreteMarinMerGeral,
      valorDespesasAduaneirasGeral  = v_valorDespesasAduaneirasGeral,
      valorBasePagamento            = v_valorBasePagamento,
      valorDescontoPagamento        = v_valorDescontoPagamento,
      valorOutrasDespesasPagamento  = v_valorOutrasDespesasPagamento,
      valorJurosPagamento           = v_valorJurosPagamento,
      valorFreteTotal               = v_valorFreteTotal,
      valorSeguroTotal              = v_valorSeguroTotal,
      valorDescontoTotal            = v_valorDescontoTotal,
      valorOutrasDespesasTotal      = v_valorOutrasDespesasTotal,
      valorAdicFreteMarinhaMerTotal = v_valorAdicFreteMarinMerTotal,
      valorDespesasAduaneirasTotal  = v_valorDespesasAduaneirasTotal,
      valorLiquidoItem              = v_valorLiquidoItem,
      valorDescontoCustoOpGeral     = v_valorDescontoCustoOpGeral,
      valorDescontoCustoOpTotal     = v_valorDescontoCustoOpTotal,
      valorAcrescimoCustoOpGeral    = v_valorAcrescimoCustoOpGeral,
      valorAcrescimoCustoOpTotal    = v_valorAcrescimoCustoOpTotal,
      precoCustoOperacao            = v_precoCustoOperacao,
      valorCustoOperacao            = v_valorCustoOperacao,
      precoCMV                      = v_precoCMV,
      valorCMV                      = v_valorCMV,
      valorAcrescimoExtempSubtotal  = v_valorAcrescimoExtempSubtotal,
      valorAcrescimoExtempGeral     = v_valorAcrescimoExtempGeral,
      valorAcrescimoExtempTotal     = v_valorAcrescimoExtempTotal
    WHERE idItemDocFiscal           = p_item_idItemDocFiscal;
    IF a.tipoProduto = '09' THEN
      r_cab_valorServicos            := r_cab_valorServicos + v_valorProdutoServico;
    ELSE
      r_cab_valorProdutos            := r_cab_valorProdutos + v_valorProdutoServico;
    END IF;
    r_cab_valorBasePagamento       := r_cab_valorBasePagamento + v_valorBasePagamento;
    IF a.usarPrecoAVista = 1 AND a.geraFinanceiro = 1 THEN
      r_cab_valorAVistaMinimo        := r_cab_valorAVistaMinimo + v_valorProdutoServico + v_valorDescontoPagamento - v_valorOutrasDespesasPagamento - v_valorJurosPagamento - v_valorDescontoTotal + v_valorOutrasDespesasTotal;
    END IF;
    r_cab_valorFreteTotal          := r_cab_valorFreteTotal + v_valorFreteTotal;
    r_cab_valorSeguroTotal         := r_cab_valorSeguroTotal + v_valorSeguroTotal;
    r_cab_valorDescontoTotal       := r_cab_valorDescontoTotal + v_valorDescontoTotal;
    r_cab_valorOutrasDespesasTotal := r_cab_valorOutrasDespesasTotal + v_valorOutrasDespesasTotal;
    r_cab_valorAdicFreteMarinTotal := r_cab_valorAdicFreteMarinTotal + v_valorAdicFreteMarinMerTotal;
    r_cab_valorDespesasAduanTotal  := r_cab_valorDespesasAduanTotal + v_valorDespesasAduaneirasTotal;
    r_cab_valorLiquidoItem         := r_cab_valorLiquidoItem + v_valorLiquidoItem;
    r_cab_valorDescCustoOpTotal    := r_cab_valorDescCustoOpTotal + v_valorDescontoCustoOpTotal;
    r_cab_valorAcrescCustoOpTotal  := r_cab_valorAcrescCustoOpTotal + v_valorAcrescimoCustoOpTotal;
    r_cab_valorCustoOperacao       := r_cab_valorCustoOperacao + v_valorCustoOperacao;
    r_cab_valorCMV                 := r_cab_valorCMV + v_valorCMV;
    r_cab_valorAcrescExtempTotal   := r_cab_valorAcrescExtempTotal + v_valorAcrescimoExtempTotal;
  END LOOP;
END ADD_DOC_FISC_CALC_IMP_RESIDUO;

/

create or replace PROCEDURE ADD_ORCAMENTO_CALC_IMP_RATEIO (
  p_cab_orcamento                IN NUMBER,
  p_troca_tipoPagamentoFrete     IN NUMBER,
  p_a_cab_tipoPagamentoFrete     IN CHAR,
  p_cab_origemDocumento          IN NUMBER,
  p_cab_modeloDocumento          IN NUMBER,
  p_cab_entradaSaida             IN CHAR,
  p_cab_atualizaCustoMedio       IN NUMBER,
  p_cab_tipoPagamentoFrete       IN CHAR,
  p_cab_valorFreteGeral          IN NUMBER,
  p_cab_valorSeguroGeral         IN NUMBER,
  p_cab_valorDescontoGeral       IN NUMBER,
  p_cab_valorOutrasDespesasGeral IN NUMBER,
  p_cab_valorAdicFreteMarinGeral IN NUMBER,
  p_cab_valorDespesasAduanGeral  IN NUMBER,
  p_cab_valorDescontoPagamento   IN NUMBER,
  p_cab_valorOutrasDespPagamento IN NUMBER,
  p_cab_valorJurosPagamento      IN NUMBER,
  p_cab_impostosEditados         IN NUMBER,
  /* Retornos */
  r_cab_valorProdutos            OUT NUMBER,
  r_cab_valorServicos            OUT NUMBER,
  r_cab_valorBasePagamento       OUT NUMBER,
  r_cab_valorAVistaMinimo        OUT NUMBER,
  r_cab_valorFreteTotal          OUT NUMBER,
  r_cab_valorSeguroTotal         OUT NUMBER,
  r_cab_valorDescontoTotal       OUT NUMBER,
  r_cab_valorOutrasDespesasTotal OUT NUMBER,
  r_cab_valorAdicFreteMarinTotal OUT NUMBER,
  r_cab_valorDespesasAduanTotal  OUT NUMBER,
  r_cab_valorLiquidoItem         OUT NUMBER,
  r_calcularImpostosItem         OUT NUMBER)
IS
  v_auxNumber                    NUMBER;
  v_valorDescontoPromocaoGeral   NUMBER;
  v_valorDescontoPromocaoPagamen NUMBER;
  v_rateioDescontofiltrarSemProm NUMBER;
  v_rateioDescontofiltrarAPrazo  NUMBER;
  v_rateioFretePorControleEntr   NUMBER;
  v_valorBaseFreteSemFinSemEntr  NUMBER;
  v_valorBaseFreteComFinSemEntr  NUMBER;
  v_valorBaseFreteSemFinComEntr  NUMBER;
  v_valorBaseFreteComFinComEntr  NUMBER;
  v_valorBaseRateio              NUMBER;
  v_valorBaseRateioComEntrega    NUMBER;
  v_valorBaseRateioFinanceiro    NUMBER;
  v_valorBaseRateioOutrasDespGer NUMBER;
  v_valorBaseRateioOutrasDespFin NUMBER;
  v_valorBaseRateioDescontoGeral NUMBER;
  v_valorBaseRateioPagamento     NUMBER;
  v_valorBaseRateioPagamFinanc   NUMBER;
  v_valorBaseRateioPagamDesconto NUMBER;
  v_valorBaseRateioPagamFinDesc  NUMBER;
  v_saldoRatFreteGeral           NUMBER;
  v_saldoRatSeguroGeral          NUMBER;
  v_saldoRatDescontoGeral        NUMBER;
  v_saldoRatOutrasDespesasGeral  NUMBER;
  v_saldoRatAdicFreteMarinGeral  NUMBER;
  v_saldoRatDespesasAduanGeral   NUMBER;
  v_saldoRatDescontoPagamento    NUMBER;
  v_saldoRatOutrasDespPagamento  NUMBER;
  v_saldoRatJurosPagamento       NUMBER;
  v_residuoFreteGeral            NUMBER;
  v_residuoSeguroGeral           NUMBER;
  v_residuoDescontoGeral         NUMBER;
  v_residuoOutrasDespesasGeral   NUMBER;
  v_residuoAdicFreteMarinGeral   NUMBER;
  v_residuoDespesasAduanGeral    NUMBER;
  v_residuoDescontoPagamento     NUMBER;
  v_residuoOutrasDespPagamento   NUMBER;
  v_residuoJurosPagamento        NUMBER;
  v_idItemOrcamentoUltimoItem    NUMBER;
  v_idItemOrcamentoRateioFrete   NUMBER;
  v_precoUnitario                NUMBER;
  v_precoUnitarioConvertido      NUMBER;
  v_valorProdutoServico          NUMBER;
  v_valorFreteGeral              NUMBER;
  v_valorSeguroGeral             NUMBER;
  v_valorDescontoGeral           NUMBER;
  v_valorOutrasDespesasGeral     NUMBER;
  v_valorAdicFreteMarinMerGeral  NUMBER;
  v_valorDespesasAduaneirasGeral NUMBER;
  v_valorBasePagamento           NUMBER;
  v_valorDescontoPagamento       NUMBER;
  v_valorOutrasDespesasPagamento NUMBER;
  v_valorJurosPagamento          NUMBER;
  v_valorFreteTotal              NUMBER;
  v_valorSeguroTotal             NUMBER;
  v_valorDescontoTotal           NUMBER;
  v_valorOutrasDespesasTotal     NUMBER;
  v_valorAdicFreteMarinMerTotal  NUMBER;
  v_valorDespesasAduaneirasTotal NUMBER;
  v_valorLiquidoItem             NUMBER;
BEGIN
  v_idItemOrcamentoUltimoItem    := 0;
  v_idItemOrcamentoRateioFrete   := 0;
  r_cab_valorProdutos            := 0;
  r_cab_valorServicos            := 0;
  r_cab_valorBasePagamento       := 0;
  r_cab_valorAVistaMinimo        := 0;
  r_cab_valorFreteTotal          := 0;
  r_cab_valorSeguroTotal         := 0;
  r_cab_valorDescontoTotal       := 0;
  r_cab_valorOutrasDespesasTotal := 0;
  r_cab_valorAdicFreteMarinTotal := 0;
  r_cab_valorDespesasAduanTotal  := 0;
  r_cab_valorLiquidoItem         := 0;
  r_calcularImpostosItem         := 0;
  v_saldoRatFreteGeral           := p_cab_valorFreteGeral;
  v_saldoRatSeguroGeral          := p_cab_valorSeguroGeral;
  v_saldoRatDescontoGeral        := p_cab_valorDescontoGeral;
  v_saldoRatOutrasDespesasGeral  := p_cab_valorOutrasDespesasGeral;
  v_saldoRatAdicFreteMarinGeral  := p_cab_valorAdicFreteMarinGeral;
  v_saldoRatDespesasAduanGeral   := p_cab_valorDespesasAduanGeral;
  v_saldoRatDescontoPagamento    := p_cab_valorDescontoPagamento;
  v_saldoRatOutrasDespPagamento  := p_cab_valorOutrasDespPagamento;
  v_saldoRatJurosPagamento       := p_cab_valorJurosPagamento;
  v_residuoFreteGeral            := 0;
  v_residuoSeguroGeral           := 0;
  v_residuoDescontoGeral         := 0;
  v_residuoOutrasDespesasGeral   := 0;
  v_residuoAdicFreteMarinGeral   := 0;
  v_residuoDespesasAduanGeral    := 0;
  v_residuoDescontoPagamento     := 0;
  v_residuoOutrasDespPagamento   := 0;
  v_residuoJurosPagamento        := 0;
  v_valorDescontoPromocaoGeral   := 0;
  v_valorDescontoPromocaoPagamen := 0;
  v_rateioDescontofiltrarSemProm := 0;
  v_rateioDescontofiltrarAPrazo  := 0;

  -- v_valorDescontoPromocaoGeral
  IF p_cab_valorDescontoGeral > 0 THEN
    SELECT COALESCE(SUM(promo.valorDesconto),0)
    INTO v_valorDescontoPromocaoGeral
    FROM MOORCAMENTOXITENS a
    JOIN MOORCAMENTOXPROMOCOES promo ON promo.idItemOrcamento = a.idItemOrcamento
    WHERE a.orcamento = p_cab_orcamento
    AND a.cancelado = 0
    AND promo.cabecalhoItemPagamento ='C';
  END IF;

  -- v_valorDescontoPromocaoPagamen
  IF p_cab_valorDescontoPagamento > 0 THEN
    SELECT COALESCE(SUM(promo.valorDesconto),0)
    INTO v_valorDescontoPromocaoPagamen
    FROM MOORCAMENTOXITENS a
    JOIN MOORCAMENTOXPROMOCOES promo ON promo.idItemOrcamento = a.idItemOrcamento
    WHERE a.orcamento = p_cab_orcamento
    AND a.cancelado = 0
    AND promo.cabecalhoItemPagamento ='P';
  END IF;

  -- v_rateioDescontofiltrarSemProm
  IF p_cab_valorDescontoGeral > v_valorDescontoPromocaoGeral OR p_cab_valorDescontoPagamento > v_valorDescontoPromocaoPagamen THEN
    SELECT
      CASE
        WHEN EXISTS(
          SELECT 1
          FROM MOORCAMENTOXITENS a
          JOIN PAMODELOSDOCUMENTO modDoc
          ON modDoc.modeloDocumento = a.modeloDocumento
          WHERE a.orcamento = p_cab_orcamento
          AND a.cancelado = 0
          AND COALESCE((
            SELECT SUM(b.valorDesconto)
            FROM MOORCAMENTOXPROMOCOES b
            WHERE b.idItemOrcamento = a.idItemOrcamento
            AND b.cabecalhoItemPagamento IN ('C','P')),0) > (
            CASE
              WHEN modDoc.diminuiDescontoPrUnit = 1
                OR modDoc.somaAcrescimosPrUnit  = 1
                OR modDoc.somaFreteSeguroPrUnit = 1
              THEN a.valorProdutoServicoBruto
              ELSE a.valorProdutoServico
            END
            - a.valorDescontoItem
            + a.valorAcrescimoItem))
        THEN 0
        WHEN COALESCE ((
          SELECT SUM (CASE WHEN modDoc.diminuiDescontoPrUnit = 1 OR modDoc.somaAcrescimosPrUnit = 1 or modDoc.somaFreteSeguroPrUnit = 1 THEN a.valorProdutoServicoBruto ELSE a.valorProdutoServico END - a.valorDescontoItem + a.valorAcrescimoItem)
          FROM MOORCAMENTOXITENS a
          JOIN PAMODELOSDOCUMENTO modDoc
          ON modDoc.modeloDocumento = a.modeloDocumento
          JOIN MOORCAMENTOXPROMOCOES b
          ON b.idItemOrcamento = a.idItemOrcamento
          WHERE a.orcamento = p_cab_orcamento
          AND a.cancelado = 0),0) > (
            CASE
              WHEN p_cab_valorDescontoGeral > v_valorDescontoPromocaoGeral
              THEN p_cab_valorDescontoGeral - v_valorDescontoPromocaoGeral
              ELSE 0
            END +
            CASE
              WHEN p_cab_valorDescontoPagamento > v_valorDescontoPromocaoPagamen
              THEN p_cab_valorDescontoPagamento - v_valorDescontoPromocaoPagamen
              ELSE 0
            END)
          AND EXISTS (
            SELECT 1
            FROM MOORCAMENTOXITENS a
            WHERE a.orcamento = p_cab_orcamento
            AND a.cancelado = 0
            AND NOT (EXISTS(
              SELECT 1
              FROM MOORCAMENTOXPROMOCOES b
              WHERE b.idItemOrcamento = a.idItemOrcamento)))
        THEN 1
        ELSE 0
      END
    INTO v_rateioDescontofiltrarSemProm
    FROM DUAL;
  END IF;

  -- v_rateioDescontofiltrarAPrazo
  IF p_cab_valorDescontoGeral > v_valorDescontoPromocaoGeral OR p_cab_valorDescontoPagamento > v_valorDescontoPromocaoPagamen THEN
    SELECT
      CASE
        WHEN COALESCE ((
          SELECT SUM (CASE WHEN modDoc.diminuiDescontoPrUnit = 1 OR modDoc.somaAcrescimosPrUnit = 1 or modDoc.somaFreteSeguroPrUnit = 1 THEN a.valorProdutoServicoBruto ELSE a.valorProdutoServico END - a.valorDescontoItem + a.valorAcrescimoItem)
          FROM MOORCAMENTOXITENS a
          JOIN PAMODELOSDOCUMENTO modDoc
          ON modDoc.modeloDocumento = a.modeloDocumento
          WHERE a.orcamento = p_cab_orcamento
          AND a.cancelado = 0
          AND a.precoSugestaoAPrazo <> a.precoSugestaoAVista
          AND a.usarPrecoAVista = 1
          AND (v_rateioDescontofiltrarSemProm = 0
            OR NOT(EXISTS(
              SELECT 1
              FROM MOORCAMENTOXPROMOCOES promo
              WHERE promo.idItemOrcamento = a.idItemOrcamento)))),0) > (
            CASE
              WHEN p_cab_valorDescontoGeral > v_valorDescontoPromocaoGeral
              THEN p_cab_valorDescontoGeral - v_valorDescontoPromocaoGeral
              ELSE 0
            END +
            CASE
              WHEN p_cab_valorDescontoPagamento > v_valorDescontoPromocaoPagamen
              THEN p_cab_valorDescontoPagamento - v_valorDescontoPromocaoPagamen
              ELSE 0
            END)
          AND EXISTS (
            SELECT 1
            FROM MOORCAMENTOXITENS a
            WHERE a.orcamento = p_cab_orcamento
            AND a.cancelado = 0
            AND (a.precoSugestaoAPrazo = a.precoSugestaoAVista
              OR a.usarPrecoAVista = 0)
            AND (v_rateioDescontofiltrarSemProm = 0
              OR NOT(EXISTS(
                SELECT 1
                FROM MOORCAMENTOXPROMOCOES promo
                WHERE promo.idItemOrcamento = a.idItemOrcamento))))
        THEN 1
        ELSE 0
      END
    INTO v_rateioDescontofiltrarAPrazo
    FROM DUAL;
  END IF;

  -- Bases Rateio
  SELECT
    COALESCE(MAX(CASE WHEN modDoc.habilitaControleEntrega = 0 OR a.controleEntrega > 0 AND contr.habilitaFrete = 1 THEN 1 ELSE 0 END),0),
    COALESCE(SUM(CASE WHEN modDoc.geraFinanceiro = 1 THEN CASE WHEN modDoc.diminuiDescontoPrUnit = 1 OR modDoc.somaAcrescimosPrUnit = 1 or modDoc.somaFreteSeguroPrUnit = 1 THEN a.valorProdutoServicoBruto ELSE a.valorProdutoServico END - a.valorDescontoItem + a.valorAcrescimoItem ELSE 0 END),0),
    COALESCE(SUM(CASE WHEN a.geraFinanceiro = 1 THEN CASE WHEN modDoc.diminuiDescontoPrUnit = 1 OR modDoc.somaAcrescimosPrUnit = 1 or modDoc.somaFreteSeguroPrUnit = 1 THEN a.valorProdutoServicoBruto ELSE a.valorProdutoServico END - a.valorDescontoItem + a.valorAcrescimoItem ELSE 0 END),0),
    COALESCE(SUM(CASE WHEN modDoc.geraFinanceiro = 1 AND (modDoc.habilitaControleEntrega = 0 OR a.controleEntrega > 0 AND contr.habilitaFrete = 1) THEN CASE WHEN modDoc.diminuiDescontoPrUnit = 1 OR modDoc.somaAcrescimosPrUnit = 1 or modDoc.somaFreteSeguroPrUnit = 1 THEN a.valorProdutoServicoBruto ELSE a.valorProdutoServico END - a.valorDescontoItem + a.valorAcrescimoItem ELSE 0 END),0),
    COALESCE(SUM(CASE WHEN a.geraFinanceiro = 1 AND (modDoc.habilitaControleEntrega = 0 OR a.controleEntrega > 0 AND contr.habilitaFrete = 1) THEN CASE WHEN modDoc.diminuiDescontoPrUnit = 1 OR modDoc.somaAcrescimosPrUnit = 1 or modDoc.somaFreteSeguroPrUnit = 1 THEN a.valorProdutoServicoBruto ELSE a.valorProdutoServico END - a.valorDescontoItem + a.valorAcrescimoItem ELSE 0 END),0),
    COALESCE(SUM(CASE WHEN modDoc.diminuiDescontoPrUnit = 1 OR modDoc.somaAcrescimosPrUnit = 1 or modDoc.somaFreteSeguroPrUnit = 1 THEN a.valorProdutoServicoBruto ELSE a.valorProdutoServico END - a.valorDescontoItem + a.valorAcrescimoItem),0),
    COALESCE(SUM(CASE WHEN modDoc.habilitaControleEntrega = 0 OR a.controleEntrega > 0 AND contr.habilitaFrete = 1 THEN CASE WHEN modDoc.diminuiDescontoPrUnit = 1 OR modDoc.somaAcrescimosPrUnit = 1 or modDoc.somaFreteSeguroPrUnit = 1 THEN a.valorProdutoServicoBruto ELSE a.valorProdutoServico END - a.valorDescontoItem + a.valorAcrescimoItem ELSE 0 END),0),
    COALESCE(SUM(CASE WHEN a.geraFinanceiro = 1 THEN CASE WHEN modDoc.diminuiDescontoPrUnit = 1 OR modDoc.somaAcrescimosPrUnit = 1 or modDoc.somaFreteSeguroPrUnit = 1 THEN a.valorProdutoServicoBruto ELSE a.valorProdutoServico END - a.valorDescontoItem + a.valorAcrescimoItem ELSE 0 END),0),
    COALESCE(SUM(CASE WHEN modDoc.diminuiDescontoPrUnit = 1 OR modDoc.somaAcrescimosPrUnit = 1 or modDoc.somaFreteSeguroPrUnit = 1 THEN a.valorProdutoServicoBruto ELSE a.valorProdutoServico - a.valorDescontoItem + a.valorAcrescimoItem END),0),
    COALESCE(SUM(CASE WHEN a.geraFinanceiro = 1 THEN CASE WHEN modDoc.diminuiDescontoPrUnit = 1 OR modDoc.somaAcrescimosPrUnit = 1 or modDoc.somaFreteSeguroPrUnit = 1 THEN a.valorProdutoServicoBruto ELSE a.valorProdutoServico - a.valorDescontoItem + a.valorAcrescimoItem END ELSE 0 END),0),
    COALESCE(SUM(CASE WHEN (v_rateioDescontofiltrarAPrazo = 0 OR a.precoSugestaoAPrazo = a.precoSugestaoAVista OR a.usarPrecoAVista = 0) AND (v_rateioDescontofiltrarSemProm = 0 OR NOT(EXISTS(SELECT 1 FROM MOORCAMENTOXPROMOCOES promo WHERE promo.idItemOrcamento = a.idItemOrcamento))) THEN CASE WHEN modDoc.diminuiDescontoPrUnit = 1 OR modDoc.somaAcrescimosPrUnit = 1 or modDoc.somaFreteSeguroPrUnit = 1 THEN a.valorProdutoServicoBruto ELSE a.valorProdutoServico - a.valorDescontoItem + a.valorAcrescimoItem END ELSE 0 END),0),
    COALESCE(SUM(CASE WHEN modDoc.diminuiDescontoPrUnit = 1 OR modDoc.somaAcrescimosPrUnit = 1 or modDoc.somaFreteSeguroPrUnit = 1 THEN a.valorProdutoServicoBruto ELSE a.valorProdutoServico END - a.valorDescontoItem + a.valorAcrescimoItem),0),
    COALESCE(SUM(CASE WHEN a.geraFinanceiro = 1 THEN CASE WHEN modDoc.diminuiDescontoPrUnit = 1 OR modDoc.somaAcrescimosPrUnit = 1 or modDoc.somaFreteSeguroPrUnit = 1 THEN a.valorProdutoServicoBruto ELSE a.valorProdutoServico END - a.valorDescontoItem + a.valorAcrescimoItem ELSE 0 END),0),
    COALESCE(SUM(CASE WHEN (v_rateioDescontofiltrarAPrazo = 0 OR a.precoSugestaoAPrazo = a.precoSugestaoAVista OR a.usarPrecoAVista = 0) AND (v_rateioDescontofiltrarSemProm = 0 OR NOT(EXISTS(SELECT 1 FROM MOORCAMENTOXPROMOCOES promo WHERE promo.idItemOrcamento = a.idItemOrcamento))) THEN CASE WHEN modDoc.diminuiDescontoPrUnit = 1 OR modDoc.somaAcrescimosPrUnit = 1 or modDoc.somaFreteSeguroPrUnit = 1 THEN a.valorProdutoServicoBruto ELSE a.valorProdutoServico END - a.valorDescontoItem + a.valorAcrescimoItem ELSE 0 END),0),
    COALESCE(SUM(CASE WHEN a.geraFinanceiro = 1 AND (v_rateioDescontofiltrarAPrazo = 0 OR a.precoSugestaoAPrazo = a.precoSugestaoAVista OR a.usarPrecoAVista = 0) AND (v_rateioDescontofiltrarSemProm = 0 OR NOT(EXISTS(SELECT 1 FROM MOORCAMENTOXPROMOCOES promo WHERE promo.idItemOrcamento = a.idItemOrcamento))) THEN CASE WHEN modDoc.diminuiDescontoPrUnit = 1 OR modDoc.somaAcrescimosPrUnit = 1 or modDoc.somaFreteSeguroPrUnit = 1 THEN a.valorProdutoServicoBruto ELSE a.valorProdutoServico END - a.valorDescontoItem + a.valorAcrescimoItem ELSE 0 END),0)
  INTO
    v_rateioFretePorControleEntr,
    v_valorBaseFreteSemFinSemEntr,
    v_valorBaseFreteComFinSemEntr,
    v_valorBaseFreteSemFinComEntr,
    v_valorBaseFreteComFinComEntr,
    v_valorBaseRateio,
    v_valorBaseRateioComEntrega,
    v_valorBaseRateioFinanceiro,
    v_valorBaseRateioOutrasDespGer,
    v_valorBaseRateioOutrasDespFin,
    v_valorBaseRateioDescontoGeral,
    v_valorBaseRateioPagamento,
    v_valorBaseRateioPagamFinanc,
    v_valorBaseRateioPagamDesconto,
    v_valorBaseRateioPagamFinDesc
  FROM MOORCAMENTOXITENS a
  JOIN PAMODELOSDOCUMENTO modDoc
  ON modDoc.modeloDocumento = a.modeloDocumento
  JOIN PACONTROLESENTREGA contr
  ON contr.controleEntrega = a.controleEntrega
  WHERE a.orcamento = p_cab_orcamento
  AND a.cancelado = 0;

  -- Efetua rateio
  FOR a IN (
    SELECT
      a.idItemOrcamento,
      a.geraFinanceiro,
      a.quantidade,
      a.quantidadeConvertida,
      a.usarPrecoAVista,
      a.precoUnitarioBruto,
      a.acrescimoUnitarioComposicao,
      a.precoUnitario,
      a.precoUnitarioConvertido,
      a.valorProdutoServicoBruto,
      a.valorProdutoServico,
      a.valorDescontoItem,
      a.valorAcrescimoItem,
      a.valorFreteItem,
      a.valorSeguroItem,
      a.valorAdicFreteMarinhaMerItem,
      a.valorDespesasAduaneirasItem,
      a.valorFreteGeral,
      a.valorSeguroGeral,
      a.valorDescontoGeral,
      a.valorOutrasDespesasGeral,
      a.valorAdicFreteMarinhaMerGeral,
      a.valorDespesasAduaneirasGeral,
      a.valorBasePagamento,
      a.valorDescontoPagamento,
      a.valorOutrasDespesasPagamento,
      a.valorJurosPagamento,
      a.valorFreteTotal,
      a.valorSeguroTotal,
      a.valorDescontoTotal,
      a.valorOutrasDespesasTotal,
      a.valorAdicFreteMarinhaMerTotal,
      a.valorDespesasAduaneirasTotal,
      a.retidoISSQN,
      a.valorISSQN,
      a.valorRetIRRF,
      a.valorRetINSS,
      a.valorRetPIS,
      a.valorRetCOFINS,
      a.valorRetCSLL,
      a.valorRetOutros,
      a.valorII,
      a.valorIOF,
      a.valorIPI,
      a.valorPIS,
      a.valorPISST,
      a.valorCOFINS,
      a.valorCOFINSST,
      a.valorCreditoSimplesNacional,
      a.valorICMS,
      a.valorICMSST,
      a.valorLiquidoItem,
      modDoc.geraFinanceiro modDoc_geraFinanceiro,
      modDoc.diminuiDescontoPrUnit,
      modDoc.somaAcrescimosPrUnit,
      modDoc.somaFreteSeguroPrUnit,
      prod.tipoProduto,
      CASE WHEN modDoc.habilitaControleEntrega = 0 OR contr.habilitaFrete = 1 THEN 1 ELSE 0 END rateioFrete,
      CASE WHEN a.precoSugestaoAPrazo <> a.precoSugestaoAVista AND a.usarPrecoAVista = 1 THEN 1 ELSE 0 END aVista,
      CASE WHEN EXISTS(SELECT 1 FROM MOORCAMENTOXPROMOCOES promo WHERE promo.idItemOrcamento = a.idItemOrcamento) THEN 1 ELSE 0 END promocao,
      COALESCE((SELECT SUM(promo.valorDesconto) FROM MOORCAMENTOXPROMOCOES promo WHERE promo.idItemOrcamento = a.idItemOrcamento AND promo.cabecalhoItemPagamento ='C'),0) valorDescontoPromocaoGeral,
      COALESCE((SELECT SUM(promo.valorDesconto) FROM MOORCAMENTOXPROMOCOES promo WHERE promo.idItemOrcamento = a.idItemOrcamento AND promo.cabecalhoItemPagamento ='P'),0) valorDescontoPromocaoPagamento,
      CASE WHEN EXISTS (SELECT 1 FROM CAPRODUTOXCOMPOSICOESPREC compPrec WHERE compPrec.produto = gradProd.produto AND compPrec.ativo = 1) THEN 1 ELSE 0 END composicaoPreco
    FROM MOORCAMENTOXITENS a
    JOIN PAMODELOSDOCUMENTO modDoc
    ON modDoc.modeloDocumento = a.modeloDocumento
    JOIN CAGRADESPRODUTO gradProd
    ON gradProd.gradeProduto = a.gradeProduto
    JOIN CAPRODUTOS prod
    ON prod.produto = gradProd.produto
    JOIN PACONTROLESENTREGA contr
    ON contr.controleEntrega = a.controleEntrega
    WHERE a.orcamento = p_cab_orcamento
    AND a.cancelado = 0
    ORDER BY a.sequencia)
  LOOP
    v_idItemOrcamentoUltimoItem    := a.idItemOrcamento;
    v_precoUnitario                := a.precoUnitario;
    v_precoUnitarioConvertido      := a.precoUnitarioConvertido;
    v_valorProdutoServico          := a.valorProdutoServico;
    v_valorDescontoGeral           := v_residuoDescontoGeral;
    v_valorFreteGeral              := v_residuoFreteGeral;
    v_valorSeguroGeral             := v_residuoSeguroGeral;
    v_valorAdicFreteMarinMerGeral  := v_residuoAdicFreteMarinGeral;
    v_valorDespesasAduaneirasGeral := v_residuoDespesasAduanGeral;
    v_valorOutrasDespesasGeral     := v_residuoOutrasDespesasGeral;
    v_valorBasePagamento           := a.valorBasePagamento;
    v_valorDescontoPagamento       := v_residuoDescontoPagamento;
    v_valorOutrasDespesasPagamento := v_residuoOutrasDespPagamento;
    v_valorJurosPagamento          := v_residuoJurosPagamento;
    v_valorFreteTotal              := a.valorFreteTotal;
    v_valorSeguroTotal             := a.valorSeguroTotal;
    v_valorDescontoTotal           := a.valorDescontoTotal;
    v_valorOutrasDespesasTotal     := a.valorOutrasDespesasTotal;
    v_valorAdicFreteMarinMerTotal  := a.valorAdicFreteMarinhaMerTotal;
    v_valorDespesasAduaneirasTotal := a.valorDespesasAduaneirasTotal;
    v_valorLiquidoItem             := a.valorLiquidoItem;

    -- v_valorDescontoGeral
    IF v_valorBaseRateioDescontoGeral > 0
      AND (v_rateioDescontofiltrarAPrazo = 0
        OR a.aVista = 0)
      AND (v_rateioDescontofiltrarSemProm = 0
        OR a.promocao = 0
        AND p_cab_valorDescontoGeral - v_valorDescontoPromocaoGeral > 0)
    THEN
      v_valorDescontoGeral := v_valorDescontoGeral + (p_cab_valorDescontoGeral - v_valorDescontoPromocaoGeral) * (CASE WHEN a.diminuiDescontoPrUnit = 1 OR a.somaAcrescimosPrUnit = 1 or a.somaFreteSeguroPrUnit = 1 THEN a.valorProdutoServicoBruto ELSE a.valorProdutoServico - a.valorDescontoItem + a.valorAcrescimoItem END) / v_valorBaseRateioDescontoGeral;
    END IF;
    IF p_cab_valorDescontoGeral           > 0
      AND v_valorDescontoPromocaoGeral    > 0
      AND a.valorDescontoPromocaoGeral > 0
    THEN
      IF p_cab_valorDescontoGeral < v_valorDescontoPromocaoGeral THEN
        v_valorDescontoGeral := v_valorDescontoGeral + a.valorDescontoPromocaoGeral * p_cab_valorDescontoGeral / v_valorDescontoPromocaoGeral;
      ELSE
        v_valorDescontoGeral := v_valorDescontoGeral + a.valorDescontoPromocaoGeral;
      END IF;
    END IF;
    IF ROUND (v_valorDescontoGeral,2) >= v_saldoRatDescontoGeral THEN
      v_valorDescontoGeral   := v_saldoRatDescontoGeral;
      v_residuoDescontoGeral := 0;
    ELSE
      v_residuoDescontoGeral := v_valorDescontoGeral - ROUND (v_valorDescontoGeral,2);
      v_valorDescontoGeral   := ROUND (v_valorDescontoGeral,2);
    END IF;
    v_saldoRatDescontoGeral := v_saldoRatDescontoGeral - v_valorDescontoGeral;

    -- v_valorFreteGeral / v_valorSeguroGeral
    IF v_valorBaseFreteComFinComEntr > 0 AND v_rateioFretePorControleEntr = 1 AND a.rateioFrete = 1 AND a.geraFinanceiro = 1 THEN
      v_idItemOrcamentoRateioFrete := a.idItemOrcamento;
      v_valorFreteGeral  := v_valorFreteGeral  + p_cab_valorFreteGeral  * (CASE WHEN a.diminuiDescontoPrUnit = 1 OR a.somaAcrescimosPrUnit = 1 or a.somaFreteSeguroPrUnit = 1 THEN a.valorProdutoServicoBruto ELSE a.valorProdutoServico END - a.valorDescontoItem + a.valorAcrescimoItem) / v_valorBaseFreteComFinComEntr;
      v_valorSeguroGeral := v_valorSeguroGeral + p_cab_valorSeguroGeral * (CASE WHEN a.diminuiDescontoPrUnit = 1 OR a.somaAcrescimosPrUnit = 1 or a.somaFreteSeguroPrUnit = 1 THEN a.valorProdutoServicoBruto ELSE a.valorProdutoServico END - a.valorDescontoItem + a.valorAcrescimoItem) / v_valorBaseFreteComFinComEntr;
    ELSIF v_valorBaseFreteSemFinComEntr > 0 AND v_valorBaseFreteComFinComEntr <= 0 AND v_rateioFretePorControleEntr = 1 AND a.rateioFrete = 1 AND a.modDoc_geraFinanceiro = 1 THEN
      v_idItemOrcamentoRateioFrete := a.idItemOrcamento;
      v_valorFreteGeral  := v_valorFreteGeral  + p_cab_valorFreteGeral  * (CASE WHEN a.diminuiDescontoPrUnit = 1 OR a.somaAcrescimosPrUnit = 1 or a.somaFreteSeguroPrUnit = 1 THEN a.valorProdutoServicoBruto ELSE a.valorProdutoServico END - a.valorDescontoItem + a.valorAcrescimoItem) / v_valorBaseFreteSemFinComEntr;
      v_valorSeguroGeral := v_valorSeguroGeral + p_cab_valorSeguroGeral * (CASE WHEN a.diminuiDescontoPrUnit = 1 OR a.somaAcrescimosPrUnit = 1 or a.somaFreteSeguroPrUnit = 1 THEN a.valorProdutoServicoBruto ELSE a.valorProdutoServico END - a.valorDescontoItem + a.valorAcrescimoItem) / v_valorBaseFreteSemFinComEntr;
    ELSIF v_valorBaseRateioComEntrega > 0 AND v_valorBaseFreteSemFinComEntr <= 0 AND v_valorBaseFreteComFinComEntr <= 0 AND v_rateioFretePorControleEntr = 1 AND a.rateioFrete = 1 THEN
      v_idItemOrcamentoRateioFrete := a.idItemOrcamento;
      v_valorFreteGeral  := v_valorFreteGeral  + p_cab_valorFreteGeral  * (CASE WHEN a.diminuiDescontoPrUnit = 1 OR a.somaAcrescimosPrUnit = 1 or a.somaFreteSeguroPrUnit = 1 THEN a.valorProdutoServicoBruto ELSE a.valorProdutoServico END - a.valorDescontoItem + a.valorAcrescimoItem) / v_valorBaseRateioComEntrega;
      v_valorSeguroGeral := v_valorSeguroGeral + p_cab_valorSeguroGeral * (CASE WHEN a.diminuiDescontoPrUnit = 1 OR a.somaAcrescimosPrUnit = 1 or a.somaFreteSeguroPrUnit = 1 THEN a.valorProdutoServicoBruto ELSE a.valorProdutoServico END - a.valorDescontoItem + a.valorAcrescimoItem) / v_valorBaseRateioComEntrega;
    ELSIF v_valorBaseFreteComFinSemEntr > 0 AND v_rateioFretePorControleEntr = 0 AND a.geraFinanceiro = 1 THEN
      v_idItemOrcamentoRateioFrete := a.idItemOrcamento;
      v_valorFreteGeral  := v_valorFreteGeral  + p_cab_valorFreteGeral  * (CASE WHEN a.diminuiDescontoPrUnit = 1 OR a.somaAcrescimosPrUnit = 1 or a.somaFreteSeguroPrUnit = 1 THEN a.valorProdutoServicoBruto ELSE a.valorProdutoServico END - a.valorDescontoItem + a.valorAcrescimoItem) / v_valorBaseFreteComFinSemEntr;
      v_valorSeguroGeral := v_valorSeguroGeral + p_cab_valorSeguroGeral * (CASE WHEN a.diminuiDescontoPrUnit = 1 OR a.somaAcrescimosPrUnit = 1 or a.somaFreteSeguroPrUnit = 1 THEN a.valorProdutoServicoBruto ELSE a.valorProdutoServico END - a.valorDescontoItem + a.valorAcrescimoItem) / v_valorBaseFreteComFinSemEntr;
    ELSIF v_valorBaseFreteSemFinSemEntr > 0 AND v_valorBaseFreteComFinSemEntr <= 0 AND v_rateioFretePorControleEntr = 0 AND a.modDoc_geraFinanceiro = 1 THEN
      v_idItemOrcamentoRateioFrete := a.idItemOrcamento;
      v_valorFreteGeral  := v_valorFreteGeral  + p_cab_valorFreteGeral  * (CASE WHEN a.diminuiDescontoPrUnit = 1 OR a.somaAcrescimosPrUnit = 1 or a.somaFreteSeguroPrUnit = 1 THEN a.valorProdutoServicoBruto ELSE a.valorProdutoServico END - a.valorDescontoItem + a.valorAcrescimoItem) / v_valorBaseFreteSemFinSemEntr;
      v_valorSeguroGeral := v_valorSeguroGeral + p_cab_valorSeguroGeral * (CASE WHEN a.diminuiDescontoPrUnit = 1 OR a.somaAcrescimosPrUnit = 1 or a.somaFreteSeguroPrUnit = 1 THEN a.valorProdutoServicoBruto ELSE a.valorProdutoServico END - a.valorDescontoItem + a.valorAcrescimoItem) / v_valorBaseFreteSemFinSemEntr;
    ELSIF v_valorBaseRateio > 0 AND (v_valorBaseRateioComEntrega <= 0 AND v_valorBaseFreteSemFinComEntr <= 0 AND v_valorBaseFreteComFinComEntr <= 0 AND v_rateioFretePorControleEntr = 1 OR v_valorBaseFreteSemFinSemEntr <= 0 AND v_valorBaseFreteComFinSemEntr <= 0 AND v_rateioFretePorControleEntr = 0) THEN
      v_idItemOrcamentoRateioFrete := a.idItemOrcamento;
      v_valorFreteGeral  := v_valorFreteGeral  + p_cab_valorFreteGeral  * (CASE WHEN a.diminuiDescontoPrUnit = 1 OR a.somaAcrescimosPrUnit = 1 or a.somaFreteSeguroPrUnit = 1 THEN a.valorProdutoServicoBruto ELSE a.valorProdutoServico END - a.valorDescontoItem + a.valorAcrescimoItem) / v_valorBaseRateio;
      v_valorSeguroGeral := v_valorSeguroGeral + p_cab_valorSeguroGeral * (CASE WHEN a.diminuiDescontoPrUnit = 1 OR a.somaAcrescimosPrUnit = 1 or a.somaFreteSeguroPrUnit = 1 THEN a.valorProdutoServicoBruto ELSE a.valorProdutoServico END - a.valorDescontoItem + a.valorAcrescimoItem) / v_valorBaseRateio;
    END IF;
    IF ROUND (v_valorFreteGeral,2) >= v_saldoRatFreteGeral THEN
      v_valorFreteGeral := v_saldoRatFreteGeral;
      v_residuoFreteGeral := 0;
    ELSE
      v_residuoFreteGeral := v_valorFreteGeral - ROUND (v_valorFreteGeral,2);
      v_valorFreteGeral := ROUND (v_valorFreteGeral,2);
    END IF;
    v_saldoRatFreteGeral := v_saldoRatFreteGeral - v_valorFreteGeral;
    IF ROUND (v_valorSeguroGeral,2) >= v_saldoRatSeguroGeral THEN
      v_valorSeguroGeral   := v_saldoRatSeguroGeral;
      v_residuoSeguroGeral := 0;
    ELSE
      v_residuoSeguroGeral := v_valorSeguroGeral  - ROUND (v_valorSeguroGeral,2);
      v_valorSeguroGeral   := ROUND (v_valorSeguroGeral,2);
    END IF;
    v_saldoRatSeguroGeral := v_saldoRatSeguroGeral - v_valorSeguroGeral;

    -- v_valorAdicFreteMarinMerGeral / v_valorDespesasAduaneirasGeral
    IF v_valorBaseRateioFinanceiro > 0 AND a.geraFinanceiro = 1 THEN 
      v_valorAdicFreteMarinMerGeral  := v_valorAdicFreteMarinMerGeral  + p_cab_valorAdicFreteMarinGeral * (CASE WHEN a.diminuiDescontoPrUnit = 1 OR a.somaAcrescimosPrUnit = 1 or a.somaFreteSeguroPrUnit = 1 THEN a.valorProdutoServicoBruto ELSE a.valorProdutoServico END - a.valorDescontoItem + a.valorAcrescimoItem) / v_valorBaseRateioFinanceiro;
      v_valorDespesasAduaneirasGeral := v_valorDespesasAduaneirasGeral + p_cab_valorDespesasAduanGeral  * (CASE WHEN a.diminuiDescontoPrUnit = 1 OR a.somaAcrescimosPrUnit = 1 or a.somaFreteSeguroPrUnit = 1 THEN a.valorProdutoServicoBruto ELSE a.valorProdutoServico END - a.valorDescontoItem + a.valorAcrescimoItem) / v_valorBaseRateioFinanceiro;
    ELSIF v_valorBaseRateio > 0 AND v_valorBaseRateioFinanceiro <= 0 THEN
      v_valorAdicFreteMarinMerGeral  := v_valorAdicFreteMarinMerGeral  + p_cab_valorAdicFreteMarinGeral * (CASE WHEN a.diminuiDescontoPrUnit = 1 OR a.somaAcrescimosPrUnit = 1 or a.somaFreteSeguroPrUnit = 1 THEN a.valorProdutoServicoBruto ELSE a.valorProdutoServico END - a.valorDescontoItem + a.valorAcrescimoItem) / v_valorBaseRateio;
      v_valorDespesasAduaneirasGeral := v_valorDespesasAduaneirasGeral + p_cab_valorDespesasAduanGeral  * (CASE WHEN a.diminuiDescontoPrUnit = 1 OR a.somaAcrescimosPrUnit = 1 or a.somaFreteSeguroPrUnit = 1 THEN a.valorProdutoServicoBruto ELSE a.valorProdutoServico END - a.valorDescontoItem + a.valorAcrescimoItem) / v_valorBaseRateio;
    END IF;
    IF ROUND (v_valorAdicFreteMarinMerGeral,2) >= v_saldoRatAdicFreteMarinGeral THEN
      v_valorAdicFreteMarinMerGeral := v_saldoRatAdicFreteMarinGeral;
      v_residuoAdicFreteMarinGeral  := 0;
    ELSE
      v_residuoAdicFreteMarinGeral  := v_valorAdicFreteMarinMerGeral - ROUND (v_valorAdicFreteMarinMerGeral,2);
      v_valorAdicFreteMarinMerGeral := ROUND (v_valorAdicFreteMarinMerGeral,2);
    END IF;
    v_saldoRatAdicFreteMarinGeral := v_saldoRatAdicFreteMarinGeral - v_valorAdicFreteMarinMerGeral;
    IF ROUND (v_valorDespesasAduaneirasGeral,2) >= v_saldoRatDespesasAduanGeral THEN
      v_valorDespesasAduaneirasGeral := v_saldoRatDespesasAduanGeral;
      v_residuoDespesasAduanGeral    := 0;
    ELSE
      v_residuoDespesasAduanGeral    := v_valorDespesasAduaneirasGeral - ROUND (v_valorDespesasAduaneirasGeral,2);
      v_valorDespesasAduaneirasGeral := ROUND (v_valorDespesasAduaneirasGeral,2);
    END IF;
    v_saldoRatDespesasAduanGeral := v_saldoRatDespesasAduanGeral - v_valorDespesasAduaneirasGeral;

    -- v_valorOutrasDespesasGeral
    IF v_valorBaseRateioOutrasDespFin > 0 AND a.geraFinanceiro = 1 THEN
      v_valorOutrasDespesasGeral := v_valorOutrasDespesasGeral + p_cab_valorOutrasDespesasGeral * (CASE WHEN a.diminuiDescontoPrUnit = 1 OR a.somaAcrescimosPrUnit = 1 or a.somaFreteSeguroPrUnit = 1 THEN a.valorProdutoServicoBruto ELSE a.valorProdutoServico - a.valorDescontoItem + a.valorAcrescimoItem END) / v_valorBaseRateioOutrasDespFin;
    ELSIF v_valorBaseRateioOutrasDespGer > 0 AND v_valorBaseRateioOutrasDespFin <= 0 THEN
      v_valorOutrasDespesasGeral := v_valorOutrasDespesasGeral + p_cab_valorOutrasDespesasGeral * (CASE WHEN a.diminuiDescontoPrUnit = 1 OR a.somaAcrescimosPrUnit = 1 or a.somaFreteSeguroPrUnit = 1 THEN a.valorProdutoServicoBruto ELSE a.valorProdutoServico - a.valorDescontoItem + a.valorAcrescimoItem END) / v_valorBaseRateioOutrasDespGer;
    END IF;
    IF ROUND (v_valorOutrasDespesasGeral,2) >= v_saldoRatOutrasDespesasGeral THEN
      v_valorOutrasDespesasGeral   := v_saldoRatOutrasDespesasGeral;
      v_residuoOutrasDespesasGeral := 0;
    ELSE
      v_residuoOutrasDespesasGeral := v_valorOutrasDespesasGeral - ROUND (v_valorOutrasDespesasGeral,2);
      v_valorOutrasDespesasGeral   := ROUND (v_valorOutrasDespesasGeral,2);
    END IF;
    v_saldoRatOutrasDespesasGeral := v_saldoRatOutrasDespesasGeral - v_valorOutrasDespesasGeral;

    -- v_valorDescontoPagamento
    IF p_cab_valorDescontoPagamento       > 0
      AND v_valorBaseRateioPagamFinDesc   > 0
      AND a.geraFinanceiro = 1
      AND (v_rateioDescontofiltrarAPrazo  = 0
        OR a.aVista = 0)
      AND (v_rateioDescontofiltrarSemProm = 0
        OR a.promocao = 0
        AND p_cab_valorDescontoPagamento - v_valorDescontoPromocaoPagamen > 0)
    THEN
      v_valorDescontoPagamento := v_valorDescontoPagamento + (p_cab_valorDescontoPagamento - v_valorDescontoPromocaoPagamen) * (CASE WHEN a.diminuiDescontoPrUnit = 1 OR a.somaAcrescimosPrUnit = 1 or a.somaFreteSeguroPrUnit = 1 THEN a.valorProdutoServicoBruto ELSE a.valorProdutoServico END - a.valorDescontoItem + a.valorAcrescimoItem) / v_valorBaseRateioPagamFinDesc;
    ELSIF p_cab_valorDescontoPagamento    > 0
      AND v_valorBaseRateioPagamDesconto  > 0
      AND v_valorBaseRateioPagamFinDesc  <= 0
      AND (v_rateioDescontofiltrarAPrazo  = 0
        OR a.aVista = 0)
      AND (v_rateioDescontofiltrarSemProm = 0
        OR a.promocao = 0
        AND p_cab_valorDescontoPagamento - v_valorDescontoPromocaoPagamen > 0)
    THEN
      v_valorDescontoPagamento := v_valorDescontoPagamento + (p_cab_valorDescontoPagamento - v_valorDescontoPromocaoPagamen) * (CASE WHEN a.diminuiDescontoPrUnit = 1 OR a.somaAcrescimosPrUnit = 1 or a.somaFreteSeguroPrUnit = 1 THEN a.valorProdutoServicoBruto ELSE a.valorProdutoServico END - a.valorDescontoItem + a.valorAcrescimoItem) / v_valorBaseRateioPagamDesconto;
    END IF;
    IF p_cab_valorDescontoPagamento           > 0
      AND v_valorDescontoPromocaoPagamen      > 0
      AND a.valorDescontoPromocaoPagamento > 0
    THEN
      IF p_cab_valorDescontoPagamento < v_valorDescontoPromocaoPagamen THEN
        v_valorDescontoPagamento := v_valorDescontoPagamento + a.valorDescontoPromocaoPagamento * p_cab_valorDescontoPagamento / v_valorDescontoPromocaoPagamen;
      ELSE
        v_valorDescontoPagamento := v_valorDescontoPagamento + a.valorDescontoPromocaoPagamento;
      END IF;
    END IF;
    IF ROUND (v_valorDescontoPagamento,2) >= v_saldoRatDescontoPagamento THEN
      v_valorDescontoPagamento   := v_saldoRatDescontoPagamento;
      v_residuoDescontoPagamento := 0;
    ELSE
      v_residuoDescontoPagamento := v_valorDescontoPagamento - ROUND (v_valorDescontoPagamento,2);
      v_valorDescontoPagamento   := ROUND (v_valorDescontoPagamento,2);
    END IF;
    v_saldoRatDescontoPagamento  := v_saldoRatDescontoPagamento - v_valorDescontoPagamento;

    -- v_valorOutrasDespesasPagamento / v_valorJurosPagamento
    IF v_valorBaseRateioPagamFinanc > 0 AND a.geraFinanceiro = 1 THEN
      v_valorOutrasDespesasPagamento := v_valorOutrasDespesasPagamento + p_cab_valorOutrasDespPagamento * (CASE WHEN a.diminuiDescontoPrUnit = 1 OR a.somaAcrescimosPrUnit = 1 or a.somaFreteSeguroPrUnit = 1 THEN a.valorProdutoServicoBruto ELSE a.valorProdutoServico END - a.valorDescontoItem + a.valorAcrescimoItem) / v_valorBaseRateioPagamFinanc;
      v_valorJurosPagamento          := v_valorJurosPagamento          + p_cab_valorJurosPagamento      * (CASE WHEN a.diminuiDescontoPrUnit = 1 OR a.somaAcrescimosPrUnit = 1 or a.somaFreteSeguroPrUnit = 1 THEN a.valorProdutoServicoBruto ELSE a.valorProdutoServico END - a.valorDescontoItem + a.valorAcrescimoItem) / v_valorBaseRateioPagamFinanc;
    ELSIF v_valorBaseRateioPagamento > 0 AND v_valorBaseRateioPagamFinanc <= 0 THEN
      v_valorOutrasDespesasPagamento := v_valorOutrasDespesasPagamento + p_cab_valorOutrasDespPagamento * (CASE WHEN a.diminuiDescontoPrUnit = 1 OR a.somaAcrescimosPrUnit = 1 or a.somaFreteSeguroPrUnit = 1 THEN a.valorProdutoServicoBruto ELSE a.valorProdutoServico END - a.valorDescontoItem + a.valorAcrescimoItem) / v_valorBaseRateioPagamento;
      v_valorJurosPagamento          := v_valorJurosPagamento          + p_cab_valorJurosPagamento      * (CASE WHEN a.diminuiDescontoPrUnit = 1 OR a.somaAcrescimosPrUnit = 1 or a.somaFreteSeguroPrUnit = 1 THEN a.valorProdutoServicoBruto ELSE a.valorProdutoServico END - a.valorDescontoItem + a.valorAcrescimoItem) / v_valorBaseRateioPagamento;
    END IF;
    IF ROUND (v_valorOutrasDespesasPagamento,2) >= v_saldoRatOutrasDespPagamento THEN
      v_valorOutrasDespesasPagamento := v_saldoRatOutrasDespPagamento;
      v_residuoOutrasDespPagamento   := 0;
    ELSE
      v_residuoOutrasDespPagamento   := v_valorOutrasDespesasPagamento - ROUND (v_valorOutrasDespesasPagamento,2);
      v_valorOutrasDespesasPagamento := ROUND (v_valorOutrasDespesasPagamento,2);
    END IF;
    v_saldoRatOutrasDespPagamento := v_saldoRatOutrasDespPagamento - v_valorOutrasDespesasPagamento;
    IF ROUND (v_valorJurosPagamento,2) >= v_saldoRatJurosPagamento THEN
      v_valorJurosPagamento   := v_saldoRatJurosPagamento;
      v_residuoJurosPagamento := 0;
    ELSE
      v_residuoJurosPagamento := v_valorJurosPagamento - ROUND (v_valorJurosPagamento,2);
      v_valorJurosPagamento   := ROUND (v_valorJurosPagamento,2);
    END IF;
    v_saldoRatJurosPagamento := v_saldoRatJurosPagamento - v_valorJurosPagamento;

    -- Recalcula Valores
    ADD_CALCULA_TOTAIS_ITEM(
      p_cab_tipoPagamentoFrete,
      a.quantidade,
      a.quantidadeConvertida,
      a.precoUnitarioBruto,
      a.acrescimoUnitarioComposicao,
      a.precoUnitario,
      a.valorDescontoItem,
      a.valorAcrescimoItem,
      a.valorFreteItem,
      a.valorSeguroItem,
      a.valorAdicFreteMarinhaMerItem,
      a.valorDespesasAduaneirasItem,
      v_valorFreteGeral,
      v_valorSeguroGeral,
      v_valorDescontoGeral,
      v_valorOutrasDespesasGeral,
      v_valorAdicFreteMarinMerGeral,
      v_valorDespesasAduaneirasGeral,
      v_valorDescontoPagamento,
      v_valorOutrasDespesasPagamento,
      v_valorJurosPagamento,
      a.diminuiDescontoPrUnit,
      a.somaAcrescimosPrUnit,
      a.somaFreteSeguroPrUnit,
      a.composicaoPreco,
      /* Retornos */
      v_precoUnitario,
      v_precoUnitarioConvertido,
      v_valorProdutoServico,
      v_valorFreteTotal,
      v_valorSeguroTotal,
      v_valorDescontoTotal,
      v_valorOutrasDespesasTotal,
      v_valorAdicFreteMarinMerTotal,
      v_valorDespesasAduaneirasTotal);
    IF p_cab_impostosEditados = 0 
        OR v_valorProdutoServico <> a.valorProdutoServico
        OR CASE WHEN p_cab_tipoPagamentoFrete   = 'V' THEN 0 ELSE v_valorFreteTotal END
        <> CASE WHEN CASE WHEN p_troca_tipoPagamentoFrete = 1 THEN p_a_cab_tipoPagamentoFrete ELSE p_cab_tipoPagamentoFrete END = 'V' THEN 0 ELSE a.valorFreteTotal END
        OR CASE WHEN p_cab_tipoPagamentoFrete   = 'V' THEN 0 ELSE v_valorSeguroTotal END
        <> CASE WHEN CASE WHEN p_troca_tipoPagamentoFrete = 1 THEN p_a_cab_tipoPagamentoFrete ELSE p_cab_tipoPagamentoFrete END = 'V' THEN 0 ELSE a.valorSeguroTotal END
        OR v_valorDescontoTotal <> a.valorDescontoTotal
        OR v_valorOutrasDespesasTotal <> a.valorOutrasDespesasTotal
        OR v_valorAdicFreteMarinMerTotal <> a.valorAdicFreteMarinhaMerTotal
        OR v_valorDespesasAduaneirasTotal <> a.valorDespesasAduaneirasTotal
        OR v_precoUnitario <> a.precoUnitario
        OR v_valorProdutoServico <> a.valorProdutoServico
    THEN
      r_calcularImpostosItem := 1;
    END IF;
    v_valorBasePagamento := FUNC_ADD_CALC_BASE_PAGAMENTO (
      p_cab_origemDocumento,
      0, -- p_cab_nfFornecedor
      p_cab_tipoPagamentoFrete,
      a.geraFinanceiro,
      v_valorProdutoServico,
      v_valorDescontoPagamento,
      v_valorOutrasDespesasPagamento,
      v_valorJurosPagamento,
      v_valorFreteTotal,
      v_valorSeguroTotal,
      v_valorDescontoTotal,
      v_valorOutrasDespesasTotal,
      0, -- p_item_valorIPIDevolucao
      a.retidoISSQN,
      a.valorISSQN,
      a.valorRetIRRF,
      a.valorRetINSS,
      a.valorRetPIS,
      a.valorRetCOFINS,
      a.valorRetCSLL,
      a.valorRetOutros,
      a.valorII,
      a.valorIOF,
      a.valorIPI,
      a.valorICMSST,
      0, -- p_item_valorICMSSTEscrit
      0, -- p_item_somarICMSST
      0, -- p_item_valorAcrescExtempTotal
      a.modDoc_geraFinanceiro);
    v_valorLiquidoItem := FUNC_ADD_CALC_VALOR_LIQUIDO (
      0, -- p_cab_nfFornecedor
      p_cab_tipoPagamentoFrete,
      v_valorProdutoServico,
      v_valorFreteTotal,
      v_valorSeguroTotal,
      v_valorDescontoTotal,
      v_valorOutrasDespesasTotal,
      0, -- p_item_valorIPIDevolucao
      a.valorII,
      a.valorIOF,
      a.valorIPI,
      a.valorICMSST,
      0, -- p_item_valorICMSSTEscrit
      0 -- p_item_somarICMSST
      );
    -- Atualiza Item
    UPDATE MOORCAMENTOXITENS SET
      precoUnitario                 = v_precoUnitario,
      precoUnitarioConvertido       = v_precoUnitarioConvertido,
      valorProdutoServico           = v_valorProdutoServico,
      valorFreteGeral               = v_valorFreteGeral,
      valorSeguroGeral              = v_valorSeguroGeral,
      valorDescontoGeral            = v_valorDescontoGeral,
      valorOutrasDespesasGeral      = v_valorOutrasDespesasGeral,
      valorAdicFreteMarinhaMerGeral = v_valorAdicFreteMarinMerGeral,
      valorDespesasAduaneirasGeral  = v_valorDespesasAduaneirasGeral,
      valorBasePagamento            = v_valorBasePagamento,
      valorDescontoPagamento        = v_valorDescontoPagamento,
      valorOutrasDespesasPagamento  = v_valorOutrasDespesasPagamento,
      valorJurosPagamento           = v_valorJurosPagamento,
      valorFreteTotal               = v_valorFreteTotal,
      valorSeguroTotal              = v_valorSeguroTotal,
      valorDescontoTotal            = v_valorDescontoTotal,
      valorOutrasDespesasTotal      = v_valorOutrasDespesasTotal,
      valorAdicFreteMarinhaMerTotal = v_valorAdicFreteMarinMerTotal,
      valorDespesasAduaneirasTotal  = v_valorDespesasAduaneirasTotal,
      valorLiquidoItem              = v_valorLiquidoItem
    WHERE idItemOrcamento           = a.idItemOrcamento;
    -- Totaliza cabeçalho
    IF a.tipoProduto = '09' THEN
      r_cab_valorServicos            := r_cab_valorServicos + v_valorProdutoServico;
    ELSE
      r_cab_valorProdutos            := r_cab_valorProdutos + v_valorProdutoServico;
    END IF;
    r_cab_valorBasePagamento       := r_cab_valorBasePagamento + v_valorBasePagamento;
    IF a.usarPrecoAVista = 1 AND a.geraFinanceiro = 1 THEN
      r_cab_valorAVistaMinimo        := r_cab_valorAVistaMinimo + v_valorProdutoServico + v_valorDescontoPagamento - v_valorOutrasDespesasPagamento - v_valorJurosPagamento - v_valorDescontoTotal + v_valorOutrasDespesasTotal;
    END IF;
    r_cab_valorFreteTotal          := r_cab_valorFreteTotal + v_valorFreteTotal;
    r_cab_valorSeguroTotal         := r_cab_valorSeguroTotal + v_valorSeguroTotal;
    r_cab_valorDescontoTotal       := r_cab_valorDescontoTotal + v_valorDescontoTotal;
    r_cab_valorOutrasDespesasTotal := r_cab_valorOutrasDespesasTotal + v_valorOutrasDespesasTotal;
    r_cab_valorAdicFreteMarinTotal := r_cab_valorAdicFreteMarinTotal + v_valorAdicFreteMarinMerTotal;
    r_cab_valorDespesasAduanTotal  := r_cab_valorDespesasAduanTotal + v_valorDespesasAduaneirasTotal;
    r_cab_valorLiquidoItem         := r_cab_valorLiquidoItem + v_valorLiquidoItem;
  END LOOP;
  -- Se sobrou resíduo atualiza último item
  IF v_idItemOrcamentoUltimoItem <> 0 AND (v_saldoRatDescontoGeral <> 0 OR v_saldoRatOutrasDespesasGeral <> 0 OR v_saldoRatDescontoPagamento <> 0 OR v_saldoRatOutrasDespPagamento <> 0 OR v_saldoRatJurosPagamento <> 0 OR v_saldoRatFreteGeral <> 0 OR v_saldoRatSeguroGeral <> 0 OR v_saldoRatAdicFreteMarinGeral <> 0 OR v_saldoRatDespesasAduanGeral <> 0) THEN
    ADD_ORCAMENTO_CALC_IMP_RESIDUO (
      p_troca_tipoPagamentoFrete,
      p_a_cab_tipoPagamentoFrete,
      p_cab_origemDocumento,
      p_cab_atualizaCustoMedio,
      p_cab_tipoPagamentoFrete,
      r_cab_valorProdutos,
      r_cab_valorServicos,
      r_cab_valorBasePagamento,
      r_cab_valorAVistaMinimo,
      r_cab_valorFreteTotal,
      r_cab_valorSeguroTotal,
      r_cab_valorDescontoTotal,
      r_cab_valorOutrasDespesasTotal,
      r_cab_valorAdicFreteMarinTotal,
      r_cab_valorDespesasAduanTotal,
      p_cab_impostosEditados,
      r_cab_valorLiquidoItem,
      CASE WHEN v_idItemOrcamentoRateioFrete = 0 THEN v_idItemOrcamentoUltimoItem ELSE v_idItemOrcamentoRateioFrete END,
      v_saldoRatFreteGeral,
      v_saldoRatSeguroGeral,
      v_saldoRatDescontoGeral,
      v_saldoRatOutrasDespesasGeral,
      v_saldoRatAdicFreteMarinGeral,
      v_saldoRatDespesasAduanGeral,
      v_saldoRatDescontoPagamento,
      v_saldoRatOutrasDespPagamento,
      v_saldoRatJurosPagamento,
      r_calcularImpostosItem,
      /* Retornos */
      r_cab_valorProdutos,
      r_cab_valorServicos,
      r_cab_valorBasePagamento,
      r_cab_valorAVistaMinimo,
      r_cab_valorFreteTotal,
      r_cab_valorSeguroTotal,
      r_cab_valorDescontoTotal,
      r_cab_valorOutrasDespesasTotal,
      r_cab_valorAdicFreteMarinTotal,
      r_cab_valorDespesasAduanTotal,
      r_cab_valorLiquidoItem,
      r_calcularImpostosItem);
  END IF;
END ADD_ORCAMENTO_CALC_IMP_RATEIO;

/

create or replace PROCEDURE ADD_PRE_DOC_CALC_IMP_RATEIO (
  p_cab_preDocumento             IN NUMBER,
  p_troca_tipoPagamentoFrete     IN NUMBER,
  p_a_cab_tipoPagamentoFrete     IN CHAR,
  p_cab_origemDocumento          IN NUMBER,
  p_cab_entradaSaida             IN CHAR,
  p_cab_devolucaoAnulacaoRetorno IN NUMBER,
  p_cab_atualizaCustoMedio       IN NUMBER,
  p_cab_estabelecimento          IN NUMBER,
  p_cab_tipoPagamentoFrete       IN CHAR,
  p_cab_valorFreteGeral          IN NUMBER,
  p_cab_valorSeguroGeral         IN NUMBER,
  p_cab_valorDescontoGeral       IN NUMBER,
  p_cab_valorOutrasDespesasGeral IN NUMBER,
  p_cab_valorAdicFreteMarinGeral IN NUMBER,
  p_cab_valorDespesasAduanGeral  IN NUMBER,
  p_cab_valorDescontoPagamento   IN NUMBER,
  p_cab_valorOutrasDespPagamento IN NUMBER,
  p_cab_valorJurosPagamento      IN NUMBER,
  p_cab_impostosEditados         IN NUMBER,
  p_cab_valorDescCustoOpGeral    IN NUMBER,
  p_cab_valorAcrescCustoOpGeral  IN NUMBER,
  p_cab_valorAcrescExtempGeral   IN NUMBER,
  p_habilitaControleEntrega      IN NUMBER,
  /* Retornos */
  r_cab_valorProdutos            OUT NUMBER,
  r_cab_valorServicos            OUT NUMBER,
  r_cab_valorBasePagamento       OUT NUMBER,
  r_cab_valorAVistaMinimo        OUT NUMBER,
  r_cab_valorFreteTotal          OUT NUMBER,
  r_cab_valorSeguroTotal         OUT NUMBER,
  r_cab_valorDescontoTotal       OUT NUMBER,
  r_cab_valorOutrasDespesasTotal OUT NUMBER,
  r_cab_valorAdicFreteMarinTotal OUT NUMBER,
  r_cab_valorDespesasAduanTotal  OUT NUMBER,
  r_cab_valorLiquidoItem         OUT NUMBER,
  r_cab_valorDescCustoOpTotal    OUT NUMBER,
  r_cab_valorAcrescCustoOpTotal  OUT NUMBER,
  r_cab_valorCustoOperacao       OUT NUMBER,
  r_cab_valorCMV                 OUT NUMBER,
  r_cab_valorAcrescExtempTotal   OUT NUMBER,
  r_calcularImpostosItem         OUT NUMBER)
IS
  v_auxNumber                    NUMBER;
  v_valorDescontoPromocaoGeral   NUMBER;
  v_valorDescontoPromocaoPagamen NUMBER;
  v_rateioDescontofiltrarSemProm NUMBER;
  v_rateioDescontofiltrarAPrazo  NUMBER;
  v_rateioFretePorControleEntr   NUMBER;
  v_valorBaseFreteSemFinSemEntr  NUMBER;
  v_valorBaseFreteComFinSemEntr  NUMBER;
  v_valorBaseFreteSemFinComEntr  NUMBER;
  v_valorBaseFreteComFinComEntr  NUMBER;
  v_valorBaseRateio              NUMBER;
  v_valorBaseRateioComEntrega    NUMBER;
  v_valorBaseRateioFinanceiro    NUMBER;
  v_valorBaseRateioOutrasDespGer NUMBER;
  v_valorBaseRateioOutrasDespFin NUMBER;
  v_valorBaseRateioDescontoGeral NUMBER;
  v_valorBaseRateioPagamento     NUMBER;
  v_valorBaseRateioPagamFinanc   NUMBER;
  v_valorBaseRateioPagamDesconto NUMBER;
  v_valorBaseRateioPagamFinDesc  NUMBER;
  v_saldoRatFreteGeral           NUMBER;
  v_saldoRatSeguroGeral          NUMBER;
  v_saldoRatDescontoGeral        NUMBER;
  v_saldoRatOutrasDespesasGeral  NUMBER;
  v_saldoRatAdicFreteMarinGeral  NUMBER;
  v_saldoRatDespesasAduanGeral   NUMBER;
  v_saldoRatDescontoPagamento    NUMBER;
  v_saldoRatOutrasDespPagamento  NUMBER;
  v_saldoRatJurosPagamento       NUMBER;
  v_saldoRatDescCustoOpGeral     NUMBER;
  v_saldoRatAcrescCustoOpGeral   NUMBER;
  v_saldoRatAcrescExtempGeral    NUMBER;
  v_residuoFreteGeral            NUMBER;
  v_residuoSeguroGeral           NUMBER;
  v_residuoDescontoGeral         NUMBER;
  v_residuoOutrasDespesasGeral   NUMBER;
  v_residuoAdicFreteMarinGeral   NUMBER;
  v_residuoDespesasAduanGeral    NUMBER;
  v_residuoDescontoPagamento     NUMBER;
  v_residuoOutrasDespPagamento   NUMBER;
  v_residuoJurosPagamento        NUMBER;
  v_residuoDescCustoOpGeral      NUMBER;
  v_residuoAcrescCustoOpGeral    NUMBER;
  v_residuoAcrescExtempGeral     NUMBER;
  v_idItemPreDocUltimoItem       NUMBER;
  v_idItemPreDocRateioFrete      NUMBER;
  v_precoUnitario                NUMBER;
  v_precoUnitarioConvertido      NUMBER;
  v_valorProdutoServico          NUMBER;
  v_valorFreteGeral              NUMBER;
  v_valorSeguroGeral             NUMBER;
  v_valorDescontoGeral           NUMBER;
  v_valorOutrasDespesasGeral     NUMBER;
  v_valorAdicFreteMarinMerGeral  NUMBER;
  v_valorDespesasAduaneirasGeral NUMBER;
  v_valorBasePagamento           NUMBER;
  v_valorDescontoPagamento       NUMBER;
  v_valorOutrasDespesasPagamento NUMBER;
  v_valorJurosPagamento          NUMBER;
  v_valorFreteTotal              NUMBER;
  v_valorSeguroTotal             NUMBER;
  v_valorDescontoTotal           NUMBER;
  v_valorOutrasDespesasTotal     NUMBER;
  v_valorAdicFreteMarinMerTotal  NUMBER;
  v_valorDespesasAduaneirasTotal NUMBER;
  v_valorLiquidoItem             NUMBER;
  v_valorDescontoCustoOpGeral    NUMBER;
  v_valorDescontoCustoOpTotal    NUMBER;
  v_valorAcrescimoCustoOpGeral   NUMBER;
  v_valorAcrescimoCustoOpTotal   NUMBER;
  v_precoCustoOperacao           NUMBER;
  v_valorCustoOperacao           NUMBER;
  v_precoCMV                     NUMBER;
  v_valorCMV                     NUMBER;
  v_valorAcrescimoExtempSubtotal NUMBER;
  v_valorAcrescimoExtempGeral    NUMBER;
  v_valorAcrescimoExtempTotal    NUMBER;
  v_calculoImpostosPendenteItem  NUMBER;
BEGIN
  r_cab_valorProdutos            := 0;
  r_cab_valorServicos            := 0;
  r_cab_valorBasePagamento       := 0;
  r_cab_valorAVistaMinimo        := 0;
  r_cab_valorFreteTotal          := 0;
  r_cab_valorSeguroTotal         := 0;
  r_cab_valorDescontoTotal       := 0;
  r_cab_valorOutrasDespesasTotal := 0;
  r_cab_valorAdicFreteMarinTotal := 0;
  r_cab_valorDespesasAduanTotal  := 0;
  r_cab_valorLiquidoItem         := 0;
  r_cab_valorDescCustoOpTotal    := 0;
  r_cab_valorAcrescCustoOpTotal  := 0;
  r_cab_valorCustoOperacao       := 0;
  r_cab_valorCMV                 := 0;
  r_cab_valorAcrescExtempTotal   := 0;
  r_calcularImpostosItem         := 0;
  v_saldoRatFreteGeral           := p_cab_valorFreteGeral;
  v_saldoRatSeguroGeral          := p_cab_valorSeguroGeral;
  v_saldoRatDescontoGeral        := p_cab_valorDescontoGeral;
  v_saldoRatOutrasDespesasGeral  := p_cab_valorOutrasDespesasGeral;
  v_saldoRatAdicFreteMarinGeral  := p_cab_valorAdicFreteMarinGeral;
  v_saldoRatDespesasAduanGeral   := p_cab_valorDespesasAduanGeral;
  v_saldoRatDescontoPagamento    := p_cab_valorDescontoPagamento;
  v_saldoRatOutrasDespPagamento  := p_cab_valorOutrasDespPagamento;
  v_saldoRatJurosPagamento       := p_cab_valorJurosPagamento;
  v_saldoRatDescCustoOpGeral     := p_cab_valorDescCustoOpGeral;
  v_saldoRatAcrescCustoOpGeral   := p_cab_valorAcrescCustoOpGeral;
  v_saldoRatAcrescExtempGeral    := p_cab_valorAcrescExtempGeral;
  v_residuoFreteGeral            := 0;
  v_residuoSeguroGeral           := 0;
  v_residuoDescontoGeral         := 0;
  v_residuoOutrasDespesasGeral   := 0;
  v_residuoAdicFreteMarinGeral   := 0;
  v_residuoDespesasAduanGeral    := 0;
  v_residuoDescontoPagamento     := 0;
  v_residuoOutrasDespPagamento   := 0;
  v_residuoJurosPagamento        := 0;
  v_residuoDescCustoOpGeral      := 0;
  v_residuoAcrescCustoOpGeral    := 0;
  v_residuoAcrescExtempGeral     := 0;
  v_idItemPreDocUltimoItem       := 0;
  v_idItemPreDocRateioFrete      := 0;
  v_valorDescontoPromocaoGeral   := 0;
  v_valorDescontoPromocaoPagamen := 0;
  v_rateioDescontofiltrarSemProm := 0;
  v_rateioDescontofiltrarAPrazo  := 0;

  -- v_valorDescontoPromocaoGeral
  IF p_cab_valorDescontoGeral > 0 THEN
    SELECT COALESCE(SUM(promo.valorDesconto),0)
    INTO v_valorDescontoPromocaoGeral
    FROM MOPREDOCUMXITENS a
    JOIN MOPREDOCUMXPROMOCOES promo
    ON promo.idItemPreDocumento = a.idItemPreDocumento
    WHERE a.preDocumento = p_cab_preDocumento
    AND a.cancelado = 0
    AND promo.cabecalhoItemPagamento ='C';
  END IF;

  -- v_valorDescontoPromocaoPagamen
  IF p_cab_valorDescontoPagamento > 0 THEN
    SELECT COALESCE(SUM(promo.valorDesconto),0)
    INTO v_valorDescontoPromocaoPagamen
    FROM MOPREDOCUMXITENS a
    JOIN MOPREDOCUMXPROMOCOES promo
    ON promo.idItemPreDocumento = a.idItemPreDocumento
    WHERE a.preDocumento = p_cab_preDocumento
    AND a.cancelado = 0
    AND promo.cabecalhoItemPagamento ='P';
  END IF;

  -- v_rateioDescontofiltrarSemProm
  IF p_cab_valorDescontoGeral > v_valorDescontoPromocaoGeral OR p_cab_valorDescontoPagamento > v_valorDescontoPromocaoPagamen THEN
    SELECT
      CASE
        WHEN EXISTS(
          SELECT 1
          FROM MOPREDOCUMXITENS a
          JOIN PAMODELOSDOCUMENTO modDoc
          ON modDoc.modeloDocumento = a.modeloDocumento
          WHERE a.preDocumento = p_cab_preDocumento
          AND a.cancelado = 0
          AND COALESCE((
            SELECT SUM(b.valorDesconto)
            FROM MOPREDOCUMXPROMOCOES b
            WHERE b.idItemPreDocumento = a.idItemPreDocumento
            AND b.cabecalhoItemPagamento IN ('C','P')),0) > (
            CASE
              WHEN modDoc.diminuiDescontoPrUnit = 1
                OR modDoc.somaAcrescimosPrUnit  = 1
                OR modDoc.somaFreteSeguroPrUnit = 1
              THEN a.valorProdutoServicoBruto
              ELSE a.valorProdutoServico
            END
            - a.valorDescontoItem
            + a.valorAcrescimoItem))
        THEN 0
        WHEN COALESCE ((
          SELECT SUM (CASE WHEN modDoc.diminuiDescontoPrUnit = 1 OR modDoc.somaAcrescimosPrUnit = 1 or modDoc.somaFreteSeguroPrUnit = 1 THEN a.valorProdutoServicoBruto ELSE a.valorProdutoServico END - a.valorDescontoItem + a.valorAcrescimoItem)
          FROM MOPREDOCUMXITENS a
          JOIN PAMODELOSDOCUMENTO modDoc
          ON modDoc.modeloDocumento = a.modeloDocumento
          JOIN MOPREDOCUMXPROMOCOES b
          ON b.idItemPreDocumento = a.idItemPreDocumento
          WHERE a.preDocumento = p_cab_preDocumento
          AND a.cancelado = 0),0) > (
            CASE
              WHEN p_cab_valorDescontoGeral > v_valorDescontoPromocaoGeral
              THEN p_cab_valorDescontoGeral - v_valorDescontoPromocaoGeral
              ELSE 0
            END +
            CASE
              WHEN p_cab_valorDescontoPagamento > v_valorDescontoPromocaoPagamen
              THEN p_cab_valorDescontoPagamento - v_valorDescontoPromocaoPagamen
              ELSE 0
            END)
          AND EXISTS (
            SELECT 1
            FROM MOPREDOCUMXITENS a
            WHERE a.preDocumento = p_cab_preDocumento
            AND a.cancelado = 0
            AND NOT (EXISTS(
              SELECT 1
              FROM MOPREDOCUMXPROMOCOES b
              WHERE b.idItemPreDocumento = a.idItemPreDocumento)))
        THEN 1
        ELSE 0
      END
    INTO v_rateioDescontofiltrarSemProm
    FROM DUAL;
  END IF;

  -- v_rateioDescontofiltrarAPrazo
  IF p_cab_valorDescontoGeral > v_valorDescontoPromocaoGeral OR p_cab_valorDescontoPagamento > v_valorDescontoPromocaoPagamen THEN
    SELECT
      CASE
        WHEN COALESCE ((
          SELECT SUM (CASE WHEN modDoc.diminuiDescontoPrUnit = 1 OR modDoc.somaAcrescimosPrUnit = 1 or modDoc.somaFreteSeguroPrUnit = 1 THEN a.valorProdutoServicoBruto ELSE a.valorProdutoServico END - a.valorDescontoItem + a.valorAcrescimoItem)
          FROM MOPREDOCUMXITENS a
          JOIN PAMODELOSDOCUMENTO modDoc
          ON modDoc.modeloDocumento = a.modeloDocumento
          WHERE a.preDocumento = p_cab_preDocumento
          AND a.cancelado = 0
          AND a.precoSugestaoAPrazo <> a.precoSugestaoAVista
          AND a.usarPrecoAVista = 1
          AND (v_rateioDescontofiltrarSemProm = 0
            OR NOT(EXISTS(
              SELECT 1
              FROM MOPREDOCUMXPROMOCOES promo
              WHERE promo.idItemPreDocumento = a.idItemPreDocumento)))),0) > (
            CASE
              WHEN p_cab_valorDescontoGeral > v_valorDescontoPromocaoGeral
              THEN p_cab_valorDescontoGeral - v_valorDescontoPromocaoGeral
              ELSE 0
            END +
            CASE
              WHEN p_cab_valorDescontoPagamento > v_valorDescontoPromocaoPagamen
              THEN p_cab_valorDescontoPagamento - v_valorDescontoPromocaoPagamen
              ELSE 0
            END)
          AND EXISTS (
            SELECT 1
            FROM MOPREDOCUMXITENS a
            WHERE a.preDocumento = p_cab_preDocumento
            AND a.cancelado = 0
            AND (a.precoSugestaoAPrazo = a.precoSugestaoAVista
              OR a.usarPrecoAVista = 0)
            AND (v_rateioDescontofiltrarSemProm = 0
              OR NOT(EXISTS(
                SELECT 1
                FROM MOPREDOCUMXPROMOCOES promo
                WHERE promo.idItemPreDocumento = a.idItemPreDocumento))))
        THEN 1
        ELSE 0
      END
    INTO v_rateioDescontofiltrarAPrazo
    FROM DUAL;
  END IF;

  -- Bases Rateio
  SELECT
    MAX(COALESCE((CASE WHEN p_habilitaControleEntrega = 0 OR EXISTS(SELECT 1 FROM MOPREDOCUMXORCAMENTOITEM docXorc JOIN MOORCAMENTOXITENS itemOrc ON itemOrc.idItemOrcamento = docXorc.idItemOrcamento JOIN PACONTROLESENTREGA contr ON contr.controleEntrega = itemOrc.controleEntrega WHERE docXorc.idItemPreDocumento = a.idItemPreDocumento AND itemOrc.controleEntrega > 0 AND contr.habilitaFrete = 1) THEN 1 ELSE 0 END),0)),
    COALESCE(SUM(CASE WHEN modDoc.geraFinanceiro = 1 THEN CASE WHEN modDoc.diminuiDescontoPrUnit = 1 OR modDoc.somaAcrescimosPrUnit = 1 or modDoc.somaFreteSeguroPrUnit = 1 THEN a.valorProdutoServicoBruto ELSE a.valorProdutoServico END - a.valorDescontoItem + a.valorAcrescimoItem ELSE 0 END),0),
    COALESCE(SUM(CASE WHEN a.geraFinanceiro = 1 THEN CASE WHEN modDoc.diminuiDescontoPrUnit = 1 OR modDoc.somaAcrescimosPrUnit = 1 or modDoc.somaFreteSeguroPrUnit = 1 THEN a.valorProdutoServicoBruto ELSE a.valorProdutoServico END - a.valorDescontoItem + a.valorAcrescimoItem ELSE 0 END),0),
    COALESCE(SUM(CASE WHEN modDoc.geraFinanceiro = 1 AND (p_habilitaControleEntrega = 0 OR EXISTS(SELECT 1 FROM MOPREDOCUMXORCAMENTOITEM docXorc JOIN MOORCAMENTOXITENS itemOrc ON itemOrc.idItemOrcamento = docXorc.idItemOrcamento JOIN PACONTROLESENTREGA contr ON contr.controleEntrega = itemOrc.controleEntrega WHERE docXorc.idItemPreDocumento = a.idItemPreDocumento AND itemOrc.controleEntrega > 0 AND contr.habilitaFrete = 1)) THEN CASE WHEN modDoc.diminuiDescontoPrUnit = 1 OR modDoc.somaAcrescimosPrUnit = 1 or modDoc.somaFreteSeguroPrUnit = 1 THEN a.valorProdutoServicoBruto ELSE a.valorProdutoServico - a.valorDescontoItem + a.valorAcrescimoItem END ELSE 0 END),0),
    COALESCE(SUM(CASE WHEN a.geraFinanceiro = 1 AND (p_habilitaControleEntrega = 0 OR EXISTS(SELECT 1 FROM MOPREDOCUMXORCAMENTOITEM docXorc JOIN MOORCAMENTOXITENS itemOrc ON itemOrc.idItemOrcamento = docXorc.idItemOrcamento JOIN PACONTROLESENTREGA contr ON contr.controleEntrega = itemOrc.controleEntrega WHERE docXorc.idItemPreDocumento = a.idItemPreDocumento AND itemOrc.controleEntrega > 0 AND contr.habilitaFrete = 1)) THEN CASE WHEN modDoc.diminuiDescontoPrUnit = 1 OR modDoc.somaAcrescimosPrUnit = 1 or modDoc.somaFreteSeguroPrUnit = 1 THEN a.valorProdutoServicoBruto ELSE a.valorProdutoServico - a.valorDescontoItem + a.valorAcrescimoItem END ELSE 0 END),0),
    COALESCE(SUM(CASE WHEN modDoc.diminuiDescontoPrUnit = 1 OR modDoc.somaAcrescimosPrUnit = 1 or modDoc.somaFreteSeguroPrUnit = 1 THEN a.valorProdutoServicoBruto ELSE a.valorProdutoServico END - a.valorDescontoItem + a.valorAcrescimoItem),0),
    COALESCE(SUM(CASE WHEN p_habilitaControleEntrega = 0 OR EXISTS(SELECT 1 FROM MOPREDOCUMXORCAMENTOITEM docXorc JOIN MOORCAMENTOXITENS itemOrc ON itemOrc.idItemOrcamento = docXorc.idItemOrcamento JOIN PACONTROLESENTREGA contr ON contr.controleEntrega = itemOrc.controleEntrega WHERE docXorc.idItemPreDocumento = a.idItemPreDocumento AND itemOrc.controleEntrega > 0 AND contr.habilitaFrete = 1) THEN CASE WHEN modDoc.diminuiDescontoPrUnit = 1 OR modDoc.somaAcrescimosPrUnit = 1 or modDoc.somaFreteSeguroPrUnit = 1 THEN a.valorProdutoServicoBruto ELSE a.valorProdutoServico - a.valorDescontoItem + a.valorAcrescimoItem END ELSE 0 END),0),
    COALESCE(SUM(CASE WHEN a.geraFinanceiro = 1 THEN CASE WHEN modDoc.diminuiDescontoPrUnit = 1 OR modDoc.somaAcrescimosPrUnit = 1 or modDoc.somaFreteSeguroPrUnit = 1 THEN a.valorProdutoServicoBruto ELSE a.valorProdutoServico END - a.valorDescontoItem + a.valorAcrescimoItem ELSE 0 END),0),
    COALESCE(SUM(CASE WHEN modDoc.diminuiDescontoPrUnit = 1 OR modDoc.somaAcrescimosPrUnit = 1 or modDoc.somaFreteSeguroPrUnit = 1 THEN a.valorProdutoServicoBruto ELSE a.valorProdutoServico - a.valorDescontoItem + a.valorAcrescimoItem END),0),
    COALESCE(SUM(CASE WHEN a.geraFinanceiro = 1 THEN CASE WHEN modDoc.diminuiDescontoPrUnit = 1 OR modDoc.somaAcrescimosPrUnit = 1 or modDoc.somaFreteSeguroPrUnit = 1 THEN a.valorProdutoServicoBruto ELSE a.valorProdutoServico - a.valorDescontoItem + a.valorAcrescimoItem END ELSE 0 END),0),
    COALESCE(SUM(CASE WHEN (v_rateioDescontofiltrarAPrazo = 0 OR a.precoSugestaoAPrazo = a.precoSugestaoAVista OR a.usarPrecoAVista = 0) AND (v_rateioDescontofiltrarSemProm = 0 OR NOT(EXISTS(SELECT 1 FROM MOPREDOCUMXPROMOCOES promo WHERE promo.idItemPreDocumento = a.idItemPreDocumento))) THEN CASE WHEN modDoc.diminuiDescontoPrUnit = 1 OR modDoc.somaAcrescimosPrUnit = 1 or modDoc.somaFreteSeguroPrUnit = 1 THEN a.valorProdutoServicoBruto ELSE a.valorProdutoServico END - a.valorDescontoItem + a.valorAcrescimoItem ELSE 0 END),0),
    COALESCE(SUM(CASE WHEN modDoc.diminuiDescontoPrUnit = 1 OR modDoc.somaAcrescimosPrUnit = 1 or modDoc.somaFreteSeguroPrUnit = 1 THEN a.valorProdutoServicoBruto ELSE a.valorProdutoServico END - a.valorDescontoItem + a.valorAcrescimoItem),0),
    COALESCE(SUM(CASE WHEN a.geraFinanceiro = 1 THEN CASE WHEN modDoc.diminuiDescontoPrUnit = 1 OR modDoc.somaAcrescimosPrUnit = 1 or modDoc.somaFreteSeguroPrUnit = 1 THEN a.valorProdutoServicoBruto ELSE a.valorProdutoServico END - a.valorDescontoItem + a.valorAcrescimoItem ELSE 0 END),0),
    COALESCE(SUM(CASE WHEN (v_rateioDescontofiltrarAPrazo = 0 OR a.precoSugestaoAPrazo = a.precoSugestaoAVista OR a.usarPrecoAVista = 0) AND (v_rateioDescontofiltrarSemProm = 0 OR NOT(EXISTS(SELECT 1 FROM MOPREDOCUMXPROMOCOES promo WHERE promo.idItemPreDocumento = a.idItemPreDocumento))) THEN CASE WHEN modDoc.diminuiDescontoPrUnit = 1 OR modDoc.somaAcrescimosPrUnit = 1 or modDoc.somaFreteSeguroPrUnit = 1 THEN a.valorProdutoServicoBruto ELSE a.valorProdutoServico END - a.valorDescontoItem + a.valorAcrescimoItem ELSE 0 END),0),
    COALESCE(SUM(CASE WHEN a.geraFinanceiro = 1 AND (v_rateioDescontofiltrarAPrazo = 0 OR a.precoSugestaoAPrazo = a.precoSugestaoAVista OR a.usarPrecoAVista = 0) AND (v_rateioDescontofiltrarSemProm = 0 OR NOT(EXISTS(SELECT 1 FROM MOPREDOCUMXPROMOCOES promo WHERE promo.idItemPreDocumento = a.idItemPreDocumento))) THEN CASE WHEN modDoc.diminuiDescontoPrUnit = 1 OR modDoc.somaAcrescimosPrUnit = 1 or modDoc.somaFreteSeguroPrUnit = 1 THEN a.valorProdutoServicoBruto ELSE a.valorProdutoServico END - a.valorDescontoItem + a.valorAcrescimoItem ELSE 0 END),0)
  INTO
    v_rateioFretePorControleEntr,
    v_valorBaseFreteSemFinSemEntr,
    v_valorBaseFreteComFinSemEntr,
    v_valorBaseFreteSemFinComEntr,
    v_valorBaseFreteComFinComEntr,
    v_valorBaseRateio,
    v_valorBaseRateioComEntrega,
    v_valorBaseRateioFinanceiro,
    v_valorBaseRateioOutrasDespGer,
    v_valorBaseRateioOutrasDespFin,
    v_valorBaseRateioDescontoGeral,
    v_valorBaseRateioPagamento,
    v_valorBaseRateioPagamFinanc,
    v_valorBaseRateioPagamDesconto,
    v_valorBaseRateioPagamFinDesc
  FROM MOPREDOCUMXITENS a
  JOIN PAMODELOSDOCUMENTO modDoc
  ON modDoc.modeloDocumento = a.modeloDocumento
  WHERE a.preDocumento = p_cab_preDocumento
  AND a.cancelado = 0;

  -- Efetua rateio
  FOR a IN (
    SELECT
      a.idItemPreDocumento,
      a.modeloDocumento,
      a.geraFinanceiro,
      a.quantidade,
      a.quantidadeConvertida,
      a.usarPrecoAVista,
      a.precoUnitarioBruto,
      a.acrescimoUnitarioComposicao,
      a.precoUnitario,
      a.precoUnitarioConvertido,
      a.valorProdutoServicoBruto,
      a.valorProdutoServico,
      a.valorDescontoItem,
      a.valorAcrescimoItem,
      a.valorFreteItem,
      a.valorSeguroItem,
      a.valorAdicFreteMarinhaMerItem,
      a.valorDespesasAduaneirasItem,
      a.valorFreteGeral,
      a.valorSeguroGeral,
      a.valorDescontoGeral,
      a.valorOutrasDespesasGeral,
      a.valorAdicFreteMarinhaMerGeral,
      a.valorDespesasAduaneirasGeral,
      a.valorBasePagamento,
      a.valorDescontoPagamento,
      a.valorOutrasDespesasPagamento,
      a.valorJurosPagamento,
      a.valorFreteTotal,
      a.valorSeguroTotal,
      a.valorDescontoTotal,
      a.valorOutrasDespesasTotal,
      a.valorAdicFreteMarinhaMerTotal,
      a.valorDespesasAduaneirasTotal,
      a.valorIPIDevolucao,
      a.retidoISSQN,
      a.valorISSQN,
      a.valorRetIRRF,
      a.valorRetINSS,
      a.valorRetPIS,
      a.valorRetCOFINS,
      a.valorRetCSLL,
      a.valorRetOutros,
      a.valorII,
      a.valorIOF,
      a.valorIPI,
      a.valorPIS,
      a.valorPISST,
      a.valorCOFINS,
      a.valorCOFINSST,
      a.valorCreditoSimplesNacional,
      a.valorICMS,
      a.valorICMSST,
      a.valorLiquidoItem,
      a.valorDescontoCustoOpItem,
      a.valorDescontoCustoOpGeral,
      a.valorDescontoCustoOpTotal,
      a.valorAcrescimoCustoOpItem,
      a.valorAcrescimoCustoOpGeral,
      a.valorAcrescimoCustoOpTotal,
      a.precoCustoOperacao,
      a.valorCustoOperacao,
      a.precoCMV,
      a.valorCMV,
      a.quantidadeExtemporanea,
      a.acrescimoUnitarioExtemporaneo,
      a.valorAcrescimoExtempSubtotal,
      a.valorAcrescimoExtempItem,
      a.valorAcrescimoExtempGeral,
      a.valorAcrescimoExtempTotal,
      modDoc.diminuiDescontoPrUnit,
      modDoc.somaAcrescimosPrUnit,
      modDoc.somaFreteSeguroPrUnit,
      modDoc.geraFinanceiro modDoc_geraFinanceiro,
      prod.tipoProduto,
      CASE WHEN p_habilitaControleEntrega = 0 OR EXISTS(
        SELECT 1
        FROM MOPREDOCUMXORCAMENTOITEM docXorc
        JOIN MOORCAMENTOXITENS itemOrc
        ON itemOrc.idItemOrcamento = docXorc.idItemOrcamento
        JOIN PACONTROLESENTREGA contr
        ON contr.controleEntrega = itemOrc.controleEntrega
        WHERE docXorc.idItemPreDocumento = a.idItemPreDocumento
        AND contr.habilitaFrete = 1) THEN 1 ELSE 0 END rateioFrete,
      CASE WHEN a.precoSugestaoAPrazo <> a.precoSugestaoAVista AND a.usarPrecoAVista = 1 THEN 1 ELSE 0 END aVista,
      CASE WHEN EXISTS(
        SELECT 1
        FROM MOPREDOCUMXPROMOCOES promo
        WHERE promo.idItemPreDocumento = a.idItemPreDocumento) THEN 1 ELSE 0 END promocao,
      COALESCE((
        SELECT SUM(promo.valorDesconto)
        FROM MOPREDOCUMXPROMOCOES promo
        WHERE promo.idItemPreDocumento = a.idItemPreDocumento
        AND promo.cabecalhoItemPagamento ='C'),0) valorDescontoPromocaoGeral,
      COALESCE((
        SELECT SUM(promo.valorDesconto)
        FROM MOPREDOCUMXPROMOCOES promo
        WHERE promo.idItemPreDocumento = a.idItemPreDocumento
        AND promo.cabecalhoItemPagamento ='P'),0) valorDescontoPromocaoPagamento,
      CASE
        WHEN EXISTS (
          SELECT 1
          FROM CAPRODUTOXCOMPOSICOESPREC compPrec
          WHERE compPrec.produto = gradProd.produto
          AND compPrec.ativo = 1)
        THEN 1
        ELSE 0
      END composicaoPreco
    FROM MOPREDOCUMXITENS a
    JOIN PAMODELOSDOCUMENTO modDoc
    ON modDoc.modeloDocumento = a.modeloDocumento
    JOIN CAGRADESPRODUTO gradProd
    ON gradProd.gradeProduto = a.gradeProduto
    JOIN CAPRODUTOS prod
    ON prod.produto = gradProd.produto
    WHERE a.preDocumento = p_cab_preDocumento
    AND a.cancelado = 0
    ORDER BY a.sequencia)
  LOOP
    v_idItemPreDocUltimoItem       := a.idItemPreDocumento;
    v_precoUnitario                := a.precoUnitario;
    v_precoUnitarioConvertido      := a.precoUnitarioConvertido;
    v_valorProdutoServico          := a.valorProdutoServico;
    v_valorDescontoGeral           := v_residuoDescontoGeral;
    v_valorFreteGeral              := v_residuoFreteGeral;
    v_valorSeguroGeral             := v_residuoSeguroGeral;
    v_valorAdicFreteMarinMerGeral  := v_residuoAdicFreteMarinGeral;
    v_valorDespesasAduaneirasGeral := v_residuoDespesasAduanGeral;
    v_valorOutrasDespesasGeral     := v_residuoOutrasDespesasGeral;
    v_valorBasePagamento           := a.valorBasePagamento;
    v_valorDescontoPagamento       := v_residuoDescontoPagamento;
    v_valorOutrasDespesasPagamento := v_residuoOutrasDespPagamento;
    v_valorJurosPagamento          := v_residuoJurosPagamento;
    v_valorDescontoCustoOpGeral    := v_residuoDescCustoOpGeral;
    v_valorAcrescimoCustoOpGeral   := v_residuoAcrescCustoOpGeral;
    v_valorAcrescimoExtempGeral    := v_residuoAcrescExtempGeral;
    v_valorFreteTotal              := a.valorFreteTotal;
    v_valorSeguroTotal             := a.valorSeguroTotal;
    v_valorDescontoTotal           := a.valorDescontoTotal;
    v_valorOutrasDespesasTotal     := a.valorOutrasDespesasTotal;
    v_valorAdicFreteMarinMerTotal  := a.valorAdicFreteMarinhaMerTotal;
    v_valorDespesasAduaneirasTotal := a.valorDespesasAduaneirasTotal;
    v_valorLiquidoItem             := a.valorLiquidoItem;
    v_valorDescontoCustoOpTotal    := a.valorDescontoCustoOpTotal;
    v_valorAcrescimoCustoOpTotal   := a.valorAcrescimoCustoOpTotal;
    v_precoCustoOperacao           := a.precoCustoOperacao;
    v_valorCustoOperacao           := a.valorCustoOperacao;
    v_precoCMV                     := a.precoCMV;
    v_valorCMV                     := a.valorCMV;
    v_valorAcrescimoExtempSubtotal := a.valorAcrescimoExtempSubtotal;
    v_valorAcrescimoExtempTotal    := a.valorAcrescimoExtempTotal;

    -- v_valorDescontoGeral
    IF v_valorBaseRateioDescontoGeral > 0
      AND (v_rateioDescontofiltrarAPrazo = 0
        OR a.aVista = 0)
      AND (v_rateioDescontofiltrarSemProm = 0
        OR a.promocao = 0
        AND p_cab_valorDescontoGeral - v_valorDescontoPromocaoGeral > 0)
    THEN
      v_valorDescontoGeral := v_valorDescontoGeral + (p_cab_valorDescontoGeral - v_valorDescontoPromocaoGeral) * (CASE WHEN a.diminuiDescontoPrUnit = 1 OR a.somaAcrescimosPrUnit = 1 or a.somaFreteSeguroPrUnit = 1 THEN a.valorProdutoServicoBruto ELSE a.valorProdutoServico - a.valorDescontoItem + a.valorAcrescimoItem END) / v_valorBaseRateioDescontoGeral;
    END IF;
    IF p_cab_valorDescontoGeral           > 0
      AND v_valorDescontoPromocaoGeral    > 0
      AND a.valorDescontoPromocaoGeral > 0
    THEN
      IF p_cab_valorDescontoGeral < v_valorDescontoPromocaoGeral THEN
        v_valorDescontoGeral := v_valorDescontoGeral + a.valorDescontoPromocaoGeral * p_cab_valorDescontoGeral / v_valorDescontoPromocaoGeral;
      ELSE
        v_valorDescontoGeral := v_valorDescontoGeral + a.valorDescontoPromocaoGeral;
      END IF;
    END IF;
    IF ROUND (v_valorDescontoGeral,2) >= v_saldoRatDescontoGeral THEN
      v_valorDescontoGeral   := v_saldoRatDescontoGeral;
      v_residuoDescontoGeral := 0;
    ELSE
      v_residuoDescontoGeral := v_valorDescontoGeral - ROUND (v_valorDescontoGeral,2);
      v_valorDescontoGeral   := ROUND (v_valorDescontoGeral,2);
    END IF;
    v_saldoRatDescontoGeral := v_saldoRatDescontoGeral - v_valorDescontoGeral;

    -- v_valorFreteGeral
    -- v_valorSeguroGeral
    IF v_valorBaseFreteComFinComEntr > 0 AND v_rateioFretePorControleEntr = 1 AND a.rateioFrete = 1 AND a.geraFinanceiro = 1 THEN
      v_idItemPreDocRateioFrete := a.idItemPreDocumento;
      v_valorFreteGeral  := v_valorFreteGeral  + p_cab_valorFreteGeral  * (CASE WHEN a.diminuiDescontoPrUnit = 1 OR a.somaAcrescimosPrUnit = 1 or a.somaFreteSeguroPrUnit = 1 THEN a.valorProdutoServicoBruto ELSE a.valorProdutoServico END - a.valorDescontoItem + a.valorAcrescimoItem) / v_valorBaseFreteComFinComEntr;
      v_valorSeguroGeral := v_valorSeguroGeral + p_cab_valorSeguroGeral * (CASE WHEN a.diminuiDescontoPrUnit = 1 OR a.somaAcrescimosPrUnit = 1 or a.somaFreteSeguroPrUnit = 1 THEN a.valorProdutoServicoBruto ELSE a.valorProdutoServico END - a.valorDescontoItem + a.valorAcrescimoItem) / v_valorBaseFreteComFinComEntr;
    ELSIF v_valorBaseFreteSemFinComEntr > 0 AND v_valorBaseFreteComFinComEntr <= 0 AND v_rateioFretePorControleEntr = 1 AND a.rateioFrete = 1 AND a.modDoc_geraFinanceiro = 1 THEN
      v_idItemPreDocRateioFrete := a.idItemPreDocumento;
      v_valorFreteGeral  := v_valorFreteGeral  + p_cab_valorFreteGeral  * (CASE WHEN a.diminuiDescontoPrUnit = 1 OR a.somaAcrescimosPrUnit = 1 or a.somaFreteSeguroPrUnit = 1 THEN a.valorProdutoServicoBruto ELSE a.valorProdutoServico END - a.valorDescontoItem + a.valorAcrescimoItem) / v_valorBaseFreteSemFinComEntr;
      v_valorSeguroGeral := v_valorSeguroGeral + p_cab_valorSeguroGeral * (CASE WHEN a.diminuiDescontoPrUnit = 1 OR a.somaAcrescimosPrUnit = 1 or a.somaFreteSeguroPrUnit = 1 THEN a.valorProdutoServicoBruto ELSE a.valorProdutoServico END - a.valorDescontoItem + a.valorAcrescimoItem) / v_valorBaseFreteSemFinComEntr;
    ELSIF v_valorBaseRateioComEntrega > 0 AND v_valorBaseFreteSemFinComEntr <= 0 AND v_valorBaseFreteComFinComEntr <= 0 AND v_rateioFretePorControleEntr = 1 AND a.rateioFrete = 1 THEN
      v_idItemPreDocRateioFrete := a.idItemPreDocumento;
      v_valorFreteGeral  := v_valorFreteGeral  + p_cab_valorFreteGeral  * (CASE WHEN a.diminuiDescontoPrUnit = 1 OR a.somaAcrescimosPrUnit = 1 or a.somaFreteSeguroPrUnit = 1 THEN a.valorProdutoServicoBruto ELSE a.valorProdutoServico END - a.valorDescontoItem + a.valorAcrescimoItem) / v_valorBaseRateioComEntrega;
      v_valorSeguroGeral := v_valorSeguroGeral + p_cab_valorSeguroGeral * (CASE WHEN a.diminuiDescontoPrUnit = 1 OR a.somaAcrescimosPrUnit = 1 or a.somaFreteSeguroPrUnit = 1 THEN a.valorProdutoServicoBruto ELSE a.valorProdutoServico END - a.valorDescontoItem + a.valorAcrescimoItem) / v_valorBaseRateioComEntrega;
    ELSIF v_valorBaseFreteComFinSemEntr > 0 AND v_rateioFretePorControleEntr = 0 AND a.geraFinanceiro = 1 THEN
      v_idItemPreDocRateioFrete := a.idItemPreDocumento;
      v_valorFreteGeral  := v_valorFreteGeral  + p_cab_valorFreteGeral  * (CASE WHEN a.diminuiDescontoPrUnit = 1 OR a.somaAcrescimosPrUnit = 1 or a.somaFreteSeguroPrUnit = 1 THEN a.valorProdutoServicoBruto ELSE a.valorProdutoServico END - a.valorDescontoItem + a.valorAcrescimoItem) / v_valorBaseFreteComFinSemEntr;
      v_valorSeguroGeral := v_valorSeguroGeral + p_cab_valorSeguroGeral * (CASE WHEN a.diminuiDescontoPrUnit = 1 OR a.somaAcrescimosPrUnit = 1 or a.somaFreteSeguroPrUnit = 1 THEN a.valorProdutoServicoBruto ELSE a.valorProdutoServico END - a.valorDescontoItem + a.valorAcrescimoItem) / v_valorBaseFreteComFinSemEntr;
    ELSIF v_valorBaseFreteSemFinSemEntr > 0 AND v_valorBaseFreteComFinSemEntr <= 0 AND v_rateioFretePorControleEntr = 0 AND a.modDoc_geraFinanceiro = 1 THEN
      v_idItemPreDocRateioFrete := a.idItemPreDocumento;
      v_valorFreteGeral  := v_valorFreteGeral  + p_cab_valorFreteGeral  * (CASE WHEN a.diminuiDescontoPrUnit = 1 OR a.somaAcrescimosPrUnit = 1 or a.somaFreteSeguroPrUnit = 1 THEN a.valorProdutoServicoBruto ELSE a.valorProdutoServico END - a.valorDescontoItem + a.valorAcrescimoItem) / v_valorBaseFreteSemFinSemEntr;
      v_valorSeguroGeral := v_valorSeguroGeral + p_cab_valorSeguroGeral * (CASE WHEN a.diminuiDescontoPrUnit = 1 OR a.somaAcrescimosPrUnit = 1 or a.somaFreteSeguroPrUnit = 1 THEN a.valorProdutoServicoBruto ELSE a.valorProdutoServico END - a.valorDescontoItem + a.valorAcrescimoItem) / v_valorBaseFreteSemFinSemEntr;
    ELSIF v_valorBaseRateio > 0 AND (v_valorBaseRateioComEntrega <= 0 AND v_valorBaseFreteSemFinComEntr <= 0 AND v_valorBaseFreteComFinComEntr <= 0 AND v_rateioFretePorControleEntr = 1 OR v_valorBaseFreteSemFinSemEntr <= 0 AND v_valorBaseFreteComFinSemEntr <= 0 AND v_rateioFretePorControleEntr = 0) THEN
      v_idItemPreDocRateioFrete := a.idItemPreDocumento;
      v_valorFreteGeral  := v_valorFreteGeral  + p_cab_valorFreteGeral  * (CASE WHEN a.diminuiDescontoPrUnit = 1 OR a.somaAcrescimosPrUnit = 1 or a.somaFreteSeguroPrUnit = 1 THEN a.valorProdutoServicoBruto ELSE a.valorProdutoServico END - a.valorDescontoItem + a.valorAcrescimoItem) / v_valorBaseRateio;
      v_valorSeguroGeral := v_valorSeguroGeral + p_cab_valorSeguroGeral * (CASE WHEN a.diminuiDescontoPrUnit = 1 OR a.somaAcrescimosPrUnit = 1 or a.somaFreteSeguroPrUnit = 1 THEN a.valorProdutoServicoBruto ELSE a.valorProdutoServico END - a.valorDescontoItem + a.valorAcrescimoItem) / v_valorBaseRateio;
    END IF;
    IF ROUND (v_valorFreteGeral,2) >= v_saldoRatFreteGeral THEN
      v_valorFreteGeral := v_saldoRatFreteGeral;
      v_residuoFreteGeral := 0;
    ELSE
      v_residuoFreteGeral := v_valorFreteGeral - ROUND (v_valorFreteGeral,2);
      v_valorFreteGeral := ROUND (v_valorFreteGeral,2);
    END IF;
    v_saldoRatFreteGeral := v_saldoRatFreteGeral - v_valorFreteGeral;
    IF ROUND (v_valorSeguroGeral,2) >= v_saldoRatSeguroGeral THEN
      v_valorSeguroGeral   := v_saldoRatSeguroGeral;
      v_residuoSeguroGeral := 0;
    ELSE
      v_residuoSeguroGeral := v_valorSeguroGeral  - ROUND (v_valorSeguroGeral,2);
      v_valorSeguroGeral   := ROUND (v_valorSeguroGeral,2);
    END IF;
    v_saldoRatSeguroGeral := v_saldoRatSeguroGeral - v_valorSeguroGeral;

    -- v_valorAdicFreteMarinMerGeral
    -- v_valorDespesasAduaneirasGeral
    -- v_valorDescontoCustoOpGeral
    -- v_valorAcrescimoCustoOpGeral
    -- v_valorAcrescimoExtempGeral
    IF v_valorBaseRateioFinanceiro > 0 AND a.geraFinanceiro = 1 THEN 
      v_valorAdicFreteMarinMerGeral  := v_valorAdicFreteMarinMerGeral  + p_cab_valorAdicFreteMarinGeral * (CASE WHEN a.diminuiDescontoPrUnit = 1 OR a.somaAcrescimosPrUnit = 1 or a.somaFreteSeguroPrUnit = 1 THEN a.valorProdutoServicoBruto ELSE a.valorProdutoServico END - a.valorDescontoItem + a.valorAcrescimoItem) / v_valorBaseRateioFinanceiro;
      v_valorDespesasAduaneirasGeral := v_valorDespesasAduaneirasGeral + p_cab_valorDespesasAduanGeral  * (CASE WHEN a.diminuiDescontoPrUnit = 1 OR a.somaAcrescimosPrUnit = 1 or a.somaFreteSeguroPrUnit = 1 THEN a.valorProdutoServicoBruto ELSE a.valorProdutoServico END - a.valorDescontoItem + a.valorAcrescimoItem) / v_valorBaseRateioFinanceiro;
      v_valorDescontoCustoOpGeral    := v_valorDescontoCustoOpGeral    + p_cab_valorDescCustoOpGeral    * (CASE WHEN a.diminuiDescontoPrUnit = 1 OR a.somaAcrescimosPrUnit = 1 or a.somaFreteSeguroPrUnit = 1 THEN a.valorProdutoServicoBruto ELSE a.valorProdutoServico END - a.valorDescontoItem + a.valorAcrescimoItem) / v_valorBaseRateioFinanceiro;
      v_valorAcrescimoCustoOpGeral   := v_valorAcrescimoCustoOpGeral   + p_cab_valorAcrescCustoOpGeral  * (CASE WHEN a.diminuiDescontoPrUnit = 1 OR a.somaAcrescimosPrUnit = 1 or a.somaFreteSeguroPrUnit = 1 THEN a.valorProdutoServicoBruto ELSE a.valorProdutoServico END - a.valorDescontoItem + a.valorAcrescimoItem) / v_valorBaseRateioFinanceiro;
      v_valorAcrescimoExtempGeral    := v_valorAcrescimoExtempGeral    + p_cab_valorAcrescExtempGeral   * (CASE WHEN a.diminuiDescontoPrUnit = 1 OR a.somaAcrescimosPrUnit = 1 or a.somaFreteSeguroPrUnit = 1 THEN a.valorProdutoServicoBruto ELSE a.valorProdutoServico END - a.valorDescontoItem + a.valorAcrescimoItem) / v_valorBaseRateioFinanceiro;
    ELSIF v_valorBaseRateio > 0 AND v_valorBaseRateioFinanceiro <= 0 THEN
      v_valorAdicFreteMarinMerGeral  := v_valorAdicFreteMarinMerGeral  + p_cab_valorAdicFreteMarinGeral * (CASE WHEN a.diminuiDescontoPrUnit = 1 OR a.somaAcrescimosPrUnit = 1 or a.somaFreteSeguroPrUnit = 1 THEN a.valorProdutoServicoBruto ELSE a.valorProdutoServico END - a.valorDescontoItem + a.valorAcrescimoItem) / v_valorBaseRateio;
      v_valorDespesasAduaneirasGeral := v_valorDespesasAduaneirasGeral + p_cab_valorDespesasAduanGeral  * (CASE WHEN a.diminuiDescontoPrUnit = 1 OR a.somaAcrescimosPrUnit = 1 or a.somaFreteSeguroPrUnit = 1 THEN a.valorProdutoServicoBruto ELSE a.valorProdutoServico END - a.valorDescontoItem + a.valorAcrescimoItem) / v_valorBaseRateio;
      v_valorDescontoCustoOpGeral    := v_valorDescontoCustoOpGeral    + p_cab_valorDescCustoOpGeral    * (CASE WHEN a.diminuiDescontoPrUnit = 1 OR a.somaAcrescimosPrUnit = 1 or a.somaFreteSeguroPrUnit = 1 THEN a.valorProdutoServicoBruto ELSE a.valorProdutoServico END - a.valorDescontoItem + a.valorAcrescimoItem) / v_valorBaseRateio;
      v_valorAcrescimoCustoOpGeral   := v_valorAcrescimoCustoOpGeral   + p_cab_valorAcrescCustoOpGeral  * (CASE WHEN a.diminuiDescontoPrUnit = 1 OR a.somaAcrescimosPrUnit = 1 or a.somaFreteSeguroPrUnit = 1 THEN a.valorProdutoServicoBruto ELSE a.valorProdutoServico END - a.valorDescontoItem + a.valorAcrescimoItem) / v_valorBaseRateio;
      v_valorAcrescimoExtempGeral    := v_valorAcrescimoExtempGeral    + p_cab_valorAcrescExtempGeral   * (CASE WHEN a.diminuiDescontoPrUnit = 1 OR a.somaAcrescimosPrUnit = 1 or a.somaFreteSeguroPrUnit = 1 THEN a.valorProdutoServicoBruto ELSE a.valorProdutoServico END - a.valorDescontoItem + a.valorAcrescimoItem) / v_valorBaseRateio;
    END IF;
    IF ROUND (v_valorAdicFreteMarinMerGeral,2) >= v_saldoRatAdicFreteMarinGeral THEN
      v_valorAdicFreteMarinMerGeral := v_saldoRatAdicFreteMarinGeral;
      v_residuoAdicFreteMarinGeral  := 0;
    ELSE
      v_residuoAdicFreteMarinGeral  := v_valorAdicFreteMarinMerGeral - ROUND (v_valorAdicFreteMarinMerGeral,2);
      v_valorAdicFreteMarinMerGeral := ROUND (v_valorAdicFreteMarinMerGeral,2);
    END IF;
    v_saldoRatAdicFreteMarinGeral := v_saldoRatAdicFreteMarinGeral - v_valorAdicFreteMarinMerGeral;
    IF ROUND (v_valorDespesasAduaneirasGeral,2) >= v_saldoRatDespesasAduanGeral THEN
      v_valorDespesasAduaneirasGeral := v_saldoRatDespesasAduanGeral;
      v_residuoDespesasAduanGeral    := 0;
    ELSE
      v_residuoDespesasAduanGeral    := v_valorDespesasAduaneirasGeral - ROUND (v_valorDespesasAduaneirasGeral,2);
      v_valorDespesasAduaneirasGeral := ROUND (v_valorDespesasAduaneirasGeral,2);
    END IF;
    v_saldoRatDespesasAduanGeral := v_saldoRatDespesasAduanGeral - v_valorDespesasAduaneirasGeral;
    IF ROUND (v_valorDescontoCustoOpGeral,2) >= v_saldoRatDescCustoOpGeral THEN
      v_valorDescontoCustoOpGeral := v_saldoRatDescCustoOpGeral;
      v_residuoDescCustoOpGeral   := 0;
    ELSE
      v_residuoDescCustoOpGeral   := v_valorDescontoCustoOpGeral - ROUND (v_valorDescontoCustoOpGeral,2);
      v_valorDescontoCustoOpGeral := ROUND (v_valorDescontoCustoOpGeral,2);
    END IF;
    v_saldoRatDescCustoOpGeral := v_saldoRatDescCustoOpGeral - v_valorDescontoCustoOpGeral;
    IF ROUND (v_valorAcrescimoCustoOpGeral,2) >= v_saldoRatAcrescCustoOpGeral THEN
      v_valorAcrescimoCustoOpGeral := v_saldoRatAcrescCustoOpGeral;
      v_residuoAcrescCustoOpGeral  := 0;
    ELSE
      v_residuoAcrescCustoOpGeral  := v_valorAcrescimoCustoOpGeral - ROUND (v_valorAcrescimoCustoOpGeral,2);
      v_valorAcrescimoCustoOpGeral := ROUND (v_valorAcrescimoCustoOpGeral,2);
    END IF;
    v_saldoRatAcrescCustoOpGeral := v_saldoRatAcrescCustoOpGeral - v_valorAcrescimoCustoOpGeral;
    IF ROUND (v_valorAcrescimoExtempGeral,2) >= v_saldoRatAcrescExtempGeral THEN
      v_valorAcrescimoExtempGeral := v_saldoRatAcrescExtempGeral;
      v_residuoAcrescExtempGeral  := 0;
    ELSE
      v_residuoAcrescExtempGeral  := v_valorAcrescimoExtempGeral - ROUND (v_valorAcrescimoExtempGeral,2);
      v_valorAcrescimoExtempGeral := ROUND (v_valorAcrescimoExtempGeral,2);
    END IF;
    v_saldoRatAcrescExtempGeral := v_saldoRatAcrescExtempGeral - v_valorAcrescimoExtempGeral;

    -- v_valorOutrasDespesasGeral
    IF v_valorBaseRateioOutrasDespFin > 0 AND a.geraFinanceiro = 1 THEN
      v_valorOutrasDespesasGeral := v_valorOutrasDespesasGeral + p_cab_valorOutrasDespesasGeral * (CASE WHEN a.diminuiDescontoPrUnit = 1 OR a.somaAcrescimosPrUnit = 1 or a.somaFreteSeguroPrUnit = 1 THEN a.valorProdutoServicoBruto ELSE a.valorProdutoServico - a.valorDescontoItem + a.valorAcrescimoItem END) / v_valorBaseRateioOutrasDespFin;
    ELSIF v_valorBaseRateioOutrasDespGer > 0 AND v_valorBaseRateioOutrasDespFin <= 0 THEN
      v_valorOutrasDespesasGeral := v_valorOutrasDespesasGeral + p_cab_valorOutrasDespesasGeral * (CASE WHEN a.diminuiDescontoPrUnit = 1 OR a.somaAcrescimosPrUnit = 1 or a.somaFreteSeguroPrUnit = 1 THEN a.valorProdutoServicoBruto ELSE a.valorProdutoServico - a.valorDescontoItem + a.valorAcrescimoItem END) / v_valorBaseRateioOutrasDespGer;
    END IF;
    IF ROUND (v_valorOutrasDespesasGeral,2) >= v_saldoRatOutrasDespesasGeral THEN
      v_valorOutrasDespesasGeral   := v_saldoRatOutrasDespesasGeral;
      v_residuoOutrasDespesasGeral := 0;
    ELSE
      v_residuoOutrasDespesasGeral := v_valorOutrasDespesasGeral - ROUND (v_valorOutrasDespesasGeral,2);
      v_valorOutrasDespesasGeral   := ROUND (v_valorOutrasDespesasGeral,2);
    END IF;
    v_saldoRatOutrasDespesasGeral := v_saldoRatOutrasDespesasGeral - v_valorOutrasDespesasGeral;

    -- v_valorDescontoPagamento
    IF p_cab_valorDescontoPagamento       > 0
      AND v_valorBaseRateioPagamFinDesc   > 0
      AND a.geraFinanceiro = 1
      AND (v_rateioDescontofiltrarAPrazo  = 0
        OR a.aVista = 0)
      AND (v_rateioDescontofiltrarSemProm = 0
        OR a.promocao = 0
        AND p_cab_valorDescontoPagamento - v_valorDescontoPromocaoPagamen > 0)
    THEN
      v_valorDescontoPagamento := v_valorDescontoPagamento + (p_cab_valorDescontoPagamento - v_valorDescontoPromocaoPagamen) * (CASE WHEN a.diminuiDescontoPrUnit = 1 OR a.somaAcrescimosPrUnit = 1 or a.somaFreteSeguroPrUnit = 1 THEN a.valorProdutoServicoBruto ELSE a.valorProdutoServico END - a.valorDescontoItem + a.valorAcrescimoItem) / v_valorBaseRateioPagamFinDesc;
    ELSIF p_cab_valorDescontoPagamento    > 0
      AND v_valorBaseRateioPagamDesconto  > 0
      AND v_valorBaseRateioPagamFinDesc  <= 0
      AND (v_rateioDescontofiltrarAPrazo  = 0
        OR a.aVista = 0)
      AND (v_rateioDescontofiltrarSemProm = 0
        OR a.promocao = 0
        AND p_cab_valorDescontoPagamento - v_valorDescontoPromocaoPagamen > 0)
    THEN
      v_valorDescontoPagamento := v_valorDescontoPagamento + (p_cab_valorDescontoPagamento - v_valorDescontoPromocaoPagamen) * (CASE WHEN a.diminuiDescontoPrUnit = 1 OR a.somaAcrescimosPrUnit = 1 or a.somaFreteSeguroPrUnit = 1 THEN a.valorProdutoServicoBruto ELSE a.valorProdutoServico END - a.valorDescontoItem + a.valorAcrescimoItem) / v_valorBaseRateioPagamDesconto;
    END IF;
    IF p_cab_valorDescontoPagamento           > 0
      AND v_valorDescontoPromocaoPagamen      > 0
      AND a.valorDescontoPromocaoPagamento > 0
    THEN
      IF p_cab_valorDescontoPagamento < v_valorDescontoPromocaoPagamen THEN
        v_valorDescontoPagamento := v_valorDescontoPagamento + a.valorDescontoPromocaoPagamento * p_cab_valorDescontoPagamento / v_valorDescontoPromocaoPagamen;
      ELSE
        v_valorDescontoPagamento := v_valorDescontoPagamento + a.valorDescontoPromocaoPagamento;
      END IF;
    END IF;
    IF ROUND (v_valorDescontoPagamento,2) >= v_saldoRatDescontoPagamento THEN
      v_valorDescontoPagamento   := v_saldoRatDescontoPagamento;
      v_residuoDescontoPagamento := 0;
    ELSE
      v_residuoDescontoPagamento := v_valorDescontoPagamento - ROUND (v_valorDescontoPagamento,2);
      v_valorDescontoPagamento   := ROUND (v_valorDescontoPagamento,2);
    END IF;
    v_saldoRatDescontoPagamento  := v_saldoRatDescontoPagamento - v_valorDescontoPagamento;

    -- v_valorOutrasDespesasPagamento
    -- v_valorJurosPagamento
    IF v_valorBaseRateioPagamFinanc > 0 AND a.geraFinanceiro = 1 THEN
      v_valorOutrasDespesasPagamento := v_valorOutrasDespesasPagamento + p_cab_valorOutrasDespPagamento * (CASE WHEN a.diminuiDescontoPrUnit = 1 OR a.somaAcrescimosPrUnit = 1 or a.somaFreteSeguroPrUnit = 1 THEN a.valorProdutoServicoBruto ELSE a.valorProdutoServico END - a.valorDescontoItem + a.valorAcrescimoItem) / v_valorBaseRateioPagamFinanc;
      v_valorJurosPagamento          := v_valorJurosPagamento          + p_cab_valorJurosPagamento      * (CASE WHEN a.diminuiDescontoPrUnit = 1 OR a.somaAcrescimosPrUnit = 1 or a.somaFreteSeguroPrUnit = 1 THEN a.valorProdutoServicoBruto ELSE a.valorProdutoServico END - a.valorDescontoItem + a.valorAcrescimoItem) / v_valorBaseRateioPagamFinanc;
    ELSIF v_valorBaseRateioPagamento > 0 AND v_valorBaseRateioPagamFinanc <= 0 THEN
      v_valorOutrasDespesasPagamento := v_valorOutrasDespesasPagamento + p_cab_valorOutrasDespPagamento * (CASE WHEN a.diminuiDescontoPrUnit = 1 OR a.somaAcrescimosPrUnit = 1 or a.somaFreteSeguroPrUnit = 1 THEN a.valorProdutoServicoBruto ELSE a.valorProdutoServico END - a.valorDescontoItem + a.valorAcrescimoItem) / v_valorBaseRateioPagamento;
      v_valorJurosPagamento          := v_valorJurosPagamento          + p_cab_valorJurosPagamento      * (CASE WHEN a.diminuiDescontoPrUnit = 1 OR a.somaAcrescimosPrUnit = 1 or a.somaFreteSeguroPrUnit = 1 THEN a.valorProdutoServicoBruto ELSE a.valorProdutoServico END - a.valorDescontoItem + a.valorAcrescimoItem) / v_valorBaseRateioPagamento;
    END IF;
    IF ROUND (v_valorOutrasDespesasPagamento,2) >= v_saldoRatOutrasDespPagamento THEN
      v_valorOutrasDespesasPagamento := v_saldoRatOutrasDespPagamento;
      v_residuoOutrasDespPagamento   := 0;
    ELSE
      v_residuoOutrasDespPagamento   := v_valorOutrasDespesasPagamento - ROUND (v_valorOutrasDespesasPagamento,2);
      v_valorOutrasDespesasPagamento := ROUND (v_valorOutrasDespesasPagamento,2);
    END IF;
    v_saldoRatOutrasDespPagamento := v_saldoRatOutrasDespPagamento - v_valorOutrasDespesasPagamento;
    IF ROUND (v_valorJurosPagamento,2) >= v_saldoRatJurosPagamento THEN
      v_valorJurosPagamento   := v_saldoRatJurosPagamento;
      v_residuoJurosPagamento := 0;
    ELSE
      v_residuoJurosPagamento := v_valorJurosPagamento - ROUND (v_valorJurosPagamento,2);
      v_valorJurosPagamento   := ROUND (v_valorJurosPagamento,2);
    END IF;
    v_saldoRatJurosPagamento := v_saldoRatJurosPagamento - v_valorJurosPagamento;

    -- Recalcula Valores
    ADD_CALCULA_TOTAIS_ITEM(
      p_cab_tipoPagamentoFrete,
      a.quantidade,
      a.quantidadeConvertida,
      a.precoUnitarioBruto,
      a.acrescimoUnitarioComposicao,
      a.precoUnitario,
      a.valorDescontoItem,
      a.valorAcrescimoItem,
      a.valorFreteItem,
      a.valorSeguroItem,
      a.valorAdicFreteMarinhaMerItem,
      a.valorDespesasAduaneirasItem,
      v_valorFreteGeral,
      v_valorSeguroGeral,
      v_valorDescontoGeral,
      v_valorOutrasDespesasGeral,
      v_valorAdicFreteMarinMerGeral,
      v_valorDespesasAduaneirasGeral,
      v_valorDescontoPagamento,
      v_valorOutrasDespesasPagamento,
      v_valorJurosPagamento,
      a.diminuiDescontoPrUnit,
      a.somaAcrescimosPrUnit,
      a.somaFreteSeguroPrUnit,
      a.composicaoPreco,
      /* Retornos */
      v_precoUnitario,
      v_precoUnitarioConvertido,
      v_valorProdutoServico,
      v_valorFreteTotal,
      v_valorSeguroTotal,
      v_valorDescontoTotal,
      v_valorOutrasDespesasTotal,
      v_valorAdicFreteMarinMerTotal,
      v_valorDespesasAduaneirasTotal);
    v_valorAcrescimoExtempSubtotal := FUNC_ADD_CALC_EXTEMP_SUBTOTAL(
      a.quantidade,
      v_precoUnitario,
      a.quantidadeExtemporanea,
      a.acrescimoUnitarioExtemporaneo);
    v_valorAcrescimoExtempTotal := FUNC_ADD_CALC_EXTEMP_TOTAL(
      v_valorAcrescimoExtempSubtotal,
      a.valorAcrescimoExtempItem,
      v_valorAcrescimoExtempGeral);
    IF p_cab_impostosEditados = 0 
        OR v_valorProdutoServico <> a.valorProdutoServico
        OR CASE WHEN p_cab_tipoPagamentoFrete = 'V' THEN 0 ELSE v_valorFreteTotal END
        <> CASE WHEN CASE WHEN p_troca_tipoPagamentoFrete = 1 THEN p_a_cab_tipoPagamentoFrete ELSE p_cab_tipoPagamentoFrete END = 'V' THEN 0 ELSE a.valorFreteTotal END
        OR CASE WHEN p_cab_tipoPagamentoFrete = 'V' THEN 0 ELSE v_valorSeguroTotal END
        <> CASE WHEN CASE WHEN p_troca_tipoPagamentoFrete = 1 THEN p_a_cab_tipoPagamentoFrete ELSE p_cab_tipoPagamentoFrete END = 'V' THEN 0 ELSE a.valorSeguroTotal END
        OR v_valorDescontoTotal <> a.valorDescontoTotal
        OR v_valorOutrasDespesasTotal <> a.valorOutrasDespesasTotal
        OR v_valorAdicFreteMarinMerTotal <> a.valorAdicFreteMarinhaMerTotal
        OR v_valorDespesasAduaneirasTotal <> a.valorDespesasAduaneirasTotal
        OR v_precoUnitario <> a.precoUnitario
        OR v_valorProdutoServico <> a.valorProdutoServico
    THEN
      r_calcularImpostosItem := 1;
    END IF;
    v_valorBasePagamento := FUNC_ADD_CALC_BASE_PAGAMENTO (
      p_cab_origemDocumento,
      0, -- p_cab_nfFornecedor
      p_cab_tipoPagamentoFrete,
      a.geraFinanceiro,
      v_valorProdutoServico,
      v_valorDescontoPagamento,
      v_valorOutrasDespesasPagamento,
      v_valorJurosPagamento,
      v_valorFreteTotal,
      v_valorSeguroTotal,
      v_valorDescontoTotal,
      v_valorOutrasDespesasTotal,
      a.valorIPIDevolucao,
      a.retidoISSQN,
      a.valorISSQN,
      a.valorRetIRRF,
      a.valorRetINSS,
      a.valorRetPIS,
      a.valorRetCOFINS,
      a.valorRetCSLL,
      a.valorRetOutros,
      a.valorII,
      a.valorIOF,
      a.valorIPI,
      a.valorICMSST,
      0, -- p_item_valorICMSSTEscrit
      0, -- p_item_somarICMSST
      v_valorAcrescimoExtempTotal,
      a.modDoc_geraFinanceiro);
    v_valorLiquidoItem := FUNC_ADD_CALC_VALOR_LIQUIDO (
      0, -- p_cab_nfFornecedor
      p_cab_tipoPagamentoFrete,
      v_valorProdutoServico,
      v_valorFreteTotal,
      v_valorSeguroTotal,
      v_valorDescontoTotal,
      v_valorOutrasDespesasTotal,
      a.valorIPIDevolucao,
      a.valorII,
      a.valorIOF,
      a.valorIPI,
      a.valorICMSST,
      0, -- p_item_valorICMSSTEscrit
      0 -- p_item_somarICMSST
      );
    ADD_CALCULA_CUSTO_CMV (
      p_cab_atualizaCustoMedio,
      p_cab_estabelecimento,
      0,
      a.modeloDocumento,
      a.quantidade,
      a.valorII,
      a.valorIOF,
      a.valorIPI,
      a.valorIPIDevolucao,
      a.valorPIS,
      a.valorPISST,
      a.valorCOFINS,
      a.valorCOFINSST,
      a.valorCreditoSimplesNacional,
      a.valorICMS,
      a.valorICMSST,
      0,
      v_valorLiquidoItem,
      a.valorDescontoCustoOpItem,
      v_valorDescontoCustoOpGeral,
      a.valorAcrescimoCustoOpItem,
      v_valorAcrescimoCustoOpGeral,
      v_valorAcrescimoExtempTotal,
      /* Retornos */
      v_valorDescontoCustoOpTotal,
      v_valorAcrescimoCustoOpTotal,
      v_precoCustoOperacao,
      v_valorCustoOperacao,
      v_precoCMV,
      v_valorCMV);

    -- Atualiza Item
    UPDATE MOPREDOCUMXITENS SET
      precoUnitario                 = v_precoUnitario,
      precoUnitarioConvertido       = v_precoUnitarioConvertido,
      valorProdutoServico           = v_valorProdutoServico,
      valorFreteGeral               = v_valorFreteGeral,
      valorSeguroGeral              = v_valorSeguroGeral,
      valorDescontoGeral            = v_valorDescontoGeral,
      valorOutrasDespesasGeral      = v_valorOutrasDespesasGeral,
      valorAdicFreteMarinhaMerGeral = v_valorAdicFreteMarinMerGeral,
      valorDespesasAduaneirasGeral  = v_valorDespesasAduaneirasGeral,
      valorBasePagamento            = v_valorBasePagamento,
      valorDescontoPagamento        = v_valorDescontoPagamento,
      valorOutrasDespesasPagamento  = v_valorOutrasDespesasPagamento,
      valorJurosPagamento           = v_valorJurosPagamento,
      valorFreteTotal               = v_valorFreteTotal,
      valorSeguroTotal              = v_valorSeguroTotal,
      valorDescontoTotal            = v_valorDescontoTotal,
      valorOutrasDespesasTotal      = v_valorOutrasDespesasTotal,
      valorAdicFreteMarinhaMerTotal = v_valorAdicFreteMarinMerTotal,
      valorDespesasAduaneirasTotal  = v_valorDespesasAduaneirasTotal,
      valorLiquidoItem              = v_valorLiquidoItem,
      valorDescontoCustoOpGeral     = v_valorDescontoCustoOpGeral,
      valorDescontoCustoOpTotal     = v_valorDescontoCustoOpTotal,
      valorAcrescimoCustoOpGeral    = v_valorAcrescimoCustoOpGeral,
      valorAcrescimoCustoOpTotal    = v_valorAcrescimoCustoOpTotal,
      precoCustoOperacao            = v_precoCustoOperacao,
      valorCustoOperacao            = v_valorCustoOperacao,
      precoCMV                      = v_precoCMV,
      valorCMV                      = v_valorCMV,
      valorAcrescimoExtempSubtotal  = v_valorAcrescimoExtempSubtotal,
      valorAcrescimoExtempGeral     = v_valorAcrescimoExtempGeral,
      valorAcrescimoExtempTotal     = v_valorAcrescimoExtempTotal
    WHERE idItemPreDocumento        = a.idItemPreDocumento;
    IF a.tipoProduto = '09' THEN
      r_cab_valorServicos            := r_cab_valorServicos + v_valorProdutoServico;
    ELSE
      r_cab_valorProdutos            := r_cab_valorProdutos + v_valorProdutoServico;
    END IF;
    r_cab_valorBasePagamento       := r_cab_valorBasePagamento + v_valorBasePagamento;
    IF a.usarPrecoAVista = 1 AND a.geraFinanceiro = 1 THEN
      r_cab_valorAVistaMinimo        := r_cab_valorAVistaMinimo + v_valorProdutoServico + v_valorDescontoPagamento - v_valorOutrasDespesasPagamento - v_valorJurosPagamento - v_valorDescontoTotal + v_valorOutrasDespesasTotal;
    END IF;
    r_cab_valorFreteTotal          := r_cab_valorFreteTotal + v_valorFreteTotal;
    r_cab_valorSeguroTotal         := r_cab_valorSeguroTotal + v_valorSeguroTotal;
    r_cab_valorDescontoTotal       := r_cab_valorDescontoTotal + v_valorDescontoTotal;
    r_cab_valorOutrasDespesasTotal := r_cab_valorOutrasDespesasTotal + v_valorOutrasDespesasTotal;
    r_cab_valorAdicFreteMarinTotal := r_cab_valorAdicFreteMarinTotal + v_valorAdicFreteMarinMerTotal;
    r_cab_valorDespesasAduanTotal  := r_cab_valorDespesasAduanTotal + v_valorDespesasAduaneirasTotal;
    r_cab_valorLiquidoItem         := r_cab_valorLiquidoItem + v_valorLiquidoItem;
    r_cab_valorDescCustoOpTotal    := r_cab_valorDescCustoOpTotal + v_valorDescontoCustoOpTotal;
    r_cab_valorAcrescCustoOpTotal  := r_cab_valorAcrescCustoOpTotal + v_valorAcrescimoCustoOpTotal;
    r_cab_valorCustoOperacao       := r_cab_valorCustoOperacao + v_valorCustoOperacao;
    r_cab_valorCMV                 := r_cab_valorCMV + v_valorCMV;
    r_cab_valorAcrescExtempTotal   := r_cab_valorAcrescExtempTotal + v_valorAcrescimoExtempTotal;
  END LOOP;
  IF v_idItemPreDocUltimoItem <> 0 AND (v_saldoRatDescontoGeral <> 0 OR v_saldoRatOutrasDespesasGeral <> 0 OR v_saldoRatDescontoPagamento <> 0 OR v_saldoRatOutrasDespPagamento <> 0 OR v_saldoRatJurosPagamento <> 0 OR v_saldoRatFreteGeral <> 0 OR v_saldoRatSeguroGeral <> 0 OR v_saldoRatAdicFreteMarinGeral <> 0 OR v_saldoRatDespesasAduanGeral <> 0) THEN
    ADD_PRE_DOC_CALC_IMP_RESIDUO (
      p_troca_tipoPagamentoFrete,
      p_a_cab_tipoPagamentoFrete,
      p_cab_origemDocumento,
      p_cab_atualizaCustoMedio,
      p_cab_estabelecimento,
      p_cab_tipoPagamentoFrete,
      r_cab_valorProdutos,
      r_cab_valorServicos,
      r_cab_valorBasePagamento,
      r_cab_valorAVistaMinimo,
      r_cab_valorFreteTotal,
      r_cab_valorSeguroTotal,
      r_cab_valorDescontoTotal,
      r_cab_valorOutrasDespesasTotal,
      r_cab_valorAdicFreteMarinTotal,
      r_cab_valorDespesasAduanTotal,
      p_cab_impostosEditados,
      r_cab_valorLiquidoItem,
      r_cab_valorDescCustoOpTotal,
      r_cab_valorAcrescCustoOpTotal,
      r_cab_valorCustoOperacao,
      r_cab_valorCMV,
      r_cab_valorAcrescExtempTotal,
      CASE WHEN v_idItemPreDocRateioFrete = 0 THEN v_idItemPreDocUltimoItem ELSE v_idItemPreDocRateioFrete END,
      v_saldoRatFreteGeral,
      v_saldoRatSeguroGeral,
      v_saldoRatDescontoGeral,
      v_saldoRatOutrasDespesasGeral,
      v_saldoRatAdicFreteMarinGeral,
      v_saldoRatDespesasAduanGeral,
      v_saldoRatDescontoPagamento,
      v_saldoRatOutrasDespPagamento,
      v_saldoRatJurosPagamento,
      v_saldoRatDescCustoOpGeral,
      v_saldoRatAcrescCustoOpGeral,
      v_saldoRatAcrescExtempGeral,
      r_calcularImpostosItem,
      /* Retornos */
      r_cab_valorProdutos,
      r_cab_valorServicos,
      r_cab_valorBasePagamento,
      r_cab_valorAVistaMinimo,
      r_cab_valorFreteTotal,
      r_cab_valorSeguroTotal,
      r_cab_valorDescontoTotal,
      r_cab_valorOutrasDespesasTotal,
      r_cab_valorAdicFreteMarinTotal,
      r_cab_valorDespesasAduanTotal,
      r_cab_valorLiquidoItem,
      r_cab_valorDescCustoOpTotal,
      r_cab_valorAcrescCustoOpTotal,
      r_cab_valorCustoOperacao,
      r_cab_valorCMV,
      r_cab_valorAcrescExtempTotal,
      r_calcularImpostosItem);
  END IF;
END ADD_PRE_DOC_CALC_IMP_RATEIO;

/

create or replace PROCEDURE ADD_DOC_FISC_CALC_IMP_RATEIO (
  p_cab_idDocumentoFiscal        IN NUMBER,
  p_troca_tipoPagamentoFrete     IN NUMBER,
  p_a_cab_tipoPagamentoFrete     IN CHAR,
  p_cab_origemDocumento          IN NUMBER,
  p_cab_entradaSaida             IN CHAR,
  p_cab_devolucaoAnulacaoRetorno IN NUMBER,
  p_cab_atualizaCustoMedio       IN NUMBER,
  p_cab_estabelecimento          IN NUMBER,
  p_cab_nfFornecedor             IN NUMBER,
  p_cab_tipoPagamentoFrete       IN CHAR,
  p_cab_valorFreteGeral          IN NUMBER,
  p_cab_valorSeguroGeral         IN NUMBER,
  p_cab_valorDescontoGeral       IN NUMBER,
  p_cab_valorOutrasDespesasGeral IN NUMBER,
  p_cab_valorAdicFreteMarinGeral IN NUMBER,
  p_cab_valorDespesasAduanGeral  IN NUMBER,
  p_cab_valorDescontoPagamento   IN NUMBER,
  p_cab_valorOutrasDespPagamento IN NUMBER,
  p_cab_valorJurosPagamento      IN NUMBER,
  p_cab_impostosEditados         IN NUMBER,
  p_cab_valorDescCustoOpGeral    IN NUMBER,
  p_cab_valorAcrescCustoOpGeral  IN NUMBER,
  p_cab_valorAcrescExtempGeral   IN NUMBER,
  p_habilitaControleEntrega      IN NUMBER,
  /* Retornos */
  r_cab_valorProdutos            OUT NUMBER,
  r_cab_valorServicos            OUT NUMBER,
  r_cab_valorBasePagamento       OUT NUMBER,
  r_cab_valorAVistaMinimo        OUT NUMBER,
  r_cab_valorFreteTotal          OUT NUMBER,
  r_cab_valorSeguroTotal         OUT NUMBER,
  r_cab_valorDescontoTotal       OUT NUMBER,
  r_cab_valorOutrasDespesasTotal OUT NUMBER,
  r_cab_valorAdicFreteMarinTotal OUT NUMBER,
  r_cab_valorDespesasAduanTotal  OUT NUMBER,
  r_cab_valorLiquidoItem         OUT NUMBER,
  r_cab_valorDescCustoOpTotal    OUT NUMBER,
  r_cab_valorAcrescCustoOpTotal  OUT NUMBER,
  r_cab_valorCustoOperacao       OUT NUMBER,
  r_cab_valorCMV                 OUT NUMBER,
  r_cab_valorAcrescExtempTotal   OUT NUMBER,
  r_calcularImpostosItem         OUT NUMBER)
IS
  v_auxNumber                    NUMBER;
  v_valorDescontoPromocaoGeral   NUMBER;
  v_valorDescontoPromocaoPagamen NUMBER;
  v_rateioDescontofiltrarSemProm NUMBER;
  v_rateioDescontofiltrarAPrazo  NUMBER;
  v_rateioFretePorControleEntr   NUMBER;
  v_valorBaseFreteSemFinSemEntr  NUMBER;
  v_valorBaseFreteComFinSemEntr  NUMBER;
  v_valorBaseFreteSemFinComEntr  NUMBER;
  v_valorBaseFreteComFinComEntr  NUMBER;
  v_valorBaseRateio              NUMBER;
  v_valorBaseRateioComEntrega    NUMBER;
  v_valorBaseRateioFinanceiro    NUMBER;
  v_valorBaseRateioOutrasDespGer NUMBER;
  v_valorBaseRateioOutrasDespFin NUMBER;
  v_valorBaseRateioDescontoGeral NUMBER;
  v_valorBaseRateioPagamento     NUMBER;
  v_valorBaseRateioPagamFinanc   NUMBER;
  v_valorBaseRateioPagamDesconto NUMBER;
  v_valorBaseRateioPagamFinDesc  NUMBER;
  v_saldoRatFreteGeral           NUMBER;
  v_saldoRatSeguroGeral          NUMBER;
  v_saldoRatDescontoGeral        NUMBER;
  v_saldoRatOutrasDespesasGeral  NUMBER;
  v_saldoRatAdicFreteMarinGeral  NUMBER;
  v_saldoRatDespesasAduanGeral   NUMBER;
  v_saldoRatDescontoPagamento    NUMBER;
  v_saldoRatOutrasDespPagamento  NUMBER;
  v_saldoRatJurosPagamento       NUMBER;
  v_saldoRatDescCustoOpGeral     NUMBER;
  v_saldoRatAcrescCustoOpGeral   NUMBER;
  v_saldoRatAcrescExtempGeral    NUMBER;
  v_residuoFreteGeral            NUMBER;
  v_residuoSeguroGeral           NUMBER;
  v_residuoDescontoGeral         NUMBER;
  v_residuoOutrasDespesasGeral   NUMBER;
  v_residuoAdicFreteMarinGeral   NUMBER;
  v_residuoDespesasAduanGeral    NUMBER;
  v_residuoDescontoPagamento     NUMBER;
  v_residuoOutrasDespPagamento   NUMBER;
  v_residuoJurosPagamento        NUMBER;
  v_residuoDescCustoOpGeral      NUMBER;
  v_residuoAcrescCustoOpGeral    NUMBER;
  v_residuoAcrescExtempGeral     NUMBER;
  v_idItemDocFiscalUltimoItem    NUMBER;
  v_idItemDocFiscalRateioFrete   NUMBER;
  v_precoUnitario                NUMBER;
  v_precoUnitarioConvertido      NUMBER;
  v_valorProdutoServico          NUMBER;
  v_valorFreteGeral              NUMBER;
  v_valorSeguroGeral             NUMBER;
  v_valorDescontoGeral           NUMBER;
  v_valorOutrasDespesasGeral     NUMBER;
  v_valorAdicFreteMarinMerGeral  NUMBER;
  v_valorDespesasAduaneirasGeral NUMBER;
  v_valorBasePagamento           NUMBER;
  v_valorDescontoPagamento       NUMBER;
  v_valorOutrasDespesasPagamento NUMBER;
  v_valorJurosPagamento          NUMBER;
  v_valorFreteTotal              NUMBER;
  v_valorSeguroTotal             NUMBER;
  v_valorDescontoTotal           NUMBER;
  v_valorOutrasDespesasTotal     NUMBER;
  v_valorAdicFreteMarinMerTotal  NUMBER;
  v_valorDespesasAduaneirasTotal NUMBER;
  v_valorLiquidoItem             NUMBER;
  v_valorDescontoCustoOpGeral    NUMBER;
  v_valorDescontoCustoOpTotal    NUMBER;
  v_valorAcrescimoCustoOpGeral   NUMBER;
  v_valorAcrescimoCustoOpTotal   NUMBER;
  v_precoCustoOperacao           NUMBER;
  v_valorCustoOperacao           NUMBER;
  v_precoCMV                     NUMBER;
  v_valorCMV                     NUMBER;
  v_valorAcrescimoExtempSubtotal NUMBER;
  v_valorAcrescimoExtempGeral    NUMBER;
  v_valorAcrescimoExtempTotal    NUMBER;
  v_calculoImpostosPendenteItem  NUMBER;
BEGIN
  r_cab_valorProdutos            := 0;
  r_cab_valorServicos            := 0;
  r_cab_valorBasePagamento       := 0;
  r_cab_valorAVistaMinimo        := 0;
  r_cab_valorFreteTotal          := 0;
  r_cab_valorSeguroTotal         := 0;
  r_cab_valorDescontoTotal       := 0;
  r_cab_valorOutrasDespesasTotal := 0;
  r_cab_valorAdicFreteMarinTotal := 0;
  r_cab_valorDespesasAduanTotal  := 0;
  r_cab_valorLiquidoItem         := 0;
  r_cab_valorDescCustoOpTotal    := 0;
  r_cab_valorAcrescCustoOpTotal  := 0;
  r_cab_valorCustoOperacao       := 0;
  r_cab_valorCMV                 := 0;
  r_cab_valorAcrescExtempTotal   := 0;
  r_calcularImpostosItem         := 0;
  v_saldoRatFreteGeral           := p_cab_valorFreteGeral;
  v_saldoRatSeguroGeral          := p_cab_valorSeguroGeral;
  v_saldoRatDescontoGeral        := p_cab_valorDescontoGeral;
  v_saldoRatOutrasDespesasGeral  := p_cab_valorOutrasDespesasGeral;
  v_saldoRatAdicFreteMarinGeral  := p_cab_valorAdicFreteMarinGeral;
  v_saldoRatDespesasAduanGeral   := p_cab_valorDespesasAduanGeral;
  v_saldoRatDescontoPagamento    := p_cab_valorDescontoPagamento;
  v_saldoRatOutrasDespPagamento  := p_cab_valorOutrasDespPagamento;
  v_saldoRatJurosPagamento       := p_cab_valorJurosPagamento;
  v_saldoRatDescCustoOpGeral     := p_cab_valorDescCustoOpGeral;
  v_saldoRatAcrescCustoOpGeral   := p_cab_valorAcrescCustoOpGeral;
  v_saldoRatAcrescExtempGeral    := p_cab_valorAcrescExtempGeral;
  v_residuoFreteGeral            := 0;
  v_residuoSeguroGeral           := 0;
  v_residuoDescontoGeral         := 0;
  v_residuoOutrasDespesasGeral   := 0;
  v_residuoAdicFreteMarinGeral   := 0;
  v_residuoDespesasAduanGeral    := 0;
  v_residuoDescontoPagamento     := 0;
  v_residuoOutrasDespPagamento   := 0;
  v_residuoJurosPagamento        := 0;
  v_residuoDescCustoOpGeral      := 0;
  v_residuoAcrescCustoOpGeral    := 0;
  v_residuoAcrescExtempGeral     := 0;
  v_idItemDocFiscalUltimoItem    := 0;
  v_idItemDocFiscalRateioFrete   := 0;
  v_valorDescontoPromocaoGeral   := 0;
  v_valorDescontoPromocaoPagamen := 0;
  v_rateioDescontofiltrarSemProm := 0;
  v_rateioDescontofiltrarAPrazo  := 0;
  
  -- v_valorDescontoPromocaoGeral
  IF p_cab_valorDescontoGeral > 0 THEN
    SELECT COALESCE(SUM(promo.valorDesconto),0)
    INTO v_valorDescontoPromocaoGeral
    FROM MODOCFISCALXITENS a
    JOIN MODOCFISCALXPROMOCOES promo
    ON promo.idItemDocFiscal = a.idItemDocFiscal
    WHERE a.idDocumentoFiscal = p_cab_idDocumentoFiscal
    AND a.cancelado = 0
    AND promo.cabecalhoItemPagamento ='C';
  END IF;
  
  -- v_valorDescontoPromocaoPagamen
  IF p_cab_valorDescontoPagamento > 0 THEN
    SELECT COALESCE(SUM(promo.valorDesconto),0)
    INTO v_valorDescontoPromocaoPagamen
    FROM MODOCFISCALXITENS a
    JOIN MODOCFISCALXPROMOCOES promo
    ON promo.idItemDocFiscal = a.idItemDocFiscal
    WHERE a.idDocumentoFiscal = p_cab_idDocumentoFiscal
    AND a.cancelado = 0
    AND promo.cabecalhoItemPagamento ='P';
  END IF;

  -- v_rateioDescontofiltrarSemProm
  IF p_cab_valorDescontoGeral > v_valorDescontoPromocaoGeral OR p_cab_valorDescontoPagamento > v_valorDescontoPromocaoPagamen THEN
    SELECT
      CASE
        WHEN EXISTS(
          SELECT 1
          FROM MODOCFISCALXITENS a
          JOIN PAMODELOSDOCUMENTO modDoc
          ON modDoc.modeloDocumento = a.modeloDocumento
          WHERE a.idDocumentoFiscal = p_cab_idDocumentoFiscal
          AND a.cancelado = 0
          AND COALESCE((
            SELECT SUM(b.valorDesconto)
            FROM MODOCFISCALXPROMOCOES b
            WHERE b.idItemDocFiscal = a.idItemDocFiscal
            AND b.cabecalhoItemPagamento IN ('C','P')),0) > (
            CASE
              WHEN modDoc.diminuiDescontoPrUnit = 1
                OR modDoc.somaAcrescimosPrUnit  = 1
                OR modDoc.somaFreteSeguroPrUnit = 1
              THEN a.valorProdutoServicoBruto
              ELSE a.valorProdutoServico
            END
            - a.valorDescontoItem
            + a.valorAcrescimoItem))
        THEN 0
        WHEN COALESCE ((
          SELECT SUM (CASE WHEN modDoc.diminuiDescontoPrUnit = 1 OR modDoc.somaAcrescimosPrUnit = 1 or modDoc.somaFreteSeguroPrUnit = 1 THEN a.valorProdutoServicoBruto ELSE a.valorProdutoServico END - a.valorDescontoItem + a.valorAcrescimoItem)
          FROM MODOCFISCALXITENS a
          JOIN PAMODELOSDOCUMENTO modDoc
          ON modDoc.modeloDocumento = a.modeloDocumento
          JOIN MODOCFISCALXPROMOCOES b
          ON b.idItemDocFiscal = a.idItemDocFiscal
          WHERE a.idDocumentoFiscal = p_cab_idDocumentoFiscal
          AND a.cancelado = 0),0) > (
            CASE
              WHEN p_cab_valorDescontoGeral > v_valorDescontoPromocaoGeral
              THEN p_cab_valorDescontoGeral - v_valorDescontoPromocaoGeral
              ELSE 0
            END +
            CASE
              WHEN p_cab_valorDescontoPagamento > v_valorDescontoPromocaoPagamen
              THEN p_cab_valorDescontoPagamento - v_valorDescontoPromocaoPagamen
              ELSE 0
            END)
          AND EXISTS (
            SELECT 1
            FROM MODOCFISCALXITENS a
            WHERE a.idDocumentoFiscal = p_cab_idDocumentoFiscal
            AND a.cancelado = 0
            AND NOT (EXISTS(
              SELECT 1
              FROM MODOCFISCALXPROMOCOES b
              WHERE b.idItemDocFiscal = a.idItemDocFiscal)))
        THEN 1
        ELSE 0
      END
    INTO v_rateioDescontofiltrarSemProm
    FROM DUAL;
  END IF;

  -- v_rateioDescontofiltrarAPrazo
  IF p_cab_valorDescontoGeral > v_valorDescontoPromocaoGeral OR p_cab_valorDescontoPagamento > v_valorDescontoPromocaoPagamen THEN
    SELECT
      CASE
        WHEN COALESCE ((
          SELECT SUM (CASE WHEN modDoc.diminuiDescontoPrUnit = 1 OR modDoc.somaAcrescimosPrUnit = 1 or modDoc.somaFreteSeguroPrUnit = 1 THEN a.valorProdutoServicoBruto ELSE a.valorProdutoServico END - a.valorDescontoItem + a.valorAcrescimoItem)
          FROM MODOCFISCALXITENS a
          JOIN PAMODELOSDOCUMENTO modDoc
          ON modDoc.modeloDocumento = a.modeloDocumento
          WHERE a.idDocumentoFiscal = p_cab_idDocumentoFiscal
          AND a.cancelado = 0
          AND a.precoSugestaoAPrazo <> a.precoSugestaoAVista
          AND a.usarPrecoAVista = 1
          AND (v_rateioDescontofiltrarSemProm = 0
            OR NOT(EXISTS(
              SELECT 1
              FROM MODOCFISCALXPROMOCOES promo
              WHERE promo.idItemDocFiscal = a.idItemDocFiscal)))),0) > (
            CASE
              WHEN p_cab_valorDescontoGeral > v_valorDescontoPromocaoGeral
              THEN p_cab_valorDescontoGeral - v_valorDescontoPromocaoGeral
              ELSE 0
            END +
            CASE
              WHEN p_cab_valorDescontoPagamento > v_valorDescontoPromocaoPagamen
              THEN p_cab_valorDescontoPagamento - v_valorDescontoPromocaoPagamen
              ELSE 0
            END)
          AND EXISTS (
            SELECT 1
            FROM MODOCFISCALXITENS a
            WHERE a.idDocumentoFiscal = p_cab_idDocumentoFiscal
            AND a.cancelado = 0
            AND (a.precoSugestaoAPrazo = a.precoSugestaoAVista
              OR a.usarPrecoAVista = 0)
            AND (v_rateioDescontofiltrarSemProm = 0
              OR NOT(EXISTS(
                SELECT 1
                FROM MODOCFISCALXPROMOCOES promo
                WHERE promo.idItemDocFiscal = a.idItemDocFiscal))))
        THEN 1
        ELSE 0
      END
    INTO v_rateioDescontofiltrarAPrazo
    FROM DUAL;
  END IF;
  
  -- Bases Rateio
  SELECT
    MAX(COALESCE((CASE WHEN p_habilitaControleEntrega = 0 OR EXISTS(SELECT 1 FROM MODOCFISCALXORCAMENTOITEM docXorc JOIN MOORCAMENTOXITENS itemOrc ON itemOrc.idItemOrcamento = docXorc.idItemOrcamento JOIN PACONTROLESENTREGA contr ON contr.controleEntrega = itemOrc.controleEntrega WHERE docXorc.idItemDocFiscal = a.idItemDocFiscal AND itemOrc.controleEntrega > 0 AND contr.habilitaFrete = 1) THEN 1 ELSE 0 END),0)),
    COALESCE(SUM(CASE WHEN modDoc.geraFinanceiro = 1 THEN CASE WHEN modDoc.diminuiDescontoPrUnit = 1 OR modDoc.somaAcrescimosPrUnit = 1 or modDoc.somaFreteSeguroPrUnit = 1 THEN a.valorProdutoServicoBruto ELSE a.valorProdutoServico END - a.valorDescontoItem + a.valorAcrescimoItem ELSE 0 END),0),
    COALESCE(SUM(CASE WHEN a.geraFinanceiro = 1 THEN CASE WHEN modDoc.diminuiDescontoPrUnit = 1 OR modDoc.somaAcrescimosPrUnit = 1 or modDoc.somaFreteSeguroPrUnit = 1 THEN a.valorProdutoServicoBruto ELSE a.valorProdutoServico END - a.valorDescontoItem + a.valorAcrescimoItem ELSE 0 END),0),
    COALESCE(SUM(CASE WHEN modDoc.geraFinanceiro = 1 AND (p_habilitaControleEntrega = 0 OR EXISTS(SELECT 1 FROM MODOCFISCALXORCAMENTOITEM docXorc JOIN MOORCAMENTOXITENS itemOrc ON itemOrc.idItemOrcamento = docXorc.idItemOrcamento JOIN PACONTROLESENTREGA contr ON contr.controleEntrega = itemOrc.controleEntrega WHERE docXorc.idItemDocFiscal = a.idItemDocFiscal AND itemOrc.controleEntrega > 0 AND contr.habilitaFrete = 1)) THEN CASE WHEN modDoc.diminuiDescontoPrUnit = 1 OR modDoc.somaAcrescimosPrUnit = 1 or modDoc.somaFreteSeguroPrUnit = 1 THEN a.valorProdutoServicoBruto ELSE a.valorProdutoServico END - a.valorDescontoItem + a.valorAcrescimoItem ELSE 0 END),0),
    COALESCE(SUM(CASE WHEN a.geraFinanceiro = 1 AND (p_habilitaControleEntrega = 0 OR EXISTS(SELECT 1 FROM MODOCFISCALXORCAMENTOITEM docXorc JOIN MOORCAMENTOXITENS itemOrc ON itemOrc.idItemOrcamento = docXorc.idItemOrcamento JOIN PACONTROLESENTREGA contr ON contr.controleEntrega = itemOrc.controleEntrega WHERE docXorc.idItemDocFiscal = a.idItemDocFiscal AND itemOrc.controleEntrega > 0 AND contr.habilitaFrete = 1)) THEN CASE WHEN modDoc.diminuiDescontoPrUnit = 1 OR modDoc.somaAcrescimosPrUnit = 1 or modDoc.somaFreteSeguroPrUnit = 1 THEN a.valorProdutoServicoBruto ELSE a.valorProdutoServico END - a.valorDescontoItem + a.valorAcrescimoItem ELSE 0 END),0),
    COALESCE(SUM(CASE WHEN modDoc.diminuiDescontoPrUnit = 1 OR modDoc.somaAcrescimosPrUnit = 1 or modDoc.somaFreteSeguroPrUnit = 1 THEN a.valorProdutoServicoBruto ELSE a.valorProdutoServico END - a.valorDescontoItem + a.valorAcrescimoItem),0),
    COALESCE(SUM(CASE WHEN p_habilitaControleEntrega = 0 OR EXISTS(SELECT 1 FROM MODOCFISCALXORCAMENTOITEM docXorc JOIN MOORCAMENTOXITENS itemOrc ON itemOrc.idItemOrcamento = docXorc.idItemOrcamento JOIN PACONTROLESENTREGA contr ON contr.controleEntrega = itemOrc.controleEntrega WHERE docXorc.idItemDocFiscal = a.idItemDocFiscal AND itemOrc.controleEntrega > 0 AND contr.habilitaFrete = 1) THEN CASE WHEN modDoc.diminuiDescontoPrUnit = 1 OR modDoc.somaAcrescimosPrUnit = 1 or modDoc.somaFreteSeguroPrUnit = 1 THEN a.valorProdutoServicoBruto ELSE a.valorProdutoServico END - a.valorDescontoItem + a.valorAcrescimoItem ELSE 0 END),0),
    COALESCE(SUM(CASE WHEN a.geraFinanceiro = 1 THEN CASE WHEN modDoc.diminuiDescontoPrUnit = 1 OR modDoc.somaAcrescimosPrUnit = 1 or modDoc.somaFreteSeguroPrUnit = 1 THEN a.valorProdutoServicoBruto ELSE a.valorProdutoServico END - a.valorDescontoItem + a.valorAcrescimoItem ELSE 0 END),0),
    COALESCE(SUM(CASE WHEN modDoc.diminuiDescontoPrUnit = 1 OR modDoc.somaAcrescimosPrUnit = 1 or modDoc.somaFreteSeguroPrUnit = 1 THEN a.valorProdutoServicoBruto ELSE a.valorProdutoServico - a.valorDescontoItem + a.valorAcrescimoItem END),0),
    COALESCE(SUM(CASE WHEN a.geraFinanceiro = 1 THEN CASE WHEN modDoc.diminuiDescontoPrUnit = 1 OR modDoc.somaAcrescimosPrUnit = 1 or modDoc.somaFreteSeguroPrUnit = 1 THEN a.valorProdutoServicoBruto ELSE a.valorProdutoServico - a.valorDescontoItem + a.valorAcrescimoItem END ELSE 0 END),0),
    COALESCE(SUM(CASE WHEN (v_rateioDescontofiltrarAPrazo = 0 OR a.precoSugestaoAPrazo = a.precoSugestaoAVista OR a.usarPrecoAVista = 0) AND (v_rateioDescontofiltrarSemProm = 0 OR NOT(EXISTS(SELECT 1 FROM MODOCFISCALXPROMOCOES promo WHERE promo.idItemDocFiscal = a.idItemDocFiscal))) THEN CASE WHEN modDoc.diminuiDescontoPrUnit = 1 OR modDoc.somaAcrescimosPrUnit = 1 or modDoc.somaFreteSeguroPrUnit = 1 THEN a.valorProdutoServicoBruto ELSE a.valorProdutoServico - a.valorDescontoItem + a.valorAcrescimoItem END ELSE 0 END),0),
    COALESCE(SUM(CASE WHEN modDoc.diminuiDescontoPrUnit = 1 OR modDoc.somaAcrescimosPrUnit = 1 or modDoc.somaFreteSeguroPrUnit = 1 THEN a.valorProdutoServicoBruto ELSE a.valorProdutoServico END - a.valorDescontoItem + a.valorAcrescimoItem),0),
    COALESCE(SUM(CASE WHEN a.geraFinanceiro = 1 THEN CASE WHEN modDoc.diminuiDescontoPrUnit = 1 OR modDoc.somaAcrescimosPrUnit = 1 or modDoc.somaFreteSeguroPrUnit = 1 THEN a.valorProdutoServicoBruto ELSE a.valorProdutoServico END - a.valorDescontoItem + a.valorAcrescimoItem ELSE 0 END),0),
    COALESCE(SUM(CASE WHEN (v_rateioDescontofiltrarAPrazo = 0 OR a.precoSugestaoAPrazo = a.precoSugestaoAVista OR a.usarPrecoAVista = 0) AND (v_rateioDescontofiltrarSemProm = 0 OR NOT(EXISTS(SELECT 1 FROM MODOCFISCALXPROMOCOES promo WHERE promo.idItemDocFiscal = a.idItemDocFiscal))) THEN CASE WHEN modDoc.diminuiDescontoPrUnit = 1 OR modDoc.somaAcrescimosPrUnit = 1 or modDoc.somaFreteSeguroPrUnit = 1 THEN a.valorProdutoServicoBruto ELSE a.valorProdutoServico END - a.valorDescontoItem + a.valorAcrescimoItem ELSE 0 END),0),
    COALESCE(SUM(CASE WHEN a.geraFinanceiro = 1 AND (v_rateioDescontofiltrarAPrazo = 0 OR a.precoSugestaoAPrazo = a.precoSugestaoAVista OR a.usarPrecoAVista = 0) AND (v_rateioDescontofiltrarSemProm = 0 OR NOT(EXISTS(SELECT 1 FROM MODOCFISCALXPROMOCOES promo WHERE promo.idItemDocFiscal = a.idItemDocFiscal))) THEN CASE WHEN modDoc.diminuiDescontoPrUnit = 1 OR modDoc.somaAcrescimosPrUnit = 1 or modDoc.somaFreteSeguroPrUnit = 1 THEN a.valorProdutoServicoBruto ELSE a.valorProdutoServico END - a.valorDescontoItem + a.valorAcrescimoItem ELSE 0 END),0)
  INTO
    v_rateioFretePorControleEntr,
    v_valorBaseFreteSemFinSemEntr,
    v_valorBaseFreteComFinSemEntr,
    v_valorBaseFreteSemFinComEntr,
    v_valorBaseFreteComFinComEntr,
    v_valorBaseRateio,
    v_valorBaseRateioComEntrega,
    v_valorBaseRateioFinanceiro,
    v_valorBaseRateioOutrasDespGer,
    v_valorBaseRateioOutrasDespFin,
    v_valorBaseRateioDescontoGeral,
    v_valorBaseRateioPagamento,
    v_valorBaseRateioPagamFinanc,
    v_valorBaseRateioPagamDesconto,
    v_valorBaseRateioPagamFinDesc
  FROM MODOCFISCALXITENS a
  JOIN PAMODELOSDOCUMENTO modDoc
  ON modDoc.modeloDocumento = a.modeloDocumento
  WHERE a.idDocumentoFiscal = p_cab_idDocumentoFiscal
  AND a.cancelado = 0;

  -- Efetua rateio
  FOR a IN (
    SELECT
      a.idItemDocFiscal,
      a.modeloDocumento,
      a.geraFinanceiro,
      a.quantidade,
      a.quantidadeConvertida,
      a.usarPrecoAVista,
      a.precoUnitarioBruto,
      a.acrescimoUnitarioComposicao,
      a.precoUnitario,
      a.precoUnitarioConvertido,
      a.valorProdutoServicoBruto,
      a.valorProdutoServico,
      a.valorDescontoItem,
      a.valorAcrescimoItem,
      a.valorFreteItem,
      a.valorSeguroItem,
      a.valorAdicFreteMarinhaMerItem,
      a.valorDespesasAduaneirasItem,
      a.valorFreteGeral,
      a.valorSeguroGeral,
      a.valorDescontoGeral,
      a.valorOutrasDespesasGeral,
      a.valorAdicFreteMarinhaMerGeral,
      a.valorDespesasAduaneirasGeral,
      a.valorBasePagamento,
      a.valorDescontoPagamento,
      a.valorOutrasDespesasPagamento,
      a.valorJurosPagamento,
      a.valorFreteTotal,
      a.valorSeguroTotal,
      a.valorDescontoTotal,
      a.valorOutrasDespesasTotal,
      a.valorAdicFreteMarinhaMerTotal,
      a.valorDespesasAduaneirasTotal,
      a.valorIPIDevolucao,
      a.retidoISSQN,
      a.valorISSQN,
      a.valorRetIRRF,
      a.valorRetINSS,
      a.valorRetPIS,
      a.valorRetCOFINS,
      a.valorRetCSLL,
      a.valorRetOutros,
      a.valorII,
      a.valorIOF,
      a.valorIPI,
      a.valorPIS,
      a.valorPISST,
      a.valorCOFINS,
      a.valorCOFINSST,
      a.valorCreditoSimplesNacional,
      a.valorICMS,
      a.valorICMSST,
      a.valorICMSSTEscrituracao,
      a.somarICMSST,
      a.valorLiquidoItem,
      a.valorDescontoCustoOpItem,
      a.valorDescontoCustoOpGeral,
      a.valorDescontoCustoOpTotal,
      a.valorAcrescimoCustoOpItem,
      a.valorAcrescimoCustoOpGeral,
      a.valorAcrescimoCustoOpTotal,
      a.precoCustoOperacao,
      a.valorCustoOperacao,
      a.precoCMV,
      a.valorCMV,
      a.quantidadeExtemporanea,
      a.acrescimoUnitarioExtemporaneo,
      a.valorAcrescimoExtempSubtotal,
      a.valorAcrescimoExtempItem,
      a.valorAcrescimoExtempGeral,
      a.valorAcrescimoExtempTotal,
      modDoc.geraFinanceiro modDoc_geraFinanceiro,
      modDoc.diminuiDescontoPrUnit,
      modDoc.somaAcrescimosPrUnit,
      modDoc.somaFreteSeguroPrUnit,
      prod.tipoProduto,
      CASE WHEN p_habilitaControleEntrega = 0 OR EXISTS(
        SELECT 1
        FROM MODOCFISCALXORCAMENTOITEM docXorc
        JOIN MOORCAMENTOXITENS itemOrc
        ON itemOrc.idItemOrcamento = docXorc.idItemOrcamento
        JOIN PACONTROLESENTREGA contr
        ON contr.controleEntrega = itemOrc.controleEntrega
        WHERE docXorc.idItemDocFiscal = a.idItemDocFiscal
        AND contr.habilitaFrete = 1) THEN 1 ELSE 0 END rateioFrete,
      CASE WHEN a.precoSugestaoAPrazo <> a.precoSugestaoAVista AND a.usarPrecoAVista = 1 THEN 1 ELSE 0 END aVista,
      CASE WHEN EXISTS(
        SELECT 1
        FROM MODOCFISCALXPROMOCOES promo
        WHERE promo.idItemDocFiscal = a.idItemDocFiscal) THEN 1 ELSE 0 END promocao,
      COALESCE((
        SELECT SUM(promo.valorDesconto)
        FROM MODOCFISCALXPROMOCOES promo
        WHERE promo.idItemDocFiscal = a.idItemDocFiscal
        AND promo.cabecalhoItemPagamento ='C'),0) valorDescontoPromocaoGeral,
      COALESCE((
        SELECT SUM(promo.valorDesconto)
        FROM MODOCFISCALXPROMOCOES promo
        WHERE promo.idItemDocFiscal = a.idItemDocFiscal
        AND promo.cabecalhoItemPagamento ='P'),0) valorDescontoPromocaoPagamento,
      CASE
        WHEN EXISTS (
          SELECT 1
          FROM CAPRODUTOXCOMPOSICOESPREC compPrec
          WHERE compPrec.produto = gradProd.produto
          AND compPrec.ativo = 1)
        THEN 1
        ELSE 0
      END composicaoPreco
    FROM MODOCFISCALXITENS a
    JOIN PAMODELOSDOCUMENTO modDoc
    ON modDoc.modeloDocumento = a.modeloDocumento
    JOIN CAGRADESPRODUTO gradProd
    ON gradProd.gradeProduto = a.gradeProduto
    JOIN CAPRODUTOS prod
    ON prod.produto = gradProd.produto
    WHERE a.idDocumentoFiscal = p_cab_idDocumentoFiscal
    AND a.cancelado = 0
    ORDER BY a.sequencia)
  LOOP
    v_idItemDocFiscalUltimoItem    := a.idItemDocFiscal;
    v_precoUnitario                := a.precoUnitario;
    v_precoUnitarioConvertido      := a.precoUnitarioConvertido;
    v_valorProdutoServico          := a.valorProdutoServico;
    v_valorDescontoGeral           := v_residuoDescontoGeral;
    v_valorFreteGeral              := v_residuoFreteGeral;
    v_valorSeguroGeral             := v_residuoSeguroGeral;
    v_valorAdicFreteMarinMerGeral  := v_residuoAdicFreteMarinGeral;
    v_valorDespesasAduaneirasGeral := v_residuoDespesasAduanGeral;
    v_valorOutrasDespesasGeral     := v_residuoOutrasDespesasGeral;
    v_valorBasePagamento           := a.valorBasePagamento;
    v_valorDescontoPagamento       := v_residuoDescontoPagamento;
    v_valorOutrasDespesasPagamento := v_residuoOutrasDespPagamento;
    v_valorJurosPagamento          := v_residuoJurosPagamento;
    v_valorDescontoCustoOpGeral    := v_residuoDescCustoOpGeral;
    v_valorAcrescimoCustoOpGeral   := v_residuoAcrescCustoOpGeral;
    v_valorAcrescimoExtempGeral    := v_residuoAcrescExtempGeral;
    v_valorFreteTotal              := a.valorFreteTotal;
    v_valorSeguroTotal             := a.valorSeguroTotal;
    v_valorDescontoTotal           := a.valorDescontoTotal;
    v_valorOutrasDespesasTotal     := a.valorOutrasDespesasTotal;
    v_valorAdicFreteMarinMerTotal  := a.valorAdicFreteMarinhaMerTotal;
    v_valorDespesasAduaneirasTotal := a.valorDespesasAduaneirasTotal;
    v_valorLiquidoItem             := a.valorLiquidoItem;
    v_valorDescontoCustoOpTotal    := a.valorDescontoCustoOpTotal;
    v_valorAcrescimoCustoOpTotal   := a.valorAcrescimoCustoOpTotal;
    v_precoCustoOperacao           := a.precoCustoOperacao;
    v_valorCustoOperacao           := a.valorCustoOperacao;
    v_precoCMV                     := a.precoCMV;
    v_valorCMV                     := a.valorCMV;
    v_valorAcrescimoExtempSubtotal := a.valorAcrescimoExtempSubtotal;
    v_valorAcrescimoExtempTotal    := a.valorAcrescimoExtempTotal;

    -- v_valorDescontoGeral
    IF v_valorBaseRateioDescontoGeral > 0
      AND (v_rateioDescontofiltrarAPrazo = 0
        OR a.aVista = 0)
      AND (v_rateioDescontofiltrarSemProm = 0
        OR a.promocao = 0
        AND p_cab_valorDescontoGeral - v_valorDescontoPromocaoGeral > 0)
    THEN
      v_valorDescontoGeral := v_valorDescontoGeral + (p_cab_valorDescontoGeral - v_valorDescontoPromocaoGeral) * (CASE WHEN a.diminuiDescontoPrUnit = 1 OR a.somaAcrescimosPrUnit = 1 or a.somaFreteSeguroPrUnit = 1 THEN a.valorProdutoServicoBruto ELSE a.valorProdutoServico - a.valorDescontoItem + a.valorAcrescimoItem END) / v_valorBaseRateioDescontoGeral;
    END IF;
    IF p_cab_valorDescontoGeral        > 0
      AND v_valorDescontoPromocaoGeral > 0
      AND a.valorDescontoPromocaoGeral > 0
    THEN
      IF p_cab_valorDescontoGeral < v_valorDescontoPromocaoGeral THEN
        v_valorDescontoGeral := v_valorDescontoGeral + a.valorDescontoPromocaoGeral * p_cab_valorDescontoGeral / v_valorDescontoPromocaoGeral;
      ELSE
        v_valorDescontoGeral := v_valorDescontoGeral + a.valorDescontoPromocaoGeral;
      END IF;
    END IF;
    IF ROUND (v_valorDescontoGeral,2) >= v_saldoRatDescontoGeral THEN
      v_valorDescontoGeral   := v_saldoRatDescontoGeral;
      v_residuoDescontoGeral := 0;
    ELSE
      v_residuoDescontoGeral := v_valorDescontoGeral - ROUND (v_valorDescontoGeral,2);
      v_valorDescontoGeral   := ROUND (v_valorDescontoGeral,2);
    END IF;
    v_saldoRatDescontoGeral := v_saldoRatDescontoGeral - v_valorDescontoGeral;

    -- v_valorFreteGeral
    -- v_valorSeguroGeral
    IF v_valorBaseFreteComFinComEntr > 0 AND v_rateioFretePorControleEntr = 1 AND a.rateioFrete = 1 AND a.geraFinanceiro = 1 THEN
      v_idItemDocFiscalRateioFrete := a.idItemDocFiscal;
      v_valorFreteGeral  := v_valorFreteGeral  + p_cab_valorFreteGeral  * (CASE WHEN a.diminuiDescontoPrUnit = 1 OR a.somaAcrescimosPrUnit = 1 or a.somaFreteSeguroPrUnit = 1 THEN a.valorProdutoServicoBruto ELSE a.valorProdutoServico END - a.valorDescontoItem + a.valorAcrescimoItem) / v_valorBaseFreteComFinComEntr;
      v_valorSeguroGeral := v_valorSeguroGeral + p_cab_valorSeguroGeral * (CASE WHEN a.diminuiDescontoPrUnit = 1 OR a.somaAcrescimosPrUnit = 1 or a.somaFreteSeguroPrUnit = 1 THEN a.valorProdutoServicoBruto ELSE a.valorProdutoServico END - a.valorDescontoItem + a.valorAcrescimoItem) / v_valorBaseFreteComFinComEntr;
    ELSIF v_valorBaseFreteSemFinComEntr > 0 AND v_valorBaseFreteComFinComEntr <= 0 AND v_rateioFretePorControleEntr = 1 AND a.rateioFrete = 1 AND a.modDoc_geraFinanceiro = 1 THEN
      v_idItemDocFiscalRateioFrete := a.idItemDocFiscal;
      v_valorFreteGeral  := v_valorFreteGeral  + p_cab_valorFreteGeral  * (CASE WHEN a.diminuiDescontoPrUnit = 1 OR a.somaAcrescimosPrUnit = 1 or a.somaFreteSeguroPrUnit = 1 THEN a.valorProdutoServicoBruto ELSE a.valorProdutoServico END - a.valorDescontoItem + a.valorAcrescimoItem) / v_valorBaseFreteSemFinComEntr;
      v_valorSeguroGeral := v_valorSeguroGeral + p_cab_valorSeguroGeral * (CASE WHEN a.diminuiDescontoPrUnit = 1 OR a.somaAcrescimosPrUnit = 1 or a.somaFreteSeguroPrUnit = 1 THEN a.valorProdutoServicoBruto ELSE a.valorProdutoServico END - a.valorDescontoItem + a.valorAcrescimoItem) / v_valorBaseFreteSemFinComEntr;
    ELSIF v_valorBaseRateioComEntrega > 0 AND v_valorBaseFreteSemFinComEntr <= 0 AND v_valorBaseFreteComFinComEntr <= 0 AND v_rateioFretePorControleEntr = 1 AND a.rateioFrete = 1 THEN
      v_idItemDocFiscalRateioFrete := a.idItemDocFiscal;
      v_valorFreteGeral  := v_valorFreteGeral  + p_cab_valorFreteGeral  * (CASE WHEN a.diminuiDescontoPrUnit = 1 OR a.somaAcrescimosPrUnit = 1 or a.somaFreteSeguroPrUnit = 1 THEN a.valorProdutoServicoBruto ELSE a.valorProdutoServico END - a.valorDescontoItem + a.valorAcrescimoItem) / v_valorBaseRateioComEntrega;
      v_valorSeguroGeral := v_valorSeguroGeral + p_cab_valorSeguroGeral * (CASE WHEN a.diminuiDescontoPrUnit = 1 OR a.somaAcrescimosPrUnit = 1 or a.somaFreteSeguroPrUnit = 1 THEN a.valorProdutoServicoBruto ELSE a.valorProdutoServico END - a.valorDescontoItem + a.valorAcrescimoItem) / v_valorBaseRateioComEntrega;
    ELSIF v_valorBaseFreteComFinSemEntr > 0 AND v_rateioFretePorControleEntr = 0 AND a.geraFinanceiro = 1 THEN
      v_idItemDocFiscalRateioFrete := a.idItemDocFiscal;
      v_valorFreteGeral  := v_valorFreteGeral  + p_cab_valorFreteGeral  * (CASE WHEN a.diminuiDescontoPrUnit = 1 OR a.somaAcrescimosPrUnit = 1 or a.somaFreteSeguroPrUnit = 1 THEN a.valorProdutoServicoBruto ELSE a.valorProdutoServico END - a.valorDescontoItem + a.valorAcrescimoItem) / v_valorBaseFreteComFinSemEntr;
      v_valorSeguroGeral := v_valorSeguroGeral + p_cab_valorSeguroGeral * (CASE WHEN a.diminuiDescontoPrUnit = 1 OR a.somaAcrescimosPrUnit = 1 or a.somaFreteSeguroPrUnit = 1 THEN a.valorProdutoServicoBruto ELSE a.valorProdutoServico END - a.valorDescontoItem + a.valorAcrescimoItem) / v_valorBaseFreteComFinSemEntr;
    ELSIF v_valorBaseFreteSemFinSemEntr > 0 AND v_valorBaseFreteComFinSemEntr <= 0 AND v_rateioFretePorControleEntr = 0 AND a.modDoc_geraFinanceiro = 1 THEN
      v_idItemDocFiscalRateioFrete := a.idItemDocFiscal;
      v_valorFreteGeral  := v_valorFreteGeral  + p_cab_valorFreteGeral  * (CASE WHEN a.diminuiDescontoPrUnit = 1 OR a.somaAcrescimosPrUnit = 1 or a.somaFreteSeguroPrUnit = 1 THEN a.valorProdutoServicoBruto ELSE a.valorProdutoServico END - a.valorDescontoItem + a.valorAcrescimoItem) / v_valorBaseFreteSemFinSemEntr;
      v_valorSeguroGeral := v_valorSeguroGeral + p_cab_valorSeguroGeral * (CASE WHEN a.diminuiDescontoPrUnit = 1 OR a.somaAcrescimosPrUnit = 1 or a.somaFreteSeguroPrUnit = 1 THEN a.valorProdutoServicoBruto ELSE a.valorProdutoServico END - a.valorDescontoItem + a.valorAcrescimoItem) / v_valorBaseFreteSemFinSemEntr;
    ELSIF v_valorBaseRateio > 0 AND (v_valorBaseRateioComEntrega <= 0 AND v_valorBaseFreteSemFinComEntr <= 0 AND v_valorBaseFreteComFinComEntr <= 0 AND v_rateioFretePorControleEntr = 1 OR v_valorBaseFreteSemFinSemEntr <= 0 AND v_valorBaseFreteComFinSemEntr <= 0 AND v_rateioFretePorControleEntr = 0) THEN
      v_idItemDocFiscalRateioFrete := a.idItemDocFiscal;
      v_valorFreteGeral  := v_valorFreteGeral  + p_cab_valorFreteGeral  * (CASE WHEN a.diminuiDescontoPrUnit = 1 OR a.somaAcrescimosPrUnit = 1 or a.somaFreteSeguroPrUnit = 1 THEN a.valorProdutoServicoBruto ELSE a.valorProdutoServico END - a.valorDescontoItem + a.valorAcrescimoItem) / v_valorBaseRateio;
      v_valorSeguroGeral := v_valorSeguroGeral + p_cab_valorSeguroGeral * (CASE WHEN a.diminuiDescontoPrUnit = 1 OR a.somaAcrescimosPrUnit = 1 or a.somaFreteSeguroPrUnit = 1 THEN a.valorProdutoServicoBruto ELSE a.valorProdutoServico END - a.valorDescontoItem + a.valorAcrescimoItem) / v_valorBaseRateio;
    END IF;
    IF ROUND (v_valorFreteGeral,2) >= v_saldoRatFreteGeral THEN
      v_valorFreteGeral := v_saldoRatFreteGeral;
      v_residuoFreteGeral := 0;
    ELSE
      v_residuoFreteGeral := v_valorFreteGeral - ROUND (v_valorFreteGeral,2);
      v_valorFreteGeral := ROUND (v_valorFreteGeral,2);
    END IF;
    v_saldoRatFreteGeral := v_saldoRatFreteGeral - v_valorFreteGeral;
    IF ROUND (v_valorSeguroGeral,2) >= v_saldoRatSeguroGeral THEN
      v_valorSeguroGeral   := v_saldoRatSeguroGeral;
      v_residuoSeguroGeral := 0;
    ELSE
      v_residuoSeguroGeral := v_valorSeguroGeral  - ROUND (v_valorSeguroGeral,2);
      v_valorSeguroGeral   := ROUND (v_valorSeguroGeral,2);
    END IF;
    v_saldoRatSeguroGeral := v_saldoRatSeguroGeral - v_valorSeguroGeral;

    -- v_valorAdicFreteMarinMerGeral
    -- v_valorDespesasAduaneirasGeral
    -- v_valorDescontoCustoOpGeral
    -- v_valorAcrescimoCustoOpGeral
    -- v_valorAcrescimoExtempGeral
    IF v_valorBaseRateioFinanceiro > 0 AND a.geraFinanceiro = 1 THEN 
      v_valorAdicFreteMarinMerGeral  := v_valorAdicFreteMarinMerGeral  + p_cab_valorAdicFreteMarinGeral * (CASE WHEN a.diminuiDescontoPrUnit = 1 OR a.somaAcrescimosPrUnit = 1 or a.somaFreteSeguroPrUnit = 1 THEN a.valorProdutoServicoBruto ELSE a.valorProdutoServico END - a.valorDescontoItem + a.valorAcrescimoItem) / v_valorBaseRateioFinanceiro;
      v_valorDespesasAduaneirasGeral := v_valorDespesasAduaneirasGeral + p_cab_valorDespesasAduanGeral  * (CASE WHEN a.diminuiDescontoPrUnit = 1 OR a.somaAcrescimosPrUnit = 1 or a.somaFreteSeguroPrUnit = 1 THEN a.valorProdutoServicoBruto ELSE a.valorProdutoServico END - a.valorDescontoItem + a.valorAcrescimoItem) / v_valorBaseRateioFinanceiro;
      v_valorDescontoCustoOpGeral    := v_valorDescontoCustoOpGeral    + p_cab_valorDescCustoOpGeral    * (CASE WHEN a.diminuiDescontoPrUnit = 1 OR a.somaAcrescimosPrUnit = 1 or a.somaFreteSeguroPrUnit = 1 THEN a.valorProdutoServicoBruto ELSE a.valorProdutoServico END - a.valorDescontoItem + a.valorAcrescimoItem) / v_valorBaseRateioFinanceiro;
      v_valorAcrescimoCustoOpGeral   := v_valorAcrescimoCustoOpGeral   + p_cab_valorAcrescCustoOpGeral  * (CASE WHEN a.diminuiDescontoPrUnit = 1 OR a.somaAcrescimosPrUnit = 1 or a.somaFreteSeguroPrUnit = 1 THEN a.valorProdutoServicoBruto ELSE a.valorProdutoServico END - a.valorDescontoItem + a.valorAcrescimoItem) / v_valorBaseRateioFinanceiro;
      v_valorAcrescimoExtempGeral    := v_valorAcrescimoExtempGeral    + p_cab_valorAcrescExtempGeral   * (CASE WHEN a.diminuiDescontoPrUnit = 1 OR a.somaAcrescimosPrUnit = 1 or a.somaFreteSeguroPrUnit = 1 THEN a.valorProdutoServicoBruto ELSE a.valorProdutoServico END - a.valorDescontoItem + a.valorAcrescimoItem) / v_valorBaseRateioFinanceiro;
    ELSIF v_valorBaseRateio > 0 AND v_valorBaseRateioFinanceiro <= 0 THEN
      v_valorAdicFreteMarinMerGeral  := v_valorAdicFreteMarinMerGeral  + p_cab_valorAdicFreteMarinGeral * (CASE WHEN a.diminuiDescontoPrUnit = 1 OR a.somaAcrescimosPrUnit = 1 or a.somaFreteSeguroPrUnit = 1 THEN a.valorProdutoServicoBruto ELSE a.valorProdutoServico END - a.valorDescontoItem + a.valorAcrescimoItem) / v_valorBaseRateio;
      v_valorDespesasAduaneirasGeral := v_valorDespesasAduaneirasGeral + p_cab_valorDespesasAduanGeral  * (CASE WHEN a.diminuiDescontoPrUnit = 1 OR a.somaAcrescimosPrUnit = 1 or a.somaFreteSeguroPrUnit = 1 THEN a.valorProdutoServicoBruto ELSE a.valorProdutoServico END - a.valorDescontoItem + a.valorAcrescimoItem) / v_valorBaseRateio;
      v_valorDescontoCustoOpGeral    := v_valorDescontoCustoOpGeral    + p_cab_valorDescCustoOpGeral    * (CASE WHEN a.diminuiDescontoPrUnit = 1 OR a.somaAcrescimosPrUnit = 1 or a.somaFreteSeguroPrUnit = 1 THEN a.valorProdutoServicoBruto ELSE a.valorProdutoServico END - a.valorDescontoItem + a.valorAcrescimoItem) / v_valorBaseRateio;
      v_valorAcrescimoCustoOpGeral   := v_valorAcrescimoCustoOpGeral   + p_cab_valorAcrescCustoOpGeral  * (CASE WHEN a.diminuiDescontoPrUnit = 1 OR a.somaAcrescimosPrUnit = 1 or a.somaFreteSeguroPrUnit = 1 THEN a.valorProdutoServicoBruto ELSE a.valorProdutoServico END - a.valorDescontoItem + a.valorAcrescimoItem) / v_valorBaseRateio;
      v_valorAcrescimoExtempGeral    := v_valorAcrescimoExtempGeral    + p_cab_valorAcrescExtempGeral   * (CASE WHEN a.diminuiDescontoPrUnit = 1 OR a.somaAcrescimosPrUnit = 1 or a.somaFreteSeguroPrUnit = 1 THEN a.valorProdutoServicoBruto ELSE a.valorProdutoServico END - a.valorDescontoItem + a.valorAcrescimoItem) / v_valorBaseRateio;
    END IF;
    IF ROUND (v_valorAdicFreteMarinMerGeral,2) >= v_saldoRatAdicFreteMarinGeral THEN
      v_valorAdicFreteMarinMerGeral := v_saldoRatAdicFreteMarinGeral;
      v_residuoAdicFreteMarinGeral  := 0;
    ELSE
      v_residuoAdicFreteMarinGeral  := v_valorAdicFreteMarinMerGeral - ROUND (v_valorAdicFreteMarinMerGeral,2);
      v_valorAdicFreteMarinMerGeral := ROUND (v_valorAdicFreteMarinMerGeral,2);
    END IF;
    v_saldoRatAdicFreteMarinGeral := v_saldoRatAdicFreteMarinGeral - v_valorAdicFreteMarinMerGeral;
    IF ROUND (v_valorDespesasAduaneirasGeral,2) >= v_saldoRatDespesasAduanGeral THEN
      v_valorDespesasAduaneirasGeral := v_saldoRatDespesasAduanGeral;
      v_residuoDespesasAduanGeral    := 0;
    ELSE
      v_residuoDespesasAduanGeral    := v_valorDespesasAduaneirasGeral - ROUND (v_valorDespesasAduaneirasGeral,2);
      v_valorDespesasAduaneirasGeral := ROUND (v_valorDespesasAduaneirasGeral,2);
    END IF;
    v_saldoRatDespesasAduanGeral := v_saldoRatDespesasAduanGeral - v_valorDespesasAduaneirasGeral;
    IF ROUND (v_valorDescontoCustoOpGeral,2) >= v_saldoRatDescCustoOpGeral THEN
      v_valorDescontoCustoOpGeral := v_saldoRatDescCustoOpGeral;
      v_residuoDescCustoOpGeral   := 0;
    ELSE
      v_residuoDescCustoOpGeral   := v_valorDescontoCustoOpGeral - ROUND (v_valorDescontoCustoOpGeral,2);
      v_valorDescontoCustoOpGeral := ROUND (v_valorDescontoCustoOpGeral,2);
    END IF;
    v_saldoRatDescCustoOpGeral := v_saldoRatDescCustoOpGeral - v_valorDescontoCustoOpGeral;
    IF ROUND (v_valorAcrescimoCustoOpGeral,2) >= v_saldoRatAcrescCustoOpGeral THEN
      v_valorAcrescimoCustoOpGeral := v_saldoRatAcrescCustoOpGeral;
      v_residuoAcrescCustoOpGeral  := 0;
    ELSE
      v_residuoAcrescCustoOpGeral  := v_valorAcrescimoCustoOpGeral - ROUND (v_valorAcrescimoCustoOpGeral,2);
      v_valorAcrescimoCustoOpGeral := ROUND (v_valorAcrescimoCustoOpGeral,2);
    END IF;
    v_saldoRatAcrescCustoOpGeral := v_saldoRatAcrescCustoOpGeral - v_valorAcrescimoCustoOpGeral;
    IF ROUND (v_valorAcrescimoExtempGeral,2) >= v_saldoRatAcrescExtempGeral THEN
      v_valorAcrescimoExtempGeral := v_saldoRatAcrescExtempGeral;
      v_residuoAcrescExtempGeral  := 0;
    ELSE
      v_residuoAcrescExtempGeral  := v_valorAcrescimoExtempGeral - ROUND (v_valorAcrescimoExtempGeral,2);
      v_valorAcrescimoExtempGeral := ROUND (v_valorAcrescimoExtempGeral,2);
    END IF;
    v_saldoRatAcrescExtempGeral := v_saldoRatAcrescExtempGeral - v_valorAcrescimoExtempGeral;

    -- v_valorOutrasDespesasGeral
    IF v_valorBaseRateioOutrasDespFin > 0 AND a.geraFinanceiro = 1 THEN
      v_valorOutrasDespesasGeral := v_valorOutrasDespesasGeral + p_cab_valorOutrasDespesasGeral * (CASE WHEN a.diminuiDescontoPrUnit = 1 OR a.somaAcrescimosPrUnit = 1 or a.somaFreteSeguroPrUnit = 1 THEN a.valorProdutoServicoBruto ELSE a.valorProdutoServico - a.valorDescontoItem + a.valorAcrescimoItem END) / v_valorBaseRateioOutrasDespFin;
    ELSIF v_valorBaseRateioOutrasDespGer > 0 AND v_valorBaseRateioOutrasDespFin <= 0 THEN
      v_valorOutrasDespesasGeral := v_valorOutrasDespesasGeral + p_cab_valorOutrasDespesasGeral * (CASE WHEN a.diminuiDescontoPrUnit = 1 OR a.somaAcrescimosPrUnit = 1 or a.somaFreteSeguroPrUnit = 1 THEN a.valorProdutoServicoBruto ELSE a.valorProdutoServico - a.valorDescontoItem + a.valorAcrescimoItem END) / v_valorBaseRateioOutrasDespGer;
    END IF;
    IF ROUND (v_valorOutrasDespesasGeral,2) >= v_saldoRatOutrasDespesasGeral THEN
      v_valorOutrasDespesasGeral   := v_saldoRatOutrasDespesasGeral;
      v_residuoOutrasDespesasGeral := 0;
    ELSE
      v_residuoOutrasDespesasGeral := v_valorOutrasDespesasGeral - ROUND (v_valorOutrasDespesasGeral,2);
      v_valorOutrasDespesasGeral   := ROUND (v_valorOutrasDespesasGeral,2);
    END IF;
    v_saldoRatOutrasDespesasGeral := v_saldoRatOutrasDespesasGeral - v_valorOutrasDespesasGeral;

    -- v_valorDescontoPagamento
    IF p_cab_valorDescontoPagamento       > 0
      AND v_valorBaseRateioPagamFinDesc   > 0
      AND a.geraFinanceiro = 1
      AND (v_rateioDescontofiltrarAPrazo  = 0
        OR a.aVista = 0)
      AND (v_rateioDescontofiltrarSemProm = 0
        OR a.promocao = 0
        AND p_cab_valorDescontoPagamento - v_valorDescontoPromocaoPagamen > 0)
    THEN
      v_valorDescontoPagamento := v_valorDescontoPagamento + (p_cab_valorDescontoPagamento - v_valorDescontoPromocaoPagamen) * (CASE WHEN a.diminuiDescontoPrUnit = 1 OR a.somaAcrescimosPrUnit = 1 or a.somaFreteSeguroPrUnit = 1 THEN a.valorProdutoServicoBruto ELSE a.valorProdutoServico END - a.valorDescontoItem + a.valorAcrescimoItem) / v_valorBaseRateioPagamFinDesc;
    ELSIF p_cab_valorDescontoPagamento    > 0
      AND v_valorBaseRateioPagamDesconto  > 0
      AND v_valorBaseRateioPagamFinDesc  <= 0
      AND (v_rateioDescontofiltrarAPrazo  = 0
        OR a.aVista = 0)
      AND (v_rateioDescontofiltrarSemProm = 0
        OR a.promocao = 0
        AND p_cab_valorDescontoPagamento - v_valorDescontoPromocaoPagamen > 0)
    THEN
      v_valorDescontoPagamento := v_valorDescontoPagamento + (p_cab_valorDescontoPagamento - v_valorDescontoPromocaoPagamen) * (CASE WHEN a.diminuiDescontoPrUnit = 1 OR a.somaAcrescimosPrUnit = 1 or a.somaFreteSeguroPrUnit = 1 THEN a.valorProdutoServicoBruto ELSE a.valorProdutoServico END - a.valorDescontoItem + a.valorAcrescimoItem) / v_valorBaseRateioPagamDesconto;
    END IF;
    IF p_cab_valorDescontoPagamento        > 0
      AND v_valorDescontoPromocaoPagamen   > 0
      AND a.valorDescontoPromocaoPagamento > 0
    THEN
      IF p_cab_valorDescontoPagamento < v_valorDescontoPromocaoPagamen THEN
        v_valorDescontoPagamento := v_valorDescontoPagamento + a.valorDescontoPromocaoPagamento * p_cab_valorDescontoPagamento / v_valorDescontoPromocaoPagamen;
      ELSE
        v_valorDescontoPagamento := v_valorDescontoPagamento + a.valorDescontoPromocaoPagamento;
      END IF;
    END IF;
    IF ROUND (v_valorDescontoPagamento,2) >= v_saldoRatDescontoPagamento THEN
      v_valorDescontoPagamento   := v_saldoRatDescontoPagamento;
      v_residuoDescontoPagamento := 0;
    ELSE
      v_residuoDescontoPagamento := v_valorDescontoPagamento - ROUND (v_valorDescontoPagamento,2);
      v_valorDescontoPagamento   := ROUND (v_valorDescontoPagamento,2);
    END IF;
    v_saldoRatDescontoPagamento  := v_saldoRatDescontoPagamento - v_valorDescontoPagamento;

    -- v_valorOutrasDespesasPagamento
    -- v_valorJurosPagamento
    IF v_valorBaseRateioPagamFinanc > 0 AND a.geraFinanceiro = 1 THEN
      v_valorOutrasDespesasPagamento := v_valorOutrasDespesasPagamento + p_cab_valorOutrasDespPagamento * (CASE WHEN a.diminuiDescontoPrUnit = 1 OR a.somaAcrescimosPrUnit = 1 or a.somaFreteSeguroPrUnit = 1 THEN a.valorProdutoServicoBruto ELSE a.valorProdutoServico END - a.valorDescontoItem + a.valorAcrescimoItem) / v_valorBaseRateioPagamFinanc;
      v_valorJurosPagamento          := v_valorJurosPagamento          + p_cab_valorJurosPagamento      * (CASE WHEN a.diminuiDescontoPrUnit = 1 OR a.somaAcrescimosPrUnit = 1 or a.somaFreteSeguroPrUnit = 1 THEN a.valorProdutoServicoBruto ELSE a.valorProdutoServico END - a.valorDescontoItem + a.valorAcrescimoItem) / v_valorBaseRateioPagamFinanc;
    ELSIF v_valorBaseRateioPagamento > 0 AND v_valorBaseRateioPagamFinanc <= 0 THEN
      v_valorOutrasDespesasPagamento := v_valorOutrasDespesasPagamento + p_cab_valorOutrasDespPagamento * (CASE WHEN a.diminuiDescontoPrUnit = 1 OR a.somaAcrescimosPrUnit = 1 or a.somaFreteSeguroPrUnit = 1 THEN a.valorProdutoServicoBruto ELSE a.valorProdutoServico END - a.valorDescontoItem + a.valorAcrescimoItem) / v_valorBaseRateioPagamento;
      v_valorJurosPagamento          := v_valorJurosPagamento          + p_cab_valorJurosPagamento      * (CASE WHEN a.diminuiDescontoPrUnit = 1 OR a.somaAcrescimosPrUnit = 1 or a.somaFreteSeguroPrUnit = 1 THEN a.valorProdutoServicoBruto ELSE a.valorProdutoServico END - a.valorDescontoItem + a.valorAcrescimoItem) / v_valorBaseRateioPagamento;
    END IF;
    IF ROUND (v_valorOutrasDespesasPagamento,2) >= v_saldoRatOutrasDespPagamento THEN
      v_valorOutrasDespesasPagamento := v_saldoRatOutrasDespPagamento;
      v_residuoOutrasDespPagamento   := 0;
    ELSE
      v_residuoOutrasDespPagamento   := v_valorOutrasDespesasPagamento - ROUND (v_valorOutrasDespesasPagamento,2);
      v_valorOutrasDespesasPagamento := ROUND (v_valorOutrasDespesasPagamento,2);
    END IF;
    v_saldoRatOutrasDespPagamento := v_saldoRatOutrasDespPagamento - v_valorOutrasDespesasPagamento;
    IF ROUND (v_valorJurosPagamento,2) >= v_saldoRatJurosPagamento THEN
      v_valorJurosPagamento   := v_saldoRatJurosPagamento;
      v_residuoJurosPagamento := 0;
    ELSE
      v_residuoJurosPagamento := v_valorJurosPagamento - ROUND (v_valorJurosPagamento,2);
      v_valorJurosPagamento   := ROUND (v_valorJurosPagamento,2);
    END IF;
    v_saldoRatJurosPagamento := v_saldoRatJurosPagamento - v_valorJurosPagamento;

    -- Recalcula Valores
    ADD_CALCULA_TOTAIS_ITEM(
      p_cab_tipoPagamentoFrete,
      a.quantidade,
      a.quantidadeConvertida,
      a.precoUnitarioBruto,
      a.acrescimoUnitarioComposicao,
      a.precoUnitario,
      a.valorDescontoItem,
      a.valorAcrescimoItem,
      a.valorFreteItem,
      a.valorSeguroItem,
      a.valorAdicFreteMarinhaMerItem,
      a.valorDespesasAduaneirasItem,
      v_valorFreteGeral,
      v_valorSeguroGeral,
      v_valorDescontoGeral,
      v_valorOutrasDespesasGeral,
      v_valorAdicFreteMarinMerGeral,
      v_valorDespesasAduaneirasGeral,
      v_valorDescontoPagamento,
      v_valorOutrasDespesasPagamento,
      v_valorJurosPagamento,
      a.diminuiDescontoPrUnit,
      a.somaAcrescimosPrUnit,
      a.somaFreteSeguroPrUnit,
      a.composicaoPreco,
      /* Retornos */
      v_precoUnitario,
      v_precoUnitarioConvertido,
      v_valorProdutoServico,
      v_valorFreteTotal,
      v_valorSeguroTotal,
      v_valorDescontoTotal,
      v_valorOutrasDespesasTotal,
      v_valorAdicFreteMarinMerTotal,
      v_valorDespesasAduaneirasTotal);
    v_valorAcrescimoExtempSubtotal := FUNC_ADD_CALC_EXTEMP_SUBTOTAL(
      a.quantidade,
      v_precoUnitario,
      a.quantidadeExtemporanea,
      a.acrescimoUnitarioExtemporaneo);
    v_valorAcrescimoExtempTotal := FUNC_ADD_CALC_EXTEMP_TOTAL(
      v_valorAcrescimoExtempSubtotal,
      a.valorAcrescimoExtempItem,
      v_valorAcrescimoExtempGeral);
    IF p_cab_impostosEditados = 0 
        OR v_valorProdutoServico <> a.valorProdutoServico
        OR CASE WHEN p_cab_tipoPagamentoFrete   = 'V' THEN 0 ELSE v_valorFreteTotal END
        <> CASE WHEN CASE WHEN p_troca_tipoPagamentoFrete = 1 THEN p_a_cab_tipoPagamentoFrete ELSE p_cab_tipoPagamentoFrete END = 'V' THEN 0 ELSE a.valorFreteTotal END
        OR CASE WHEN p_cab_tipoPagamentoFrete   = 'V' THEN 0 ELSE v_valorSeguroTotal END
        <> CASE WHEN CASE WHEN p_troca_tipoPagamentoFrete = 1 THEN p_a_cab_tipoPagamentoFrete ELSE p_cab_tipoPagamentoFrete END = 'V' THEN 0 ELSE a.valorSeguroTotal END
        OR v_valorDescontoTotal <> a.valorDescontoTotal
        OR v_valorOutrasDespesasTotal <> a.valorOutrasDespesasTotal
        OR v_valorAdicFreteMarinMerTotal <> a.valorAdicFreteMarinhaMerTotal
        OR v_valorDespesasAduaneirasTotal <> a.valorDespesasAduaneirasTotal
        OR v_precoUnitario <> a.precoUnitario
        OR v_valorProdutoServico <> a.valorProdutoServico
    THEN
      r_calcularImpostosItem := 1;
    END IF;
    v_valorBasePagamento := FUNC_ADD_CALC_BASE_PAGAMENTO (
      p_cab_origemDocumento,
      p_cab_nfFornecedor,
      p_cab_tipoPagamentoFrete,
      a.geraFinanceiro,
      v_valorProdutoServico,
      v_valorDescontoPagamento,
      v_valorOutrasDespesasPagamento,
      v_valorJurosPagamento,
      v_valorFreteTotal,
      v_valorSeguroTotal,
      v_valorDescontoTotal,
      v_valorOutrasDespesasTotal,
      a.valorIPIDevolucao,
      a.retidoISSQN,
      a.valorISSQN,
      a.valorRetIRRF,
      a.valorRetINSS,
      a.valorRetPIS,
      a.valorRetCOFINS,
      a.valorRetCSLL,
      a.valorRetOutros,
      a.valorII,
      a.valorIOF,
      a.valorIPI,
      a.valorICMSST,
      a.valorICMSSTEscrituracao,
      a.somarICMSST,
      v_valorAcrescimoExtempTotal,
      a.modDoc_geraFinanceiro);
    v_valorLiquidoItem := FUNC_ADD_CALC_VALOR_LIQUIDO (
      p_cab_nfFornecedor,
      p_cab_tipoPagamentoFrete,
      v_valorProdutoServico,
      v_valorFreteTotal,
      v_valorSeguroTotal,
      v_valorDescontoTotal,
      v_valorOutrasDespesasTotal,
      a.valorIPIDevolucao,
      a.valorII,
      a.valorIOF,
      a.valorIPI,
      a.valorICMSST,
      a.valorICMSSTEscrituracao,
      a.somarICMSST);
    ADD_CALCULA_CUSTO_CMV (
      p_cab_atualizaCustoMedio,
      p_cab_estabelecimento,
      p_cab_nfFornecedor,
      a.modeloDocumento,
      a.quantidade,
      a.valorII,
      a.valorIOF,
      a.valorIPI,
      a.valorIPIDevolucao,
      a.valorPIS,
      a.valorPISST,
      a.valorCOFINS,
      a.valorCOFINSST,
      a.valorCreditoSimplesNacional,
      a.valorICMS,
      a.valorICMSST,
      a.valorICMSSTEscrituracao,
      v_valorLiquidoItem,
      a.valorDescontoCustoOpItem,
      v_valorDescontoCustoOpGeral,
      a.valorAcrescimoCustoOpItem,
      v_valorAcrescimoCustoOpGeral,
      v_valorAcrescimoExtempTotal,
      /* Retornos */
      v_valorDescontoCustoOpTotal,
      v_valorAcrescimoCustoOpTotal,
      v_precoCustoOperacao,
      v_valorCustoOperacao,
      v_precoCMV,
      v_valorCMV);

    -- Atualiza Item
    UPDATE MODOCFISCALXITENS SET
      precoUnitario                 = v_precoUnitario,
      precoUnitarioConvertido       = v_precoUnitarioConvertido,
      valorProdutoServico           = v_valorProdutoServico,
      valorFreteGeral               = v_valorFreteGeral,
      valorSeguroGeral              = v_valorSeguroGeral,
      valorDescontoGeral            = v_valorDescontoGeral,
      valorOutrasDespesasGeral      = v_valorOutrasDespesasGeral,
      valorAdicFreteMarinhaMerGeral = v_valorAdicFreteMarinMerGeral,
      valorDespesasAduaneirasGeral  = v_valorDespesasAduaneirasGeral,
      valorBasePagamento            = v_valorBasePagamento,
      valorDescontoPagamento        = v_valorDescontoPagamento,
      valorOutrasDespesasPagamento  = v_valorOutrasDespesasPagamento,
      valorJurosPagamento           = v_valorJurosPagamento,
      valorFreteTotal               = v_valorFreteTotal,
      valorSeguroTotal              = v_valorSeguroTotal,
      valorDescontoTotal            = v_valorDescontoTotal,
      valorOutrasDespesasTotal      = v_valorOutrasDespesasTotal,
      valorAdicFreteMarinhaMerTotal = v_valorAdicFreteMarinMerTotal,
      valorDespesasAduaneirasTotal  = v_valorDespesasAduaneirasTotal,
      valorLiquidoItem              = v_valorLiquidoItem,
      valorDescontoCustoOpGeral     = v_valorDescontoCustoOpGeral,
      valorDescontoCustoOpTotal     = v_valorDescontoCustoOpTotal,
      valorAcrescimoCustoOpGeral    = v_valorAcrescimoCustoOpGeral,
      valorAcrescimoCustoOpTotal    = v_valorAcrescimoCustoOpTotal,
      precoCustoOperacao            = v_precoCustoOperacao,
      valorCustoOperacao            = v_valorCustoOperacao,
      precoCMV                      = v_precoCMV,
      valorCMV                      = v_valorCMV,
      valorAcrescimoExtempSubtotal  = v_valorAcrescimoExtempSubtotal,
      valorAcrescimoExtempGeral     = v_valorAcrescimoExtempGeral,
      valorAcrescimoExtempTotal     = v_valorAcrescimoExtempTotal
    WHERE idItemDocFiscal           = a.idItemDocFiscal;
    IF a.tipoProduto = '09' THEN
      r_cab_valorServicos            := r_cab_valorServicos + v_valorProdutoServico;
    ELSE
      r_cab_valorProdutos            := r_cab_valorProdutos + v_valorProdutoServico;
    END IF;
    r_cab_valorBasePagamento       := r_cab_valorBasePagamento + v_valorBasePagamento;
    IF a.usarPrecoAVista = 1 AND a.geraFinanceiro = 1 THEN
      r_cab_valorAVistaMinimo        := r_cab_valorAVistaMinimo + v_valorProdutoServico + v_valorDescontoPagamento - v_valorOutrasDespesasPagamento - v_valorJurosPagamento - v_valorDescontoTotal + v_valorOutrasDespesasTotal;
    END IF;
    r_cab_valorFreteTotal          := r_cab_valorFreteTotal + v_valorFreteTotal;
    r_cab_valorSeguroTotal         := r_cab_valorSeguroTotal + v_valorSeguroTotal;
    r_cab_valorDescontoTotal       := r_cab_valorDescontoTotal + v_valorDescontoTotal;
    r_cab_valorOutrasDespesasTotal := r_cab_valorOutrasDespesasTotal + v_valorOutrasDespesasTotal;
    r_cab_valorAdicFreteMarinTotal := r_cab_valorAdicFreteMarinTotal + v_valorAdicFreteMarinMerTotal;
    r_cab_valorDespesasAduanTotal  := r_cab_valorDespesasAduanTotal + v_valorDespesasAduaneirasTotal;
    r_cab_valorLiquidoItem         := r_cab_valorLiquidoItem + v_valorLiquidoItem;
    r_cab_valorDescCustoOpTotal    := r_cab_valorDescCustoOpTotal + v_valorDescontoCustoOpTotal;
    r_cab_valorAcrescCustoOpTotal  := r_cab_valorAcrescCustoOpTotal + v_valorAcrescimoCustoOpTotal;
    r_cab_valorCustoOperacao       := r_cab_valorCustoOperacao + v_valorCustoOperacao;
    r_cab_valorCMV                 := r_cab_valorCMV + v_valorCMV;
    r_cab_valorAcrescExtempTotal   := r_cab_valorAcrescExtempTotal + v_valorAcrescimoExtempTotal;
  END LOOP;
  IF v_idItemDocFiscalUltimoItem <> 0 AND (v_saldoRatDescontoGeral <> 0 OR v_saldoRatOutrasDespesasGeral <> 0 OR v_saldoRatDescontoPagamento <> 0 OR v_saldoRatOutrasDespPagamento <> 0 OR v_saldoRatJurosPagamento <> 0 OR v_saldoRatFreteGeral <> 0 OR v_saldoRatSeguroGeral <> 0 OR v_saldoRatAdicFreteMarinGeral <> 0 OR v_saldoRatDespesasAduanGeral <> 0) THEN
    ADD_DOC_FISC_CALC_IMP_RESIDUO (
      p_troca_tipoPagamentoFrete,
      p_a_cab_tipoPagamentoFrete,
      p_cab_origemDocumento,
      p_cab_atualizaCustoMedio,
      p_cab_estabelecimento,
      p_cab_nfFornecedor,
      p_cab_tipoPagamentoFrete,
      r_cab_valorProdutos,
      r_cab_valorServicos,
      r_cab_valorBasePagamento,
      r_cab_valorAVistaMinimo,
      r_cab_valorFreteTotal,
      r_cab_valorSeguroTotal,
      r_cab_valorDescontoTotal,
      r_cab_valorOutrasDespesasTotal,
      r_cab_valorAdicFreteMarinTotal,
      r_cab_valorDespesasAduanTotal,
      p_cab_impostosEditados,
      r_cab_valorLiquidoItem,
      r_cab_valorDescCustoOpTotal,
      r_cab_valorAcrescCustoOpTotal,
      r_cab_valorCustoOperacao,
      r_cab_valorCMV,
      r_cab_valorAcrescExtempTotal,
      v_idItemDocFiscalUltimoItem,
      v_saldoRatFreteGeral,
      v_saldoRatSeguroGeral,
      v_saldoRatDescontoGeral,
      v_saldoRatOutrasDespesasGeral,
      v_saldoRatAdicFreteMarinGeral,
      v_saldoRatDespesasAduanGeral,
      v_saldoRatDescontoPagamento,
      v_saldoRatOutrasDespPagamento,
      v_saldoRatJurosPagamento,
      v_saldoRatDescCustoOpGeral,
      v_saldoRatAcrescCustoOpGeral,
      v_saldoRatAcrescExtempGeral,
      r_calcularImpostosItem,
      /* Retornos */
      r_cab_valorProdutos,
      r_cab_valorServicos,
      r_cab_valorBasePagamento,
      r_cab_valorAVistaMinimo,
      r_cab_valorFreteTotal,
      r_cab_valorSeguroTotal,
      r_cab_valorDescontoTotal,
      r_cab_valorOutrasDespesasTotal,
      r_cab_valorAdicFreteMarinTotal,
      r_cab_valorDespesasAduanTotal,
      r_cab_valorLiquidoItem,
      r_cab_valorDescCustoOpTotal,
      r_cab_valorAcrescCustoOpTotal,
      r_cab_valorCustoOperacao,
      r_cab_valorCMV,
      r_cab_valorAcrescExtempTotal,
      r_calcularImpostosItem);
  END IF;
END ADD_DOC_FISC_CALC_IMP_RATEIO;

/

create or replace PROCEDURE ADD_ORCAMENTO_CALC_IMP_ITENS (
  p_config_64_casasDecSaidas     IN CHAR,
  p_config_209_filtrarGrupoEcon  IN NUMBER,
  p_config_362_calcCustoPorGrade IN NUMBER,
  p_cab_orcamento                IN NUMBER,
  p_cab_origemDocumento          IN NUMBER,
  p_cab_entradaSaida             IN CHAR,
  p_cab_estabelecimento          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,
  /* Retornos */
  r_cab_valorProdutos            OUT NUMBER,
  r_cab_valorServicos            OUT NUMBER,
  r_cab_valorBasePagamento       OUT NUMBER,
  r_cab_valorAVistaMinimo        OUT NUMBER,
  r_cab_valorFreteTotal          OUT NUMBER,
  r_cab_valorSeguroTotal         OUT NUMBER,
  r_cab_valorDescontoTotal       OUT NUMBER,
  r_cab_valorOutrasDespesasTotal OUT NUMBER,
  r_cab_valorAdicFreteMarinTotal OUT NUMBER,
  r_cab_valorDespesasAduanTotal  OUT NUMBER,
  r_cab_valorLiquidoItem         OUT NUMBER)
IS
  v_auxNumber                    NUMBER;
  v_precoUnitario                NUMBER;
  v_precoUnitarioConvertido      NUMBER;
  v_valorProdutoServico          NUMBER;
  v_valorBasePagamento           NUMBER;
  v_valorFreteTotal              NUMBER;
  v_valorSeguroTotal             NUMBER;
  v_valorDescontoTotal           NUMBER;
  v_valorOutrasDespesasTotal     NUMBER;
  v_valorAdicFreteMarinMerTotal  NUMBER;
  v_valorDespesasAduaneirasTotal NUMBER;
  v_baseISSQN                    NUMBER;
  v_valorISSQN                   NUMBER;
  v_baseRetIRRF                  NUMBER;
  v_valorRetIRRF                 NUMBER;
  v_baseRetINSS                  NUMBER;
  v_valorRetINSS                 NUMBER;
  v_baseRetPIS                   NUMBER;
  v_valorRetPIS                  NUMBER;
  v_baseRetCOFINS                NUMBER;
  v_valorRetCOFINS               NUMBER;
  v_baseRetCSLL                  NUMBER;
  v_valorRetCSLL                 NUMBER;
  v_baseRetOutros                NUMBER;
  v_valorRetOutros               NUMBER;
  v_baseII                       NUMBER;
  v_valorII                      NUMBER;
  v_baseIOF                      NUMBER;
  v_valorIOF                     NUMBER;
  v_baseIPI                      NUMBER;
  v_valorIPI                     NUMBER;
  v_basePIS                      NUMBER;
  v_valorPIS                     NUMBER;
  v_basePISST                    NUMBER;
  v_valorPISST                   NUMBER;
  v_baseCOFINS                   NUMBER;
  v_valorCOFINS                  NUMBER;
  v_baseCOFINSST                 NUMBER;
  v_valorCOFINSST                NUMBER;
  v_baseCreditoSimplesNacional   NUMBER;
  v_valorCreditoSimplesNacional  NUMBER;
  v_baseICMS                     NUMBER;
  v_valorICMSOperacao            NUMBER;
  v_valorICMSDiferido            NUMBER;
  v_valorICMS                    NUMBER;
  v_valorICMSDesoneracao         NUMBER;
  v_baseICMSST                   NUMBER;
  v_valorICMSST                  NUMBER;
  v_baseICMSSTAnteriormente      NUMBER;
  v_valorICMSSTAnteriormente     NUMBER;
  v_valorICMSProprioSubstituto   NUMBER;
  v_baseICMSEfetivo              NUMBER;
  v_valorICMSEfetivo             NUMBER;
  v_baseICMSUFDestinatario       NUMBER;
  v_valorICMSUFDestinatario      NUMBER;
  v_baseICMSUFRemetente          NUMBER;
  v_valorICMSUFRemetente         NUMBER;
  v_baseFCP                      NUMBER;
  v_valorFCP                     NUMBER;
  v_baseFCPST                    NUMBER;
  v_valorFCPST                   NUMBER;
  v_baseFCPSTAnteriormente       NUMBER;
  v_valorFCPSTAnteriormente      NUMBER;
  v_baseFCPUFDestinatario        NUMBER;
  v_valorFCPUFDestinatario       NUMBER;
  v_baseEstimadaImpostos         NUMBER;
  v_valorEstimadoImpFederais     NUMBER;
  v_valorEstimadoImpEstaduais    NUMBER;
  v_valorEstimadoImpMunicipais   NUMBER;
  v_valorLiquidoItem             NUMBER;
BEGIN
  r_cab_valorProdutos            := 0;
  r_cab_valorServicos            := 0;
  r_cab_valorBasePagamento       := 0;
  r_cab_valorAVistaMinimo        := 0;
  r_cab_valorFreteTotal          := 0;
  r_cab_valorSeguroTotal         := 0;
  r_cab_valorDescontoTotal       := 0;
  r_cab_valorOutrasDespesasTotal := 0;
  r_cab_valorAdicFreteMarinTotal := 0;
  r_cab_valorDespesasAduanTotal  := 0;
  r_cab_valorLiquidoItem         := 0;
  FOR a IN (
    SELECT
      a.*,
      gradProd.produto,
      gradProd.cor,
      gradProd.tamanho,
      prod.controleEstoque,
      prod.tipoProduto,
      prod.precoPautaTabelado,
      modDoc.geraFinanceiro modDoc_geraFinanceiro,
      modDoc.diminuiDescontoPrUnit,
      modDoc.somaAcrescimosPrUnit,
      modDoc.somaFreteSeguroPrUnit,
      CASE
        WHEN EXISTS (
          SELECT 1
          FROM CAPRODUTOXCOMPOSICOESPREC compPrec
          WHERE compPrec.produto = gradProd.produto
          AND compPrec.ativo = 1)
        THEN 1
        ELSE 0
      END composicaoPreco
    FROM MOORCAMENTOXITENS a
    JOIN CAGRADESPRODUTO gradProd
    ON gradProd.gradeProduto = a.gradeProduto
    JOIN CAPRODUTOS prod
    ON prod.produto = gradProd.produto
    JOIN PAMODELOSDOCUMENTO modDoc
    ON modDoc.modeloDocumento = a.modeloDocumento
    WHERE a.orcamento = p_cab_orcamento
    AND a.cancelado = 0
    ORDER BY a.sequencia)
  LOOP
    v_precoUnitario                := a.precoUnitario;
    v_precoUnitarioConvertido      := a.precoUnitarioConvertido;
    v_valorProdutoServico          := a.valorProdutoServico;
    v_valorBasePagamento           := a.valorBasePagamento;
    v_valorFreteTotal              := a.valorFreteTotal;
    v_valorSeguroTotal             := a.valorSeguroTotal;
    v_valorDescontoTotal           := a.valorDescontoTotal;
    v_valorOutrasDespesasTotal     := a.valorOutrasDespesasTotal;
    v_valorAdicFreteMarinMerTotal  := a.valorAdicFreteMarinhaMerTotal;
    v_valorDespesasAduaneirasTotal := a.valorDespesasAduaneirasTotal;
    v_baseISSQN                    := a.baseISSQN;
    v_valorISSQN                   := a.valorISSQN;
    v_baseRetIRRF                  := a.baseRetIRRF;
    v_valorRetIRRF                 := a.valorRetIRRF;
    v_baseRetINSS                  := a.baseRetINSS;
    v_valorRetINSS                 := a.valorRetINSS;
    v_baseRetOutros                := a.baseRetOutros;
    v_valorRetOutros               := a.valorRetOutros;
    v_baseRetPIS                   := a.baseRetPIS;
    v_valorRetPIS                  := a.valorRetPIS;
    v_baseRetCOFINS                := a.baseRetCOFINS;
    v_valorRetCOFINS               := a.valorRetCOFINS;
    v_baseRetCSLL                  := a.baseRetCSLL;
    v_valorRetCSLL                 := a.valorRetCSLL;
    v_baseII                       := a.baseII;
    v_valorII                      := a.valorII;
    v_baseIOF                      := a.baseIOF;
    v_valorIOF                     := a.valorIOF;
    v_baseIPI                      := a.baseIPI;
    v_valorIPI                     := a.valorIPI;
    v_basePIS                      := a.basePIS;
    v_valorPIS                     := a.valorPIS;
    v_basePISST                    := a.basePISST;
    v_valorPISST                   := a.valorPISST;
    v_baseCOFINS                   := a.baseCOFINS;
    v_valorCOFINS                  := a.valorCOFINS;
    v_baseCOFINSST                 := a.baseCOFINSST;
    v_valorCOFINSST                := a.valorCOFINSST;
    v_baseCreditoSimplesNacional   := a.baseCreditoSimplesNacional;
    v_valorCreditoSimplesNacional  := a.valorCreditoSimplesNacional;
    v_baseICMS                     := a.baseICMS;
    v_valorICMSOperacao            := a.valorICMSOperacao;
    v_valorICMSDiferido            := a.valorICMSDiferido;
    v_valorICMS                    := a.valorICMS;
    v_valorICMSDesoneracao         := a.valorICMSDesoneracao;
    v_baseICMSST                   := a.baseICMSST;
    v_valorICMSST                  := a.valorICMSST;
    v_baseICMSSTAnteriormente      := a.baseICMSSTAnteriormente;
    v_valorICMSSTAnteriormente     := a.valorICMSSTAnteriormente;
    v_valorICMSProprioSubstituto   := a.valorICMSProprioSubstituto;
    v_baseICMSEfetivo              := a.baseICMSEfetivo;
    v_valorICMSEfetivo             := a.valorICMSEfetivo;
    v_baseICMSUFDestinatario       := a.baseICMSUFDestinatario;
    v_valorICMSUFDestinatario      := a.valorICMSUFDestinatario;
    v_baseICMSUFRemetente          := a.baseICMSUFRemetente;
    v_valorICMSUFRemetente         := a.valorICMSUFRemetente;
    v_baseFCP                      := a.baseFCP;
    v_valorFCP                     := a.valorFCP;
    v_baseFCPST                    := a.baseFCPST;
    v_valorFCPST                   := a.valorFCPST;
    v_baseFCPSTAnteriormente       := a.baseFCPSTAnteriormente;
    v_valorFCPSTAnteriormente      := a.valorFCPSTAnteriormente;
    v_baseFCPUFDestinatario        := a.baseFCPUFDestinatario;
    v_valorFCPUFDestinatario       := a.valorFCPUFDestinatario;
    v_baseEstimadaImpostos         := a.baseEstimadaImpostos;
    v_valorEstimadoImpFederais     := a.valorEstimadoImpFederais;
    v_valorEstimadoImpEstaduais    := a.valorEstimadoImpEstaduais;
    v_valorEstimadoImpMunicipais   := a.valorEstimadoImpMunicipais;
    v_valorLiquidoItem             := a.valorLiquidoItem;
    ADD_CALCULA_TOTAIS_ITEM(
      p_cab_tipoPagamentoFrete,
      a.quantidade,
      a.quantidadeConvertida,
      a.precoUnitarioBruto,
      a.acrescimoUnitarioComposicao,
      a.precoUnitario,
      a.valorDescontoItem,
      a.valorAcrescimoItem,
      a.valorFreteItem,
      a.valorSeguroItem,
      a.valorAdicFreteMarinhaMerItem,
      a.valorDespesasAduaneirasItem,
      a.valorFreteGeral,
      a.valorSeguroGeral,
      a.valorDescontoGeral,
      a.valorOutrasDespesasGeral,
      a.valorAdicFreteMarinhaMerGeral,
      a.valorDespesasAduaneirasGeral,
      a.valorDescontoPagamento,
      a.valorOutrasDespesasPagamento,
      a.valorJurosPagamento,
      a.diminuiDescontoPrUnit,
      a.somaAcrescimosPrUnit,
      a.somaFreteSeguroPrUnit,
      a.composicaoPreco,
      /* Retornos */
      v_precoUnitario,
      v_precoUnitarioConvertido,
      v_valorProdutoServico,
      v_valorFreteTotal,
      v_valorSeguroTotal,
      v_valorDescontoTotal,
      v_valorOutrasDespesasTotal,
      v_valorAdicFreteMarinMerTotal,
      v_valorDespesasAduaneirasTotal);
    ADD_CALCULA_IMPOSTOS_ITEM (
      p_config_64_casasDecSaidas,
      p_config_209_filtrarGrupoEcon,
      p_config_362_calcCustoPorGrade,
      p_cab_entradaSaida,
      0,
      p_cab_estabelecimento,
      0,
      p_cab_dataEntradaSaida,
      p_cab_pessoa,
      p_cab_localDestinoOperacao,
      p_cab_indicadorConsumidorFinal,
      p_cab_tipoPagamentoFrete,
      p_pess_indicadorInscricaoEstad,
      a.personalizacao,
      a.quantidade,
      v_valorProdutoServico,
      v_valorFreteTotal,
      v_valorSeguroTotal,
      v_valorDescontoTotal,
      v_valorOutrasDespesasTotal,
      v_valorAdicFreteMarinMerTotal,
      v_valorDespesasAduaneirasTotal,
      a.cfop,
      1,
      a.indicadorISSQN,
      a.aliquotaISSQN,
      v_baseISSQN,
      v_valorISSQN,
      1,
      a.retencaoIRRF,
      v_baseRetIRRF,
      v_valorRetIRRF,
      1,
      a.retencaoINSS,
      v_baseRetINSS,
      v_valorRetINSS,
      1,
      a.retencaoPIS,
      v_baseRetPIS,
      v_valorRetPIS,
      1,
      a.retencaoCOFINS,
      v_baseRetCOFINS,
      v_valorRetCOFINS,
      1,
      a.retencaoCSLL,
      v_baseRetCSLL,
      v_valorRetCSLL,
      1,
      a.retencaoOutros,
      v_baseRetOutros,
      v_valorRetOutros,
      1,
      a.aliquotaII,
      v_baseII,
      v_valorII,
      1,
      a.aliquotaIOF,
      v_baseIOF,
      v_valorIOF,
      1,
      a.aliquotaIPI,
      a.valorAliquotaIPI,
      v_baseIPI,
      v_valorIPI,
      0,
      1,
      a.aliquotaPIS,
      a.valorAliquotaPIS,
      v_basePIS,
      v_valorPIS,
      1,
      a.aliquotaPISST,
      a.valorAliquotaPISST,
      v_basePISST,
      v_valorPISST,
      1,
      a.aliquotaCOFINS,
      a.valorAliquotaCOFINS,
      v_baseCOFINS,
      v_valorCOFINS,
      1,
      a.aliquotaCOFINSST,
      a.valorAliquotaCOFINSST,
      v_baseCOFINSST,
      v_valorCOFINSST,
      1,
      a.stSimplesNacional,
      a.creditoSimplesNacional,
      v_baseCreditoSimplesNacional,
      v_valorCreditoSimplesNacional,
      1,
      a.stICMS,
      a.modalidadeBaseCalcICMS,
      a.reducaoBaseICMS,
      a.aliquotaICMS,
      a.diferimentoICMS,
      v_baseICMS,
      v_valorICMSOperacao,
      v_valorICMSDiferido,
      v_valorICMS,
      v_valorICMSDesoneracao,
      1,
      a.modalidadeBaseCalcICMSST,
      a.margemValorAdicionadoST,
      a.reducaoBaseST,
      a.aliquotaICMSST,
      v_baseICMSST,
      v_valorICMSST,
      1,
      v_baseICMSSTAnteriormente,
      v_valorICMSSTAnteriormente,
      v_valorICMSProprioSubstituto,
      a.reducaoBaseICMSEfetivo,
      a.aliquotaICMSEfetivo,
      v_baseICMSEfetivo,
      v_valorICMSEfetivo,
      0,
      '  ',
      0,
      0,
      0,
      0,
      0,
      0,
      0,
      0,
      0,
      0,
      0,
      0,
      1,
      a.aliquotaICMSUFDestinatario,
      a.aliquotaICMSInterestadual,
      a.partilhaICMSInterestadual,
      v_baseICMSUFDestinatario,
      v_valorICMSUFDestinatario,
      v_baseICMSUFRemetente,
      v_valorICMSUFRemetente,
      1,
      a.aliquotaFCP,
      v_baseFCP,
      v_valorFCP,
      a.aliquotaFCPST,
      v_baseFCPST,
      v_valorFCPST,
      a.aliquotaFCPSTAnteriormente,
      v_baseFCPSTAnteriormente,
      v_valorFCPSTAnteriormente,
      a.aliquotaFCPUFDestinatario,
      v_baseFCPUFDestinatario,
      v_valorFCPUFDestinatario,
      1,
      a.aliquotaEstimadaImpFederais,
      a.aliquotaEstimadaImpEstaduais,
      a.aliquotaEstimadaImpMunicipais,
      v_baseEstimadaImpostos,
      v_valorEstimadoImpFederais,
      v_valorEstimadoImpEstaduais,
      v_valorEstimadoImpMunicipais,
      a.produto,
      a.cor,
      a.tamanho,
      a.controleEstoque,
      a.tipoProduto,
      a.precoPautaTabelado,
      /* Retornos */
      v_baseISSQN,
      v_valorISSQN,
      v_baseRetIRRF,
      v_valorRetIRRF,
      v_baseRetINSS,
      v_valorRetINSS,
      v_baseRetPIS,
      v_valorRetPIS,
      v_baseRetCOFINS,
      v_valorRetCOFINS,
      v_baseRetCSLL,
      v_valorRetCSLL,
      v_baseRetOutros,
      v_valorRetOutros,
      v_baseII,
      v_valorII,
      v_baseIOF,
      v_valorIOF,
      v_baseIPI,
      v_valorIPI,
      v_basePIS,
      v_valorPIS,
      v_basePISST,
      v_valorPISST,
      v_baseCOFINS,
      v_valorCOFINS,
      v_baseCOFINSST,
      v_valorCOFINSST,
      v_baseCreditoSimplesNacional,
      v_valorCreditoSimplesNacional,
      v_baseICMS,
      v_valorICMSOperacao,
      v_valorICMSDiferido,
      v_valorICMS,
      v_valorICMSDesoneracao,
      v_baseICMSST,
      v_valorICMSST,
      v_baseICMSSTAnteriormente,
      v_valorICMSSTAnteriormente,
      v_valorICMSProprioSubstituto,
      v_baseICMSEfetivo,
      v_valorICMSEfetivo,
      v_auxNumber,
      v_auxNumber,
      v_auxNumber,
      v_auxNumber,
      v_auxNumber,
      v_baseICMSUFDestinatario,
      v_valorICMSUFDestinatario,
      v_baseICMSUFRemetente,
      v_valorICMSUFRemetente,
      v_baseFCP,
      v_valorFCP,
      v_baseFCPST,
      v_valorFCPST,
      v_baseFCPSTAnteriormente,
      v_valorFCPSTAnteriormente,
      v_baseFCPUFDestinatario,
      v_valorFCPUFDestinatario,
      v_baseEstimadaImpostos,
      v_valorEstimadoImpFederais,
      v_valorEstimadoImpEstaduais,
      v_valorEstimadoImpMunicipais);
    v_valorBasePagamento := FUNC_ADD_CALC_BASE_PAGAMENTO (
      p_cab_origemDocumento,
      0, -- p_cab_nfFornecedor
      p_cab_tipoPagamentoFrete,
      a.geraFinanceiro,
      v_valorProdutoServico,
      a.valorDescontoPagamento,
      a.valorOutrasDespesasPagamento,
      a.valorJurosPagamento,
      v_valorFreteTotal,
      v_valorSeguroTotal,
      v_valorDescontoTotal,
      v_valorOutrasDespesasTotal,
      0, -- p_item_valorIPIDevolucao
      a.retidoISSQN,
      v_valorISSQN,
      v_valorRetIRRF,
      v_valorRetINSS,
      v_valorRetPIS,
      v_valorRetCOFINS,
      v_valorRetCSLL,
      v_valorRetOutros,
      v_valorII,
      v_valorIOF,
      v_valorIPI,
      v_valorICMSST,
      0, -- p_item_valorICMSSTEscrit
      0, -- p_item_somarICMSST
      0, -- p_item_valorAcrescExtempTotal
      a.modDoc_geraFinanceiro);
    v_valorLiquidoItem := FUNC_ADD_CALC_VALOR_LIQUIDO (
      0, -- p_cab_nfFornecedor
      p_cab_tipoPagamentoFrete,
      v_valorProdutoServico,
      v_valorFreteTotal,
      v_valorSeguroTotal,
      v_valorDescontoTotal,
      v_valorOutrasDespesasTotal,
      0, -- p_item_valorIPIDevolucao
      v_valorII,
      v_valorIOF,
      v_valorIPI,
      v_valorICMSST,
      0, -- p_item_valorICMSSTEscrit
      0 -- p_item_somarICMSST
      );
    UPDATE MOORCAMENTOXITENS SET
      precoUnitario                 = v_precoUnitario,
      precoUnitarioConvertido       = v_precoUnitarioConvertido,
      valorProdutoServico           = v_valorProdutoServico,
      valorBasePagamento            = v_valorBasePagamento,
      valorFreteTotal               = v_valorFreteTotal,
      valorSeguroTotal              = v_valorSeguroTotal,
      valorDescontoTotal            = v_valorDescontoTotal,
      valorOutrasDespesasTotal      = v_valorOutrasDespesasTotal,
      valorAdicFreteMarinhaMerTotal = v_valorAdicFreteMarinMerTotal,
      valorDespesasAduaneirasTotal  = v_valorDespesasAduaneirasTotal,
      baseISSQN                     = v_baseISSQN,
      valorISSQN                    = v_valorISSQN,
      baseRetIRRF                   = v_baseRetIRRF,
      valorRetIRRF                  = v_valorRetIRRF,
      baseRetINSS                   = v_baseRetINSS,
      valorRetINSS                  = v_valorRetINSS,
      baseRetPIS                    = v_baseRetPIS,
      valorRetPIS                   = v_valorRetPIS,
      baseRetCOFINS                 = v_baseRetCOFINS,
      valorRetCOFINS                = v_valorRetCOFINS,
      baseRetCSLL                   = v_baseRetCSLL,
      valorRetCSLL                  = v_valorRetCSLL,
      baseRetOutros                 = v_baseRetOutros,
      valorRetOutros                = v_valorRetOutros,
      baseII                        = v_baseII,
      valorII                       = v_valorII,
      baseIOF                       = v_baseIOF,
      valorIOF                      = v_valorIOF,
      baseIPI                       = v_baseIPI,
      valorIPI                      = v_valorIPI,
      basePIS                       = v_basePIS,
      valorPIS                      = v_valorPIS,
      basePISST                     = v_basePISST,
      valorPISST                    = v_valorPISST,
      baseCOFINS                    = v_baseCOFINS,
      valorCOFINS                   = v_valorCOFINS,
      baseCOFINSST                  = v_baseCOFINSST,
      valorCOFINSST                 = v_valorCOFINSST,
      baseCreditoSimplesNacional    = v_baseCreditoSimplesNacional,
      valorCreditoSimplesNacional   = v_valorCreditoSimplesNacional,
      baseICMS                      = v_baseICMS,
      valorICMSOperacao             = v_valorICMSOperacao,
      valorICMSDiferido             = v_valorICMSDiferido,
      valorICMS                     = v_valorICMS,
      valorICMSDesoneracao          = v_valorICMSDesoneracao,
      baseICMSST                    = v_baseICMSST,
      valorICMSST                   = v_valorICMSST,
      baseICMSSTAnteriormente       = v_baseICMSSTAnteriormente,
      valorICMSSTAnteriormente      = v_valorICMSSTAnteriormente,
      valorICMSProprioSubstituto    = v_valorICMSProprioSubstituto,
      baseICMSEfetivo               = v_baseICMSEfetivo,
      valorICMSEfetivo              = v_valorICMSEfetivo,
      baseICMSUFDestinatario        = v_baseICMSUFDestinatario,
      valorICMSUFDestinatario       = v_valorICMSUFDestinatario,
      baseICMSUFRemetente           = v_baseICMSUFRemetente,
      valorICMSUFRemetente          = v_valorICMSUFRemetente,
      baseFCP                       = v_baseFCP,
      valorFCP                      = v_valorFCP,
      baseFCPST                     = v_baseFCPST,
      valorFCPST                    = v_valorFCPST,
      baseFCPSTAnteriormente        = v_baseFCPSTAnteriormente,
      valorFCPSTAnteriormente       = v_valorFCPSTAnteriormente,
      baseFCPUFDestinatario         = v_baseFCPUFDestinatario,
      valorFCPUFDestinatario        = v_valorFCPUFDestinatario,
      baseEstimadaImpostos          = v_baseEstimadaImpostos,
      valorEstimadoImpFederais      = v_valorEstimadoImpFederais,
      valorEstimadoImpEstaduais     = v_valorEstimadoImpEstaduais,
      valorEstimadoImpMunicipais    = v_valorEstimadoImpMunicipais,
      valorLiquidoItem              = v_valorLiquidoItem
    WHERE idItemOrcamento           = a.idItemOrcamento;
    IF a.tipoProduto = '09' THEN
      r_cab_valorServicos            := r_cab_valorServicos + v_valorProdutoServico;
    ELSE
      r_cab_valorProdutos            := r_cab_valorProdutos + v_valorProdutoServico;
    END IF;
    r_cab_valorBasePagamento       := r_cab_valorBasePagamento + v_valorBasePagamento;
    IF a.usarPrecoAVista = 1 AND a.geraFinanceiro = 1 THEN
      r_cab_valorAVistaMinimo        := r_cab_valorAVistaMinimo + v_valorProdutoServico + a.valorDescontoPagamento - a.valorOutrasDespesasPagamento - a.valorJurosPagamento - v_valorDescontoTotal + v_valorOutrasDespesasTotal;
    END IF;
    r_cab_valorFreteTotal          := r_cab_valorFreteTotal + v_valorFreteTotal;
    r_cab_valorSeguroTotal         := r_cab_valorSeguroTotal + v_valorSeguroTotal;
    r_cab_valorDescontoTotal       := r_cab_valorDescontoTotal + v_valorDescontoTotal;
    r_cab_valorOutrasDespesasTotal := r_cab_valorOutrasDespesasTotal + v_valorOutrasDespesasTotal;
    r_cab_valorAdicFreteMarinTotal := r_cab_valorAdicFreteMarinTotal + v_valorAdicFreteMarinMerTotal;
    r_cab_valorDespesasAduanTotal  := r_cab_valorDespesasAduanTotal + v_valorDespesasAduaneirasTotal;
    r_cab_valorLiquidoItem         := r_cab_valorLiquidoItem + v_valorLiquidoItem;
  END LOOP;
END ADD_ORCAMENTO_CALC_IMP_ITENS;

/

create or replace PROCEDURE ADD_PRE_DOC_CALC_IMP_ITENS (
  p_config_64_casasDecSaidas     IN CHAR,
  p_config_209_filtrarGrupoEcon  IN NUMBER,
  p_config_362_calcCustoPorGrade IN NUMBER,
  p_cab_preDocumento             IN NUMBER,
  p_cab_origemDocumento          IN NUMBER,
  p_cab_entradaSaida             IN CHAR,
  p_cab_devolucaoAnulacaoRetorno IN NUMBER,
  p_cab_atualizaCustoMedio       IN NUMBER,
  p_cab_estabelecimento          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,
  /* Retornos */
  r_cab_valorProdutos            OUT NUMBER,
  r_cab_valorServicos            OUT NUMBER,
  r_cab_valorBasePagamento       OUT NUMBER,
  r_cab_valorAVistaMinimo        OUT NUMBER,
  r_cab_valorFreteTotal          OUT NUMBER,
  r_cab_valorSeguroTotal         OUT NUMBER,
  r_cab_valorDescontoTotal       OUT NUMBER,
  r_cab_valorOutrasDespesasTotal OUT NUMBER,
  r_cab_valorAdicFreteMarinTotal OUT NUMBER,
  r_cab_valorDespesasAduanTotal  OUT NUMBER,
  r_cab_valorLiquidoItem         OUT NUMBER,
  r_cab_valorDescCustoOpTotal    OUT NUMBER,
  r_cab_valorAcrescCustoOpTotal  OUT NUMBER,
  r_cab_valorCustoOperacao       OUT NUMBER,
  r_cab_valorCMV                 OUT NUMBER,
  r_cab_valorAcrescExtempTotal   OUT NUMBER)
IS
  v_auxNumber                    NUMBER;
  v_precoUnitario                NUMBER;
  v_precoUnitarioConvertido      NUMBER;
  v_valorProdutoServico          NUMBER;
  v_valorBasePagamento           NUMBER;
  v_valorFreteTotal              NUMBER;
  v_valorSeguroTotal             NUMBER;
  v_valorDescontoTotal           NUMBER;
  v_valorOutrasDespesasTotal     NUMBER;
  v_valorAdicFreteMarinMerTotal  NUMBER;
  v_valorDespesasAduaneirasTotal NUMBER;
  v_baseISSQN                    NUMBER;
  v_valorISSQN                   NUMBER;
  v_baseRetIRRF                  NUMBER;
  v_valorRetIRRF                 NUMBER;
  v_baseRetINSS                  NUMBER;
  v_valorRetINSS                 NUMBER;
  v_baseRetPIS                   NUMBER;
  v_valorRetPIS                  NUMBER;
  v_baseRetCOFINS                NUMBER;
  v_valorRetCOFINS               NUMBER;
  v_baseRetCSLL                  NUMBER;
  v_valorRetCSLL                 NUMBER;
  v_baseRetOutros                NUMBER;
  v_valorRetOutros               NUMBER;
  v_baseII                       NUMBER;
  v_valorII                      NUMBER;
  v_baseIOF                      NUMBER;
  v_valorIOF                     NUMBER;
  v_baseIPI                      NUMBER;
  v_valorIPI                     NUMBER;
  v_basePIS                      NUMBER;
  v_valorPIS                     NUMBER;
  v_basePISST                    NUMBER;
  v_valorPISST                   NUMBER;
  v_baseCOFINS                   NUMBER;
  v_valorCOFINS                  NUMBER;
  v_baseCOFINSST                 NUMBER;
  v_valorCOFINSST                NUMBER;
  v_baseCreditoSimplesNacional   NUMBER;
  v_valorCreditoSimplesNacional  NUMBER;
  v_baseICMS                     NUMBER;
  v_valorICMSOperacao            NUMBER;
  v_valorICMSDiferido            NUMBER;
  v_valorICMS                    NUMBER;
  v_valorICMSDesoneracao         NUMBER;
  v_baseICMSST                   NUMBER;
  v_valorICMSST                  NUMBER;
  v_baseICMSSTAnteriormente      NUMBER;
  v_valorICMSSTAnteriormente     NUMBER;
  v_valorICMSProprioSubstituto   NUMBER;
  v_baseICMSEfetivo              NUMBER;
  v_valorICMSEfetivo             NUMBER;
  v_baseICMSUFDestinatario       NUMBER;
  v_valorICMSUFDestinatario      NUMBER;
  v_baseICMSUFRemetente          NUMBER;
  v_valorICMSUFRemetente         NUMBER;
  v_baseFCP                      NUMBER;
  v_valorFCP                     NUMBER;
  v_baseFCPST                    NUMBER;
  v_valorFCPST                   NUMBER;
  v_baseFCPSTAnteriormente       NUMBER;
  v_valorFCPSTAnteriormente      NUMBER;
  v_baseFCPUFDestinatario        NUMBER;
  v_valorFCPUFDestinatario       NUMBER;
  v_baseEstimadaImpostos         NUMBER;
  v_valorEstimadoImpFederais     NUMBER;
  v_valorEstimadoImpEstaduais    NUMBER;
  v_valorEstimadoImpMunicipais   NUMBER;
  v_valorLiquidoItem             NUMBER;
  v_valorDescontoCustoOpTotal    NUMBER;
  v_valorAcrescimoCustoOpTotal   NUMBER;
  v_precoCustoOperacao           NUMBER;
  v_valorCustoOperacao           NUMBER;
  v_precoCMV                     NUMBER;
  v_valorCMV                     NUMBER;
  v_valorAcrescimoExtempSubtotal NUMBER;
  v_valorAcrescimoExtempTotal    NUMBER;
BEGIN
  r_cab_valorProdutos            := 0;
  r_cab_valorServicos            := 0;
  r_cab_valorBasePagamento       := 0;
  r_cab_valorAVistaMinimo        := 0;
  r_cab_valorFreteTotal          := 0;
  r_cab_valorSeguroTotal         := 0;
  r_cab_valorDescontoTotal       := 0;
  r_cab_valorOutrasDespesasTotal := 0;
  r_cab_valorAdicFreteMarinTotal := 0;
  r_cab_valorDespesasAduanTotal  := 0;
  r_cab_valorLiquidoItem         := 0;
  r_cab_valorDescCustoOpTotal    := 0;
  r_cab_valorAcrescCustoOpTotal  := 0;
  r_cab_valorCustoOperacao       := 0;
  r_cab_valorCMV                 := 0;
  r_cab_valorAcrescExtempTotal   := 0;  
  FOR a IN (
    SELECT
      a.*,
      gradProd.produto,
      gradProd.cor,
      gradProd.tamanho,
      prod.controleEstoque,
      prod.tipoProduto,
      prod.precoPautaTabelado,
      modDoc.geraFinanceiro modDoc_geraFinanceiro,
      modDoc.diminuiDescontoPrUnit,
      modDoc.somaAcrescimosPrUnit,
      modDoc.somaFreteSeguroPrUnit,
      CASE
        WHEN EXISTS (
          SELECT 1
          FROM CAPRODUTOXCOMPOSICOESPREC compPrec
          WHERE compPrec.produto = gradProd.produto
          AND compPrec.ativo = 1)
        THEN 1
        ELSE 0
      END composicaoPreco
    FROM MOPREDOCUMXITENS a
    JOIN CAGRADESPRODUTO gradProd
    ON gradProd.gradeProduto = a.gradeProduto
    JOIN CAPRODUTOS prod
    ON prod.produto = gradProd.produto
    JOIN PAMODELOSDOCUMENTO modDoc
    ON modDoc.modeloDocumento = a.modeloDocumento
    WHERE a.preDocumento = p_cab_preDocumento
    AND a.cancelado = 0
    ORDER BY a.sequencia)
  LOOP
    v_precoUnitario                := a.precoUnitario;
    v_precoUnitarioConvertido      := a.precoUnitarioConvertido;
    v_valorProdutoServico          := a.valorProdutoServico;
    v_valorBasePagamento           := a.valorBasePagamento;
    v_valorFreteTotal              := a.valorFreteTotal;
    v_valorSeguroTotal             := a.valorSeguroTotal;
    v_valorDescontoTotal           := a.valorDescontoTotal;
    v_valorOutrasDespesasTotal     := a.valorOutrasDespesasTotal;
    v_valorAdicFreteMarinMerTotal  := a.valorAdicFreteMarinhaMerTotal;
    v_valorDespesasAduaneirasTotal := a.valorDespesasAduaneirasTotal;
    v_baseISSQN                    := a.baseISSQN;
    v_valorISSQN                   := a.valorISSQN;
    v_baseRetIRRF                  := a.baseRetIRRF;
    v_valorRetIRRF                 := a.valorRetIRRF;
    v_baseRetINSS                  := a.baseRetINSS;
    v_valorRetINSS                 := a.valorRetINSS;
    v_baseRetPIS                   := a.baseRetPIS;
    v_valorRetPIS                  := a.valorRetPIS;
    v_baseRetCOFINS                := a.baseRetCOFINS;
    v_valorRetCOFINS               := a.valorRetCOFINS;
    v_baseRetCSLL                  := a.baseRetCSLL;
    v_valorRetCSLL                 := a.valorRetCSLL;
    v_baseRetOutros                := a.baseRetOutros;
    v_valorRetOutros               := a.valorRetOutros;
    v_baseII                       := a.baseII;
    v_valorII                      := a.valorII;
    v_baseIOF                      := a.baseIOF;
    v_valorIOF                     := a.valorIOF;
    v_baseIPI                      := a.baseIPI;
    v_valorIPI                     := a.valorIPI;
    v_basePIS                      := a.basePIS;
    v_valorPIS                     := a.valorPIS;
    v_basePISST                    := a.basePISST;
    v_valorPISST                   := a.valorPISST;
    v_baseCOFINS                   := a.baseCOFINS;
    v_valorCOFINS                  := a.valorCOFINS;
    v_baseCOFINSST                 := a.baseCOFINSST;
    v_valorCOFINSST                := a.valorCOFINSST;
    v_baseCreditoSimplesNacional   := a.baseCreditoSimplesNacional;
    v_valorCreditoSimplesNacional  := a.valorCreditoSimplesNacional;
    v_baseICMS                     := a.baseICMS;
    v_valorICMSOperacao            := a.valorICMSOperacao;
    v_valorICMSDiferido            := a.valorICMSDiferido;
    v_valorICMS                    := a.valorICMS;
    v_valorICMSDesoneracao         := a.valorICMSDesoneracao;
    v_baseICMSST                   := a.baseICMSST;
    v_valorICMSST                  := a.valorICMSST;
    v_baseICMSSTAnteriormente      := a.baseICMSSTAnteriormente;
    v_valorICMSSTAnteriormente     := a.valorICMSSTAnteriormente;
    v_valorICMSProprioSubstituto   := a.valorICMSProprioSubstituto;
    v_baseICMSEfetivo              := a.baseICMSEfetivo;
    v_valorICMSEfetivo             := a.valorICMSEfetivo;
    v_baseICMSUFDestinatario       := a.baseICMSUFDestinatario;
    v_valorICMSUFDestinatario      := a.valorICMSUFDestinatario;
    v_baseICMSUFRemetente          := a.baseICMSUFRemetente;
    v_valorICMSUFRemetente         := a.valorICMSUFRemetente;
    v_baseFCP                      := a.baseFCP;
    v_valorFCP                     := a.valorFCP;
    v_baseFCPST                    := a.baseFCPST;
    v_valorFCPST                   := a.valorFCPST;
    v_baseFCPSTAnteriormente       := a.baseFCPSTAnteriormente;
    v_valorFCPSTAnteriormente      := a.valorFCPSTAnteriormente;
    v_baseFCPUFDestinatario        := a.baseFCPUFDestinatario;
    v_valorFCPUFDestinatario       := a.valorFCPUFDestinatario;
    v_baseEstimadaImpostos         := a.baseEstimadaImpostos;
    v_valorEstimadoImpFederais     := a.valorEstimadoImpFederais;
    v_valorEstimadoImpEstaduais    := a.valorEstimadoImpEstaduais;
    v_valorEstimadoImpMunicipais   := a.valorEstimadoImpMunicipais;
    v_valorLiquidoItem             := a.valorLiquidoItem;
    v_valorDescontoCustoOpTotal    := a.valorDescontoCustoOpTotal;
    v_valorAcrescimoCustoOpTotal   := a.valorAcrescimoCustoOpTotal;
    v_precoCustoOperacao           := a.precoCustoOperacao;
    v_valorCustoOperacao           := a.valorCustoOperacao;
    v_precoCMV                     := a.precoCMV;
    v_valorCMV                     := a.valorCMV;
    v_valorAcrescimoExtempSubtotal := a.valorAcrescimoExtempSubtotal;
    v_valorAcrescimoExtempTotal    := a.valorAcrescimoExtempTotal;
    ADD_CALCULA_TOTAIS_ITEM(
      p_cab_tipoPagamentoFrete,
      a.quantidade,
      a.quantidadeConvertida,
      a.precoUnitarioBruto,
      a.acrescimoUnitarioComposicao,
      a.precoUnitario,
      a.valorDescontoItem,
      a.valorAcrescimoItem,
      a.valorFreteItem,
      a.valorSeguroItem,
      a.valorAdicFreteMarinhaMerItem,
      a.valorDespesasAduaneirasItem,
      a.valorFreteGeral,
      a.valorSeguroGeral,
      a.valorDescontoGeral,
      a.valorOutrasDespesasGeral,
      a.valorAdicFreteMarinhaMerGeral,
      a.valorDespesasAduaneirasGeral,
      a.valorDescontoPagamento,
      a.valorOutrasDespesasPagamento,
      a.valorJurosPagamento,
      a.diminuiDescontoPrUnit,
      a.somaAcrescimosPrUnit,
      a.somaFreteSeguroPrUnit,
      a.composicaoPreco,
      /* Retornos */
      v_precoUnitario,
      v_precoUnitarioConvertido,
      v_valorProdutoServico,
      v_valorFreteTotal,
      v_valorSeguroTotal,
      v_valorDescontoTotal,
      v_valorOutrasDespesasTotal,
      v_valorAdicFreteMarinMerTotal,
      v_valorDespesasAduaneirasTotal);
    v_valorAcrescimoExtempSubtotal := FUNC_ADD_CALC_EXTEMP_SUBTOTAL(
      a.quantidade,
      v_precoUnitario,
      a.quantidadeExtemporanea,
      a.acrescimoUnitarioExtemporaneo);
    v_valorAcrescimoExtempTotal := FUNC_ADD_CALC_EXTEMP_TOTAL(
      v_valorAcrescimoExtempSubtotal,
      a.valorAcrescimoExtempItem,
      a.valorAcrescimoExtempGeral);
    ADD_CALCULA_IMPOSTOS_ITEM (
      p_config_64_casasDecSaidas,
      p_config_209_filtrarGrupoEcon,
      p_config_362_calcCustoPorGrade,
      p_cab_entradaSaida,
      p_cab_devolucaoAnulacaoRetorno,
      p_cab_estabelecimento,
      0,
      p_cab_dataEntradaSaida,
      p_cab_pessoa,
      p_cab_localDestinoOperacao,
      p_cab_indicadorConsumidorFinal,
      p_cab_tipoPagamentoFrete,
      p_pess_indicadorInscricaoEstad,
      a.personalizacao,
      a.quantidade,
      v_valorProdutoServico,
      v_valorFreteTotal,
      v_valorSeguroTotal,
      v_valorDescontoTotal,
      v_valorOutrasDespesasTotal,
      v_valorAdicFreteMarinMerTotal,
      v_valorDespesasAduaneirasTotal,
      a.cfop,
      1,
      a.indicadorISSQN,
      a.aliquotaISSQN,
      v_baseISSQN,
      v_valorISSQN,
      1,
      a.retencaoIRRF,
      v_baseRetIRRF,
      v_valorRetIRRF,
      1,
      a.retencaoINSS,
      v_baseRetINSS,
      v_valorRetINSS,
      1,
      a.retencaoPIS,
      v_baseRetPIS,
      v_valorRetPIS,
      1,
      a.retencaoCOFINS,
      v_baseRetCOFINS,
      v_valorRetCOFINS,
      1,
      a.retencaoCSLL,
      v_baseRetCSLL,
      v_valorRetCSLL,
      1,
      a.retencaoOutros,
      v_baseRetOutros,
      v_valorRetOutros,
      1,
      a.aliquotaII,
      v_baseII,
      v_valorII,
      1,
      a.aliquotaIOF,
      v_baseIOF,
      v_valorIOF,
      1,
      a.aliquotaIPI,
      a.valorAliquotaIPI,
      v_baseIPI,
      v_valorIPI,
      a.valorIPIDevolucao,
      1,
      a.aliquotaPIS,
      a.valorAliquotaPIS,
      v_basePIS,
      v_valorPIS,
      1,
      a.aliquotaPISST,
      a.valorAliquotaPISST,
      v_basePISST,
      v_valorPISST,
      1,
      a.aliquotaCOFINS,
      a.valorAliquotaCOFINS,
      v_baseCOFINS,
      v_valorCOFINS,
      1,
      a.aliquotaCOFINSST,
      a.valorAliquotaCOFINSST,
      v_baseCOFINSST,
      v_valorCOFINSST,
      1,
      a.stSimplesNacional,
      a.creditoSimplesNacional,
      v_baseCreditoSimplesNacional,
      v_valorCreditoSimplesNacional,
      1,
      a.stICMS,
      a.modalidadeBaseCalcICMS,
      a.reducaoBaseICMS,
      a.aliquotaICMS,
      a.diferimentoICMS,
      v_baseICMS,
      v_valorICMSOperacao,
      v_valorICMSDiferido,
      v_valorICMS,
      v_valorICMSDesoneracao,
      1,
      a.modalidadeBaseCalcICMSST,
      a.margemValorAdicionadoST,
      a.reducaoBaseST,
      a.aliquotaICMSST,
      v_baseICMSST,
      v_valorICMSST,
      1,
      v_baseICMSSTAnteriormente,
      v_valorICMSSTAnteriormente,
      v_valorICMSProprioSubstituto,
      a.reducaoBaseICMSEfetivo,
      a.aliquotaICMSEfetivo,
      v_baseICMSEfetivo,
      v_valorICMSEfetivo,
      0,
      '  ',
      0,
      0,
      0,
      0,
      0,
      0,
      0,
      0,
      0,
      0,
      0,
      0,
      1,
      a.aliquotaICMSUFDestinatario,
      a.aliquotaICMSInterestadual,
      a.partilhaICMSInterestadual,
      v_baseICMSUFDestinatario,
      v_valorICMSUFDestinatario,
      v_baseICMSUFRemetente,
      v_valorICMSUFRemetente,
      1,
      a.aliquotaFCP,
      v_baseFCP,
      v_valorFCP,
      a.aliquotaFCPST,
      v_baseFCPST,
      v_valorFCPST,
      a.aliquotaFCPSTAnteriormente,
      v_baseFCPSTAnteriormente,
      v_valorFCPSTAnteriormente,
      a.aliquotaFCPUFDestinatario,
      v_baseFCPUFDestinatario,
      v_valorFCPUFDestinatario,
      1,
      a.aliquotaEstimadaImpFederais,
      a.aliquotaEstimadaImpEstaduais,
      a.aliquotaEstimadaImpMunicipais,
      v_baseEstimadaImpostos,
      v_valorEstimadoImpFederais,
      v_valorEstimadoImpEstaduais,
      v_valorEstimadoImpMunicipais,
      a.produto,
      a.cor,
      a.tamanho,
      a.controleEstoque,
      a.tipoProduto,
      a.precoPautaTabelado,
      /* Retornos */
      v_baseISSQN,
      v_valorISSQN,
      v_baseRetIRRF,
      v_valorRetIRRF,
      v_baseRetINSS,
      v_valorRetINSS,
      v_baseRetPIS,
      v_valorRetPIS,
      v_baseRetCOFINS,
      v_valorRetCOFINS,
      v_baseRetCSLL,
      v_valorRetCSLL,
      v_baseRetOutros,
      v_valorRetOutros,
      v_baseII,
      v_valorII,
      v_baseIOF,
      v_valorIOF,
      v_baseIPI,
      v_valorIPI,
      v_basePIS,
      v_valorPIS,
      v_basePISST,
      v_valorPISST,
      v_baseCOFINS,
      v_valorCOFINS,
      v_baseCOFINSST,
      v_valorCOFINSST,
      v_baseCreditoSimplesNacional,
      v_valorCreditoSimplesNacional,
      v_baseICMS,
      v_valorICMSOperacao,
      v_valorICMSDiferido,
      v_valorICMS,
      v_valorICMSDesoneracao,
      v_baseICMSST,
      v_valorICMSST,
      v_baseICMSSTAnteriormente,
      v_valorICMSSTAnteriormente,
      v_valorICMSProprioSubstituto,
      v_baseICMSEfetivo,
      v_valorICMSEfetivo,
      v_auxNumber,
      v_auxNumber,
      v_auxNumber,
      v_auxNumber,
      v_auxNumber,
      v_baseICMSUFDestinatario,
      v_valorICMSUFDestinatario,
      v_baseICMSUFRemetente,
      v_valorICMSUFRemetente,
      v_baseFCP,
      v_valorFCP,
      v_baseFCPST,
      v_valorFCPST,
      v_baseFCPSTAnteriormente,
      v_valorFCPSTAnteriormente,
      v_baseFCPUFDestinatario,
      v_valorFCPUFDestinatario,
      v_baseEstimadaImpostos,
      v_valorEstimadoImpFederais,
      v_valorEstimadoImpEstaduais,
      v_valorEstimadoImpMunicipais);
    v_valorBasePagamento := FUNC_ADD_CALC_BASE_PAGAMENTO (
      p_cab_origemDocumento,
      0, -- p_cab_nfFornecedor
      p_cab_tipoPagamentoFrete,
      a.geraFinanceiro,
      v_valorProdutoServico,
      a.valorDescontoPagamento,
      a.valorOutrasDespesasPagamento,
      a.valorJurosPagamento,
      v_valorFreteTotal,
      v_valorSeguroTotal,
      v_valorDescontoTotal,
      v_valorOutrasDespesasTotal,
      a.valorIPIDevolucao,
      a.retidoISSQN,
      v_valorISSQN,
      v_valorRetIRRF,
      v_valorRetINSS,
      v_valorRetPIS,
      v_valorRetCOFINS,
      v_valorRetCSLL,
      v_valorRetOutros,
      v_valorII,
      v_valorIOF,
      v_valorIPI,
      v_valorICMSST,
      0, -- p_item_valorICMSSTEscrit
      0, -- p_item_somarICMSST
      v_valorAcrescimoExtempTotal,
      a.modDoc_geraFinanceiro);
    v_valorLiquidoItem := FUNC_ADD_CALC_VALOR_LIQUIDO (
      0, -- p_cab_nfFornecedor
      p_cab_tipoPagamentoFrete,
      v_valorProdutoServico,
      v_valorFreteTotal,
      v_valorSeguroTotal,
      v_valorDescontoTotal,
      v_valorOutrasDespesasTotal,
      a.valorIPIDevolucao,
      v_valorII,
      v_valorIOF,
      v_valorIPI,
      v_valorICMSST,
      0, -- p_item_valorICMSSTEscrit
      0 -- p_item_somarICMSST
      );
    ADD_CALCULA_CUSTO_CMV (
      p_cab_atualizaCustoMedio,
      p_cab_estabelecimento,
      0,
      a.modeloDocumento,
      a.quantidade,
      v_valorII,
      v_valorIOF,
      v_valorIPI,
      a.valorIPIDevolucao,
      v_valorPIS,
      v_valorPISST,
      v_valorCOFINS,
      v_valorCOFINSST,
      v_valorCreditoSimplesNacional,
      v_valorICMS,
      v_valorICMSST,
      0,
      v_valorLiquidoItem,
      a.valorDescontoCustoOpItem,
      a.valorDescontoCustoOpGeral,
      a.valorAcrescimoCustoOpItem,
      a.valorAcrescimoCustoOpGeral,
      v_valorAcrescimoExtempTotal,
      /* Retornos */
      v_valorDescontoCustoOpTotal,
      v_valorAcrescimoCustoOpTotal,
      v_precoCustoOperacao,
      v_valorCustoOperacao,
      v_precoCMV,
      v_valorCMV);
    UPDATE MOPREDOCUMXITENS SET
      precoUnitario                 = v_precoUnitario,
      precoUnitarioConvertido       = v_precoUnitarioConvertido,
      valorProdutoServico           = v_valorProdutoServico,
      valorBasePagamento            = v_valorBasePagamento,
      valorFreteTotal               = v_valorFreteTotal,
      valorSeguroTotal              = v_valorSeguroTotal,
      valorDescontoTotal            = v_valorDescontoTotal,
      valorOutrasDespesasTotal      = v_valorOutrasDespesasTotal,
      valorAdicFreteMarinhaMerTotal = v_valorAdicFreteMarinMerTotal,
      valorDespesasAduaneirasTotal  = v_valorDespesasAduaneirasTotal,
      baseISSQN                     = v_baseISSQN,
      valorISSQN                    = v_valorISSQN,
      baseRetIRRF                   = v_baseRetIRRF,
      valorRetIRRF                  = v_valorRetIRRF,
      baseRetINSS                   = v_baseRetINSS,
      valorRetINSS                  = v_valorRetINSS,
      baseRetPIS                    = v_baseRetPIS,
      valorRetPIS                   = v_valorRetPIS,
      baseRetCOFINS                 = v_baseRetCOFINS,
      valorRetCOFINS                = v_valorRetCOFINS,
      baseRetCSLL                   = v_baseRetCSLL,
      valorRetCSLL                  = v_valorRetCSLL,
      baseRetOutros                 = v_baseRetOutros,
      valorRetOutros                = v_valorRetOutros,
      baseII                        = v_baseII,
      valorII                       = v_valorII,
      baseIOF                       = v_baseIOF,
      valorIOF                      = v_valorIOF,
      baseIPI                       = v_baseIPI,
      valorIPI                      = v_valorIPI,
      basePIS                       = v_basePIS,
      valorPIS                      = v_valorPIS,
      basePISST                     = v_basePISST,
      valorPISST                    = v_valorPISST,
      baseCOFINS                    = v_baseCOFINS,
      valorCOFINS                   = v_valorCOFINS,
      baseCOFINSST                  = v_baseCOFINSST,
      valorCOFINSST                 = v_valorCOFINSST,
      baseCreditoSimplesNacional    = v_baseCreditoSimplesNacional,
      valorCreditoSimplesNacional   = v_valorCreditoSimplesNacional,
      baseICMS                      = v_baseICMS,
      valorICMSOperacao             = v_valorICMSOperacao,
      valorICMSDiferido             = v_valorICMSDiferido,
      valorICMS                     = v_valorICMS,
      valorICMSDesoneracao          = v_valorICMSDesoneracao,
      baseICMSST                    = v_baseICMSST,
      valorICMSST                   = v_valorICMSST,
      baseICMSSTAnteriormente       = v_baseICMSSTAnteriormente,
      valorICMSSTAnteriormente      = v_valorICMSSTAnteriormente,
      valorICMSProprioSubstituto    = v_valorICMSProprioSubstituto,
      baseICMSEfetivo               = v_baseICMSEfetivo,
      valorICMSEfetivo              = v_valorICMSEfetivo,
      baseICMSUFDestinatario        = v_baseICMSUFDestinatario,
      valorICMSUFDestinatario       = v_valorICMSUFDestinatario,
      baseICMSUFRemetente           = v_baseICMSUFRemetente,
      valorICMSUFRemetente          = v_valorICMSUFRemetente,
      baseFCP                       = v_baseFCP,
      valorFCP                      = v_valorFCP,
      baseFCPST                     = v_baseFCPST,
      valorFCPST                    = v_valorFCPST,
      baseFCPSTAnteriormente        = v_baseFCPSTAnteriormente,
      valorFCPSTAnteriormente       = v_valorFCPSTAnteriormente,
      baseFCPUFDestinatario         = v_baseFCPUFDestinatario,
      valorFCPUFDestinatario        = v_valorFCPUFDestinatario,
      baseEstimadaImpostos          = v_baseEstimadaImpostos,
      valorEstimadoImpFederais      = v_valorEstimadoImpFederais,
      valorEstimadoImpEstaduais     = v_valorEstimadoImpEstaduais,
      valorEstimadoImpMunicipais    = v_valorEstimadoImpMunicipais,
      valorLiquidoItem              = v_valorLiquidoItem,
      valorDescontoCustoOpTotal     = v_valorDescontoCustoOpTotal,
      valorAcrescimoCustoOpTotal    = v_valorAcrescimoCustoOpTotal,
      precoCustoOperacao            = v_precoCustoOperacao,
      valorCustoOperacao            = v_valorCustoOperacao,
      precoCMV                      = v_precoCMV,
      valorCMV                      = v_valorCMV,
      valorAcrescimoExtempSubtotal  = v_valorAcrescimoExtempSubtotal,
      valorAcrescimoExtempTotal     = v_valorAcrescimoExtempTotal
    WHERE idItemPreDocumento        = a.idItemPreDocumento;
    IF a.tipoProduto = '09' THEN
      r_cab_valorServicos            := r_cab_valorServicos + v_valorProdutoServico;
    ELSE
      r_cab_valorProdutos            := r_cab_valorProdutos + v_valorProdutoServico;
    END IF;
    r_cab_valorBasePagamento       := r_cab_valorBasePagamento + v_valorBasePagamento;
    IF a.usarPrecoAVista = 1 AND a.geraFinanceiro = 1 THEN
      r_cab_valorAVistaMinimo        := r_cab_valorAVistaMinimo + v_valorProdutoServico + a.valorDescontoPagamento - a.valorOutrasDespesasPagamento - a.valorJurosPagamento - v_valorDescontoTotal + v_valorOutrasDespesasTotal;
    END IF;
    r_cab_valorFreteTotal          := r_cab_valorFreteTotal + v_valorFreteTotal;
    r_cab_valorSeguroTotal         := r_cab_valorSeguroTotal + v_valorSeguroTotal;
    r_cab_valorDescontoTotal       := r_cab_valorDescontoTotal + v_valorDescontoTotal;
    r_cab_valorOutrasDespesasTotal := r_cab_valorOutrasDespesasTotal + v_valorOutrasDespesasTotal;
    r_cab_valorAdicFreteMarinTotal := r_cab_valorAdicFreteMarinTotal + v_valorAdicFreteMarinMerTotal;
    r_cab_valorDespesasAduanTotal  := r_cab_valorDespesasAduanTotal + v_valorDespesasAduaneirasTotal;
    r_cab_valorLiquidoItem         := r_cab_valorLiquidoItem + v_valorLiquidoItem;
    r_cab_valorDescCustoOpTotal    := r_cab_valorDescCustoOpTotal + v_valorDescontoCustoOpTotal;
    r_cab_valorAcrescCustoOpTotal  := r_cab_valorAcrescCustoOpTotal + v_valorAcrescimoCustoOpTotal;
    r_cab_valorCustoOperacao       := r_cab_valorCustoOperacao + v_valorCustoOperacao;
    r_cab_valorCMV                 := r_cab_valorCMV + v_valorCMV;
    r_cab_valorAcrescExtempTotal   := r_cab_valorAcrescExtempTotal + v_valorAcrescimoExtempTotal;
  END LOOP;
END ADD_PRE_DOC_CALC_IMP_ITENS;

/

create or replace PROCEDURE ADD_DOC_FISC_CALC_IMP_ITENS (
  p_config_64_casasDecSaidas     IN CHAR,
  p_config_209_filtrarGrupoEcon  IN NUMBER,
  p_config_362_calcCustoPorGrade IN NUMBER,
  p_cab_idDocumentoFiscal        IN NUMBER,
  p_cab_origemDocumento          IN NUMBER,
  p_cab_entradaSaida             IN CHAR,
  p_cab_devolucaoAnulacaoRetorno IN NUMBER,
  p_cab_atualizaCustoMedio       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,
  /* Retornos */
  r_cab_valorProdutos            OUT NUMBER,
  r_cab_valorServicos            OUT NUMBER,
  r_cab_valorBasePagamento       OUT NUMBER,
  r_cab_valorAVistaMinimo        OUT NUMBER,
  r_cab_valorFreteTotal          OUT NUMBER,
  r_cab_valorSeguroTotal         OUT NUMBER,
  r_cab_valorDescontoTotal       OUT NUMBER,
  r_cab_valorOutrasDespesasTotal OUT NUMBER,
  r_cab_valorAdicFreteMarinTotal OUT NUMBER,
  r_cab_valorDespesasAduanTotal  OUT NUMBER,
  r_cab_valorLiquidoItem         OUT NUMBER,
  r_cab_valorDescCustoOpTotal    OUT NUMBER,
  r_cab_valorAcrescCustoOpTotal  OUT NUMBER,
  r_cab_valorCustoOperacao       OUT NUMBER,
  r_cab_valorCMV                 OUT NUMBER,
  r_cab_valorAcrescExtempTotal   OUT NUMBER)
IS
  v_auxNumber                    NUMBER;
  v_precoUnitario                NUMBER;
  v_precoUnitarioConvertido      NUMBER;
  v_valorProdutoServico          NUMBER;
  v_valorBasePagamento           NUMBER;
  v_valorFreteTotal              NUMBER;
  v_valorSeguroTotal             NUMBER;
  v_valorDescontoTotal           NUMBER;
  v_valorOutrasDespesasTotal     NUMBER;
  v_valorAdicFreteMarinMerTotal  NUMBER;
  v_valorDespesasAduaneirasTotal NUMBER;
  v_baseISSQN                    NUMBER;
  v_valorISSQN                   NUMBER;
  v_baseRetIRRF                  NUMBER;
  v_valorRetIRRF                 NUMBER;
  v_baseRetINSS                  NUMBER;
  v_valorRetINSS                 NUMBER;
  v_baseRetPIS                   NUMBER;
  v_valorRetPIS                  NUMBER;
  v_baseRetCOFINS                NUMBER;
  v_valorRetCOFINS               NUMBER;
  v_baseRetCSLL                  NUMBER;
  v_valorRetCSLL                 NUMBER;
  v_baseRetOutros                NUMBER;
  v_valorRetOutros               NUMBER;
  v_baseII                       NUMBER;
  v_valorII                      NUMBER;
  v_baseIOF                      NUMBER;
  v_valorIOF                     NUMBER;
  v_baseIPI                      NUMBER;
  v_valorIPI                     NUMBER;
  v_basePIS                      NUMBER;
  v_valorPIS                     NUMBER;
  v_basePISST                    NUMBER;
  v_valorPISST                   NUMBER;
  v_baseCOFINS                   NUMBER;
  v_valorCOFINS                  NUMBER;
  v_baseCOFINSST                 NUMBER;
  v_valorCOFINSST                NUMBER;
  v_baseCreditoSimplesNacional   NUMBER;
  v_valorCreditoSimplesNacional  NUMBER;
  v_baseICMS                     NUMBER;
  v_valorICMSOperacao            NUMBER;
  v_valorICMSDiferido            NUMBER;
  v_valorICMS                    NUMBER;
  v_valorICMSDesoneracao         NUMBER;
  v_baseICMSST                   NUMBER;
  v_valorICMSST                  NUMBER;
  v_baseICMSSTAnteriormente      NUMBER;
  v_valorICMSSTAnteriormente     NUMBER;
  v_valorICMSProprioSubstituto   NUMBER;
  v_baseICMSEfetivo              NUMBER;
  v_valorICMSEfetivo             NUMBER;
  v_baseICMSEscrituracao         NUMBER;
  v_valorICMSEscrituracao        NUMBER;
  v_valorICMSDesonEscrituracao   NUMBER;
  v_baseICMSSTEscrituracao       NUMBER;
  v_valorICMSSTEscrituracao      NUMBER;
  v_baseICMSUFDestinatario       NUMBER;
  v_valorICMSUFDestinatario      NUMBER;
  v_baseICMSUFRemetente          NUMBER;
  v_valorICMSUFRemetente         NUMBER;
  v_baseFCP                      NUMBER;
  v_valorFCP                     NUMBER;
  v_baseFCPST                    NUMBER;
  v_valorFCPST                   NUMBER;
  v_baseFCPSTAnteriormente       NUMBER;
  v_valorFCPSTAnteriormente      NUMBER;
  v_baseFCPUFDestinatario        NUMBER;
  v_valorFCPUFDestinatario       NUMBER;
  v_baseEstimadaImpostos         NUMBER;
  v_valorEstimadoImpFederais     NUMBER;
  v_valorEstimadoImpEstaduais    NUMBER;
  v_valorEstimadoImpMunicipais   NUMBER;
  v_valorLiquidoItem             NUMBER;
  v_valorDescontoCustoOpTotal    NUMBER;
  v_valorAcrescimoCustoOpTotal   NUMBER;
  v_precoCustoOperacao           NUMBER;
  v_valorCustoOperacao           NUMBER;
  v_precoCMV                     NUMBER;
  v_valorCMV                     NUMBER;
  v_valorAcrescimoExtempSubtotal NUMBER;
  v_valorAcrescimoExtempTotal    NUMBER;
BEGIN  
  r_cab_valorProdutos            := 0;
  r_cab_valorServicos            := 0;
  r_cab_valorBasePagamento       := 0;
  r_cab_valorAVistaMinimo        := 0;
  r_cab_valorFreteTotal          := 0;
  r_cab_valorSeguroTotal         := 0;
  r_cab_valorDescontoTotal       := 0;
  r_cab_valorOutrasDespesasTotal := 0;
  r_cab_valorAdicFreteMarinTotal := 0;
  r_cab_valorDespesasAduanTotal  := 0;
  r_cab_valorLiquidoItem         := 0;
  r_cab_valorDescCustoOpTotal    := 0;
  r_cab_valorAcrescCustoOpTotal  := 0;
  r_cab_valorCustoOperacao       := 0;
  r_cab_valorCMV                 := 0;
  r_cab_valorAcrescExtempTotal   := 0;
  FOR a IN (
    SELECT
      a.*,
      gradProd.produto,
      gradProd.cor,
      gradProd.tamanho,
      prod.controleEstoque,
      prod.tipoProduto,
      prod.precoPautaTabelado,
      modDoc.geraFinanceiro modDoc_geraFinanceiro,
      modDoc.diminuiDescontoPrUnit,
      modDoc.somaAcrescimosPrUnit,
      modDoc.somaFreteSeguroPrUnit,
      CASE
        WHEN EXISTS (
          SELECT 1
          FROM CAPRODUTOXCOMPOSICOESPREC compPrec
          WHERE compPrec.produto = gradProd.produto
          AND compPrec.ativo = 1)
        THEN 1
        ELSE 0
      END composicaoPreco
    FROM MODOCFISCALXITENS a
    JOIN CAGRADESPRODUTO gradProd
    ON gradProd.gradeProduto = a.gradeProduto
    JOIN CAPRODUTOS prod
    ON prod.produto = gradProd.produto
    JOIN PAMODELOSDOCUMENTO modDoc
    ON modDoc.modeloDocumento = a.modeloDocumento
    WHERE a.idDocumentoFiscal = p_cab_idDocumentoFiscal
    AND a.cancelado = 0
    ORDER BY a.sequencia)
  LOOP
    v_precoUnitario                := a.precoUnitario;
    v_precoUnitarioConvertido      := a.precoUnitarioConvertido;
    v_valorProdutoServico          := a.valorProdutoServico;
    v_valorBasePagamento           := a.valorBasePagamento;
    v_valorFreteTotal              := a.valorFreteTotal;
    v_valorSeguroTotal             := a.valorSeguroTotal;
    v_valorDescontoTotal           := a.valorDescontoTotal;
    v_valorOutrasDespesasTotal     := a.valorOutrasDespesasTotal;
    v_valorAdicFreteMarinMerTotal  := a.valorAdicFreteMarinhaMerTotal;
    v_valorDespesasAduaneirasTotal := a.valorDespesasAduaneirasTotal;
    v_baseISSQN                    := a.baseISSQN;
    v_valorISSQN                   := a.valorISSQN;
    v_baseRetIRRF                  := a.baseRetIRRF;
    v_valorRetIRRF                 := a.valorRetIRRF;
    v_baseRetINSS                  := a.baseRetINSS;
    v_valorRetINSS                 := a.valorRetINSS;
    v_baseRetPIS                   := a.baseRetPIS;
    v_valorRetPIS                  := a.valorRetPIS;
    v_baseRetCOFINS                := a.baseRetCOFINS;
    v_valorRetCOFINS               := a.valorRetCOFINS;
    v_baseRetCSLL                  := a.baseRetCSLL;
    v_valorRetCSLL                 := a.valorRetCSLL;
    v_baseRetOutros                := a.baseRetOutros;
    v_valorRetOutros               := a.valorRetOutros;
    v_baseII                       := a.baseII;
    v_valorII                      := a.valorII;
    v_baseIOF                      := a.baseIOF;
    v_valorIOF                     := a.valorIOF;
    v_baseIPI                      := a.baseIPI;
    v_valorIPI                     := a.valorIPI;
    v_basePIS                      := a.basePIS;
    v_valorPIS                     := a.valorPIS;
    v_basePISST                    := a.basePISST;
    v_valorPISST                   := a.valorPISST;
    v_baseCOFINS                   := a.baseCOFINS;
    v_valorCOFINS                  := a.valorCOFINS;
    v_baseCOFINSST                 := a.baseCOFINSST;
    v_valorCOFINSST                := a.valorCOFINSST;
    v_baseCreditoSimplesNacional   := a.baseCreditoSimplesNacional;
    v_valorCreditoSimplesNacional  := a.valorCreditoSimplesNacional;
    v_baseICMS                     := a.baseICMS;
    v_valorICMSOperacao            := a.valorICMSOperacao;
    v_valorICMSDiferido            := a.valorICMSDiferido;
    v_valorICMS                    := a.valorICMS;
    v_valorICMSDesoneracao         := a.valorICMSDesoneracao;
    v_baseICMSST                   := a.baseICMSST;
    v_valorICMSST                  := a.valorICMSST;
    v_baseICMSSTAnteriormente      := a.baseICMSSTAnteriormente;
    v_valorICMSSTAnteriormente     := a.valorICMSSTAnteriormente;
    v_valorICMSProprioSubstituto   := a.valorICMSProprioSubstituto;
    v_baseICMSEfetivo              := a.baseICMSEfetivo;
    v_valorICMSEfetivo             := a.valorICMSEfetivo;
    v_baseICMSEscrituracao         := a.baseICMSEscrituracao;
    v_valorICMSEscrituracao        := a.valorICMSEscrituracao;
    v_valorICMSDesonEscrituracao   := a.valorICMSDesonEscrituracao;
    v_baseICMSSTEscrituracao       := a.baseICMSSTEscrituracao;
    v_valorICMSSTEscrituracao      := a.valorICMSSTEscrituracao;
    v_baseICMSUFDestinatario       := a.baseICMSUFDestinatario;
    v_valorICMSUFDestinatario      := a.valorICMSUFDestinatario;
    v_baseICMSUFRemetente          := a.baseICMSUFRemetente;
    v_valorICMSUFRemetente         := a.valorICMSUFRemetente;
    v_baseFCP                      := a.baseFCP;
    v_valorFCP                     := a.valorFCP;
    v_baseFCPST                    := a.baseFCPST;
    v_valorFCPST                   := a.valorFCPST;
    v_baseFCPSTAnteriormente       := a.baseFCPSTAnteriormente;
    v_valorFCPSTAnteriormente      := a.valorFCPSTAnteriormente;
    v_baseFCPUFDestinatario        := a.baseFCPUFDestinatario;
    v_valorFCPUFDestinatario       := a.valorFCPUFDestinatario;
    v_baseEstimadaImpostos         := a.baseEstimadaImpostos;
    v_valorEstimadoImpFederais     := a.valorEstimadoImpFederais;
    v_valorEstimadoImpEstaduais    := a.valorEstimadoImpEstaduais;
    v_valorEstimadoImpMunicipais   := a.valorEstimadoImpMunicipais;
    v_valorLiquidoItem             := a.valorLiquidoItem;
    v_valorDescontoCustoOpTotal    := a.valorDescontoCustoOpTotal;
    v_valorAcrescimoCustoOpTotal   := a.valorAcrescimoCustoOpTotal;
    v_precoCustoOperacao           := a.precoCustoOperacao;
    v_valorCustoOperacao           := a.valorCustoOperacao;
    v_precoCMV                     := a.precoCMV;
    v_valorCMV                     := a.valorCMV;
    v_valorAcrescimoExtempSubtotal := a.valorAcrescimoExtempSubtotal;
    v_valorAcrescimoExtempTotal    := a.valorAcrescimoExtempTotal;
    ADD_CALCULA_TOTAIS_ITEM(
      p_cab_tipoPagamentoFrete,
      a.quantidade,
      a.quantidadeConvertida,
      a.precoUnitarioBruto,
      a.acrescimoUnitarioComposicao,
      a.precoUnitario,
      a.valorDescontoItem,
      a.valorAcrescimoItem,
      a.valorFreteItem,
      a.valorSeguroItem,
      a.valorAdicFreteMarinhaMerItem,
      a.valorDespesasAduaneirasItem,
      a.valorFreteGeral,
      a.valorSeguroGeral,
      a.valorDescontoGeral,
      a.valorOutrasDespesasGeral,
      a.valorAdicFreteMarinhaMerGeral,
      a.valorDespesasAduaneirasGeral,
      a.valorDescontoPagamento,
      a.valorOutrasDespesasPagamento,
      a.valorJurosPagamento,
      a.diminuiDescontoPrUnit,
      a.somaAcrescimosPrUnit,
      a.somaFreteSeguroPrUnit,
      a.composicaoPreco,
      /* Retornos */
      v_precoUnitario,
      v_precoUnitarioConvertido,
      v_valorProdutoServico,
      v_valorFreteTotal,
      v_valorSeguroTotal,
      v_valorDescontoTotal,
      v_valorOutrasDespesasTotal,
      v_valorAdicFreteMarinMerTotal,
      v_valorDespesasAduaneirasTotal);
    v_valorAcrescimoExtempSubtotal := FUNC_ADD_CALC_EXTEMP_SUBTOTAL(
      a.quantidade,
      v_precoUnitario,
      a.quantidadeExtemporanea,
      a.acrescimoUnitarioExtemporaneo);
    v_valorAcrescimoExtempTotal := FUNC_ADD_CALC_EXTEMP_TOTAL(
      v_valorAcrescimoExtempSubtotal,
      a.valorAcrescimoExtempItem,
      a.valorAcrescimoExtempGeral);
    ADD_CALCULA_IMPOSTOS_ITEM (
      p_config_64_casasDecSaidas,
      p_config_209_filtrarGrupoEcon,
      p_config_362_calcCustoPorGrade,
      p_cab_entradaSaida,
      p_cab_devolucaoAnulacaoRetorno,
      p_cab_estabelecimento,
      p_cab_nfFornecedor,
      p_cab_dataEntradaSaida,
      p_cab_pessoa,
      p_cab_localDestinoOperacao,
      p_cab_indicadorConsumidorFinal,
      p_cab_tipoPagamentoFrete,
      p_pess_indicadorInscricaoEstad,
      a.personalizacao,
      a.quantidade,
      v_valorProdutoServico,
      v_valorFreteTotal,
      v_valorSeguroTotal,
      v_valorDescontoTotal,
      v_valorOutrasDespesasTotal,
      v_valorAdicFreteMarinMerTotal,
      v_valorDespesasAduaneirasTotal,
      a.cfop,
      1,
      a.indicadorISSQN,
      a.aliquotaISSQN,
      v_baseISSQN,
      v_valorISSQN,
      1,
      a.retencaoIRRF,
      v_baseRetIRRF,
      v_valorRetIRRF,
      1,
      a.retencaoINSS,
      v_baseRetINSS,
      v_valorRetINSS,
      1,
      a.retencaoPIS,
      v_baseRetPIS,
      v_valorRetPIS,
      1,
      a.retencaoCOFINS,
      v_baseRetCOFINS,
      v_valorRetCOFINS,
      1,
      a.retencaoCSLL,
      v_baseRetCSLL,
      v_valorRetCSLL,
      1,
      a.retencaoOutros,
      v_baseRetOutros,
      v_valorRetOutros,
      1,
      a.aliquotaII,
      v_baseII,
      v_valorII,
      1,
      a.aliquotaIOF,
      v_baseIOF,
      v_valorIOF,
      1,
      a.aliquotaIPI,
      a.valorAliquotaIPI,
      v_baseIPI,
      v_valorIPI,
      a.valorIPIDevolucao,
      1,
      a.aliquotaPIS,
      a.valorAliquotaPIS,
      v_basePIS,
      v_valorPIS,
      1,
      a.aliquotaPISST,
      a.valorAliquotaPISST,
      v_basePISST,
      v_valorPISST,
      1,
      a.aliquotaCOFINS,
      a.valorAliquotaCOFINS,
      v_baseCOFINS,
      v_valorCOFINS,
      1,
      a.aliquotaCOFINSST,
      a.valorAliquotaCOFINSST,
      v_baseCOFINSST,
      v_valorCOFINSST,
      1,
      a.stSimplesNacional,
      a.creditoSimplesNacional,
      v_baseCreditoSimplesNacional,
      v_valorCreditoSimplesNacional,
      1,
      a.stICMS,
      a.modalidadeBaseCalcICMS,
      a.reducaoBaseICMS,
      a.aliquotaICMS,
      a.diferimentoICMS,
      v_baseICMS,
      v_valorICMSOperacao,
      v_valorICMSDiferido,
      v_valorICMS,
      v_valorICMSDesoneracao,
      1,
      a.modalidadeBaseCalcICMSST,
      a.margemValorAdicionadoST,
      a.reducaoBaseST,
      a.aliquotaICMSST,
      v_baseICMSST,
      v_valorICMSST,
      1,
      v_baseICMSSTAnteriormente,
      v_valorICMSSTAnteriormente,
      v_valorICMSProprioSubstituto,
      a.reducaoBaseICMSEfetivo,
      a.aliquotaICMSEfetivo,
      v_baseICMSEfetivo,
      v_valorICMSEfetivo,
      1,
      a.stICMSEscrituracao,
      a.reducaoBaseICMSEscrituracao,
      a.aliquotaICMSEscrituracao,
      a.diferimentoICMSEscrituracao,
      v_baseICMSEscrituracao,
      v_valorICMSEscrituracao,
      v_valorICMSDesonEscrituracao,
      1,
      a.margemValorAdicSTEscrituracao,
      a.reducaoBaseSTEscrituracao,
      a.aliquotaICMSSTEscrituracao,
      v_baseICMSSTEscrituracao,
      v_valorICMSSTEscrituracao,
      1,
      a.aliquotaICMSUFDestinatario,
      a.aliquotaICMSInterestadual,
      a.partilhaICMSInterestadual,
      v_baseICMSUFDestinatario,
      v_valorICMSUFDestinatario,
      v_baseICMSUFRemetente,
      v_valorICMSUFRemetente,
      1,
      a.aliquotaFCP,
      v_baseFCP,
      v_valorFCP,
      a.aliquotaFCPST,
      v_baseFCPST,
      v_valorFCPST,
      a.aliquotaFCPSTAnteriormente,
      v_baseFCPSTAnteriormente,
      v_valorFCPSTAnteriormente,
      a.aliquotaFCPUFDestinatario,
      v_baseFCPUFDestinatario,
      v_valorFCPUFDestinatario,
      1,
      a.aliquotaEstimadaImpFederais,
      a.aliquotaEstimadaImpEstaduais,
      a.aliquotaEstimadaImpMunicipais,
      v_baseEstimadaImpostos,
      v_valorEstimadoImpFederais,
      v_valorEstimadoImpEstaduais,
      v_valorEstimadoImpMunicipais,
      a.produto,
      a.cor,
      a.tamanho,
      a.controleEstoque,
      a.tipoProduto,
      a.precoPautaTabelado,
      /* Retornos */
      v_baseISSQN,
      v_valorISSQN,
      v_baseRetIRRF,
      v_valorRetIRRF,
      v_baseRetINSS,
      v_valorRetINSS,
      v_baseRetPIS,
      v_valorRetPIS,
      v_baseRetCOFINS,
      v_valorRetCOFINS,
      v_baseRetCSLL,
      v_valorRetCSLL,
      v_baseRetOutros,
      v_valorRetOutros,
      v_baseII,
      v_valorII,
      v_baseIOF,
      v_valorIOF,
      v_baseIPI,
      v_valorIPI,
      v_basePIS,
      v_valorPIS,
      v_basePISST,
      v_valorPISST,
      v_baseCOFINS,
      v_valorCOFINS,
      v_baseCOFINSST,
      v_valorCOFINSST,
      v_baseCreditoSimplesNacional,
      v_valorCreditoSimplesNacional,
      v_baseICMS,
      v_valorICMSOperacao,
      v_valorICMSDiferido,
      v_valorICMS,
      v_valorICMSDesoneracao,
      v_baseICMSST,
      v_valorICMSST,
      v_baseICMSSTAnteriormente,
      v_valorICMSSTAnteriormente,
      v_valorICMSProprioSubstituto,
      v_baseICMSEfetivo,
      v_valorICMSEfetivo,
      v_baseICMSEscrituracao,
      v_valorICMSEscrituracao,
      v_valorICMSDesonEscrituracao,
      v_baseICMSSTEscrituracao,
      v_valorICMSSTEscrituracao,
      v_baseICMSUFDestinatario,
      v_valorICMSUFDestinatario,
      v_baseICMSUFRemetente,
      v_valorICMSUFRemetente,
      v_baseFCP,
      v_valorFCP,
      v_baseFCPST,
      v_valorFCPST,
      v_baseFCPSTAnteriormente,
      v_valorFCPSTAnteriormente,
      v_baseFCPUFDestinatario,
      v_valorFCPUFDestinatario,
      v_baseEstimadaImpostos,
      v_valorEstimadoImpFederais,
      v_valorEstimadoImpEstaduais,
      v_valorEstimadoImpMunicipais);    
    v_valorBasePagamento := FUNC_ADD_CALC_BASE_PAGAMENTO (
      p_cab_origemDocumento,
      p_cab_nfFornecedor,
      p_cab_tipoPagamentoFrete,
      a.geraFinanceiro,
      v_valorProdutoServico,
      a.valorDescontoPagamento,
      a.valorOutrasDespesasPagamento,
      a.valorJurosPagamento,
      v_valorFreteTotal,
      v_valorSeguroTotal,
      v_valorDescontoTotal,
      v_valorOutrasDespesasTotal,
      a.valorIPIDevolucao,
      a.retidoISSQN,
      v_valorISSQN,
      v_valorRetIRRF,
      v_valorRetINSS,
      v_valorRetPIS,
      v_valorRetCOFINS,
      v_valorRetCSLL,
      v_valorRetOutros,
      v_valorII,
      v_valorIOF,
      v_valorIPI,
      v_valorICMSST,
      v_valorICMSSTEscrituracao,
      a.somarICMSST,
      v_valorAcrescimoExtempTotal,
      a.modDoc_geraFinanceiro);
    v_valorLiquidoItem := FUNC_ADD_CALC_VALOR_LIQUIDO (
      p_cab_nfFornecedor,
      p_cab_tipoPagamentoFrete,
      v_valorProdutoServico,
      v_valorFreteTotal,
      v_valorSeguroTotal,
      v_valorDescontoTotal,
      v_valorOutrasDespesasTotal,
      a.valorIPIDevolucao,
      v_valorII,
      v_valorIOF,
      v_valorIPI,
      v_valorICMSST,
      v_valorICMSSTEscrituracao,
      a.somarICMSST);
    ADD_CALCULA_CUSTO_CMV (
      p_cab_atualizaCustoMedio,
      p_cab_estabelecimento,
      p_cab_nfFornecedor,
      a.modeloDocumento,
      a.quantidade,
      v_valorII,
      v_valorIOF,
      v_valorIPI,
      a.valorIPIDevolucao,
      v_valorPIS,
      v_valorPISST,
      v_valorCOFINS,
      v_valorCOFINSST,
      v_valorCreditoSimplesNacional,
      v_valorICMS,
      v_valorICMSST,
      v_valorICMSSTEscrituracao,
      v_valorLiquidoItem,
      a.valorDescontoCustoOpItem,
      a.valorDescontoCustoOpGeral,
      a.valorAcrescimoCustoOpItem,
      a.valorAcrescimoCustoOpGeral,
      v_valorAcrescimoExtempTotal,
      /* Retornos */
      v_valorDescontoCustoOpTotal,
      v_valorAcrescimoCustoOpTotal,
      v_precoCustoOperacao,
      v_valorCustoOperacao,
      v_precoCMV,
      v_valorCMV);
    UPDATE MODOCFISCALXITENS SET
      precoUnitario                 = v_precoUnitario,
      precoUnitarioConvertido       = v_precoUnitarioConvertido,
      valorProdutoServico           = v_valorProdutoServico,
      valorBasePagamento            = v_valorBasePagamento,
      valorFreteTotal               = v_valorFreteTotal,
      valorSeguroTotal              = v_valorSeguroTotal,
      valorDescontoTotal            = v_valorDescontoTotal,
      valorOutrasDespesasTotal      = v_valorOutrasDespesasTotal,
      valorAdicFreteMarinhaMerTotal = v_valorAdicFreteMarinMerTotal,
      valorDespesasAduaneirasTotal  = v_valorDespesasAduaneirasTotal,
      baseISSQN                     = v_baseISSQN,
      valorISSQN                    = v_valorISSQN,
      baseRetIRRF                   = v_baseRetIRRF,
      valorRetIRRF                  = v_valorRetIRRF,
      baseRetINSS                   = v_baseRetINSS,
      valorRetINSS                  = v_valorRetINSS,
      baseRetPIS                    = v_baseRetPIS,
      valorRetPIS                   = v_valorRetPIS,
      baseRetCOFINS                 = v_baseRetCOFINS,
      valorRetCOFINS                = v_valorRetCOFINS,
      baseRetCSLL                   = v_baseRetCSLL,
      valorRetCSLL                  = v_valorRetCSLL,
      baseRetOutros                 = v_baseRetOutros,
      valorRetOutros                = v_valorRetOutros,
      baseII                        = v_baseII,
      valorII                       = v_valorII,
      baseIOF                       = v_baseIOF,
      valorIOF                      = v_valorIOF,
      baseIPI                       = v_baseIPI,
      valorIPI                      = v_valorIPI,
      basePIS                       = v_basePIS,
      valorPIS                      = v_valorPIS,
      basePISST                     = v_basePISST,
      valorPISST                    = v_valorPISST,
      baseCOFINS                    = v_baseCOFINS,
      valorCOFINS                   = v_valorCOFINS,
      baseCOFINSST                  = v_baseCOFINSST,
      valorCOFINSST                 = v_valorCOFINSST,
      baseCreditoSimplesNacional    = v_baseCreditoSimplesNacional,
      valorCreditoSimplesNacional   = v_valorCreditoSimplesNacional,
      baseICMS                      = v_baseICMS,
      valorICMSOperacao             = v_valorICMSOperacao,
      valorICMSDiferido             = v_valorICMSDiferido,
      valorICMS                     = v_valorICMS,
      valorICMSDesoneracao          = v_valorICMSDesoneracao,
      baseICMSST                    = v_baseICMSST,
      valorICMSST                   = v_valorICMSST,
      baseICMSSTAnteriormente       = v_baseICMSSTAnteriormente,
      valorICMSSTAnteriormente      = v_valorICMSSTAnteriormente,
      valorICMSProprioSubstituto    = v_valorICMSProprioSubstituto,
      baseICMSEfetivo               = v_baseICMSEfetivo,
      valorICMSEfetivo              = v_valorICMSEfetivo,
      baseICMSEscrituracao          = v_baseICMSEscrituracao,
      valorICMSEscrituracao         = v_valorICMSEscrituracao,
      valorICMSDesonEscrituracao    = v_valorICMSDesonEscrituracao,
      baseICMSSTEscrituracao        = v_baseICMSSTEscrituracao,
      valorICMSSTEscrituracao       = v_valorICMSSTEscrituracao,
      baseICMSUFDestinatario        = v_baseICMSUFDestinatario,
      valorICMSUFDestinatario       = v_valorICMSUFDestinatario,
      baseICMSUFRemetente           = v_baseICMSUFRemetente,
      valorICMSUFRemetente          = v_valorICMSUFRemetente,
      baseFCP                       = v_baseFCP,
      valorFCP                      = v_valorFCP,
      baseFCPST                     = v_baseFCPST,
      valorFCPST                    = v_valorFCPST,
      baseFCPSTAnteriormente        = v_baseFCPSTAnteriormente,
      valorFCPSTAnteriormente       = v_valorFCPSTAnteriormente,
      baseFCPUFDestinatario         = v_baseFCPUFDestinatario,
      valorFCPUFDestinatario        = v_valorFCPUFDestinatario,
      baseEstimadaImpostos          = v_baseEstimadaImpostos,
      valorEstimadoImpFederais      = v_valorEstimadoImpFederais,
      valorEstimadoImpEstaduais     = v_valorEstimadoImpEstaduais,
      valorEstimadoImpMunicipais    = v_valorEstimadoImpMunicipais,
      valorLiquidoItem              = v_valorLiquidoItem,
      valorDescontoCustoOpTotal     = v_valorDescontoCustoOpTotal,
      valorAcrescimoCustoOpTotal    = v_valorAcrescimoCustoOpTotal,
      precoCustoOperacao            = v_precoCustoOperacao,
      valorCustoOperacao            = v_valorCustoOperacao,
      precoCMV                      = v_precoCMV,
      valorCMV                      = v_valorCMV,
      valorAcrescimoExtempSubtotal  = v_valorAcrescimoExtempSubtotal,
      valorAcrescimoExtempTotal     = v_valorAcrescimoExtempTotal
    WHERE idItemDocFiscal           = a.idItemDocFiscal;
    IF a.tipoProduto = '09' THEN
      r_cab_valorServicos            := r_cab_valorServicos + v_valorProdutoServico;
    ELSE
      r_cab_valorProdutos            := r_cab_valorProdutos + v_valorProdutoServico;
    END IF;
    r_cab_valorBasePagamento       := r_cab_valorBasePagamento + v_valorBasePagamento;
    IF a.usarPrecoAVista = 1 AND a.geraFinanceiro = 1 THEN
      r_cab_valorAVistaMinimo        := r_cab_valorAVistaMinimo + v_valorProdutoServico + a.valorDescontoPagamento - a.valorOutrasDespesasPagamento - a.valorJurosPagamento - v_valorDescontoTotal + v_valorOutrasDespesasTotal;
    END IF;
    r_cab_valorFreteTotal          := r_cab_valorFreteTotal + v_valorFreteTotal;
    r_cab_valorSeguroTotal         := r_cab_valorSeguroTotal + v_valorSeguroTotal;
    r_cab_valorDescontoTotal       := r_cab_valorDescontoTotal + v_valorDescontoTotal;
    r_cab_valorOutrasDespesasTotal := r_cab_valorOutrasDespesasTotal + v_valorOutrasDespesasTotal;
    r_cab_valorAdicFreteMarinTotal := r_cab_valorAdicFreteMarinTotal + v_valorAdicFreteMarinMerTotal;
    r_cab_valorDespesasAduanTotal  := r_cab_valorDespesasAduanTotal + v_valorDespesasAduaneirasTotal;
    r_cab_valorLiquidoItem         := r_cab_valorLiquidoItem + v_valorLiquidoItem;
    r_cab_valorDescCustoOpTotal    := r_cab_valorDescCustoOpTotal + v_valorDescontoCustoOpTotal;
    r_cab_valorAcrescCustoOpTotal  := r_cab_valorAcrescCustoOpTotal + v_valorAcrescimoCustoOpTotal;
    r_cab_valorCustoOperacao       := r_cab_valorCustoOperacao + v_valorCustoOperacao;
    r_cab_valorCMV                 := r_cab_valorCMV + v_valorCMV;
    r_cab_valorAcrescExtempTotal   := r_cab_valorAcrescExtempTotal + v_valorAcrescimoExtempTotal;
  END LOOP;
END ADD_DOC_FISC_CALC_IMP_ITENS;

/

create or replace PROCEDURE ADD_ORCAMENTO_CALC_IMP_CAB (
    p_config_64_casasDecSaidas     IN CHAR,
    p_config_209_filtrarGrupoEcon  IN NUMBER,
    p_config_362_calcCustoPorGrade IN NUMBER,
    p_cab_orcamento                IN NUMBER,
    p_troca_tipoPagamentoFrete     IN NUMBER,
    p_a_cab_tipoPagamentoFrete     IN CHAR)
IS
    v_cab_valorProdutos            NUMBER;
    v_cab_valorServicos            NUMBER;
    v_cab_valorBasePagamento       NUMBER;
    v_cab_valorAVistaMinimo        NUMBER;
    v_cab_valorFreteTotal          NUMBER;
    v_cab_valorSeguroTotal         NUMBER;
    v_cab_valorDescontoTotal       NUMBER;
    v_cab_valorOutrasDespesasTotal NUMBER;
    v_cab_valorAdicFreteMarinTotal NUMBER;
    v_cab_valorDespesasAduanTotal  NUMBER;
    v_cab_valorLiquidoItem         NUMBER;
    v_calcularImpostosItem         NUMBER;
BEGIN
  FOR a IN (
    SELECT a.*,
      pess.indicadorInscricaoEstadual,
      COALESCE((
        SELECT MIN(munEndEst.uf)
        FROM PAESTABELECIMENTOS est
        JOIN CAENDERECOSPESSOA endEst
        ON endEst.pessoa = est.pessoaEstabelecimento
        JOIN SIMUNICIPIOS munEndEst
        ON munEndEst.municipio = endEst.municipio
        WHERE est.estabelecimento = a.estabelecimento
        AND endEst.ativo = 1
        AND endEst.principal = 1
        ),'  ') munEndEst_uf
    FROM MOORCAMENTOS a
    JOIN CAPESSOAS pess
    ON pess.pessoa = a.pessoa
    WHERE a.orcamento = p_cab_orcamento)
  LOOP
    v_cab_valorProdutos            := a.valorProdutos;
    v_cab_valorServicos            := a.valorServicos;
    v_cab_valorBasePagamento       := a.valorBasePagamento;
    v_cab_valorAVistaMinimo        := a.valorAVistaMinimo;
    v_cab_valorFreteTotal          := a.valorFreteTotal;
    v_cab_valorSeguroTotal         := a.valorSeguroTotal;
    v_cab_valorDescontoTotal       := a.valorDescontoTotal;
    v_cab_valorOutrasDespesasTotal := a.valorOutrasDespesasTotal;
    v_cab_valorAdicFreteMarinTotal := a.valorAdicFreteMarinhaMerTotal;
    v_cab_valorDespesasAduanTotal  := a.valorDespesasAduaneirasTotal;
    v_cab_valorLiquidoItem         := a.valorLiquidoItem;
    ADD_ORCAMENTO_CALC_IMP_RATEIO (
      a.orcamento,
      p_troca_tipoPagamentoFrete,
      p_a_cab_tipoPagamentoFrete,
      a.origemDocumento,
      a.modeloDocumento,
      a.entradaSaida,
      a.atualizaCustoMedio,
      a.tipoPagamentoFrete,
      a.valorFreteGeral,
      a.valorSeguroGeral,
      a.valorDescontoGeral,
      a.valorOutrasDespesasGeral,
      a.valorAdicFreteMarinhaMerGeral,
      a.valorDespesasAduaneirasGeral,
      a.valorDescontoPagamento,
      a.valorOutrasDespesasPagamento,
      a.valorJurosPagamento,
      a.impostosEditados,
      /* Retornos */
      v_cab_valorProdutos,
      v_cab_valorServicos,
      v_cab_valorBasePagamento,
      v_cab_valorAVistaMinimo,
      v_cab_valorFreteTotal,
      v_cab_valorSeguroTotal,
      v_cab_valorDescontoTotal,
      v_cab_valorOutrasDespesasTotal,
      v_cab_valorAdicFreteMarinTotal,
      v_cab_valorDespesasAduanTotal,
      v_cab_valorLiquidoItem,
      v_calcularImpostosItem);
    IF v_calcularImpostosItem = 1 THEN
      ADD_ORCAMENTO_CALC_IMP_ITENS(
        p_config_64_casasDecSaidas,
        p_config_209_filtrarGrupoEcon,
        p_config_362_calcCustoPorGrade,
        a.orcamento,
        a.origemDocumento,
        a.entradaSaida,
        a.estabelecimento,
        a.dataEmissao,
        a.pessoa,
        a.localDestinoOperacao,
        a.indicadorConsumidorFinal,
        a.tipoPagamentoFrete,
        a.indicadorInscricaoEstadual,
        /* Retornos */
        v_cab_valorProdutos,
        v_cab_valorServicos,
        v_cab_valorBasePagamento,
        v_cab_valorAVistaMinimo,
        v_cab_valorFreteTotal,
        v_cab_valorSeguroTotal,
        v_cab_valorDescontoTotal,
        v_cab_valorOutrasDespesasTotal,
        v_cab_valorAdicFreteMarinTotal,
        v_cab_valorDespesasAduanTotal,
        v_cab_valorLiquidoItem);
    END IF;
    UPDATE MOORCAMENTOS SET 
      valorProdutos                 = v_cab_valorProdutos,
      valorServicos                 = v_cab_valorServicos,
      valorBasePagamento            = v_cab_valorBasePagamento,
      valorAVistaMinimo             = v_cab_valorAVistaMinimo,
      valorFreteTotal               = v_cab_valorFreteTotal,
      valorSeguroTotal              = v_cab_valorSeguroTotal,
      valorDescontoTotal            = v_cab_valorDescontoTotal,
      valorOutrasDespesasTotal      = v_cab_valorOutrasDespesasTotal,
      valorAdicFreteMarinhaMerTotal = v_cab_valorAdicFreteMarinTotal,
      valorDespesasAduaneirasTotal  = v_cab_valorDespesasAduanTotal,
      valorLiquidoItem              = v_cab_valorLiquidoItem
    WHERE orcamento                 = a.orcamento;
  END LOOP;
END ADD_ORCAMENTO_CALC_IMP_CAB;

/

create or replace PROCEDURE ADD_PRE_DOC_CALC_IMP_CAB (
    p_config_64_casasDecSaidas     IN CHAR,
    p_config_209_filtrarGrupoEcon  IN NUMBER,
    p_config_362_calcCustoPorGrade IN NUMBER,
    p_cab_preDocumento             IN NUMBER,
    p_troca_tipoPagamentoFrete     IN NUMBER,
    p_a_cab_tipoPagamentoFrete     IN CHAR)
IS
    v_cab_valorProdutos            NUMBER;
    v_cab_valorServicos            NUMBER;
    v_cab_valorBasePagamento       NUMBER;
    v_cab_valorAVistaMinimo        NUMBER;
    v_cab_valorFreteTotal          NUMBER;
    v_cab_valorSeguroTotal         NUMBER;
    v_cab_valorDescontoTotal       NUMBER;
    v_cab_valorOutrasDespesasTotal NUMBER;
    v_cab_valorAdicFreteMarinTotal NUMBER;
    v_cab_valorDespesasAduanTotal  NUMBER;
    v_cab_valorLiquidoItem         NUMBER;
    v_cab_valorCustoOperacao       NUMBER;
    v_cab_valorCMV                 NUMBER;
    v_cab_valorDescCustoOpTotal    NUMBER;
    v_cab_valorAcrescCustoOpTotal  NUMBER;
    v_cab_valorAcrescExtempTotal   NUMBER;
    v_calcularImpostosItem         NUMBER;
    v_habilitaControleEntrega      NUMBER;
BEGIN
  FOR a IN (
    SELECT a.*,
      pess.indicadorInscricaoEstadual,
      COALESCE((
        SELECT MIN(munEndEst.uf)
        FROM PAESTABELECIMENTOS est
        JOIN CAENDERECOSPESSOA endEst
        ON endEst.pessoa = est.pessoaEstabelecimento
        JOIN SIMUNICIPIOS munEndEst
        ON munEndEst.municipio = endEst.municipio
        WHERE est.estabelecimento = a.estabelecimento
        AND endEst.ativo = 1
        AND endEst.principal = 1),'  ') munEndEst_uf
    FROM MOPREDOCUMENTOS a
    JOIN CAPESSOAS pess
    ON pess.pessoa = a.pessoa
    WHERE a.preDocumento = p_cab_preDocumento)
  LOOP
    v_cab_valorProdutos            := a.valorProdutos;
    v_cab_valorServicos            := a.valorServicos;
    v_cab_valorBasePagamento       := a.valorBasePagamento;
    v_cab_valorAVistaMinimo        := a.valorAVistaMinimo;
    v_cab_valorFreteTotal          := a.valorFreteTotal;
    v_cab_valorSeguroTotal         := a.valorSeguroTotal;
    v_cab_valorDescontoTotal       := a.valorDescontoTotal;
    v_cab_valorOutrasDespesasTotal := a.valorOutrasDespesasTotal;
    v_cab_valorAdicFreteMarinTotal := a.valorAdicFreteMarinhaMerTotal;
    v_cab_valorDespesasAduanTotal  := a.valorDespesasAduaneirasTotal;
    v_cab_valorLiquidoItem         := a.valorLiquidoItem;
    v_cab_valorDescCustoOpTotal    := a.valorDescontoCustoOpTotal;
    v_cab_valorAcrescCustoOpTotal  := a.valorAcrescimoCustoOpTotal;
    v_cab_valorCustoOperacao       := a.valorCustoOperacao;
    v_cab_valorCMV                 := a.valorCMV;
    v_cab_valorAcrescExtempTotal   := a.valorAcrescimoExtempTotal;    
    SELECT
      CASE
        WHEN EXISTS (
          SELECT 1
          FROM MOPREDOCUMXITENS a
          JOIN MOPREDOCUMXORCAMENTOITEM docXorc
          ON docXorc.idItemPreDocumento = a.idItemPreDocumento
          JOIN MOORCAMENTOXITENS itemOrc
          ON itemOrc.idItemOrcamento = docXorc.idItemOrcamento
          JOIN PACONTROLESENTREGA contr
          ON contr.controleEntrega = itemOrc.controleEntrega
          WHERE a.preDocumento = p_cab_preDocumento
          AND itemOrc.controleEntrega <> 0
          AND contr.habilitaFrete = 1)
        THEN 1
        ELSE 0
      END
    INTO v_habilitaControleEntrega
    FROM DUAL;
    ADD_PRE_DOC_CALC_IMP_RATEIO (
      a.preDocumento,
      p_troca_tipoPagamentoFrete,
      p_a_cab_tipoPagamentoFrete,
      a.origemDocumento,
      a.entradaSaida,
      a.devolucaoAnulacaoRetorno,
      a.atualizaCustoMedio,
      a.estabelecimento,
      a.tipoPagamentoFrete,
      a.valorFreteGeral,
      a.valorSeguroGeral,
      a.valorDescontoGeral,
      a.valorOutrasDespesasGeral,
      a.valorAdicFreteMarinhaMerGeral,
      a.valorDespesasAduaneirasGeral,
      a.valorDescontoPagamento,
      a.valorOutrasDespesasPagamento,
      a.valorJurosPagamento,
      a.impostosEditados,
      a.valorDescontoCustoOpGeral,
      a.valorAcrescimoCustoOpGeral,
      a.valorAcrescimoExtempGeral,
      v_habilitaControleEntrega,
      /* Retornos */
      v_cab_valorProdutos,
      v_cab_valorServicos,
      v_cab_valorBasePagamento,
      v_cab_valorAVistaMinimo,
      v_cab_valorFreteTotal,
      v_cab_valorSeguroTotal,
      v_cab_valorDescontoTotal,
      v_cab_valorOutrasDespesasTotal,
      v_cab_valorAdicFreteMarinTotal,
      v_cab_valorDespesasAduanTotal,
      v_cab_valorLiquidoItem,
      v_cab_valorDescCustoOpTotal,
      v_cab_valorAcrescCustoOpTotal,
      v_cab_valorCustoOperacao,
      v_cab_valorCMV,
      v_cab_valorAcrescExtempTotal,
      v_calcularImpostosItem);
    IF v_calcularImpostosItem = 1 THEN
      ADD_PRE_DOC_CALC_IMP_ITENS(
        p_config_64_casasDecSaidas,
        p_config_209_filtrarGrupoEcon,
        p_config_362_calcCustoPorGrade,
        a.preDocumento,
        a.origemDocumento,
        a.entradaSaida,
        a.devolucaoAnulacaoRetorno,
        a.atualizaCustoMedio,
        a.estabelecimento,
        a.dataEntradaSaida,
        a.pessoa,
        a.localDestinoOperacao,
        a.indicadorConsumidorFinal,
        a.tipoPagamentoFrete,
        a.indicadorInscricaoEstadual,
        /* Retornos */
        v_cab_valorProdutos,
        v_cab_valorServicos,
        v_cab_valorBasePagamento,
        v_cab_valorAVistaMinimo,
        v_cab_valorFreteTotal,
        v_cab_valorSeguroTotal,
        v_cab_valorDescontoTotal,
        v_cab_valorOutrasDespesasTotal,
        v_cab_valorAdicFreteMarinTotal,
        v_cab_valorDespesasAduanTotal,
        v_cab_valorLiquidoItem,
        v_cab_valorDescCustoOpTotal,
        v_cab_valorAcrescCustoOpTotal,
        v_cab_valorCustoOperacao,
        v_cab_valorCMV,
        v_cab_valorAcrescExtempTotal);
    END IF;
    UPDATE MOPREDOCUMENTOS SET 
      valorProdutos                 = v_cab_valorProdutos,
      valorServicos                 = v_cab_valorServicos,
      valorBasePagamento            = v_cab_valorBasePagamento,
      valorAVistaMinimo             = v_cab_valorAVistaMinimo,
      valorFreteTotal               = v_cab_valorFreteTotal,
      valorSeguroTotal              = v_cab_valorSeguroTotal,
      valorDescontoTotal            = v_cab_valorDescontoTotal,
      valorOutrasDespesasTotal      = v_cab_valorOutrasDespesasTotal,
      valorAdicFreteMarinhaMerTotal = v_cab_valorAdicFreteMarinTotal,
      valorDespesasAduaneirasTotal  = v_cab_valorDespesasAduanTotal,
      valorLiquidoItem              = v_cab_valorLiquidoItem,
      valorDescontoCustoOpTotal     = v_cab_valorDescCustoOpTotal,
      valorAcrescimoCustoOpTotal    = v_cab_valorAcrescCustoOpTotal,
      valorCustoOperacao            = v_cab_valorCustoOperacao,
      valorCMV                      = v_cab_valorCMV,
      valorAcrescimoExtempTotal     = v_cab_valorAcrescExtempTotal
    WHERE preDocumento              = a.preDocumento;
  END LOOP;
END ADD_PRE_DOC_CALC_IMP_CAB;

/

create or replace PROCEDURE ADD_DOC_FISC_CALC_IMP_CAB (
    p_config_64_casasDecSaidas     IN CHAR,
    p_config_209_filtrarGrupoEcon  IN NUMBER,
    p_config_362_calcCustoPorGrade IN NUMBER,
    p_cab_idDocumentoFiscal        IN NUMBER,
    p_troca_tipoPagamentoFrete     IN NUMBER,
    p_a_cab_tipoPagamentoFrete     IN CHAR)
IS
    v_cab_valorProdutos            NUMBER;
    v_cab_valorServicos            NUMBER;
    v_cab_valorBasePagamento       NUMBER;
    v_cab_valorAVistaMinimo        NUMBER;
    v_cab_valorFreteTotal          NUMBER;
    v_cab_valorSeguroTotal         NUMBER;
    v_cab_valorDescontoTotal       NUMBER;
    v_cab_valorOutrasDespesasTotal NUMBER;
    v_cab_valorAdicFreteMarinTotal NUMBER;
    v_cab_valorDespesasAduanTotal  NUMBER;
    v_cab_valorLiquidoItem         NUMBER;
    v_cab_valorCustoOperacao       NUMBER;
    v_cab_valorCMV                 NUMBER;
    v_cab_valorDescCustoOpTotal    NUMBER;
    v_cab_valorAcrescCustoOpTotal  NUMBER;
    v_cab_valorAcrescExtempTotal   NUMBER;
    v_calcularImpostosItem         NUMBER;
    v_habilitaControleEntrega      NUMBER;
BEGIN
  FOR a IN (
    SELECT a.*,
      pess.indicadorInscricaoEstadual,
      COALESCE((
        SELECT MIN(munEndEst.uf)
        FROM PAESTABELECIMENTOS est
        JOIN CAENDERECOSPESSOA endEst
        ON endEst.pessoa = est.pessoaEstabelecimento
        JOIN SIMUNICIPIOS munEndEst
        ON munEndEst.municipio = endEst.municipio
        WHERE est.estabelecimento = a.estabelecimento
        AND endEst.ativo = 1
        AND endEst.principal = 1),'  ') munEndEst_uf
    FROM MODOCUMENTOSFISCAIS a
    JOIN CAPESSOAS pess
    ON pess.pessoa = a.pessoa
    WHERE a.idDocumentoFiscal = p_cab_idDocumentoFiscal)
  LOOP
    v_cab_valorProdutos            := a.valorProdutos;
    v_cab_valorServicos            := a.valorServicos;
    v_cab_valorBasePagamento       := a.valorBasePagamento;
    v_cab_valorAVistaMinimo        := a.valorAVistaMinimo;
    v_cab_valorFreteTotal          := a.valorFreteTotal;
    v_cab_valorSeguroTotal         := a.valorSeguroTotal;
    v_cab_valorDescontoTotal       := a.valorDescontoTotal;
    v_cab_valorOutrasDespesasTotal := a.valorOutrasDespesasTotal;
    v_cab_valorAdicFreteMarinTotal := a.valorAdicFreteMarinhaMerTotal;
    v_cab_valorDespesasAduanTotal  := a.valorDespesasAduaneirasTotal;
    v_cab_valorLiquidoItem         := a.valorLiquidoItem;
    v_cab_valorDescCustoOpTotal    := a.valorDescontoCustoOpTotal;
    v_cab_valorAcrescCustoOpTotal  := a.valorAcrescimoCustoOpTotal;
    v_cab_valorCustoOperacao       := a.valorCustoOperacao;
    v_cab_valorCMV                 := a.valorCMV;
    v_cab_valorAcrescExtempTotal   := a.valorAcrescimoExtempTotal;
    SELECT
      CASE
        WHEN EXISTS (
          SELECT 1
          FROM MODOCFISCALXITENS a
          JOIN MODOCFISCALXORCAMENTOITEM docXorc
          ON docXorc.idItemDocFiscal = a.idItemDocFiscal
          JOIN MOORCAMENTOXITENS itemOrc
          ON itemOrc.idItemOrcamento = docXorc.idItemOrcamento
          JOIN PACONTROLESENTREGA contr
          ON contr.controleEntrega = itemOrc.controleEntrega
          WHERE a.idDocumentoFiscal = p_cab_idDocumentoFiscal
          AND itemOrc.controleEntrega <> 0
          AND contr.habilitaFrete = 1)
        THEN 1
        ELSE 0
      END
    INTO v_habilitaControleEntrega
    FROM DUAL;
    ADD_DOC_FISC_CALC_IMP_RATEIO (
      a.idDocumentoFiscal,
      p_troca_tipoPagamentoFrete,
      p_a_cab_tipoPagamentoFrete,
      a.origemDocumento,
      a.entradaSaida,
      a.devolucaoAnulacaoRetorno,
      a.atualizaCustoMedio,
      a.estabelecimento,
      a.nfFornecedor,
      a.tipoPagamentoFrete,
      a.valorFreteGeral,
      a.valorSeguroGeral,
      a.valorDescontoGeral,
      a.valorOutrasDespesasGeral,
      a.valorAdicFreteMarinhaMerGeral,
      a.valorDespesasAduaneirasGeral,
      a.valorDescontoPagamento,
      a.valorOutrasDespesasPagamento,
      a.valorJurosPagamento,
      a.impostosEditados,
      a.valorDescontoCustoOpGeral,
      a.valorAcrescimoCustoOpGeral,
      a.valorAcrescimoExtempGeral,
      v_habilitaControleEntrega,
      /* Retornos */
      v_cab_valorProdutos,
      v_cab_valorServicos,
      v_cab_valorBasePagamento,
      v_cab_valorAVistaMinimo,
      v_cab_valorFreteTotal,
      v_cab_valorSeguroTotal,
      v_cab_valorDescontoTotal,
      v_cab_valorOutrasDespesasTotal,
      v_cab_valorAdicFreteMarinTotal,
      v_cab_valorDespesasAduanTotal,
      v_cab_valorLiquidoItem,
      v_cab_valorDescCustoOpTotal,
      v_cab_valorAcrescCustoOpTotal,
      v_cab_valorCustoOperacao,
      v_cab_valorCMV,
      v_cab_valorAcrescExtempTotal,
      v_calcularImpostosItem);
    IF v_calcularImpostosItem = 1 THEN
      ADD_DOC_FISC_CALC_IMP_ITENS(
        p_config_64_casasDecSaidas,
        p_config_209_filtrarGrupoEcon,
        p_config_362_calcCustoPorGrade,
        a.idDocumentoFiscal,
        a.origemDocumento,
        a.entradaSaida,
        a.devolucaoAnulacaoRetorno,
        a.atualizaCustoMedio,
        a.estabelecimento,
        a.nfFornecedor,
        a.dataEntradaSaida,
        a.pessoa,
        a.localDestinoOperacao,
        a.indicadorConsumidorFinal,
        a.tipoPagamentoFrete,
        a.indicadorInscricaoEstadual,
        /* Retornos */
        v_cab_valorProdutos,
        v_cab_valorServicos,
        v_cab_valorBasePagamento,
        v_cab_valorAVistaMinimo,
        v_cab_valorFreteTotal,
        v_cab_valorSeguroTotal,
        v_cab_valorDescontoTotal,
        v_cab_valorOutrasDespesasTotal,
        v_cab_valorAdicFreteMarinTotal,
        v_cab_valorDespesasAduanTotal,
        v_cab_valorLiquidoItem,
        v_cab_valorDescCustoOpTotal,
        v_cab_valorAcrescCustoOpTotal,
        v_cab_valorCustoOperacao,
        v_cab_valorCMV,
        v_cab_valorAcrescExtempTotal);
    END IF;
