SET DEFINE OFF;

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_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,
    p_modDoc_diminuiDescontoPrUnit IN NUMBER,
    p_modDoc_somaAcrescimosPrUnit  IN NUMBER,
    p_modDoc_somaFreteSeguroPrUnit IN NUMBER,
    p_modDoc_habilitaControleEntr  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_valorImpSomaPagamento    OUT NUMBER,
    r_cab_valorImpDiminuiPagamento 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_valorBaseRateio              NUMBER;
    v_valorBaseRateioFrete         NUMBER;
    v_valorBaseRateioFinanceiro    NUMBER;
    v_valorBaseRateioFinancFrete   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_valorImpSomaPagamento        NUMBER;
    v_valorImpDiminuiPagamento     NUMBER;
    v_valorLiquidoItem             NUMBER;
    CURSOR c_item IS
      SELECT
        a.idItemOrcamento,
        a.servico,
        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.valorIRRF,
        a.valorINSS,
        a.valorRetPIS,
        a.valorRetCOFINS,
        a.valorRetCSLL,
        a.valorII,
        a.valorIOF,
        a.valorIPI,
        a.valorPIS,
        a.valorPISST,
        a.valorCOFINS,
        a.valorCOFINSST,
        a.valorCreditoSimplesNacional,
        a.valorICMS,
        a.valorICMSST,
        a.valorImpostosSomaPagamento,
        a.valorImpostosDiminuiPagamento,
        a.valorLiquidoItem,
        CASE WHEN p_modDoc_habilitaControleEntr = 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
      FROM MOORCAMENTOXITENS a
      JOIN PACONTROLESENTREGA contr ON contr.controleEntrega = a.controleEntrega
      WHERE a.orcamento = p_cab_orcamento
      AND a.cancelado = 0
      ORDER BY a.sequencia;
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_valorImpSomaPagamento    := 0;
  r_cab_valorImpDiminuiPagamento := 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
          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 p_modDoc_diminuiDescontoPrUnit = 1
                OR p_modDoc_somaAcrescimosPrUnit  = 1
                OR p_modDoc_somaFreteSeguroPrUnit = 1
              THEN a.valorProdutoServicoBruto
              ELSE a.valorProdutoServico
            END
            - a.valorDescontoItem
            + a.valorAcrescimoItem))
        THEN 0
        WHEN COALESCE ((
          SELECT SUM (CASE WHEN p_modDoc_diminuiDescontoPrUnit = 1 OR p_modDoc_somaAcrescimosPrUnit = 1 or p_modDoc_somaFreteSeguroPrUnit = 1 THEN a.valorProdutoServicoBruto ELSE a.valorProdutoServico END - a.valorDescontoItem + a.valorAcrescimoItem)
          FROM MOORCAMENTOXITENS a
          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 p_modDoc_diminuiDescontoPrUnit = 1 OR p_modDoc_somaAcrescimosPrUnit = 1 or p_modDoc_somaFreteSeguroPrUnit = 1 THEN a.valorProdutoServicoBruto ELSE a.valorProdutoServico END - a.valorDescontoItem + a.valorAcrescimoItem)
          FROM MOORCAMENTOXITENS a
          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 p_modDoc_habilitaControleEntr = 0 OR a.controleEntrega > 0 AND contr.habilitaFrete = 1 THEN 1 ELSE 0 END),0),
    COALESCE(SUM(CASE WHEN p_modDoc_diminuiDescontoPrUnit = 1 OR p_modDoc_somaAcrescimosPrUnit = 1 or p_modDoc_somaFreteSeguroPrUnit = 1 THEN a.valorProdutoServicoBruto ELSE a.valorProdutoServico END - a.valorDescontoItem + a.valorAcrescimoItem),0),
    COALESCE(SUM(CASE WHEN p_modDoc_habilitaControleEntr = 0 OR a.controleEntrega > 0 AND contr.habilitaFrete = 1 THEN CASE WHEN p_modDoc_diminuiDescontoPrUnit = 1 OR p_modDoc_somaAcrescimosPrUnit = 1 or p_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 p_modDoc_diminuiDescontoPrUnit = 1 OR p_modDoc_somaAcrescimosPrUnit = 1 or p_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_modDoc_habilitaControleEntr = 0 OR a.controleEntrega > 0 AND contr.habilitaFrete = 1) THEN CASE WHEN p_modDoc_diminuiDescontoPrUnit = 1 OR p_modDoc_somaAcrescimosPrUnit = 1 or p_modDoc_somaFreteSeguroPrUnit = 1 THEN a.valorProdutoServicoBruto ELSE a.valorProdutoServico END - a.valorDescontoItem + a.valorAcrescimoItem ELSE 0 END),0),
    COALESCE(SUM(CASE WHEN p_modDoc_diminuiDescontoPrUnit = 1 OR p_modDoc_somaAcrescimosPrUnit = 1 or p_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 p_modDoc_diminuiDescontoPrUnit = 1 OR p_modDoc_somaAcrescimosPrUnit = 1 or p_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 p_modDoc_diminuiDescontoPrUnit = 1 OR p_modDoc_somaAcrescimosPrUnit = 1 or p_modDoc_somaFreteSeguroPrUnit = 1 THEN a.valorProdutoServicoBruto ELSE a.valorProdutoServico - a.valorDescontoItem + a.valorAcrescimoItem END ELSE 0 END),0),
    COALESCE(SUM(CASE WHEN p_modDoc_diminuiDescontoPrUnit = 1 OR p_modDoc_somaAcrescimosPrUnit = 1 or p_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 p_modDoc_diminuiDescontoPrUnit = 1 OR p_modDoc_somaAcrescimosPrUnit = 1 or p_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 p_modDoc_diminuiDescontoPrUnit = 1 OR p_modDoc_somaAcrescimosPrUnit = 1 or p_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 p_modDoc_diminuiDescontoPrUnit = 1 OR p_modDoc_somaAcrescimosPrUnit = 1 or p_modDoc_somaFreteSeguroPrUnit = 1 THEN a.valorProdutoServicoBruto ELSE a.valorProdutoServico END - a.valorDescontoItem + a.valorAcrescimoItem ELSE 0 END),0)
  INTO
    v_rateioFretePorControleEntr,
    v_valorBaseRateio,
    v_valorBaseRateioFrete,
    v_valorBaseRateioFinanceiro,
    v_valorBaseRateioFinancFrete,
    v_valorBaseRateioOutrasDespGer,
    v_valorBaseRateioOutrasDespFin,
    v_valorBaseRateioDescontoGeral,
    v_valorBaseRateioPagamento,
    v_valorBaseRateioPagamFinanc,
    v_valorBaseRateioPagamDesconto,
    v_valorBaseRateioPagamFinDesc
  FROM MOORCAMENTOXITENS a
  JOIN PACONTROLESENTREGA contr ON contr.controleEntrega = a.controleEntrega
  WHERE a.orcamento = p_cab_orcamento
  AND a.cancelado = 0;

  -- Efetua rateio
  FOR item IN c_item LOOP
    v_idItemOrcamentoUltimoItem    := item.idItemOrcamento;
    v_precoUnitario                := item.precoUnitario;
    v_precoUnitarioConvertido      := item.precoUnitarioConvertido;
    v_valorProdutoServico          := item.valorProdutoServico;
    v_valorBasePagamento           := item.valorBasePagamento;
    v_valorFreteTotal              := item.valorFreteTotal;
    v_valorSeguroTotal             := item.valorSeguroTotal;
    v_valorDescontoTotal           := item.valorDescontoTotal;
    v_valorOutrasDespesasTotal     := item.valorOutrasDespesasTotal;
    v_valorAdicFreteMarinMerTotal  := item.valorAdicFreteMarinhaMerTotal;
    v_valorDespesasAduaneirasTotal := item.valorDespesasAduaneirasTotal;
    v_valorImpSomaPagamento        := item.valorImpostosSomaPagamento;
    v_valorImpDiminuiPagamento     := item.valorImpostosDiminuiPagamento;
    v_valorLiquidoItem             := item.valorLiquidoItem;

    IF CASE WHEN v_rateioFretePorControleEntr = 1 THEN v_valorBaseRateioFinancFrete ELSE v_valorBaseRateioFinanceiro END > 0 THEN
      IF item.geraFinanceiro = 1 AND (v_rateioFretePorControleEntr = 0 OR item.rateioFrete = 1) THEN
        v_idItemOrcamentoRateioFrete := item.idItemOrcamento;
      END IF;
    ELSIF v_rateioFretePorControleEntr = 0 OR item.rateioFrete = 1 THEN
      v_idItemOrcamentoRateioFrete := item.idItemOrcamento;
    END IF;

    -- v_valorFreteGeral
    v_auxNumber := v_residuoFreteGeral +
      CASE
        WHEN CASE WHEN v_rateioFretePorControleEntr = 1 THEN v_valorBaseRateioFinancFrete ELSE v_valorBaseRateioFinanceiro END > 0
        THEN 
          CASE
            WHEN item.geraFinanceiro = 1 AND (v_rateioFretePorControleEntr = 0 OR item.rateioFrete = 1)
            THEN
              CASE
                WHEN CASE WHEN v_rateioFretePorControleEntr = 1 THEN v_valorBaseRateioFinancFrete ELSE v_valorBaseRateioFinanceiro END = 0
                THEN 0
                ELSE p_cab_valorFreteGeral
                  * (CASE WHEN p_modDoc_diminuiDescontoPrUnit = 1 OR p_modDoc_somaAcrescimosPrUnit = 1 or p_modDoc_somaFreteSeguroPrUnit = 1 THEN item.valorProdutoServicoBruto ELSE item.valorProdutoServico END - item.valorDescontoItem + item.valorAcrescimoItem)
                  / CASE WHEN v_rateioFretePorControleEntr = 1 THEN v_valorBaseRateioFinancFrete ELSE v_valorBaseRateioFinanceiro END
              END
            ELSE 0
          END
        WHEN v_rateioFretePorControleEntr = 0 OR item.rateioFrete = 1
        THEN
          CASE
            WHEN CASE WHEN v_rateioFretePorControleEntr = 1 THEN v_valorBaseRateioFrete ELSE v_valorBaseRateio END = 0
            THEN 0
            ELSE p_cab_valorFreteGeral
              * (CASE WHEN p_modDoc_diminuiDescontoPrUnit = 1 OR p_modDoc_somaAcrescimosPrUnit = 1 or p_modDoc_somaFreteSeguroPrUnit = 1 THEN item.valorProdutoServicoBruto ELSE item.valorProdutoServico END - item.valorDescontoItem + item.valorAcrescimoItem)
              / CASE WHEN v_rateioFretePorControleEntr = 1 THEN v_valorBaseRateioFrete ELSE v_valorBaseRateio END
          END
        ELSE 0
      END;
    v_valorFreteGeral    := ROUND (v_auxNumber,2);
    v_residuoFreteGeral  := v_auxNumber - v_valorFreteGeral;
    v_saldoRatFreteGeral := v_saldoRatFreteGeral - v_valorFreteGeral;

    -- v_valorSeguroGeral
    v_auxNumber := v_residuoSeguroGeral +
      CASE
        WHEN CASE WHEN v_rateioFretePorControleEntr = 1 THEN v_valorBaseRateioFinancFrete ELSE v_valorBaseRateioFinanceiro END > 0
        THEN 
          CASE
            WHEN item.geraFinanceiro = 1 AND (v_rateioFretePorControleEntr = 0 OR item.rateioFrete = 1)
            THEN
              CASE
                WHEN CASE WHEN v_rateioFretePorControleEntr = 1 THEN v_valorBaseRateioFinancFrete ELSE v_valorBaseRateioFinanceiro END = 0
                THEN 0
                ELSE p_cab_valorSeguroGeral
                  * (CASE WHEN p_modDoc_diminuiDescontoPrUnit = 1 OR p_modDoc_somaAcrescimosPrUnit = 1 or p_modDoc_somaFreteSeguroPrUnit = 1 THEN item.valorProdutoServicoBruto ELSE item.valorProdutoServico END - item.valorDescontoItem + item.valorAcrescimoItem)
                  / CASE WHEN v_rateioFretePorControleEntr = 1 THEN v_valorBaseRateioFinancFrete ELSE v_valorBaseRateioFinanceiro END
              END
            ELSE 0
          END
        WHEN v_rateioFretePorControleEntr = 0 OR item.rateioFrete = 1
        THEN
          CASE
            WHEN CASE WHEN v_rateioFretePorControleEntr = 1 THEN v_valorBaseRateioFrete ELSE v_valorBaseRateio END = 0
            THEN 0
            ELSE p_cab_valorSeguroGeral
              * (CASE WHEN p_modDoc_diminuiDescontoPrUnit = 1 OR p_modDoc_somaAcrescimosPrUnit = 1 or p_modDoc_somaFreteSeguroPrUnit = 1 THEN item.valorProdutoServicoBruto ELSE item.valorProdutoServico END - item.valorDescontoItem + item.valorAcrescimoItem)
              / CASE WHEN v_rateioFretePorControleEntr = 1 THEN v_valorBaseRateioFrete ELSE v_valorBaseRateio END
          END
        ELSE 0
      END;
    v_valorSeguroGeral    := ROUND (v_auxNumber,2);
    v_residuoSeguroGeral  := v_auxNumber - v_valorSeguroGeral;
    v_saldoRatSeguroGeral := v_saldoRatSeguroGeral - v_valorSeguroGeral;

    -- v_valorAdicFreteMarinMerGeral
    v_auxNumber := v_residuoAdicFreteMarinGeral +
      CASE
        WHEN v_valorBaseRateioFinanceiro > 0 AND item.geraFinanceiro = 1
        THEN p_cab_valorAdicFreteMarinGeral
          * (CASE WHEN p_modDoc_diminuiDescontoPrUnit = 1 OR p_modDoc_somaAcrescimosPrUnit = 1 or p_modDoc_somaFreteSeguroPrUnit = 1 THEN item.valorProdutoServicoBruto ELSE item.valorProdutoServico END - item.valorDescontoItem + item.valorAcrescimoItem)
          / v_valorBaseRateioFinanceiro
        WHEN v_valorBaseRateioFinanceiro <= 0 AND v_valorBaseRateio > 0
        THEN p_cab_valorAdicFreteMarinGeral
          * (CASE WHEN p_modDoc_diminuiDescontoPrUnit = 1 OR p_modDoc_somaAcrescimosPrUnit = 1 or p_modDoc_somaFreteSeguroPrUnit = 1 THEN item.valorProdutoServicoBruto ELSE item.valorProdutoServico END - item.valorDescontoItem + item.valorAcrescimoItem)
          / v_valorBaseRateio
        ELSE 0
      END;
    v_valorAdicFreteMarinMerGeral := ROUND (v_auxNumber,2);
    v_residuoAdicFreteMarinGeral  := v_auxNumber - v_valorAdicFreteMarinMerGeral;
    v_saldoRatAdicFreteMarinGeral := v_saldoRatAdicFreteMarinGeral - v_valorAdicFreteMarinMerGeral;

    -- v_valorDespesasAduaneirasGeral
    v_auxNumber := v_residuoDespesasAduanGeral +
      CASE
        WHEN v_valorBaseRateioFinanceiro > 0 AND item.geraFinanceiro = 1
        THEN p_cab_valorDespesasAduanGeral
          * (CASE WHEN p_modDoc_diminuiDescontoPrUnit = 1 OR p_modDoc_somaAcrescimosPrUnit = 1 or p_modDoc_somaFreteSeguroPrUnit = 1 THEN item.valorProdutoServicoBruto ELSE item.valorProdutoServico END - item.valorDescontoItem + item.valorAcrescimoItem)
          / v_valorBaseRateioFinanceiro
        WHEN v_valorBaseRateioFinanceiro <= 0 AND v_valorBaseRateio > 0
        THEN p_cab_valorDespesasAduanGeral
          * (CASE WHEN p_modDoc_diminuiDescontoPrUnit = 1 OR p_modDoc_somaAcrescimosPrUnit = 1 or p_modDoc_somaFreteSeguroPrUnit = 1 THEN item.valorProdutoServicoBruto ELSE item.valorProdutoServico END - item.valorDescontoItem + item.valorAcrescimoItem)
          / v_valorBaseRateio
        ELSE 0
      END;
    v_valorDespesasAduaneirasGeral := ROUND (v_auxNumber,2);
    v_residuoDespesasAduanGeral    := v_auxNumber - v_valorDespesasAduaneirasGeral;
    v_saldoRatDespesasAduanGeral   := v_saldoRatDespesasAduanGeral - v_valorDespesasAduaneirasGeral;

    -- v_valorOutrasDespesasGeral
    v_auxNumber := v_residuoOutrasDespesasGeral +
      CASE
        WHEN v_valorBaseRateioOutrasDespFin > 0 AND item.geraFinanceiro = 1
        THEN p_cab_valorOutrasDespesasGeral
          * (CASE WHEN p_modDoc_diminuiDescontoPrUnit = 1 OR p_modDoc_somaAcrescimosPrUnit = 1 or p_modDoc_somaFreteSeguroPrUnit = 1 THEN item.valorProdutoServicoBruto ELSE item.valorProdutoServico - item.valorDescontoItem + item.valorAcrescimoItem END)
          / v_valorBaseRateioOutrasDespFin
        WHEN v_valorBaseRateioOutrasDespFin <= 0 AND v_valorBaseRateioOutrasDespGer > 0
        THEN p_cab_valorOutrasDespesasGeral
          * (CASE WHEN p_modDoc_diminuiDescontoPrUnit = 1 OR p_modDoc_somaAcrescimosPrUnit = 1 or p_modDoc_somaFreteSeguroPrUnit = 1 THEN item.valorProdutoServicoBruto ELSE item.valorProdutoServico - item.valorDescontoItem + item.valorAcrescimoItem END)
          / v_valorBaseRateioOutrasDespGer
        ELSE 0
      END;
    v_valorOutrasDespesasGeral    := ROUND (v_auxNumber,2);
    v_residuoOutrasDespesasGeral  := v_auxNumber - v_valorOutrasDespesasGeral;
    v_saldoRatOutrasDespesasGeral := v_saldoRatOutrasDespesasGeral - v_valorOutrasDespesasGeral;

    -- v_valorOutrasDespesasPagamento
    v_auxNumber := v_residuoOutrasDespPagamento +
      CASE
        WHEN v_valorBaseRateioPagamFinanc > 0 AND item.geraFinanceiro = 1
        THEN p_cab_valorOutrasDespPagamento
          * (CASE WHEN p_modDoc_diminuiDescontoPrUnit = 1 OR p_modDoc_somaAcrescimosPrUnit = 1 or p_modDoc_somaFreteSeguroPrUnit = 1 THEN item.valorProdutoServicoBruto ELSE item.valorProdutoServico END - item.valorDescontoItem + item.valorAcrescimoItem)
          / v_valorBaseRateioPagamFinanc
        WHEN v_valorBaseRateioPagamFinanc <= 0 AND v_valorBaseRateioPagamento > 0
        THEN p_cab_valorOutrasDespPagamento
          * (CASE WHEN p_modDoc_diminuiDescontoPrUnit = 1 OR p_modDoc_somaAcrescimosPrUnit = 1 or p_modDoc_somaFreteSeguroPrUnit = 1 THEN item.valorProdutoServicoBruto ELSE item.valorProdutoServico END - item.valorDescontoItem + item.valorAcrescimoItem)
          / v_valorBaseRateioPagamento
        ELSE 0
      END;
    v_valorOutrasDespesasPagamento := ROUND (v_auxNumber,2);
    v_residuoOutrasDespPagamento := v_auxNumber - v_valorOutrasDespesasPagamento;
    v_saldoRatOutrasDespPagamento := v_saldoRatOutrasDespPagamento - v_valorOutrasDespesasPagamento;

    -- v_valorJurosPagamento
    v_auxNumber := v_residuoJurosPagamento +
      CASE
        WHEN v_valorBaseRateioPagamFinanc > 0 AND item.geraFinanceiro = 1
        THEN p_cab_valorJurosPagamento
          * (CASE WHEN p_modDoc_diminuiDescontoPrUnit = 1 OR p_modDoc_somaAcrescimosPrUnit = 1 or p_modDoc_somaFreteSeguroPrUnit = 1 THEN item.valorProdutoServicoBruto ELSE item.valorProdutoServico END - item.valorDescontoItem + item.valorAcrescimoItem)
          / v_valorBaseRateioPagamFinanc
        WHEN v_valorBaseRateioPagamFinanc <= 0 AND v_valorBaseRateioPagamento > 0
        THEN p_cab_valorJurosPagamento
          * (CASE WHEN p_modDoc_diminuiDescontoPrUnit = 1 OR p_modDoc_somaAcrescimosPrUnit = 1 or p_modDoc_somaFreteSeguroPrUnit = 1 THEN item.valorProdutoServicoBruto ELSE item.valorProdutoServico END - item.valorDescontoItem + item.valorAcrescimoItem)
          / v_valorBaseRateioPagamento
        ELSE 0
      END;
    v_valorJurosPagamento := ROUND (v_auxNumber,2);
    v_residuoJurosPagamento := v_auxNumber - v_valorJurosPagamento;
    v_saldoRatJurosPagamento := v_saldoRatJurosPagamento - v_valorJurosPagamento;

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

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

    -- Recalcula Valores
    ADD_CALCULA_TOTAIS_ITEM(
      p_cab_tipoPagamentoFrete,
      p_modDoc_diminuiDescontoPrUnit,
      p_modDoc_somaAcrescimosPrUnit,
      p_modDoc_somaFreteSeguroPrUnit,
      item.quantidade,
      item.quantidadeConvertida,
      item.precoUnitarioBruto,
      item.acrescimoUnitarioComposicao,
      item.precoUnitario,
      item.valorDescontoItem,
      item.valorAcrescimoItem,
      item.valorFreteItem,
      item.valorSeguroItem,
      item.valorAdicFreteMarinhaMerItem,
      item.valorDespesasAduaneirasItem,
      v_valorFreteGeral,
      v_valorSeguroGeral,
      v_valorDescontoGeral,
      v_valorOutrasDespesasGeral,
      v_valorAdicFreteMarinMerGeral,
      v_valorDespesasAduaneirasGeral,
      v_valorDescontoPagamento,
      v_valorOutrasDespesasPagamento,
      v_valorJurosPagamento,
      0,
      0,
      0,
      0,
      /* Retornos */
      v_precoUnitario,
      v_precoUnitarioConvertido,
      v_valorProdutoServico,
      v_auxNumber,
      v_auxNumber,
      v_valorFreteTotal,
      v_valorSeguroTotal,
      v_valorDescontoTotal,
      v_valorOutrasDespesasTotal,
      v_valorAdicFreteMarinMerTotal,
      v_valorDespesasAduaneirasTotal,
      v_auxNumber,
      v_auxNumber);
    IF p_cab_impostosEditados = 0 
        OR v_valorProdutoServico <> item.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 item.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 item.valorSeguroTotal END
        OR v_valorDescontoTotal <> item.valorDescontoTotal
        OR v_valorOutrasDespesasTotal <> item.valorOutrasDespesasTotal
        OR v_valorAdicFreteMarinMerTotal <> item.valorAdicFreteMarinhaMerTotal
        OR v_valorDespesasAduaneirasTotal <> item.valorDespesasAduaneirasTotal
        OR v_precoUnitario <> item.precoUnitario
        OR v_valorProdutoServico <> item.valorProdutoServico
    THEN
      r_calcularImpostosItem := 1;
    END IF;
    ADD_CALCULA_VALOR_LIQUIDO (
      0,
      p_cab_tipoPagamentoFrete,
      item.geraFinanceiro,
      v_valorProdutoServico,
      v_valorDescontoPagamento,
      v_valorOutrasDespesasPagamento,
      v_valorJurosPagamento,
      v_valorFreteTotal,
      v_valorSeguroTotal,
      v_valorDescontoTotal,
      v_valorOutrasDespesasTotal,
      item.valorIRRF,
      item.valorINSS,
      item.valorRetPIS,
      item.valorRetCOFINS,
      item.valorRetCSLL,
      item.valorII,
      item.valorIOF,
      item.valorIPI,
      0,
      item.valorICMSST,
      0,
      0,
      0,
      /* Retornos */
      v_valorBasePagamento,
      v_valorImpSomaPagamento,
      v_valorImpDiminuiPagamento,
      v_valorLiquidoItem);
    -- 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,
      valorImpostosSomaPagamento    = v_valorImpSomaPagamento,
      valorImpostosDiminuiPagamento = v_valorImpDiminuiPagamento,
      valorLiquidoItem              = v_valorLiquidoItem
    WHERE idItemOrcamento           = item.idItemOrcamento;
    -- Totaliza cabeçalho
    IF item.servico = 1 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 item.usarPrecoAVista = 1 AND item.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_valorImpSomaPagamento    := r_cab_valorImpSomaPagamento + v_valorImpSomaPagamento;
    r_cab_valorImpDiminuiPagamento := r_cab_valorImpDiminuiPagamento + v_valorImpDiminuiPagamento;
    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_modeloDocumento,
      p_cab_entradaSaida,
      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_valorImpSomaPagamento,
      r_cab_valorImpDiminuiPagamento,
      r_cab_valorLiquidoItem,
      p_modDoc_diminuiDescontoPrUnit,
      p_modDoc_somaAcrescimosPrUnit,
      p_modDoc_somaFreteSeguroPrUnit,
      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_valorImpSomaPagamento,
      r_cab_valorImpDiminuiPagamento,
      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_modeloDocumento          IN NUMBER,
    p_cab_entradaSaida             IN CHAR,
    p_cab_devolucaoAnulacaoRetorno IN NUMBER,
    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,
    p_cab_valorDescCustoOpGeral    IN NUMBER,
    p_cab_valorAcrescCustoOpGeral  IN NUMBER,
    p_cab_valorAcrescExtempGeral   IN NUMBER,
    p_modDoc_diminuiDescontoPrUnit IN NUMBER,
    p_modDoc_somaAcrescimosPrUnit  IN NUMBER,
    p_modDoc_somaFreteSeguroPrUnit IN NUMBER,
    p_modDoc_habilitaControleEntr  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_valorImpSomaPagamento    OUT NUMBER,
    r_cab_valorImpDiminuiPagamento 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_valorBaseRateio              NUMBER;
    v_valorBaseRateioFrete         NUMBER;
    v_valorBaseRateioFinanceiro    NUMBER;
    v_valorBaseRateioFinancFrete   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_valorImpSomaPagamento        NUMBER;
    v_valorImpDiminuiPagamento     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;
    CURSOR c_item IS
      SELECT
        a.idItemPreDocumento,
        a.servico,
        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.valorIRRF,
        a.valorINSS,
        a.valorRetPIS,
        a.valorRetCOFINS,
        a.valorRetCSLL,
        a.valorII,
        a.valorIOF,
        a.valorIPI,
        a.valorIPIDevolucao,
        a.valorPIS,
        a.valorPISST,
        a.valorCOFINS,
        a.valorCOFINSST,
        a.valorCreditoSimplesNacional,
        a.valorICMS,
        a.valorICMSST,
        a.valorImpostosSomaPagamento,
        a.valorImpostosDiminuiPagamento,
        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,
        CASE WHEN p_modDoc_habilitaControleEntr = 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
      FROM MOPREDOCUMXITENS a
      WHERE a.preDocumento = p_cab_preDocumento
      AND a.cancelado = 0
      ORDER BY a.sequencia;
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_valorImpSomaPagamento    := 0;
  r_cab_valorImpDiminuiPagamento := 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
          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 p_modDoc_diminuiDescontoPrUnit = 1
                OR p_modDoc_somaAcrescimosPrUnit  = 1
                OR p_modDoc_somaFreteSeguroPrUnit = 1
              THEN a.valorProdutoServicoBruto
              ELSE a.valorProdutoServico
            END
            - a.valorDescontoItem
            + a.valorAcrescimoItem))
        THEN 0
        WHEN COALESCE ((
          SELECT SUM (CASE WHEN p_modDoc_diminuiDescontoPrUnit = 1 OR p_modDoc_somaAcrescimosPrUnit = 1 or p_modDoc_somaFreteSeguroPrUnit = 1 THEN a.valorProdutoServicoBruto ELSE a.valorProdutoServico END - a.valorDescontoItem + a.valorAcrescimoItem)
          FROM MOPREDOCUMXITENS a
          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 p_modDoc_diminuiDescontoPrUnit = 1 OR p_modDoc_somaAcrescimosPrUnit = 1 or p_modDoc_somaFreteSeguroPrUnit = 1 THEN a.valorProdutoServicoBruto ELSE a.valorProdutoServico END - a.valorDescontoItem + a.valorAcrescimoItem)
          FROM MOPREDOCUMXITENS a
          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_modDoc_habilitaControleEntr = 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 p_modDoc_diminuiDescontoPrUnit = 1 OR p_modDoc_somaAcrescimosPrUnit = 1 or p_modDoc_somaFreteSeguroPrUnit = 1 THEN a.valorProdutoServicoBruto ELSE a.valorProdutoServico END - a.valorDescontoItem + a.valorAcrescimoItem),0),
    COALESCE(SUM(CASE WHEN p_modDoc_habilitaControleEntr = 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 p_modDoc_diminuiDescontoPrUnit = 1 OR p_modDoc_somaAcrescimosPrUnit = 1 or p_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 p_modDoc_diminuiDescontoPrUnit = 1 OR p_modDoc_somaAcrescimosPrUnit = 1 or p_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_modDoc_habilitaControleEntr = 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 p_modDoc_diminuiDescontoPrUnit = 1 OR p_modDoc_somaAcrescimosPrUnit = 1 or p_modDoc_somaFreteSeguroPrUnit = 1 THEN a.valorProdutoServicoBruto ELSE a.valorProdutoServico - a.valorDescontoItem + a.valorAcrescimoItem END ELSE 0 END),0),
    COALESCE(SUM(CASE WHEN p_modDoc_diminuiDescontoPrUnit = 1 OR p_modDoc_somaAcrescimosPrUnit = 1 or p_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 p_modDoc_diminuiDescontoPrUnit = 1 OR p_modDoc_somaAcrescimosPrUnit = 1 or p_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 p_modDoc_diminuiDescontoPrUnit = 1 OR p_modDoc_somaAcrescimosPrUnit = 1 or p_modDoc_somaFreteSeguroPrUnit = 1 THEN a.valorProdutoServicoBruto ELSE a.valorProdutoServico END - a.valorDescontoItem + a.valorAcrescimoItem ELSE 0 END),0),
    COALESCE(SUM(CASE WHEN p_modDoc_diminuiDescontoPrUnit = 1 OR p_modDoc_somaAcrescimosPrUnit = 1 or p_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 p_modDoc_diminuiDescontoPrUnit = 1 OR p_modDoc_somaAcrescimosPrUnit = 1 or p_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 p_modDoc_diminuiDescontoPrUnit = 1 OR p_modDoc_somaAcrescimosPrUnit = 1 or p_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 p_modDoc_diminuiDescontoPrUnit = 1 OR p_modDoc_somaAcrescimosPrUnit = 1 or p_modDoc_somaFreteSeguroPrUnit = 1 THEN a.valorProdutoServicoBruto ELSE a.valorProdutoServico END - a.valorDescontoItem + a.valorAcrescimoItem ELSE 0 END),0)
  INTO
    v_rateioFretePorControleEntr,
    v_valorBaseRateio,
    v_valorBaseRateioFrete,
    v_valorBaseRateioFinanceiro,
    v_valorBaseRateioFinancFrete,
    v_valorBaseRateioOutrasDespGer,
    v_valorBaseRateioOutrasDespFin,
    v_valorBaseRateioDescontoGeral,
    v_valorBaseRateioPagamento,
    v_valorBaseRateioPagamFinanc,
    v_valorBaseRateioPagamDesconto,
    v_valorBaseRateioPagamFinDesc
  FROM MOPREDOCUMXITENS a
  WHERE a.preDocumento = p_cab_preDocumento
  AND a.cancelado = 0;

  -- Efetua rateio
  FOR item IN c_item LOOP
    v_idItemPreDocUltimoItem       := item.idItemPreDocumento;
    v_precoUnitario                := item.precoUnitario;
    v_precoUnitarioConvertido      := item.precoUnitarioConvertido;
    v_valorProdutoServico          := item.valorProdutoServico;
    v_valorBasePagamento           := item.valorBasePagamento;
    v_valorFreteTotal              := item.valorFreteTotal;
    v_valorSeguroTotal             := item.valorSeguroTotal;
    v_valorDescontoTotal           := item.valorDescontoTotal;
    v_valorOutrasDespesasTotal     := item.valorOutrasDespesasTotal;
    v_valorAdicFreteMarinMerTotal  := item.valorAdicFreteMarinhaMerTotal;
    v_valorDespesasAduaneirasTotal := item.valorDespesasAduaneirasTotal;
    v_valorImpSomaPagamento        := item.valorImpostosSomaPagamento;
    v_valorImpDiminuiPagamento     := item.valorImpostosDiminuiPagamento;
    v_valorLiquidoItem             := item.valorLiquidoItem;
    v_valorDescontoCustoOpTotal    := item.valorDescontoCustoOpTotal;
    v_valorAcrescimoCustoOpTotal   := item.valorAcrescimoCustoOpTotal;
    v_precoCustoOperacao           := item.precoCustoOperacao;
    v_valorCustoOperacao           := item.valorCustoOperacao;
    v_precoCMV                     := item.precoCMV;
    v_valorCMV                     := item.valorCMV;
    v_valorAcrescimoExtempSubtotal := item.valorAcrescimoExtempSubtotal;
    v_valorAcrescimoExtempTotal    := item.valorAcrescimoExtempTotal;

    IF CASE WHEN v_rateioFretePorControleEntr = 1 THEN v_valorBaseRateioFinancFrete ELSE v_valorBaseRateioFinanceiro END > 0 THEN
      IF item.geraFinanceiro = 1 AND (v_rateioFretePorControleEntr = 0 OR item.rateioFrete = 1) THEN
        v_idItemPreDocRateioFrete := item.idItemPreDocumento;
      END IF;
    ELSIF v_rateioFretePorControleEntr = 0 OR item.rateioFrete = 1 THEN
      v_idItemPreDocRateioFrete := item.idItemPreDocumento;
    END IF;

    -- v_valorFreteGeral
    v_auxNumber := v_residuoFreteGeral +
      CASE
        WHEN CASE WHEN v_rateioFretePorControleEntr = 1 THEN v_valorBaseRateioFinancFrete ELSE v_valorBaseRateioFinanceiro END > 0
        THEN 
          CASE
            WHEN item.geraFinanceiro = 1 AND (v_rateioFretePorControleEntr = 0 OR item.rateioFrete = 1)
            THEN
              CASE
                WHEN CASE WHEN v_rateioFretePorControleEntr = 1 THEN v_valorBaseRateioFinancFrete ELSE v_valorBaseRateioFinanceiro END = 0
                THEN 0
                ELSE p_cab_valorFreteGeral
                  * (CASE WHEN p_modDoc_diminuiDescontoPrUnit = 1 OR p_modDoc_somaAcrescimosPrUnit = 1 or p_modDoc_somaFreteSeguroPrUnit = 1 THEN item.valorProdutoServicoBruto ELSE item.valorProdutoServico END - item.valorDescontoItem + item.valorAcrescimoItem)
                  / CASE WHEN v_rateioFretePorControleEntr = 1 THEN v_valorBaseRateioFinancFrete ELSE v_valorBaseRateioFinanceiro END
              END
            ELSE 0
          END
        WHEN v_rateioFretePorControleEntr = 0 OR item.rateioFrete = 1
        THEN
          CASE
            WHEN CASE WHEN v_rateioFretePorControleEntr = 1 THEN v_valorBaseRateioFrete ELSE v_valorBaseRateio END = 0
            THEN 0
            ELSE p_cab_valorFreteGeral
              * (CASE WHEN p_modDoc_diminuiDescontoPrUnit = 1 OR p_modDoc_somaAcrescimosPrUnit = 1 or p_modDoc_somaFreteSeguroPrUnit = 1 THEN item.valorProdutoServicoBruto ELSE item.valorProdutoServico END - item.valorDescontoItem + item.valorAcrescimoItem)
              / CASE WHEN v_rateioFretePorControleEntr = 1 THEN v_valorBaseRateioFrete ELSE v_valorBaseRateio END
          END
        ELSE 0
      END;
    v_valorFreteGeral    := ROUND (v_auxNumber,2);
    v_residuoFreteGeral  := v_auxNumber - v_valorFreteGeral;
    v_saldoRatFreteGeral := v_saldoRatFreteGeral - v_valorFreteGeral;

    -- v_valorSeguroGeral
    v_auxNumber := v_residuoSeguroGeral +
      CASE
        WHEN CASE WHEN v_rateioFretePorControleEntr = 1 THEN v_valorBaseRateioFinancFrete ELSE v_valorBaseRateioFinanceiro END > 0
        THEN 
          CASE
            WHEN item.geraFinanceiro = 1 AND (v_rateioFretePorControleEntr = 0 OR item.rateioFrete = 1)
            THEN
              CASE
                WHEN CASE WHEN v_rateioFretePorControleEntr = 1 THEN v_valorBaseRateioFinancFrete ELSE v_valorBaseRateioFinanceiro END = 0
                THEN 0
                ELSE p_cab_valorSeguroGeral
                  * (CASE WHEN p_modDoc_diminuiDescontoPrUnit = 1 OR p_modDoc_somaAcrescimosPrUnit = 1 or p_modDoc_somaFreteSeguroPrUnit = 1 THEN item.valorProdutoServicoBruto ELSE item.valorProdutoServico END - item.valorDescontoItem + item.valorAcrescimoItem)
                  / CASE WHEN v_rateioFretePorControleEntr = 1 THEN v_valorBaseRateioFinancFrete ELSE v_valorBaseRateioFinanceiro END
              END
            ELSE 0
          END
        WHEN v_rateioFretePorControleEntr = 0 OR item.rateioFrete = 1
        THEN
          CASE
            WHEN CASE WHEN v_rateioFretePorControleEntr = 1 THEN v_valorBaseRateioFrete ELSE v_valorBaseRateio END = 0
            THEN 0
            ELSE p_cab_valorSeguroGeral
              * (CASE WHEN p_modDoc_diminuiDescontoPrUnit = 1 OR p_modDoc_somaAcrescimosPrUnit = 1 or p_modDoc_somaFreteSeguroPrUnit = 1 THEN item.valorProdutoServicoBruto ELSE item.valorProdutoServico END - item.valorDescontoItem + item.valorAcrescimoItem)
              / CASE WHEN v_rateioFretePorControleEntr = 1 THEN v_valorBaseRateioFrete ELSE v_valorBaseRateio END
          END
        ELSE 0
      END;
    v_valorSeguroGeral := ROUND (v_auxNumber,2);
    v_residuoSeguroGeral := v_auxNumber - v_valorSeguroGeral;
    v_saldoRatSeguroGeral := v_saldoRatSeguroGeral - v_valorSeguroGeral;

    -- v_valorAdicFreteMarinMerGeral
    v_auxNumber := v_residuoAdicFreteMarinGeral +
      CASE
        WHEN v_valorBaseRateioFinanceiro > 0 AND item.geraFinanceiro = 1
        THEN p_cab_valorAdicFreteMarinGeral
          * (CASE WHEN p_modDoc_diminuiDescontoPrUnit = 1 OR p_modDoc_somaAcrescimosPrUnit = 1 or p_modDoc_somaFreteSeguroPrUnit = 1 THEN item.valorProdutoServicoBruto ELSE item.valorProdutoServico END - item.valorDescontoItem + item.valorAcrescimoItem)
          / v_valorBaseRateioFinanceiro
        WHEN v_valorBaseRateioFinanceiro <= 0 AND v_valorBaseRateio > 0
        THEN p_cab_valorAdicFreteMarinGeral
          * (CASE WHEN p_modDoc_diminuiDescontoPrUnit = 1 OR p_modDoc_somaAcrescimosPrUnit = 1 or p_modDoc_somaFreteSeguroPrUnit = 1 THEN item.valorProdutoServicoBruto ELSE item.valorProdutoServico END - item.valorDescontoItem + item.valorAcrescimoItem)
          / v_valorBaseRateio
        ELSE 0
      END;
    v_valorAdicFreteMarinMerGeral := ROUND (v_auxNumber,2);
    v_residuoAdicFreteMarinGeral := v_auxNumber - v_valorAdicFreteMarinMerGeral;
    v_saldoRatAdicFreteMarinGeral := v_saldoRatAdicFreteMarinGeral - v_valorAdicFreteMarinMerGeral;

    -- v_valorDespesasAduaneirasGeral
    v_auxNumber := v_residuoDespesasAduanGeral +
      CASE
        WHEN v_valorBaseRateioFinanceiro > 0 AND item.geraFinanceiro = 1
        THEN p_cab_valorDespesasAduanGeral
          * (CASE WHEN p_modDoc_diminuiDescontoPrUnit = 1 OR p_modDoc_somaAcrescimosPrUnit = 1 or p_modDoc_somaFreteSeguroPrUnit = 1 THEN item.valorProdutoServicoBruto ELSE item.valorProdutoServico END - item.valorDescontoItem + item.valorAcrescimoItem)
          / v_valorBaseRateioFinanceiro
        WHEN v_valorBaseRateioFinanceiro <= 0 AND v_valorBaseRateio > 0
        THEN p_cab_valorDespesasAduanGeral
          * (CASE WHEN p_modDoc_diminuiDescontoPrUnit = 1 OR p_modDoc_somaAcrescimosPrUnit = 1 or p_modDoc_somaFreteSeguroPrUnit = 1 THEN item.valorProdutoServicoBruto ELSE item.valorProdutoServico END - item.valorDescontoItem + item.valorAcrescimoItem)
          / v_valorBaseRateio
        ELSE 0
      END;
    v_valorDespesasAduaneirasGeral := ROUND (v_auxNumber,2);
    v_residuoDespesasAduanGeral := v_auxNumber - v_valorDespesasAduaneirasGeral;
    v_saldoRatDespesasAduanGeral := v_saldoRatDespesasAduanGeral - v_valorDespesasAduaneirasGeral;

    -- v_residuoDescCustoOpGeral
    v_auxNumber := v_residuoDescCustoOpGeral +
      CASE
        WHEN v_valorBaseRateioFinanceiro > 0 AND item.geraFinanceiro = 1
        THEN p_cab_valorDescCustoOpGeral
          * (CASE WHEN p_modDoc_diminuiDescontoPrUnit = 1 OR p_modDoc_somaAcrescimosPrUnit = 1 or p_modDoc_somaFreteSeguroPrUnit = 1 THEN item.valorProdutoServicoBruto ELSE item.valorProdutoServico END - item.valorDescontoItem + item.valorAcrescimoItem)
          / v_valorBaseRateioFinanceiro
        WHEN v_valorBaseRateioFinanceiro <= 0 AND v_valorBaseRateio > 0
        THEN p_cab_valorDescCustoOpGeral
          * (CASE WHEN p_modDoc_diminuiDescontoPrUnit = 1 OR p_modDoc_somaAcrescimosPrUnit = 1 or p_modDoc_somaFreteSeguroPrUnit = 1 THEN item.valorProdutoServicoBruto ELSE item.valorProdutoServico END - item.valorDescontoItem + item.valorAcrescimoItem)
          / v_valorBaseRateio
        ELSE 0
      END;
    v_valorDescontoCustoOpGeral := ROUND (v_auxNumber,2);
    v_residuoDescCustoOpGeral := v_auxNumber - v_valorDescontoCustoOpGeral;
    v_saldoRatDescCustoOpGeral := v_saldoRatDescCustoOpGeral - v_valorDescontoCustoOpGeral;

    -- v_valorAcrescimoCustoOpGeral
    v_auxNumber := v_residuoAcrescCustoOpGeral +
      CASE
        WHEN v_valorBaseRateioFinanceiro > 0 AND item.geraFinanceiro = 1
        THEN p_cab_valorAcrescCustoOpGeral
          * (CASE WHEN p_modDoc_diminuiDescontoPrUnit = 1 OR p_modDoc_somaAcrescimosPrUnit = 1 or p_modDoc_somaFreteSeguroPrUnit = 1 THEN item.valorProdutoServicoBruto ELSE item.valorProdutoServico END - item.valorDescontoItem + item.valorAcrescimoItem)
          / v_valorBaseRateioFinanceiro
        WHEN v_valorBaseRateioFinanceiro <= 0 AND v_valorBaseRateio > 0
        THEN p_cab_valorAcrescCustoOpGeral
          * (CASE WHEN p_modDoc_diminuiDescontoPrUnit = 1 OR p_modDoc_somaAcrescimosPrUnit = 1 or p_modDoc_somaFreteSeguroPrUnit = 1 THEN item.valorProdutoServicoBruto ELSE item.valorProdutoServico END - item.valorDescontoItem + item.valorAcrescimoItem)
          / v_valorBaseRateio
        ELSE 0
      END;
    v_valorAcrescimoCustoOpGeral := ROUND (v_auxNumber,2);
    v_residuoAcrescCustoOpGeral := v_auxNumber - v_valorAcrescimoCustoOpGeral;
    v_saldoRatAcrescCustoOpGeral := v_saldoRatAcrescCustoOpGeral - v_valorAcrescimoCustoOpGeral;

    -- v_valorAcrescimoExtempGeral
    v_auxNumber := v_residuoAcrescExtempGeral +
      CASE
        WHEN v_valorBaseRateioFinanceiro > 0 AND item.geraFinanceiro = 1
        THEN p_cab_valorAcrescExtempGeral
          * (CASE WHEN p_modDoc_diminuiDescontoPrUnit = 1 OR p_modDoc_somaAcrescimosPrUnit = 1 or p_modDoc_somaFreteSeguroPrUnit = 1 THEN item.valorProdutoServicoBruto ELSE item.valorProdutoServico END - item.valorDescontoItem + item.valorAcrescimoItem)
          / v_valorBaseRateioFinanceiro
        WHEN v_valorBaseRateioFinanceiro <= 0 AND v_valorBaseRateio > 0
        THEN p_cab_valorAcrescExtempGeral
          * (CASE WHEN p_modDoc_diminuiDescontoPrUnit = 1 OR p_modDoc_somaAcrescimosPrUnit = 1 or p_modDoc_somaFreteSeguroPrUnit = 1 THEN item.valorProdutoServicoBruto ELSE item.valorProdutoServico END - item.valorDescontoItem + item.valorAcrescimoItem)
          / v_valorBaseRateio
        ELSE 0
      END;
    v_valorAcrescimoExtempGeral := ROUND (v_auxNumber,2);
    v_residuoAcrescExtempGeral := v_auxNumber - v_valorAcrescimoExtempGeral;
    v_saldoRatAcrescExtempGeral := v_saldoRatAcrescExtempGeral - v_valorAcrescimoExtempGeral;

    -- v_valorOutrasDespesasGeral
    v_auxNumber := v_residuoOutrasDespesasGeral +
      CASE
        WHEN v_valorBaseRateioOutrasDespFin > 0 AND item.geraFinanceiro = 1
        THEN p_cab_valorOutrasDespesasGeral
          * (CASE WHEN p_modDoc_diminuiDescontoPrUnit = 1 OR p_modDoc_somaAcrescimosPrUnit = 1 or p_modDoc_somaFreteSeguroPrUnit = 1 THEN item.valorProdutoServicoBruto ELSE item.valorProdutoServico - item.valorDescontoItem + item.valorAcrescimoItem END)
          / v_valorBaseRateioOutrasDespFin
        WHEN v_valorBaseRateioOutrasDespFin <= 0 AND v_valorBaseRateioOutrasDespGer > 0
        THEN p_cab_valorOutrasDespesasGeral
          * (CASE WHEN p_modDoc_diminuiDescontoPrUnit = 1 OR p_modDoc_somaAcrescimosPrUnit = 1 or p_modDoc_somaFreteSeguroPrUnit = 1 THEN item.valorProdutoServicoBruto ELSE item.valorProdutoServico - item.valorDescontoItem + item.valorAcrescimoItem END)
          / v_valorBaseRateioOutrasDespGer
        ELSE 0
      END;
    v_valorOutrasDespesasGeral := ROUND (v_auxNumber,2);
    v_residuoOutrasDespesasGeral := v_auxNumber - v_valorOutrasDespesasGeral;
    v_saldoRatOutrasDespesasGeral := v_saldoRatOutrasDespesasGeral - v_valorOutrasDespesasGeral;

    -- v_valorOutrasDespesasPagamento
    v_auxNumber := v_residuoOutrasDespPagamento +
      CASE
        WHEN v_valorBaseRateioPagamFinanc > 0 AND item.geraFinanceiro = 1
        THEN p_cab_valorOutrasDespPagamento
          * (CASE WHEN p_modDoc_diminuiDescontoPrUnit = 1 OR p_modDoc_somaAcrescimosPrUnit = 1 or p_modDoc_somaFreteSeguroPrUnit = 1 THEN item.valorProdutoServicoBruto ELSE item.valorProdutoServico END - item.valorDescontoItem + item.valorAcrescimoItem)
          / v_valorBaseRateioPagamFinanc
        WHEN v_valorBaseRateioPagamFinanc <= 0 AND v_valorBaseRateioPagamento > 0
        THEN p_cab_valorOutrasDespPagamento
          * (CASE WHEN p_modDoc_diminuiDescontoPrUnit = 1 OR p_modDoc_somaAcrescimosPrUnit = 1 or p_modDoc_somaFreteSeguroPrUnit = 1 THEN item.valorProdutoServicoBruto ELSE item.valorProdutoServico END - item.valorDescontoItem + item.valorAcrescimoItem)
          / v_valorBaseRateioPagamento
        ELSE 0
      END;
    v_valorOutrasDespesasPagamento := ROUND (v_auxNumber,2);
    v_residuoOutrasDespPagamento := v_auxNumber - v_valorOutrasDespesasPagamento;
    v_saldoRatOutrasDespPagamento := v_saldoRatOutrasDespPagamento - v_valorOutrasDespesasPagamento;

    -- v_valorJurosPagamento
    v_auxNumber := v_residuoJurosPagamento +
      CASE
        WHEN v_valorBaseRateioPagamFinanc > 0 AND item.geraFinanceiro = 1
        THEN p_cab_valorJurosPagamento
          * (CASE WHEN p_modDoc_diminuiDescontoPrUnit = 1 OR p_modDoc_somaAcrescimosPrUnit = 1 or p_modDoc_somaFreteSeguroPrUnit = 1 THEN item.valorProdutoServicoBruto ELSE item.valorProdutoServico END - item.valorDescontoItem + item.valorAcrescimoItem)
          / v_valorBaseRateioPagamFinanc
        WHEN v_valorBaseRateioPagamFinanc <= 0 AND v_valorBaseRateioPagamento > 0
        THEN p_cab_valorJurosPagamento
          * (CASE WHEN p_modDoc_diminuiDescontoPrUnit = 1 OR p_modDoc_somaAcrescimosPrUnit = 1 or p_modDoc_somaFreteSeguroPrUnit = 1 THEN item.valorProdutoServicoBruto ELSE item.valorProdutoServico END - item.valorDescontoItem + item.valorAcrescimoItem)
          / v_valorBaseRateioPagamento
        ELSE 0
      END;
    v_valorJurosPagamento := ROUND (v_auxNumber,2);
    v_residuoJurosPagamento := v_auxNumber - v_valorJurosPagamento;
    v_saldoRatJurosPagamento := v_saldoRatJurosPagamento - v_valorJurosPagamento;

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

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

    -- Recalcula Valores
    ADD_CALCULA_TOTAIS_ITEM(
      p_cab_tipoPagamentoFrete,
      p_modDoc_diminuiDescontoPrUnit,
      p_modDoc_somaAcrescimosPrUnit,
      p_modDoc_somaFreteSeguroPrUnit,
      item.quantidade,
      item.quantidadeConvertida,
      item.precoUnitarioBruto,
      item.acrescimoUnitarioComposicao,
      item.precoUnitario,
      item.valorDescontoItem,
      item.valorAcrescimoItem,
      item.valorFreteItem,
      item.valorSeguroItem,
      item.valorAdicFreteMarinhaMerItem,
      item.valorDespesasAduaneirasItem,
      v_valorFreteGeral,
      v_valorSeguroGeral,
      v_valorDescontoGeral,
      v_valorOutrasDespesasGeral,
      v_valorAdicFreteMarinMerGeral,
      v_valorDespesasAduaneirasGeral,
      v_valorDescontoPagamento,
      v_valorOutrasDespesasPagamento,
      v_valorJurosPagamento,
      item.quantidadeExtemporanea,
      item.acrescimoUnitarioExtemporaneo,
      item.valorAcrescimoExtempItem,
      v_valorAcrescimoExtempGeral,
      /* Retornos */
      v_precoUnitario,
      v_precoUnitarioConvertido,
      v_valorProdutoServico,
      v_auxNumber,
      v_auxNumber,
      v_valorFreteTotal,
      v_valorSeguroTotal,
      v_valorDescontoTotal,
      v_valorOutrasDespesasTotal,
      v_valorAdicFreteMarinMerTotal,
      v_valorDespesasAduaneirasTotal,
      v_valorAcrescimoExtempSubtotal,
      v_valorAcrescimoExtempTotal);
    IF p_cab_impostosEditados = 0 
        OR v_valorProdutoServico <> item.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 item.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 item.valorSeguroTotal END
        OR v_valorDescontoTotal <> item.valorDescontoTotal
        OR v_valorOutrasDespesasTotal <> item.valorOutrasDespesasTotal
        OR v_valorAdicFreteMarinMerTotal <> item.valorAdicFreteMarinhaMerTotal
        OR v_valorDespesasAduaneirasTotal <> item.valorDespesasAduaneirasTotal
        OR v_precoUnitario <> item.precoUnitario
        OR v_valorProdutoServico <> item.valorProdutoServico
    THEN
      r_calcularImpostosItem := 1;
    END IF;
    ADD_CALCULA_VALOR_LIQUIDO (
      0,
      p_cab_tipoPagamentoFrete,
      item.geraFinanceiro,
      v_valorProdutoServico,
      v_valorDescontoPagamento,
      v_valorOutrasDespesasPagamento,
      v_valorJurosPagamento,
      v_valorFreteTotal,
      v_valorSeguroTotal,
      v_valorDescontoTotal,
      v_valorOutrasDespesasTotal,
      item.valorIRRF,
      item.valorINSS,
      item.valorRetPIS,
      item.valorRetCOFINS,
      item.valorRetCSLL,
      item.valorII,
      item.valorIOF,
      item.valorIPI,
      item.valorIPIDevolucao,
      item.valorICMSST,
      0,
      0,
      v_valorAcrescimoExtempTotal,
      /* Retornos */
      v_valorBasePagamento,
      v_valorImpSomaPagamento,
      v_valorImpDiminuiPagamento,
      v_valorLiquidoItem);
    ADD_CALCULA_CUSTO_CMV (
      p_cab_modeloDocumento,
      p_cab_atualizaCustoMedio,
      0,
      item.quantidade,
      item.valorII,
      item.valorIOF,
      item.valorIPI,
      item.valorIPIDevolucao,
      item.valorPIS,
      item.valorPISST,
      item.valorCOFINS,
      item.valorCOFINSST,
      item.valorCreditoSimplesNacional,
      item.valorICMS,
      item.valorICMSST,
      0,
      v_valorLiquidoItem,
      item.valorDescontoCustoOpItem,
      v_valorDescontoCustoOpGeral,
      item.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,
      valorImpostosSomaPagamento    = v_valorImpSomaPagamento,
      valorImpostosDiminuiPagamento = v_valorImpDiminuiPagamento,
      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        = item.idItemPreDocumento;
    IF item.servico = 1 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 item.usarPrecoAVista = 1 AND item.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_valorImpSomaPagamento    := r_cab_valorImpSomaPagamento + v_valorImpSomaPagamento;
    r_cab_valorImpDiminuiPagamento := r_cab_valorImpDiminuiPagamento + v_valorImpDiminuiPagamento;
    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_modeloDocumento,
      p_cab_entradaSaida,
      p_cab_devolucaoAnulacaoRetorno,
      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_valorImpSomaPagamento,
      r_cab_valorImpDiminuiPagamento,
      r_cab_valorLiquidoItem,
      r_cab_valorDescCustoOpTotal,
      r_cab_valorAcrescCustoOpTotal,
      r_cab_valorCustoOperacao,
      r_cab_valorCMV,
      r_cab_valorAcrescExtempTotal,
      p_modDoc_diminuiDescontoPrUnit,
      p_modDoc_somaAcrescimosPrUnit,
      p_modDoc_somaFreteSeguroPrUnit,
      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_valorImpSomaPagamento,
      r_cab_valorImpDiminuiPagamento,
      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_modeloDocumento          IN NUMBER,
    p_cab_entradaSaida             IN CHAR,
    p_cab_devolucaoAnulacaoRetorno IN NUMBER,
    p_cab_atualizaCustoMedio       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_modDoc_diminuiDescontoPrUnit IN NUMBER,
    p_modDoc_somaAcrescimosPrUnit  IN NUMBER,
    p_modDoc_somaFreteSeguroPrUnit IN NUMBER,
    p_modDoc_habilitaControleEntr  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_valorImpSomaPagamento    OUT NUMBER,
    r_cab_valorImpDiminuiPagamento 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_valorBaseRateio              NUMBER;
    v_valorBaseRateioFrete         NUMBER;
    v_valorBaseRateioFinanceiro    NUMBER;
    v_valorBaseRateioFinancFrete   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_valorImpSomaPagamento        NUMBER;
    v_valorImpDiminuiPagamento     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;
    CURSOR c_item IS
      SELECT
        a.idItemDocFiscal,
        a.servico,
        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.valorIRRF,
        a.valorINSS,
        a.valorRetPIS,
        a.valorRetCOFINS,
        a.valorRetCSLL,
        a.valorII,
        a.valorIOF,
        a.valorIPI,
        a.valorIPIDevolucao,
        a.valorPIS,
        a.valorPISST,
        a.valorCOFINS,
        a.valorCOFINSST,
        a.valorCreditoSimplesNacional,
        a.valorICMS,
        a.valorICMSST,
        a.valorICMSSTEscrituracao,
        a.somarICMSST,
        a.valorImpostosSomaPagamento,
        a.valorImpostosDiminuiPagamento,
        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,
        CASE WHEN p_modDoc_habilitaControleEntr = 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
      FROM MODOCFISCALXITENS a
      WHERE a.idDocumentoFiscal = p_cab_idDocumentoFiscal
      AND a.cancelado = 0
      ORDER BY a.sequencia;
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_valorImpSomaPagamento    := 0;
  r_cab_valorImpDiminuiPagamento := 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
          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 p_modDoc_diminuiDescontoPrUnit = 1
                OR p_modDoc_somaAcrescimosPrUnit  = 1
                OR p_modDoc_somaFreteSeguroPrUnit = 1
              THEN a.valorProdutoServicoBruto
              ELSE a.valorProdutoServico
            END
            - a.valorDescontoItem
            + a.valorAcrescimoItem))
        THEN 0
        WHEN COALESCE ((
          SELECT SUM (CASE WHEN p_modDoc_diminuiDescontoPrUnit = 1 OR p_modDoc_somaAcrescimosPrUnit = 1 or p_modDoc_somaFreteSeguroPrUnit = 1 THEN a.valorProdutoServicoBruto ELSE a.valorProdutoServico END - a.valorDescontoItem + a.valorAcrescimoItem)
          FROM MODOCFISCALXITENS a
          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 p_modDoc_diminuiDescontoPrUnit = 1 OR p_modDoc_somaAcrescimosPrUnit = 1 or p_modDoc_somaFreteSeguroPrUnit = 1 THEN a.valorProdutoServicoBruto ELSE a.valorProdutoServico END - a.valorDescontoItem + a.valorAcrescimoItem)
          FROM MODOCFISCALXITENS a
          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_modDoc_habilitaControleEntr = 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 p_modDoc_diminuiDescontoPrUnit = 1 OR p_modDoc_somaAcrescimosPrUnit = 1 or p_modDoc_somaFreteSeguroPrUnit = 1 THEN a.valorProdutoServicoBruto ELSE a.valorProdutoServico END - a.valorDescontoItem + a.valorAcrescimoItem),0),
    COALESCE(SUM(CASE WHEN p_modDoc_habilitaControleEntr = 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 p_modDoc_diminuiDescontoPrUnit = 1 OR p_modDoc_somaAcrescimosPrUnit = 1 or p_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 p_modDoc_diminuiDescontoPrUnit = 1 OR p_modDoc_somaAcrescimosPrUnit = 1 or p_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_modDoc_habilitaControleEntr = 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 p_modDoc_diminuiDescontoPrUnit = 1 OR p_modDoc_somaAcrescimosPrUnit = 1 or p_modDoc_somaFreteSeguroPrUnit = 1 THEN a.valorProdutoServicoBruto ELSE a.valorProdutoServico END - a.valorDescontoItem + a.valorAcrescimoItem ELSE 0 END),0),
    COALESCE(SUM(CASE WHEN p_modDoc_diminuiDescontoPrUnit = 1 OR p_modDoc_somaAcrescimosPrUnit = 1 or p_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 p_modDoc_diminuiDescontoPrUnit = 1 OR p_modDoc_somaAcrescimosPrUnit = 1 or p_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 p_modDoc_diminuiDescontoPrUnit = 1 OR p_modDoc_somaAcrescimosPrUnit = 1 or p_modDoc_somaFreteSeguroPrUnit = 1 THEN a.valorProdutoServicoBruto ELSE a.valorProdutoServico - a.valorDescontoItem + a.valorAcrescimoItem END ELSE 0 END),0),
    COALESCE(SUM(CASE WHEN p_modDoc_diminuiDescontoPrUnit = 1 OR p_modDoc_somaAcrescimosPrUnit = 1 or p_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 p_modDoc_diminuiDescontoPrUnit = 1 OR p_modDoc_somaAcrescimosPrUnit = 1 or p_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 p_modDoc_diminuiDescontoPrUnit = 1 OR p_modDoc_somaAcrescimosPrUnit = 1 or p_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 p_modDoc_diminuiDescontoPrUnit = 1 OR p_modDoc_somaAcrescimosPrUnit = 1 or p_modDoc_somaFreteSeguroPrUnit = 1 THEN a.valorProdutoServicoBruto ELSE a.valorProdutoServico END - a.valorDescontoItem + a.valorAcrescimoItem ELSE 0 END),0)
  INTO
    v_rateioFretePorControleEntr,
    v_valorBaseRateio,
    v_valorBaseRateioFrete,
    v_valorBaseRateioFinanceiro,
    v_valorBaseRateioFinancFrete,
    v_valorBaseRateioOutrasDespGer,
    v_valorBaseRateioOutrasDespFin,
    v_valorBaseRateioDescontoGeral,
    v_valorBaseRateioPagamento,
    v_valorBaseRateioPagamFinanc,
    v_valorBaseRateioPagamDesconto,
    v_valorBaseRateioPagamFinDesc
  FROM MODOCFISCALXITENS a
  WHERE a.idDocumentoFiscal = p_cab_idDocumentoFiscal
  AND a.cancelado = 0;

  -- Efetua rateio
  FOR item IN c_item LOOP
    v_idItemDocFiscalUltimoItem    := item.idItemDocFiscal;
    v_precoUnitario                := item.precoUnitario;
    v_precoUnitarioConvertido      := item.precoUnitarioConvertido;
    v_valorProdutoServico          := item.valorProdutoServico;
    v_valorBasePagamento           := item.valorBasePagamento;
    v_valorFreteTotal              := item.valorFreteTotal;
    v_valorSeguroTotal             := item.valorSeguroTotal;
    v_valorDescontoTotal           := item.valorDescontoTotal;
    v_valorOutrasDespesasTotal     := item.valorOutrasDespesasTotal;
    v_valorAdicFreteMarinMerTotal  := item.valorAdicFreteMarinhaMerTotal;
    v_valorDespesasAduaneirasTotal := item.valorDespesasAduaneirasTotal;
    v_valorImpSomaPagamento        := item.valorImpostosSomaPagamento;
    v_valorImpDiminuiPagamento     := item.valorImpostosDiminuiPagamento;
    v_valorLiquidoItem             := item.valorLiquidoItem;
    v_valorDescontoCustoOpTotal    := item.valorDescontoCustoOpTotal;
    v_valorAcrescimoCustoOpTotal   := item.valorAcrescimoCustoOpTotal;
    v_precoCustoOperacao           := item.precoCustoOperacao;
    v_valorCustoOperacao           := item.valorCustoOperacao;
    v_precoCMV                     := item.precoCMV;
    v_valorCMV                     := item.valorCMV;
    v_valorAcrescimoExtempSubtotal := item.valorAcrescimoExtempSubtotal;
    v_valorAcrescimoExtempTotal    := item.valorAcrescimoExtempTotal;

    IF CASE WHEN v_rateioFretePorControleEntr = 1 THEN v_valorBaseRateioFinancFrete ELSE v_valorBaseRateioFinanceiro END > 0 THEN
      IF item.geraFinanceiro = 1 AND (v_rateioFretePorControleEntr = 0 OR item.rateioFrete = 1) THEN
        v_idItemDocFiscalRateioFrete := item.idItemDocFiscal;
      END IF;
    ELSIF v_rateioFretePorControleEntr = 0 OR item.rateioFrete = 1 THEN
      v_idItemDocFiscalRateioFrete := item.idItemDocFiscal;
    END IF;

    -- v_valorFreteGeral
    v_auxNumber := v_residuoFreteGeral +
      CASE
        WHEN CASE WHEN v_rateioFretePorControleEntr = 1 THEN v_valorBaseRateioFinancFrete ELSE v_valorBaseRateioFinanceiro END > 0
        THEN 
          CASE
            WHEN item.geraFinanceiro = 1 AND (v_rateioFretePorControleEntr = 0 OR item.rateioFrete = 1)
            THEN
              CASE
                WHEN CASE WHEN v_rateioFretePorControleEntr = 1 THEN v_valorBaseRateioFinancFrete ELSE v_valorBaseRateioFinanceiro END = 0
                THEN 0
                ELSE p_cab_valorFreteGeral
                  * (CASE WHEN p_modDoc_diminuiDescontoPrUnit = 1 OR p_modDoc_somaAcrescimosPrUnit = 1 or p_modDoc_somaFreteSeguroPrUnit = 1 THEN item.valorProdutoServicoBruto ELSE item.valorProdutoServico END - item.valorDescontoItem + item.valorAcrescimoItem)
                  / CASE WHEN v_rateioFretePorControleEntr = 1 THEN v_valorBaseRateioFinancFrete ELSE v_valorBaseRateioFinanceiro END
              END
            ELSE 0
          END
        WHEN v_rateioFretePorControleEntr = 0 OR item.rateioFrete = 1
        THEN
          CASE
            WHEN CASE WHEN v_rateioFretePorControleEntr = 1 THEN v_valorBaseRateioFrete ELSE v_valorBaseRateio END = 0
            THEN 0
            ELSE p_cab_valorFreteGeral
              * (CASE WHEN p_modDoc_diminuiDescontoPrUnit = 1 OR p_modDoc_somaAcrescimosPrUnit = 1 or p_modDoc_somaFreteSeguroPrUnit = 1 THEN item.valorProdutoServicoBruto ELSE item.valorProdutoServico END - item.valorDescontoItem + item.valorAcrescimoItem)
              / CASE WHEN v_rateioFretePorControleEntr = 1 THEN v_valorBaseRateioFrete ELSE v_valorBaseRateio END
          END
        ELSE 0
      END;
    v_valorFreteGeral := ROUND (v_auxNumber,2);
    v_residuoFreteGeral := v_auxNumber - v_valorFreteGeral;
    v_saldoRatFreteGeral := v_saldoRatFreteGeral - v_valorFreteGeral;

    -- v_valorSeguroGeral
    v_auxNumber := v_residuoSeguroGeral +
      CASE
        WHEN CASE WHEN v_rateioFretePorControleEntr = 1 THEN v_valorBaseRateioFinancFrete ELSE v_valorBaseRateioFinanceiro END > 0
        THEN 
          CASE
            WHEN item.geraFinanceiro = 1 AND (v_rateioFretePorControleEntr = 0 OR item.rateioFrete = 1)
            THEN
              CASE
                WHEN CASE WHEN v_rateioFretePorControleEntr = 1 THEN v_valorBaseRateioFinancFrete ELSE v_valorBaseRateioFinanceiro END = 0
                THEN 0
                ELSE p_cab_valorSeguroGeral
                  * (CASE WHEN p_modDoc_diminuiDescontoPrUnit = 1 OR p_modDoc_somaAcrescimosPrUnit = 1 or p_modDoc_somaFreteSeguroPrUnit = 1 THEN item.valorProdutoServicoBruto ELSE item.valorProdutoServico END - item.valorDescontoItem + item.valorAcrescimoItem)
                  / CASE WHEN v_rateioFretePorControleEntr = 1 THEN v_valorBaseRateioFinancFrete ELSE v_valorBaseRateioFinanceiro END
              END
            ELSE 0
          END
        WHEN v_rateioFretePorControleEntr = 0 OR item.rateioFrete = 1
        THEN
          CASE
            WHEN CASE WHEN v_rateioFretePorControleEntr = 1 THEN v_valorBaseRateioFrete ELSE v_valorBaseRateio END = 0
            THEN 0
            ELSE p_cab_valorSeguroGeral
              * (CASE WHEN p_modDoc_diminuiDescontoPrUnit = 1 OR p_modDoc_somaAcrescimosPrUnit = 1 or p_modDoc_somaFreteSeguroPrUnit = 1 THEN item.valorProdutoServicoBruto ELSE item.valorProdutoServico END - item.valorDescontoItem + item.valorAcrescimoItem)
              / CASE WHEN v_rateioFretePorControleEntr = 1 THEN v_valorBaseRateioFrete ELSE v_valorBaseRateio END
          END
        ELSE 0
      END;
    v_valorSeguroGeral := ROUND (v_auxNumber,2);
    v_residuoSeguroGeral := v_auxNumber - v_valorSeguroGeral;
    v_saldoRatSeguroGeral := v_saldoRatSeguroGeral - v_valorSeguroGeral;

    -- v_valorAdicFreteMarinMerGeral
    v_auxNumber := v_residuoAdicFreteMarinGeral +
      CASE
        WHEN v_valorBaseRateioFinanceiro > 0 AND item.geraFinanceiro = 1
        THEN p_cab_valorAdicFreteMarinGeral
          * (CASE WHEN p_modDoc_diminuiDescontoPrUnit = 1 OR p_modDoc_somaAcrescimosPrUnit = 1 or p_modDoc_somaFreteSeguroPrUnit = 1 THEN item.valorProdutoServicoBruto ELSE item.valorProdutoServico END - item.valorDescontoItem + item.valorAcrescimoItem)
          / v_valorBaseRateioFinanceiro
        WHEN v_valorBaseRateioFinanceiro <= 0 AND v_valorBaseRateio > 0
        THEN p_cab_valorAdicFreteMarinGeral
          * (CASE WHEN p_modDoc_diminuiDescontoPrUnit = 1 OR p_modDoc_somaAcrescimosPrUnit = 1 or p_modDoc_somaFreteSeguroPrUnit = 1 THEN item.valorProdutoServicoBruto ELSE item.valorProdutoServico END - item.valorDescontoItem + item.valorAcrescimoItem)
          / v_valorBaseRateio
        ELSE 0
      END;
    v_valorAdicFreteMarinMerGeral := ROUND (v_auxNumber,2);
    v_residuoAdicFreteMarinGeral := v_auxNumber - v_valorAdicFreteMarinMerGeral;
    v_saldoRatAdicFreteMarinGeral := v_saldoRatAdicFreteMarinGeral - v_valorAdicFreteMarinMerGeral;

    -- v_valorDespesasAduaneirasGeral
    v_auxNumber := v_residuoDespesasAduanGeral +
      CASE
        WHEN v_valorBaseRateioFinanceiro > 0 AND item.geraFinanceiro = 1
        THEN p_cab_valorDespesasAduanGeral
          * (CASE WHEN p_modDoc_diminuiDescontoPrUnit = 1 OR p_modDoc_somaAcrescimosPrUnit = 1 or p_modDoc_somaFreteSeguroPrUnit = 1 THEN item.valorProdutoServicoBruto ELSE item.valorProdutoServico END - item.valorDescontoItem + item.valorAcrescimoItem)
          / v_valorBaseRateioFinanceiro
        WHEN v_valorBaseRateioFinanceiro <= 0 AND v_valorBaseRateio > 0
        THEN p_cab_valorDespesasAduanGeral
          * (CASE WHEN p_modDoc_diminuiDescontoPrUnit = 1 OR p_modDoc_somaAcrescimosPrUnit = 1 or p_modDoc_somaFreteSeguroPrUnit = 1 THEN item.valorProdutoServicoBruto ELSE item.valorProdutoServico END - item.valorDescontoItem + item.valorAcrescimoItem)
          / v_valorBaseRateio
        ELSE 0
      END;
    v_valorDespesasAduaneirasGeral := ROUND (v_auxNumber,2);
    v_residuoDespesasAduanGeral := v_auxNumber - v_valorDespesasAduaneirasGeral;
    v_saldoRatDespesasAduanGeral := v_saldoRatDespesasAduanGeral - v_valorDespesasAduaneirasGeral;

    -- v_valorDescontoCustoOpGeral
    v_auxNumber := v_residuoDescCustoOpGeral +
      CASE
        WHEN v_valorBaseRateioFinanceiro > 0 AND item.geraFinanceiro = 1
        THEN p_cab_valorDescCustoOpGeral
          * (CASE WHEN p_modDoc_diminuiDescontoPrUnit = 1 OR p_modDoc_somaAcrescimosPrUnit = 1 or p_modDoc_somaFreteSeguroPrUnit = 1 THEN item.valorProdutoServicoBruto ELSE item.valorProdutoServico END - item.valorDescontoItem + item.valorAcrescimoItem)
          / v_valorBaseRateioFinanceiro
        WHEN v_valorBaseRateioFinanceiro <= 0 AND v_valorBaseRateio > 0
        THEN p_cab_valorDescCustoOpGeral
          * (CASE WHEN p_modDoc_diminuiDescontoPrUnit = 1 OR p_modDoc_somaAcrescimosPrUnit = 1 or p_modDoc_somaFreteSeguroPrUnit = 1 THEN item.valorProdutoServicoBruto ELSE item.valorProdutoServico END - item.valorDescontoItem + item.valorAcrescimoItem)
          / v_valorBaseRateio
        ELSE 0
      END;
    v_valorDescontoCustoOpGeral := ROUND (v_auxNumber,2);
    v_residuoDescCustoOpGeral := v_auxNumber - v_valorDescontoCustoOpGeral;
    v_saldoRatDescCustoOpGeral := v_saldoRatDescCustoOpGeral - v_valorDescontoCustoOpGeral;

    -- v_valorAcrescimoCustoOpGeral
    v_auxNumber := v_residuoAcrescCustoOpGeral +
      CASE
        WHEN v_valorBaseRateioFinanceiro > 0 AND item.geraFinanceiro = 1
        THEN p_cab_valorAcrescCustoOpGeral
          * (CASE WHEN p_modDoc_diminuiDescontoPrUnit = 1 OR p_modDoc_somaAcrescimosPrUnit = 1 or p_modDoc_somaFreteSeguroPrUnit = 1 THEN item.valorProdutoServicoBruto ELSE item.valorProdutoServico END - item.valorDescontoItem + item.valorAcrescimoItem)
          / v_valorBaseRateioFinanceiro
        WHEN v_valorBaseRateioFinanceiro <= 0 AND v_valorBaseRateio > 0
        THEN p_cab_valorAcrescCustoOpGeral
          * (CASE WHEN p_modDoc_diminuiDescontoPrUnit = 1 OR p_modDoc_somaAcrescimosPrUnit = 1 or p_modDoc_somaFreteSeguroPrUnit = 1 THEN item.valorProdutoServicoBruto ELSE item.valorProdutoServico END - item.valorDescontoItem + item.valorAcrescimoItem)
          / v_valorBaseRateio
        ELSE 0
      END;
    v_valorAcrescimoCustoOpGeral := ROUND (v_auxNumber,2);
    v_residuoAcrescCustoOpGeral := v_auxNumber - v_valorAcrescimoCustoOpGeral;
    v_saldoRatAcrescCustoOpGeral := v_saldoRatAcrescCustoOpGeral - v_valorAcrescimoCustoOpGeral;

    -- v_valorAcrescimoExtempGeral
    v_auxNumber := v_residuoAcrescExtempGeral +
      CASE
        WHEN v_valorBaseRateioFinanceiro > 0 AND item.geraFinanceiro = 1
        THEN p_cab_valorAcrescExtempGeral
          * (CASE WHEN p_modDoc_diminuiDescontoPrUnit = 1 OR p_modDoc_somaAcrescimosPrUnit = 1 or p_modDoc_somaFreteSeguroPrUnit = 1 THEN item.valorProdutoServicoBruto ELSE item.valorProdutoServico END - item.valorDescontoItem + item.valorAcrescimoItem)
          / v_valorBaseRateioFinanceiro
        WHEN v_valorBaseRateioFinanceiro <= 0 AND v_valorBaseRateio > 0
        THEN p_cab_valorAcrescExtempGeral
          * (CASE WHEN p_modDoc_diminuiDescontoPrUnit = 1 OR p_modDoc_somaAcrescimosPrUnit = 1 or p_modDoc_somaFreteSeguroPrUnit = 1 THEN item.valorProdutoServicoBruto ELSE item.valorProdutoServico END - item.valorDescontoItem + item.valorAcrescimoItem)
          / v_valorBaseRateio
        ELSE 0
      END;
    v_valorAcrescimoExtempGeral := ROUND (v_auxNumber,2);
    v_residuoAcrescExtempGeral := v_auxNumber - v_valorAcrescimoExtempGeral;
    v_saldoRatAcrescExtempGeral := v_saldoRatAcrescExtempGeral - v_valorAcrescimoExtempGeral;

    -- v_valorOutrasDespesasGeral
    v_auxNumber := v_residuoOutrasDespesasGeral +
      CASE
        WHEN v_valorBaseRateioOutrasDespFin > 0 AND item.geraFinanceiro = 1
        THEN p_cab_valorOutrasDespesasGeral
          * (CASE WHEN p_modDoc_diminuiDescontoPrUnit = 1 OR p_modDoc_somaAcrescimosPrUnit = 1 or p_modDoc_somaFreteSeguroPrUnit = 1 THEN item.valorProdutoServicoBruto ELSE item.valorProdutoServico - item.valorDescontoItem + item.valorAcrescimoItem END)
          / v_valorBaseRateioOutrasDespFin
        WHEN v_valorBaseRateioOutrasDespFin <= 0 AND v_valorBaseRateioOutrasDespGer > 0
        THEN p_cab_valorOutrasDespesasGeral
          * (CASE WHEN p_modDoc_diminuiDescontoPrUnit = 1 OR p_modDoc_somaAcrescimosPrUnit = 1 or p_modDoc_somaFreteSeguroPrUnit = 1 THEN item.valorProdutoServicoBruto ELSE item.valorProdutoServico - item.valorDescontoItem + item.valorAcrescimoItem END)
          / v_valorBaseRateioOutrasDespGer
        ELSE 0
      END;
    v_valorOutrasDespesasGeral := ROUND (v_auxNumber,2);
    v_residuoOutrasDespesasGeral := v_auxNumber - v_valorOutrasDespesasGeral;
    v_saldoRatOutrasDespesasGeral := v_saldoRatOutrasDespesasGeral - v_valorOutrasDespesasGeral;

    -- v_valorOutrasDespesasPagamento
    v_auxNumber := v_residuoOutrasDespPagamento +
      CASE
        WHEN v_valorBaseRateioPagamFinanc > 0 AND item.geraFinanceiro = 1
        THEN p_cab_valorOutrasDespPagamento
          * (CASE WHEN p_modDoc_diminuiDescontoPrUnit = 1 OR p_modDoc_somaAcrescimosPrUnit = 1 or p_modDoc_somaFreteSeguroPrUnit = 1 THEN item.valorProdutoServicoBruto ELSE item.valorProdutoServico END - item.valorDescontoItem + item.valorAcrescimoItem)
          / v_valorBaseRateioPagamFinanc
        WHEN v_valorBaseRateioPagamFinanc <= 0 AND v_valorBaseRateioPagamento > 0
        THEN p_cab_valorOutrasDespPagamento
          * (CASE WHEN p_modDoc_diminuiDescontoPrUnit = 1 OR p_modDoc_somaAcrescimosPrUnit = 1 or p_modDoc_somaFreteSeguroPrUnit = 1 THEN item.valorProdutoServicoBruto ELSE item.valorProdutoServico END - item.valorDescontoItem + item.valorAcrescimoItem)
          / v_valorBaseRateioPagamento
        ELSE 0
      END;
    v_valorOutrasDespesasPagamento := ROUND (v_auxNumber,2);
    v_residuoOutrasDespPagamento := v_auxNumber - v_valorOutrasDespesasPagamento;
    v_saldoRatOutrasDespPagamento := v_saldoRatOutrasDespPagamento - v_valorOutrasDespesasPagamento;

    -- v_valorJurosPagamento
    v_auxNumber := v_residuoJurosPagamento +
      CASE
        WHEN v_valorBaseRateioPagamFinanc > 0 AND item.geraFinanceiro = 1
        THEN p_cab_valorJurosPagamento
          * (CASE WHEN p_modDoc_diminuiDescontoPrUnit = 1 OR p_modDoc_somaAcrescimosPrUnit = 1 or p_modDoc_somaFreteSeguroPrUnit = 1 THEN item.valorProdutoServicoBruto ELSE item.valorProdutoServico END - item.valorDescontoItem + item.valorAcrescimoItem)
          / v_valorBaseRateioPagamFinanc
        WHEN v_valorBaseRateioPagamFinanc <= 0 AND v_valorBaseRateioPagamento > 0
        THEN p_cab_valorJurosPagamento
          * (CASE WHEN p_modDoc_diminuiDescontoPrUnit = 1 OR p_modDoc_somaAcrescimosPrUnit = 1 or p_modDoc_somaFreteSeguroPrUnit = 1 THEN item.valorProdutoServicoBruto ELSE item.valorProdutoServico END - item.valorDescontoItem + item.valorAcrescimoItem)
          / v_valorBaseRateioPagamento
        ELSE 0
      END;
    v_valorJurosPagamento := ROUND (v_auxNumber,2);
    v_residuoJurosPagamento := v_auxNumber - v_valorJurosPagamento;
    v_saldoRatJurosPagamento := v_saldoRatJurosPagamento - v_valorJurosPagamento;

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

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

    -- Recalcula Valores
    ADD_CALCULA_TOTAIS_ITEM(
      p_cab_tipoPagamentoFrete,
      p_modDoc_diminuiDescontoPrUnit,
      p_modDoc_somaAcrescimosPrUnit,
      p_modDoc_somaFreteSeguroPrUnit,
      item.quantidade,
      item.quantidadeConvertida,
      item.precoUnitarioBruto,
      item.acrescimoUnitarioComposicao,
      item.precoUnitario,
      item.valorDescontoItem,
      item.valorAcrescimoItem,
      item.valorFreteItem,
      item.valorSeguroItem,
      item.valorAdicFreteMarinhaMerItem,
      item.valorDespesasAduaneirasItem,
      v_valorFreteGeral,
      v_valorSeguroGeral,
      v_valorDescontoGeral,
      v_valorOutrasDespesasGeral,
      v_valorAdicFreteMarinMerGeral,
      v_valorDespesasAduaneirasGeral,
      v_valorDescontoPagamento,
      v_valorOutrasDespesasPagamento,
      v_valorJurosPagamento,
      item.quantidadeExtemporanea,
      item.acrescimoUnitarioExtemporaneo,
      item.valorAcrescimoExtempItem,
      v_valorAcrescimoExtempGeral,
      /* Retornos */
      v_precoUnitario,
      v_precoUnitarioConvertido,
      v_valorProdutoServico,
      v_auxNumber,
      v_auxNumber,
      v_valorFreteTotal,
      v_valorSeguroTotal,
      v_valorDescontoTotal,
      v_valorOutrasDespesasTotal,
      v_valorAdicFreteMarinMerTotal,
      v_valorDespesasAduaneirasTotal,
      v_valorAcrescimoExtempSubtotal,
      v_valorAcrescimoExtempTotal);
    IF p_cab_impostosEditados = 0 
        OR v_valorProdutoServico <> item.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 item.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 item.valorSeguroTotal END
        OR v_valorDescontoTotal <> item.valorDescontoTotal
        OR v_valorOutrasDespesasTotal <> item.valorOutrasDespesasTotal
        OR v_valorAdicFreteMarinMerTotal <> item.valorAdicFreteMarinhaMerTotal
        OR v_valorDespesasAduaneirasTotal <> item.valorDespesasAduaneirasTotal
        OR v_precoUnitario <> item.precoUnitario
        OR v_valorProdutoServico <> item.valorProdutoServico
    THEN
      r_calcularImpostosItem := 1;
    END IF;
    ADD_CALCULA_VALOR_LIQUIDO (
      p_cab_nfFornecedor,
      p_cab_tipoPagamentoFrete,
      item.geraFinanceiro,
      v_valorProdutoServico,
      v_valorDescontoPagamento,
      v_valorOutrasDespesasPagamento,
      v_valorJurosPagamento,
      v_valorFreteTotal,
      v_valorSeguroTotal,
      v_valorDescontoTotal,
      v_valorOutrasDespesasTotal,
      item.valorIRRF,
      item.valorINSS,
      item.valorRetPIS,
      item.valorRetCOFINS,
      item.valorRetCSLL,
      item.valorII,
      item.valorIOF,
      item.valorIPI,
      item.valorIPIDevolucao,
      item.valorICMSST,
      item.valorICMSSTEscrituracao,
      item.somarICMSST,
      v_valorAcrescimoExtempTotal,
      /* Retornos */
      v_valorBasePagamento,
      v_valorImpSomaPagamento,
      v_valorImpDiminuiPagamento,
      v_valorLiquidoItem);
    ADD_CALCULA_CUSTO_CMV (
      p_cab_modeloDocumento,
      p_cab_atualizaCustoMedio,
      p_cab_nfFornecedor,
      item.quantidade,
      item.valorII,
      item.valorIOF,
      item.valorIPI,
      item.valorIPIDevolucao,
      item.valorPIS,
      item.valorPISST,
      item.valorCOFINS,
      item.valorCOFINSST,
      item.valorCreditoSimplesNacional,
      item.valorICMS,
      item.valorICMSST,
      item.valorICMSSTEscrituracao,
      v_valorLiquidoItem,
      item.valorDescontoCustoOpItem,
      v_valorDescontoCustoOpGeral,
      item.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,
      valorImpostosSomaPagamento    = v_valorImpSomaPagamento,
      valorImpostosDiminuiPagamento = v_valorImpDiminuiPagamento,
      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           = item.idItemDocFiscal;
    IF item.servico = 1 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 item.usarPrecoAVista = 1 AND item.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_valorImpSomaPagamento    := r_cab_valorImpSomaPagamento + v_valorImpSomaPagamento;
    r_cab_valorImpDiminuiPagamento := r_cab_valorImpDiminuiPagamento + v_valorImpDiminuiPagamento;
    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_modeloDocumento,
      p_cab_entradaSaida,
      p_cab_devolucaoAnulacaoRetorno,
      p_cab_atualizaCustoMedio,
      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_valorImpSomaPagamento,
      r_cab_valorImpDiminuiPagamento,
      r_cab_valorLiquidoItem,
      r_cab_valorDescCustoOpTotal,
      r_cab_valorAcrescCustoOpTotal,
      r_cab_valorCustoOperacao,
      r_cab_valorCMV,
      r_cab_valorAcrescExtempTotal,
      p_modDoc_diminuiDescontoPrUnit,
      p_modDoc_somaAcrescimosPrUnit,
      p_modDoc_somaFreteSeguroPrUnit,
      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_valorImpSomaPagamento,
      r_cab_valorImpDiminuiPagamento,
      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;

/

DROP TABLE TEMPRECEBIMENTO;
-- TEMPRECEBIMENTO
CREATE GLOBAL TEMPORARY TABLE TEMPRECEBIMENTO
  (
    uniqueMachineID               VARCHAR (18) DEFAULT ' ' NOT NULL,
    contadorSessao                NUMERIC (14,0) DEFAULT 0 NOT NULL,
    idFinanceiro                  NUMERIC (14,0) DEFAULT 0 NOT NULL,
    idBaixaFinanceiro             NUMERIC (14,0) DEFAULT 0 NOT NULL,
    ordenacao                     VARCHAR (256) DEFAULT ' ' NOT NULL,
    quebra                        VARCHAR (256) DEFAULT ' ' NOT NULL,
    selecionado                   NUMERIC (1,0) DEFAULT 0 NOT NULL,
    legenda                       NUMERIC (3,0) DEFAULT 0 NOT NULL,
    documento                     VARCHAR (60) DEFAULT ' ' NOT NULL,
    contaFinanceira               VARCHAR (60) DEFAULT ' ' NOT NULL,
    contaFinanceiraDescricao      VARCHAR (120) DEFAULT ' ' NOT NULL,
    carteiraFinanceira            NUMERIC (4,0) DEFAULT 0 NOT NULL,
    carteiraFinanceiraDescricao   VARCHAR (256) DEFAULT ' ' NOT NULL,
    meioPagamento                 NUMERIC (2,0) DEFAULT 0 NOT NULL,
    meioPagamentoDescricao        VARCHAR (60) DEFAULT ' ' NOT NULL,
    bandeiraCartaoDebCred         NUMERIC (2,0) DEFAULT 0 NOT NULL,
    bandeiraCartaoDebCrDescricao  VARCHAR (120) DEFAULT ' ' NOT NULL,
    pagamentoRecebimento          CHAR (1) DEFAULT ' ' NOT NULL,
    cotacao                       NUMERIC (12,4) DEFAULT 0 NOT NULL,
    valor                         NUMERIC (15,2) DEFAULT 0 NOT NULL,
    saldo                         NUMERIC (15,2) DEFAULT 0 NOT NULL,
    saldoIndexado                 NUMERIC (15,6) DEFAULT 0 NOT NULL,
    valorVariacaoIndexador        NUMERIC (15,2) DEFAULT 0 NOT NULL,
    valorDescontoAteVencimento    NUMERIC (15,2) DEFAULT 0 NOT NULL,
    valorDescontoAntecipado       NUMERIC (15,2) DEFAULT 0 NOT NULL,
    valorJurosDeMora              NUMERIC (15,2) DEFAULT 0 NOT NULL,
    valorMulta                    NUMERIC (15,2) DEFAULT 0 NOT NULL,
    tarifaCartao                  NUMERIC (15,8) DEFAULT 0 NOT NULL,
    valorTarifaCartao             NUMERIC (15,2) DEFAULT 0 NOT NULL,
    valorLiquido                  NUMERIC (15,2) DEFAULT 0 NOT NULL,
    saldoVariacaoIndexador        NUMERIC (15,2) DEFAULT 0 NOT NULL,
    saldoDescontoAteVencimento    NUMERIC (15,2) DEFAULT 0 NOT NULL,
    saldoDescontoAntecipado       NUMERIC (15,2) DEFAULT 0 NOT NULL,
    saldoJurosDeMora              NUMERIC (15,2) DEFAULT 0 NOT NULL,
    saldoMulta                    NUMERIC (15,2) DEFAULT 0 NOT NULL,
    saldoTarifaCartao             NUMERIC (15,2) DEFAULT 0 NOT NULL,
    saldoLiquido                  NUMERIC (15,2) DEFAULT 0 NOT NULL
  ) ON COMMIT PRESERVE ROWS;
CREATE UNIQUE INDEX TEMPRECEBIMENTO_PK1 ON TEMPRECEBIMENTO (uniqueMachineID, contadorSessao, idFinanceiro, idBaixaFinanceiro);
CREATE INDEX TEMPRECEBIMENTO_K2 ON TEMPRECEBIMENTO (uniqueMachineID, contadorSessao, ordenacao);
CREATE INDEX TEMPRECEBIMENTO_K3 ON TEMPRECEBIMENTO (uniqueMachineID, contadorSessao, documento);

INSERT INTO SIUNIDADESMEDIDA (unidadeMedida, descricao, ativo, casasDecimaisUnidadeMedida, casasDecimaisMinimoImpressao, permiteInformarTotalItem, observacoes) values ('CA', 'CA - Cartela', 1, 0, 0, 0, ' ');
INSERT INTO SIUNIDADESMEDIDA (unidadeMedida, descricao, ativo, casasDecimaisUnidadeMedida, casasDecimaisMinimoImpressao, permiteInformarTotalItem, observacoes) values ('FR', 'FR - Frasco', 1, 0, 0, 0, ' ');

COMMIT;

UPDATE SIUNIDADESMEDIDA SET descricao = 'CT - Quilate', casasDecimaisUnidadeMedida = 4 WHERE unidadeMedida = 'CT';

COMMIT;

UPDATE CAPRODUTOS SET unidadeMedida = 'CA' WHERE unidadeMedida = 'CT';
UPDATE CAPRODUTOS SET unidadeMedidaVenda = 'CA' WHERE unidadeMedidaVenda = 'CT';
UPDATE PAATIVIDADESSERVICO SET unidadeMedida = 'CA' WHERE unidadeMedida = 'CT';
UPDATE CAPRODUTOXFORNECEDORES SET unidadeMedidaCompra = 'CA' WHERE unidadeMedidaCompra = 'CT';
UPDATE MOORCAMENTOXITENS SET unidadeMedidaConversao = 'CA' WHERE unidadeMedidaConversao = 'CT';
UPDATE MOPREDOCUMXITENS SET unidadeMedidaConversao = 'CA' WHERE unidadeMedidaConversao = 'CT';
UPDATE MODOCFISCALXITENS SET unidadeMedidaConversao = 'CA' WHERE unidadeMedidaConversao = 'CT';
UPDATE MODOCUMENTOTRANSFXITENS SET unidadeMedidaConversao = 'CA' WHERE unidadeMedidaConversao = 'CT';
UPDATE MOMOTIVOSBLOQUEIOS SET unidadeMedidaConversao = 'CA' WHERE unidadeMedidaConversao = 'CT';

COMMIT;

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

COMMIT;

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

/*
*/