                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 (
      p_cab_origemDocumento,
      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_atualizaCustoMedio,
      0,
      item.modeloDocumento,
      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_origemDocumento,
      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_PRE_DOC_CALC_IMP_ITENS (
    p_config_64_casasDecSaidas     IN CHAR,
    p_config_209_filtrarGrupoEcon  IN NUMBER,
    p_config_330_redIcmsBasePisCof IN NUMBER,
    p_config_362_calcCustoPorGrade IN NUMBER,
    p_cab_preDocumento             IN NUMBER,
    p_cab_origemDocumento          IN NUMBER,
    p_cab_entradaSaida             IN CHAR,
    p_cab_devolucaoAnulacaoRetorno IN NUMBER,
    p_cab_atualizaCustoMedio       IN NUMBER,
    p_cab_estabelecimento          IN NUMBER,
    p_cab_dataEntradaSaida         IN DATE,
    p_cab_pessoa                   IN NUMBER,
    p_cab_localDestinoOperacao     IN CHAR,
    p_cab_indicadorConsumidorFinal IN CHAR,
    p_cab_tipoPagamentoFrete       IN CHAR,
    p_modDoc_diminuiDescontoPrUnit IN NUMBER,
    p_modDoc_somaAcrescimosPrUnit  IN NUMBER,
    p_modDoc_somaFreteSeguroPrUnit IN NUMBER,
    p_pess_indicadorInscricaoEstad IN CHAR,
    /* Retornos */
    r_cab_valorProdutos            OUT NUMBER,
    r_cab_valorServicos            OUT NUMBER,
    r_cab_valorBasePagamento       OUT NUMBER,
    r_cab_valorAVistaMinimo        OUT NUMBER,
    r_cab_valorFreteTotal          OUT NUMBER,
    r_cab_valorSeguroTotal         OUT NUMBER,
    r_cab_valorDescontoTotal       OUT NUMBER,
    r_cab_valorOutrasDespesasTotal OUT NUMBER,
    r_cab_valorAdicFreteMarinTotal OUT NUMBER,
    r_cab_valorDespesasAduanTotal  OUT NUMBER,
    r_cab_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)
IS
    v_auxNumber                    NUMBER;
    v_precoUnitario                NUMBER;
    v_precoUnitarioConvertido      NUMBER;
    v_valorProdutoServico          NUMBER;
    v_valorBasePagamento           NUMBER;
    v_valorFreteTotal              NUMBER;
    v_valorSeguroTotal             NUMBER;
    v_valorDescontoTotal           NUMBER;
    v_valorOutrasDespesasTotal     NUMBER;
    v_valorAdicFreteMarinMerTotal  NUMBER;
    v_valorDespesasAduaneirasTotal NUMBER;
    v_baseISSQN                    NUMBER;
    v_valorISSQN                   NUMBER;
    v_baseIRRF                     NUMBER;
    v_valorIRRF                    NUMBER;
    v_baseINSS                     NUMBER;
    v_valorINSS                    NUMBER;
    v_baseRetPIS                   NUMBER;
    v_valorRetPIS                  NUMBER;
    v_baseRetCOFINS                NUMBER;
    v_valorRetCOFINS               NUMBER;
    v_baseRetCSLL                  NUMBER;
    v_valorRetCSLL                 NUMBER;
    v_baseII                       NUMBER;
    v_valorII                      NUMBER;
    v_baseIOF                      NUMBER;
    v_valorIOF                     NUMBER;
    v_baseIPI                      NUMBER;
    v_valorIPI                     NUMBER;
    v_basePIS                      NUMBER;
    v_valorPIS                     NUMBER;
    v_basePISST                    NUMBER;
    v_valorPISST                   NUMBER;
    v_baseCOFINS                   NUMBER;
    v_valorCOFINS                  NUMBER;
    v_baseCOFINSST                 NUMBER;
    v_valorCOFINSST                NUMBER;
    v_baseCreditoSimplesNacional   NUMBER;
    v_valorCreditoSimplesNacional  NUMBER;
    v_baseICMS                     NUMBER;
    v_valorICMSOperacao            NUMBER;
    v_valorICMSDiferido            NUMBER;
    v_valorICMS                    NUMBER;
    v_valorICMSDesoneracao         NUMBER;
    v_baseICMSST                   NUMBER;
    v_valorICMSST                  NUMBER;
    v_baseICMSSTAnteriormente      NUMBER;
    v_valorICMSSTAnteriormente     NUMBER;
    v_valorICMSProprioSubstituto   NUMBER;
    v_baseICMSEfetivo              NUMBER;
    v_valorICMSEfetivo             NUMBER;
    v_baseICMSUFDestinatario       NUMBER;
    v_valorICMSUFDestinatario      NUMBER;
    v_baseICMSUFRemetente          NUMBER;
    v_valorICMSUFRemetente         NUMBER;
    v_baseFCP                      NUMBER;
    v_valorFCP                     NUMBER;
    v_baseFCPST                    NUMBER;
    v_valorFCPST                   NUMBER;
    v_baseFCPSTAnteriormente       NUMBER;
    v_valorFCPSTAnteriormente      NUMBER;
    v_baseFCPUFDestinatario        NUMBER;
    v_valorFCPUFDestinatario       NUMBER;
    v_baseEstimadaImpostos         NUMBER;
    v_valorEstimadoImpFederais     NUMBER;
    v_valorEstimadoImpEstaduais    NUMBER;
    v_valorEstimadoImpMunicipais   NUMBER;
    v_valorImpSomaPagamento        NUMBER;
    v_valorImpDiminuiPagamento     NUMBER;
    v_valorLiquidoItem             NUMBER;
    v_valorDescontoCustoOpTotal    NUMBER;
    v_valorAcrescimoCustoOpTotal   NUMBER;
    v_precoCustoOperacao           NUMBER;
    v_valorCustoOperacao           NUMBER;
    v_precoCMV                     NUMBER;
    v_valorCMV                     NUMBER;
    v_valorAcrescimoExtempSubtotal NUMBER;
    v_valorAcrescimoExtempTotal    NUMBER;
    CURSOR c_item IS
      SELECT
        a.*,
        gradProd.produto,
        gradProd.cor,
        gradProd.tamanho,
        prod.controleEstoque,
        prod.tipoProduto
      FROM MOPREDOCUMXITENS a
      JOIN CAGRADESPRODUTO gradProd ON gradProd.gradeProduto = a.gradeProduto
      JOIN CAPRODUTOS prod ON prod.produto = gradProd.produto
      WHERE a.preDocumento = p_cab_preDocumento
      AND a.cancelado = 0
      ORDER BY a.sequencia;
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;  
  FOR item IN c_item LOOP
    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_baseISSQN                    := item.baseISSQN;
    v_valorISSQN                   := item.valorISSQN;
    v_baseIRRF                     := item.baseIRRF;
    v_valorIRRF                    := item.valorIRRF;
    v_baseINSS                     := item.baseINSS;
    v_valorINSS                    := item.valorINSS;
    v_baseRetPIS                   := item.baseRetPIS;
    v_valorRetPIS                  := item.valorRetPIS;
    v_baseRetCOFINS                := item.baseRetCOFINS;
    v_valorRetCOFINS               := item.valorRetCOFINS;
    v_baseRetCSLL                  := item.baseRetCSLL;
    v_valorRetCSLL                 := item.valorRetCSLL;
    v_baseII                       := item.baseII;
    v_valorII                      := item.valorII;
    v_baseIOF                      := item.baseIOF;
    v_valorIOF                     := item.valorIOF;
    v_baseIPI                      := item.baseIPI;
    v_valorIPI                     := item.valorIPI;
    v_basePIS                      := item.basePIS;
    v_valorPIS                     := item.valorPIS;
    v_basePISST                    := item.basePISST;
    v_valorPISST                   := item.valorPISST;
    v_baseCOFINS                   := item.baseCOFINS;
    v_valorCOFINS                  := item.valorCOFINS;
    v_baseCOFINSST                 := item.baseCOFINSST;
    v_valorCOFINSST                := item.valorCOFINSST;
    v_baseCreditoSimplesNacional   := item.baseCreditoSimplesNacional;
    v_valorCreditoSimplesNacional  := item.valorCreditoSimplesNacional;
    v_baseICMS                     := item.baseICMS;
    v_valorICMSOperacao            := item.valorICMSOperacao;
    v_valorICMSDiferido            := item.valorICMSDiferido;
    v_valorICMS                    := item.valorICMS;
    v_valorICMSDesoneracao         := item.valorICMSDesoneracao;
    v_baseICMSST                   := item.baseICMSST;
    v_valorICMSST                  := item.valorICMSST;
    v_baseICMSSTAnteriormente      := item.baseICMSSTAnteriormente;
    v_valorICMSSTAnteriormente     := item.valorICMSSTAnteriormente;
    v_valorICMSProprioSubstituto   := item.valorICMSProprioSubstituto;
    v_baseICMSEfetivo              := item.baseICMSEfetivo;
    v_valorICMSEfetivo             := item.valorICMSEfetivo;
    v_baseICMSUFDestinatario       := item.baseICMSUFDestinatario;
    v_valorICMSUFDestinatario      := item.valorICMSUFDestinatario;
    v_baseICMSUFRemetente          := item.baseICMSUFRemetente;
    v_valorICMSUFRemetente         := item.valorICMSUFRemetente;
    v_baseFCP                      := item.baseFCP;
    v_valorFCP                     := item.valorFCP;
    v_baseFCPST                    := item.baseFCPST;
    v_valorFCPST                   := item.valorFCPST;
    v_baseFCPSTAnteriormente       := item.baseFCPSTAnteriormente;
    v_valorFCPSTAnteriormente      := item.valorFCPSTAnteriormente;
    v_baseFCPUFDestinatario        := item.baseFCPUFDestinatario;
    v_valorFCPUFDestinatario       := item.valorFCPUFDestinatario;
    v_baseEstimadaImpostos         := item.baseEstimadaImpostos;
    v_valorEstimadoImpFederais     := item.valorEstimadoImpFederais;
    v_valorEstimadoImpEstaduais    := item.valorEstimadoImpEstaduais;
    v_valorEstimadoImpMunicipais   := item.valorEstimadoImpMunicipais;
    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;
    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,
      item.valorFreteGeral,
      item.valorSeguroGeral,
      item.valorDescontoGeral,
      item.valorOutrasDespesasGeral,
      item.valorAdicFreteMarinhaMerGeral,
      item.valorDespesasAduaneirasGeral,
      item.valorDescontoPagamento,
      item.valorOutrasDespesasPagamento,
      item.valorJurosPagamento,
      item.quantidadeExtemporanea,
      item.acrescimoUnitarioExtemporaneo,
      item.valorAcrescimoExtempItem,
      item.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);
    ADD_CALCULA_IMPOSTOS_ITEM (
      p_config_64_casasDecSaidas,
      p_config_209_filtrarGrupoEcon,
      p_config_330_redIcmsBasePisCof,
      p_config_362_calcCustoPorGrade,
      p_cab_entradaSaida,
      p_cab_devolucaoAnulacaoRetorno,
      p_cab_estabelecimento,
      0,
      p_cab_dataEntradaSaida,
      p_cab_pessoa,
      p_cab_localDestinoOperacao,
      p_cab_indicadorConsumidorFinal,
      p_cab_tipoPagamentoFrete,
      p_pess_indicadorInscricaoEstad,
      item.personalizacao,
      item.quantidade,
      item.precoPautaTabelado,
      v_valorProdutoServico,
      v_valorFreteTotal,
      v_valorSeguroTotal,
      v_valorDescontoTotal,
      v_valorOutrasDespesasTotal,
      v_valorAdicFreteMarinMerTotal,
      v_valorDespesasAduaneirasTotal,
      item.cfop,
      1,
      item.indicadorISSQN,
      item.aliquotaISSQN,
      v_baseISSQN,
      v_valorISSQN,
      1,
      item.aliquotaIRRF,
      v_baseIRRF,
      v_valorIRRF,
      1,
      item.aliquotaINSS,
      v_baseINSS,
      v_valorINSS,
      1,
      item.retencaoPIS,
      v_baseRetPIS,
      v_valorRetPIS,
      1,
      item.retencaoCOFINS,
      v_baseRetCOFINS,
      v_valorRetCOFINS,
      1,
      item.retencaoCSLL,
      v_baseRetCSLL,
      v_valorRetCSLL,
      1,
      item.aliquotaII,
      v_baseII,
      v_valorII,
      1,
      item.aliquotaIOF,
      v_baseIOF,
      v_valorIOF,
      1,
      item.aliquotaIPI,
      item.valorAliquotaIPI,
      v_baseIPI,
      v_valorIPI,
      item.valorIPIDevolucao,
      1,
      item.aliquotaPIS,
      item.valorAliquotaPIS,
      v_basePIS,
      v_valorPIS,
      1,
      item.aliquotaPISST,
      item.valorAliquotaPISST,
      v_basePISST,
      v_valorPISST,
      1,
      item.aliquotaCOFINS,
      item.valorAliquotaCOFINS,
      v_baseCOFINS,
      v_valorCOFINS,
      1,
      item.aliquotaCOFINSST,
      item.valorAliquotaCOFINSST,
      v_baseCOFINSST,
      v_valorCOFINSST,
      1,
      item.stSimplesNacional,
      item.creditoSimplesNacional,
      v_baseCreditoSimplesNacional,
      v_valorCreditoSimplesNacional,
      1,
      item.stICMS,
      item.modalidadeBaseCalcICMS,
      item.reducaoBaseICMS,
      item.aliquotaICMS,
      item.diferimentoICMS,
      v_baseICMS,
      v_valorICMSOperacao,
      v_valorICMSDiferido,
      v_valorICMS,
      v_valorICMSDesoneracao,
      1,
      item.modalidadeBaseCalcICMSST,
      item.margemValorAdicionadoST,
      item.reducaoBaseST,
      item.aliquotaICMSST,
      v_baseICMSST,
      v_valorICMSST,
      1,
      v_baseICMSSTAnteriormente,
      v_valorICMSSTAnteriormente,
      v_valorICMSProprioSubstituto,
      item.reducaoBaseICMSEfetivo,
      item.aliquotaICMSEfetivo,
      v_baseICMSEfetivo,
      v_valorICMSEfetivo,
      0,
      '  ',
      0,
      0,
      0,
      0,
      0,
      0,
      0,
      0,
      0,
      0,
      0,
      1,
      item.aliquotaICMSUFDestinatario,
      item.aliquotaICMSInterestadual,
      item.partilhaICMSInterestadual,
      v_baseICMSUFDestinatario,
      v_valorICMSUFDestinatario,
      v_baseICMSUFRemetente,
      v_valorICMSUFRemetente,
      1,
      item.aliquotaFCP,
      v_baseFCP,
      v_valorFCP,
      item.aliquotaFCPST,
      v_baseFCPST,
      v_valorFCPST,
      item.aliquotaFCPSTAnteriormente,
      v_baseFCPSTAnteriormente,
      v_valorFCPSTAnteriormente,
      item.aliquotaFCPUFDestinatario,
      v_baseFCPUFDestinatario,
      v_valorFCPUFDestinatario,
      1,
      item.aliquotaEstimadaImpFederais,
      item.aliquotaEstimadaImpEstaduais,
      item.aliquotaEstimadaImpMunicipais,
      v_baseEstimadaImpostos,
      v_valorEstimadoImpFederais,
      v_valorEstimadoImpEstaduais,
      v_valorEstimadoImpMunicipais,
      item.produto,
      item.cor,
      item.tamanho,
      item.controleEstoque,
      item.tipoProduto,
      /* Retornos */
      v_baseISSQN,
      v_valorISSQN,
      v_baseIRRF,
      v_valorIRRF,
      v_baseINSS,
      v_valorINSS,
      v_baseRetPIS,
      v_valorRetPIS,
      v_baseRetCOFINS,
      v_valorRetCOFINS,
      v_baseRetCSLL,
      v_valorRetCSLL,
      v_baseII,
      v_valorII,
      v_baseIOF,
      v_valorIOF,
      v_baseIPI,
      v_valorIPI,
      v_basePIS,
      v_valorPIS,
      v_basePISST,
      v_valorPISST,
      v_baseCOFINS,
      v_valorCOFINS,
      v_baseCOFINSST,
      v_valorCOFINSST,
      v_baseCreditoSimplesNacional,
      v_valorCreditoSimplesNacional,
      v_baseICMS,
      v_valorICMSOperacao,
      v_valorICMSDiferido,
      v_valorICMS,
      v_valorICMSDesoneracao,
      v_baseICMSST,
      v_valorICMSST,
      v_baseICMSSTAnteriormente,
      v_valorICMSSTAnteriormente,
      v_valorICMSProprioSubstituto,
      v_baseICMSEfetivo,
      v_valorICMSEfetivo,
      v_auxNumber,
      v_auxNumber,
      v_auxNumber,
      v_auxNumber,
      v_auxNumber,
      v_baseICMSUFDestinatario,
      v_valorICMSUFDestinatario,
      v_baseICMSUFRemetente,
      v_valorICMSUFRemetente,
      v_baseFCP,
      v_valorFCP,
      v_baseFCPST,
      v_valorFCPST,
      v_baseFCPSTAnteriormente,
      v_valorFCPSTAnteriormente,
      v_baseFCPUFDestinatario,
      v_valorFCPUFDestinatario,
      v_baseEstimadaImpostos,
      v_valorEstimadoImpFederais,
      v_valorEstimadoImpEstaduais,
      v_valorEstimadoImpMunicipais);
    ADD_CALCULA_VALOR_LIQUIDO (
      p_cab_origemDocumento,
      0,
      p_cab_tipoPagamentoFrete,
      item.geraFinanceiro,
      v_valorProdutoServico,
      item.valorDescontoPagamento,
      item.valorOutrasDespesasPagamento,
      item.valorJurosPagamento,
      v_valorFreteTotal,
      v_valorSeguroTotal,
      v_valorDescontoTotal,
      v_valorOutrasDespesasTotal,
      v_valorIRRF,
      v_valorINSS,
      v_valorRetPIS,
      v_valorRetCOFINS,
      v_valorRetCSLL,
      v_valorII,
      v_valorIOF,
      v_valorIPI,
      item.valorIPIDevolucao,
      v_valorICMSST,
      0,
      0,
      v_valorAcrescimoExtempTotal,
      /* Retornos */
      v_valorBasePagamento,
      v_valorImpSomaPagamento,
      v_valorImpDiminuiPagamento,
      v_valorLiquidoItem);
    ADD_CALCULA_CUSTO_CMV (
      p_cab_atualizaCustoMedio,
      0,
      item.modeloDocumento,
      item.quantidade,
      v_valorII,
      v_valorIOF,
      v_valorIPI,
      item.valorIPIDevolucao,
      v_valorPIS,
      v_valorPISST,
      v_valorCOFINS,
      v_valorCOFINSST,
      v_valorCreditoSimplesNacional,
      v_valorICMS,
      v_valorICMSST,
      0,
      v_valorLiquidoItem,
      item.valorDescontoCustoOpItem,
      item.valorDescontoCustoOpGeral,
      item.valorAcrescimoCustoOpItem,
      item.valorAcrescimoCustoOpGeral,
      v_valorAcrescimoExtempTotal,
      /* Retornos */
      v_valorDescontoCustoOpTotal,
      v_valorAcrescimoCustoOpTotal,
      v_precoCustoOperacao,
      v_valorCustoOperacao,
      v_precoCMV,
      v_valorCMV);
    UPDATE MOPREDOCUMXITENS SET
      precoUnitario                 = v_precoUnitario,
      precoUnitarioConvertido       = v_precoUnitarioConvertido,
      valorProdutoServico           = v_valorProdutoServico,
      valorBasePagamento            = v_valorBasePagamento,
      valorFreteTotal               = v_valorFreteTotal,
      valorSeguroTotal              = v_valorSeguroTotal,
      valorDescontoTotal            = v_valorDescontoTotal,
      valorOutrasDespesasTotal      = v_valorOutrasDespesasTotal,
      valorAdicFreteMarinhaMerTotal = v_valorAdicFreteMarinMerTotal,
      valorDespesasAduaneirasTotal  = v_valorDespesasAduaneirasTotal,
      baseISSQN                     = v_baseISSQN,
      valorISSQN                    = v_valorISSQN,
      baseIRRF                      = v_baseIRRF,
      valorIRRF                     = v_valorIRRF,
      baseINSS                      = v_baseINSS,
      valorINSS                     = v_valorINSS,
      baseRetPIS                    = v_baseRetPIS,
      valorRetPIS                   = v_valorRetPIS,
      baseRetCOFINS                 = v_baseRetCOFINS,
      valorRetCOFINS                = v_valorRetCOFINS,
      baseRetCSLL                   = v_baseRetCSLL,
      valorRetCSLL                  = v_valorRetCSLL,
      baseII                        = v_baseII,
      valorII                       = v_valorII,
      baseIOF                       = v_baseIOF,
      valorIOF                      = v_valorIOF,
      baseIPI                       = v_baseIPI,
      valorIPI                      = v_valorIPI,
      basePIS                       = v_basePIS,
      valorPIS                      = v_valorPIS,
      basePISST                     = v_basePISST,
      valorPISST                    = v_valorPISST,
      baseCOFINS                    = v_baseCOFINS,
      valorCOFINS                   = v_valorCOFINS,
      baseCOFINSST                  = v_baseCOFINSST,
      valorCOFINSST                 = v_valorCOFINSST,
      baseCreditoSimplesNacional    = v_baseCreditoSimplesNacional,
      valorCreditoSimplesNacional   = v_valorCreditoSimplesNacional,
      baseICMS                      = v_baseICMS,
      valorICMSOperacao             = v_valorICMSOperacao,
      valorICMSDiferido             = v_valorICMSDiferido,
      valorICMS                     = v_valorICMS,
      valorICMSDesoneracao          = v_valorICMSDesoneracao,
      baseICMSST                    = v_baseICMSST,
      valorICMSST                   = v_valorICMSST,
      baseICMSSTAnteriormente       = v_baseICMSSTAnteriormente,
      valorICMSSTAnteriormente      = v_valorICMSSTAnteriormente,
      valorICMSProprioSubstituto    = v_valorICMSProprioSubstituto,
      baseICMSEfetivo               = v_baseICMSEfetivo,
      valorICMSEfetivo              = v_valorICMSEfetivo,
      baseICMSUFDestinatario        = v_baseICMSUFDestinatario,
      valorICMSUFDestinatario       = v_valorICMSUFDestinatario,
      baseICMSUFRemetente           = v_baseICMSUFRemetente,
      valorICMSUFRemetente          = v_valorICMSUFRemetente,
      baseFCP                       = v_baseFCP,
      valorFCP                      = v_valorFCP,
      baseFCPST                     = v_baseFCPST,
      valorFCPST                    = v_valorFCPST,
      baseFCPSTAnteriormente        = v_baseFCPSTAnteriormente,
      valorFCPSTAnteriormente       = v_valorFCPSTAnteriormente,
      baseFCPUFDestinatario         = v_baseFCPUFDestinatario,
      valorFCPUFDestinatario        = v_valorFCPUFDestinatario,
      baseEstimadaImpostos          = v_baseEstimadaImpostos,
      valorEstimadoImpFederais      = v_valorEstimadoImpFederais,
      valorEstimadoImpEstaduais     = v_valorEstimadoImpEstaduais,
      valorEstimadoImpMunicipais    = v_valorEstimadoImpMunicipais,
      valorImpostosSomaPagamento    = v_valorImpSomaPagamento,
      valorImpostosDiminuiPagamento = v_valorImpDiminuiPagamento,
      valorLiquidoItem              = v_valorLiquidoItem,
      valorDescontoCustoOpTotal     = v_valorDescontoCustoOpTotal,
      valorAcrescimoCustoOpTotal    = v_valorAcrescimoCustoOpTotal,
      precoCustoOperacao            = v_precoCustoOperacao,
      valorCustoOperacao            = v_valorCustoOperacao,
      precoCMV                      = v_precoCMV,
      valorCMV                      = v_valorCMV,
      valorAcrescimoExtempSubtotal  = v_valorAcrescimoExtempSubtotal,
      valorAcrescimoExtempTotal     = v_valorAcrescimoExtempTotal
    WHERE idItemPreDocumento        = 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 + item.valorDescontoPagamento - item.valorOutrasDespesasPagamento - item.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;
END ADD_PRE_DOC_CALC_IMP_ITENS;

/

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

/

create or replace PROCEDURE ADD_DOC_FISC_GERA_TEMP_MARGEM (
    p_uniqueMachineID              IN VARCHAR2,
    p_config_65_casasDecEntrada    IN CHAR,
    p_config_209_filtrarGrupoEcon  IN NUMBER,
    p_config_362_calcCustoPorGrade IN NUMBER,
    p_regMarg_tipoPreco            IN CHAR,
    p_regMarg_tabelaPreco          IN VARCHAR2,
    p_regMarg_fatorMultiplicador   IN NUMBER,
    p_regMarg_tipoPrecoB           IN CHAR,
    p_regMarg_tabelaPrecoB         IN VARCHAR2,
    p_regMarg_fatorMultiplicadorB  IN NUMBER,
    p_regMarg_reduzirImpostos      IN NUMBER,
    p_regMarg_reduzirTarifaCartao  IN NUMBER,
    p_regMarg_taxaCapitacaoCustoFi IN NUMBER,
    p_regMarg_exibImagemMargemCab  IN NUMBER,
    p_regMarg_regraImagemCab       IN NUMBER,
    p_regMarg_exibImagemMargemItem IN NUMBER,
    p_regMarg_regraImagemItem      IN NUMBER,
    p_cab_idDocumentoFiscal        IN NUMBER,
    /* Retornos */
    r_cab_valorTarifaCartao        OUT NUMBER,
    r_cab_valorMargem              OUT NUMBER,
    r_cab_percentualMargem         OUT NUMBER,
    r_cab_imagemMargem             OUT VARCHAR2)
IS
    v_cab_estabelecimento          NUMBER;
    v_cab_dataEmissao              DATE;
    v_cab_prazoMedioPonderado      NUMBER;
    v_cab_valorFreteTotal          NUMBER;
    v_cab_valorSeguroTotal         NUMBER;
    v_cab_valorAdicFreteMarinTotal NUMBER;
    v_cab_valorDespesasAduanTotal  NUMBER;
    v_cab_valorLiquidoItem         NUMBER;
    v_munEndEst_uf                 CHAR(2);
    v_item_valorLiquidoSemFreteSeg NUMBER;
    v_item_valorCaptacao           NUMBER;
    v_item_valorTarifaCartao       NUMBER;
    v_item_valorImpostos           NUMBER;
    v_item_precoCusto              NUMBER;
    v_item_valorCusto              NUMBER;
    v_item_valorMargem             NUMBER;
    v_item_percentualMargem        NUMBER;
    v_item_imagemMargem            VARCHAR2(256);
    CURSOR c_item IS
      SELECT
        a.sequencia,
        a.cancelado,
        a.idFormulaTinta,
        a.personalizacao,
        a.localEstoque,
        a.pessoaParticipante,
        a.quantidade,
        a.valorFreteTotal,
        a.valorSeguroTotal,
        a.valorAdicFreteMarinhaMerTotal,
        a.valorDespesasAduaneirasTotal,
        a.valorII,
        a.valorIOF,
        a.valorIPI,
        a.valorIPIDevolucao,
        a.valorPIS,
        a.valorPISST,
        a.valorCOFINS,
        a.valorCOFINSST,
        a.valorCreditoSimplesNacional,
        a.valorICMSOperacao,
        a.valorICMSDiferido,
        a.valorICMS,
        a.valorICMSDesoneracao,
        a.valorICMSST,
        a.valorICMSSTAnteriormente,
        a.valorICMSUFDestinatario,
        a.valorICMSUFRemetente,
        a.valorFCP,
        a.valorFCPST,
        a.valorFCPSTAnteriormente,
        a.valorFCPUFDestinatario,
        a.valorLiquidoItem,
        gradProd.produto,
        gradProd.cor,
        gradProd.tamanho,
        prod.controleEstoque,
        locEst.indicadorPropriedadePosseItem
      FROM MODOCFISCALXITENS a
      JOIN CAGRADESPRODUTO gradProd ON gradProd.gradeProduto = a.gradeProduto
      JOIN CAPRODUTOS prod ON prod.produto = gradProd.produto
      JOIN PALOCAISESTOQUE locEst ON locEst.localEstoque = a.localEstoque
      WHERE idDocumentoFiscal = p_cab_idDocumentoFiscal;
BEGIN
  r_cab_valorTarifaCartao := FUNC_ADD_TARIFA_CART_DOC_FISC (p_cab_idDocumentoFiscal);
  r_cab_valorMargem       := 0;
  r_cab_valorMargem       := 0;
  r_cab_percentualMargem  := 0;
  r_cab_imagemMargem      := ' ';
  DELETE TEMPMARGEMCONTRIBUICAO
  WHERE uniqueMachineID = p_uniqueMachineID
  AND orcamentoPredocumentoDocumento = 'D'
  AND idCabecalho = p_cab_idDocumentoFiscal;
  SELECT
    cab.estabelecimento,
    cab.dataEmissao,
    cab.prazoMedioPonderado,
    cab.valorFreteTotal,
    cab.valorSeguroTotal,
    cab.valorAdicFreteMarinhaMerTotal,
    cab.valorDespesasAduaneirasTotal,
    cab.valorLiquidoItem,
    COALESCE((
      SELECT MAX(munEndEst.uf)
      FROM CAENDERECOSPESSOA endEst
      JOIN SIMUNICIPIOS munEndEst
      ON munEndEst.municipio = endEst.municipio
      WHERE endEst.pessoa = est.pessoaEstabelecimento
      AND endEst.ativo = 1
      AND endEst.principal = 1),'  ')
  INTO
    v_cab_estabelecimento,
    v_cab_dataEmissao,
    v_cab_prazoMedioPonderado,
    v_cab_valorFreteTotal,
    v_cab_valorSeguroTotal,
    v_cab_valorAdicFreteMarinTotal,
    v_cab_valorDespesasAduanTotal,
    v_cab_valorLiquidoItem,
    v_munEndEst_uf
  FROM MODOCUMENTOSFISCAIS cab
  JOIN PAESTABELECIMENTOS est
  ON est.estabelecimento = cab.estabelecimento
  WHERE cab.idDocumentoFiscal = p_cab_idDocumentoFiscal;
  FOR item IN c_item LOOP
    ADD_CALCULA_MARGEM_CONTRIB (
      p_config_65_casasDecEntrada,
      p_config_209_filtrarGrupoEcon,
      p_config_362_calcCustoPorGrade,
      p_regMarg_tipoPreco,
      p_regMarg_tabelaPreco,
      p_regMarg_fatorMultiplicador,
      p_regMarg_tipoPrecoB,
      p_regMarg_tabelaPrecoB,
      p_regMarg_fatorMultiplicadorB,
      p_regMarg_reduzirImpostos,
      p_regMarg_reduzirTarifaCartao,
      p_regMarg_taxaCapitacaoCustoFi,
      p_regMarg_exibImagemMargemItem,
      p_regMarg_regraImagemItem,
      v_cab_estabelecimento,
      v_cab_dataEmissao,
      v_cab_prazoMedioPonderado,
      v_cab_valorLiquidoItem,
      r_cab_valorTarifaCartao,
      v_munEndEst_uf,
      item.idFormulaTinta,
      item.personalizacao,
      item.localEstoque,
      item.pessoaParticipante,
      item.quantidade,
      item.valorFreteTotal,
      item.valorSeguroTotal,
      item.valorAdicFreteMarinhaMerTotal,
      item.valorDespesasAduaneirasTotal,
      item.valorII,
      item.valorIOF,
      item.valorIPI,
      item.valorIPIDevolucao,
      item.valorPIS,
      item.valorPISST,
      item.valorCOFINS,
      item.valorCOFINSST,
      item.valorCreditoSimplesNacional,
      item.valorICMSOperacao,
      item.valorICMSDiferido,
      item.valorICMS,
      item.valorICMSDesoneracao,
      item.valorICMSST,
      item.valorICMSSTAnteriormente,
      item.valorICMSUFDestinatario,
      item.valorICMSUFRemetente,
      item.valorFCP,
      item.valorFCPST,
      item.valorFCPSTAnteriormente,
      item.valorFCPUFDestinatario,
      item.valorLiquidoItem,
      item.produto,
      item.cor,
      item.tamanho,
      item.controleEstoque,
      item.indicadorPropriedadePosseItem,
      /* Retornos */
      v_item_valorLiquidoSemFreteSeg,
      v_item_valorCaptacao,
      v_item_valorTarifaCartao,
      v_item_valorImpostos,
      v_item_precoCusto,
      v_item_valorCusto,
      v_item_valorMargem,
      v_item_percentualMargem);
    IF p_regMarg_exibImagemMargemItem = 1 AND p_regMarg_regraImagemItem <> 0 THEN
      v_item_imagemMargem := FUNC_ADD_BUSCA_IMAGEM_FAIXA (p_regMarg_regraImagemItem, v_item_percentualMargem);
    ELSE
      v_item_imagemMargem := ' ';
    END IF;
    IF item.cancelado = 0 THEN
      r_cab_valorMargem := r_cab_valorMargem + v_item_valorMargem;
    END IF;
    INSERT INTO TEMPMARGEMCONTRIBUICAO (
      uniqueMachineID,
      orcamentoPredocumentoDocumento,
      idCabecalho,
      sequencia,
      valorLiquidoSemFreteSeguro,
      valorCaptacao,
      valorTarifaCartao,
      valorImpostos,
      precoCusto,
      valorCusto,
      valorMargem,
      percentualMargem,
      imagemMargem
    ) VALUES (
      p_uniqueMachineID,
      'D',
      p_cab_idDocumentoFiscal,
      item.sequencia,
      v_item_valorLiquidoSemFreteSeg,
      v_item_valorCaptacao,
      v_item_valorTarifaCartao,
      v_item_valorImpostos,
      v_item_precoCusto,
      v_item_valorCusto,
      v_item_valorMargem,
      v_item_percentualMargem,
      v_item_imagemMargem);
  END LOOP;
  r_cab_percentualMargem := CASE WHEN v_cab_valorLiquidoItem - v_cab_valorFreteTotal - v_cab_valorSeguroTotal - v_cab_valorAdicFreteMarinTotal - v_cab_valorDespesasAduanTotal = 0 THEN 0 ELSE ROUND ((100 * r_cab_valorMargem / (v_cab_valorLiquidoItem - v_cab_valorFreteTotal - v_cab_valorSeguroTotal - v_cab_valorAdicFreteMarinTotal - v_cab_valorDespesasAduanTotal)), 8) END;
  IF p_regMarg_exibImagemMargemCab = 1 AND p_regMarg_regraImagemCab <> 0 THEN
    r_cab_imagemMargem := FUNC_ADD_BUSCA_IMAGEM_FAIXA (p_regMarg_regraImagemCab, r_cab_percentualMargem);
  END IF;
END ADD_DOC_FISC_GERA_TEMP_MARGEM;

/

create or replace PROCEDURE ADD_DOC_FISC_CALC_IMP_RESIDUO (
    p_troca_tipoPagamentoFrete     IN NUMBER,
    p_a_cab_tipoPagamentoFrete     IN CHAR,
    p_cab_origemDocumento          IN NUMBER,
    p_cab_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_valorProdutos            IN NUMBER,
    p_cab_valorServicos            IN NUMBER,
    p_cab_valorBasePagamento       IN NUMBER,
    p_cab_valorAVistaMinimo        IN NUMBER,
    p_cab_valorFreteTotal          IN NUMBER,
    p_cab_valorSeguroTotal         IN NUMBER,
    p_cab_valorDescontoTotal       IN NUMBER,
    p_cab_valorOutrasDespesasTotal IN NUMBER,
    p_cab_valorAdicFreteMarinTotal IN NUMBER,
    p_cab_valorDespesasAduanTotal  IN NUMBER,
    p_cab_impostosEditados         IN NUMBER,
    p_cab_valorImpSomaPagamento    IN NUMBER,
    p_cab_valorImpDiminuiPagamento IN NUMBER,
    p_cab_valorLiquidoItem         IN NUMBER,
    p_cab_valorDescCustoOpTotal    IN NUMBER,
    p_cab_valorAcrescCustoOpTotal  IN NUMBER,
    p_cab_valorCustoOperacao       IN NUMBER,
    p_cab_valorCMV                 IN NUMBER,
    p_cab_valorAcrescExtempTotal   IN NUMBER,
    p_modDoc_diminuiDescontoPrUnit IN NUMBER,
    p_modDoc_somaAcrescimosPrUnit  IN NUMBER,
    p_modDoc_somaFreteSeguroPrUnit IN NUMBER,
    p_item_idItemDocFiscal         IN NUMBER,
    p_saldoRatFreteGeral           IN NUMBER,
    p_saldoRatSeguroGeral          IN NUMBER,
    p_saldoRatDescontoGeral        IN NUMBER,
    p_saldoRatOutrasDespesasGeral  IN NUMBER,
    p_saldoRatAdicFreteMarinGeral  IN NUMBER,
    p_saldoRatDespesasAduanGeral   IN NUMBER,
    p_saldoRatDescontoPagamento    IN NUMBER,
    p_saldoRatOutrasDespPagamento  IN NUMBER,
    p_saldoRatJurosPagamento       IN NUMBER,
    p_saldoRatDescCustoOpGeral     IN NUMBER,
    p_saldoRatAcrescCustoOpGeral   IN NUMBER,
    p_saldoRatAcrescExtempGeral    IN NUMBER,
    p_calcularImpostosItem         IN NUMBER,
    /* Retornos */
    r_cab_valorProdutos            OUT NUMBER,
    r_cab_valorServicos            OUT NUMBER,
    r_cab_valorBasePagamento       OUT NUMBER,
    r_cab_valorAVistaMinimo        OUT NUMBER,
    r_cab_valorFreteTotal          OUT NUMBER,
    r_cab_valorSeguroTotal         OUT NUMBER,
    r_cab_valorDescontoTotal       OUT NUMBER,
    r_cab_valorOutrasDespesasTotal OUT NUMBER,
    r_cab_valorAdicFreteMarinTotal OUT NUMBER,
    r_cab_valorDespesasAduanTotal  OUT NUMBER,
    r_cab_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_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.modeloDocumento,
        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
      FROM MODOCFISCALXITENS a
      WHERE a.idItemDocFiscal = p_item_idItemDocFiscal
      ORDER BY a.sequencia;
BEGIN
  r_cab_valorProdutos            := p_cab_valorProdutos;
  r_cab_valorServicos            := p_cab_valorServicos;
  r_cab_valorBasePagamento       := p_cab_valorBasePagamento;
  r_cab_valorAVistaMinimo        := p_cab_valorAVistaMinimo;
  r_cab_valorFreteTotal          := p_cab_valorFreteTotal;
  r_cab_valorSeguroTotal         := p_cab_valorSeguroTotal;
  r_cab_valorDescontoTotal       := p_cab_valorDescontoTotal;
  r_cab_valorOutrasDespesasTotal := p_cab_valorOutrasDespesasTotal;
  r_cab_valorAdicFreteMarinTotal := p_cab_valorAdicFreteMarinTotal;
  r_cab_valorDespesasAduanTotal  := p_cab_valorDespesasAduanTotal;
  r_cab_valorImpSomaPagamento    := p_cab_valorImpSomaPagamento;
  r_cab_valorImpDiminuiPagamento := p_cab_valorImpDiminuiPagamento;
  r_cab_valorLiquidoItem         := p_cab_valorLiquidoItem;
  r_cab_valorDescCustoOpTotal    := p_cab_valorDescCustoOpTotal;
  r_cab_valorAcrescCustoOpTotal  := p_cab_valorAcrescCustoOpTotal;
  r_cab_valorCustoOperacao       := p_cab_valorCustoOperacao;
  r_cab_valorCMV                 := p_cab_valorCMV;
  r_cab_valorAcrescExtempTotal   := p_cab_valorAcrescExtempTotal;
  FOR item IN c_item LOOP
    v_precoUnitario                := item.precoUnitario;
    v_precoUnitarioConvertido      := item.precoUnitarioConvertido;
    v_valorProdutoServico          := item.valorProdutoServico;
    v_valorFreteGeral              := item.valorFreteGeral;
    v_valorSeguroGeral             := item.valorSeguroGeral;
    v_valorDescontoGeral           := item.valorDescontoGeral;
    v_valorOutrasDespesasGeral     := item.valorOutrasDespesasGeral;
    v_valorAdicFreteMarinMerGeral  := item.valorAdicFreteMarinhaMerGeral;
    v_valorDespesasAduaneirasGeral := item.valorDespesasAduaneirasGeral;
    v_valorBasePagamento           := item.valorBasePagamento;
    v_valorDescontoPagamento       := item.valorDescontoPagamento;
    v_valorOutrasDespesasPagamento := item.valorOutrasDespesasPagamento;
    v_valorJurosPagamento          := item.valorJurosPagamento;
    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_valorDescontoCustoOpGeral    := item.valorDescontoCustoOpGeral;
    v_valorDescontoCustoOpTotal    := item.valorDescontoCustoOpTotal;
    v_valorAcrescimoCustoOpGeral   := item.valorAcrescimoCustoOpGeral;
    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_valorAcrescimoExtempGeral    := item.valorAcrescimoExtempGeral;
    v_valorAcrescimoExtempTotal    := item.valorAcrescimoExtempTotal;    
    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;
    v_valorFreteGeral              := v_valorFreteGeral + p_saldoRatFreteGeral;
    v_valorSeguroGeral             := v_valorSeguroGeral + p_saldoRatSeguroGeral;
    v_valorAdicFreteMarinMerGeral  := v_valorAdicFreteMarinMerGeral + p_saldoRatAdicFreteMarinGeral;
    v_valorDespesasAduaneirasGeral := v_valorDespesasAduaneirasGeral + p_saldoRatDespesasAduanGeral;
    v_valorDescontoGeral           := v_valorDescontoGeral + p_saldoRatDescontoGeral;
    v_valorOutrasDespesasGeral     := v_valorDespesasAduaneirasGeral + p_saldoRatOutrasDespesasGeral;
    v_valorDescontoPagamento       := v_valorDescontoPagamento + p_saldoRatDescontoPagamento;
    v_valorOutrasDespesasPagamento := v_valorOutrasDespesasPagamento + p_saldoRatOutrasDespPagamento;
    v_valorJurosPagamento          := v_valorJurosPagamento + p_saldoRatJurosPagamento;
    v_valorDescontoCustoOpGeral    := v_valorDescontoCustoOpGeral + p_saldoRatDescCustoOpGeral;
    v_valorAcrescimoCustoOpGeral   := v_valorAcrescimoCustoOpGeral + p_saldoRatAcrescCustoOpGeral;
    v_valorAcrescimoExtempGeral    := v_valorAcrescimoExtempGeral + p_saldoRatAcrescExtempGeral;
    ADD_CALCULA_TOTAIS_ITEM(
      p_cab_tipoPagamentoFrete,
      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_origemDocumento,
      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_atualizaCustoMedio,
      p_cab_nfFornecedor,
      item.modeloDocumento,
      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);
    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           = p_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;
END ADD_DOC_FISC_CALC_IMP_RESIDUO;

/

create or replace PROCEDURE ADD_DOC_FISC_CALC_IMP_RATEIO (
    p_cab_idDocumentoFiscal        IN NUMBER,
    p_troca_tipoPagamentoFrete     IN NUMBER,
    p_a_cab_tipoPagamentoFrete     IN CHAR,
    p_cab_origemDocumento          IN NUMBER,
    p_cab_entradaSaida             IN CHAR,
    p_cab_devolucaoAnulacaoRetorno IN NUMBER,
    p_cab_atualizaCustoMedio       IN NUMBER,
    p_cab_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.modeloDocumento,
        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_origemDocumento,
      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_atualizaCustoMedio,
      p_cab_nfFornecedor,
      item.modeloDocumento,
      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_origemDocumento,
      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;

/

create or replace PROCEDURE ADD_DOC_FISC_CALC_IMP_ITENS (
    p_config_64_casasDecSaidas     IN CHAR,
    p_config_209_filtrarGrupoEcon  IN NUMBER,
    p_config_330_redIcmsBasePisCof IN NUMBER,
    p_config_362_calcCustoPorGrade IN NUMBER,
    p_cab_idDocumentoFiscal        IN NUMBER,
    p_cab_origemDocumento          IN NUMBER,
    p_cab_entradaSaida             IN CHAR,
    p_cab_devolucaoAnulacaoRetorno IN NUMBER,
    p_cab_atualizaCustoMedio       IN NUMBER,
    p_cab_estabelecimento          IN NUMBER,
    p_cab_nfFornecedor             IN NUMBER,
    p_cab_dataEntradaSaida         IN DATE,
    p_cab_pessoa                   IN NUMBER,
    p_cab_localDestinoOperacao     IN CHAR,
    p_cab_indicadorConsumidorFinal IN CHAR,
    p_cab_tipoPagamentoFrete       IN CHAR,
    p_modDoc_diminuiDescontoPrUnit IN NUMBER,
    p_modDoc_somaAcrescimosPrUnit  IN NUMBER,
    p_modDoc_somaFreteSeguroPrUnit IN NUMBER,
    p_pess_indicadorInscricaoEstad IN CHAR,
    /* Retornos */
    r_cab_valorProdutos            OUT NUMBER,
    r_cab_valorServicos            OUT NUMBER,
    r_cab_valorBasePagamento       OUT NUMBER,
    r_cab_valorAVistaMinimo        OUT NUMBER,
    r_cab_valorFreteTotal          OUT NUMBER,
    r_cab_valorSeguroTotal         OUT NUMBER,
    r_cab_valorDescontoTotal       OUT NUMBER,
    r_cab_valorOutrasDespesasTotal OUT NUMBER,
    r_cab_valorAdicFreteMarinTotal OUT NUMBER,
    r_cab_valorDespesasAduanTotal  OUT NUMBER,
    r_cab_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)
IS
    v_auxNumber                    NUMBER;
    v_precoUnitario                NUMBER;
    v_precoUnitarioConvertido      NUMBER;
    v_valorProdutoServico          NUMBER;
    v_valorBasePagamento           NUMBER;
    v_valorFreteTotal              NUMBER;
    v_valorSeguroTotal             NUMBER;
    v_valorDescontoTotal           NUMBER;
    v_valorOutrasDespesasTotal     NUMBER;
    v_valorAdicFreteMarinMerTotal  NUMBER;
    v_valorDespesasAduaneirasTotal NUMBER;
    v_baseISSQN                    NUMBER;
    v_valorISSQN                   NUMBER;
    v_baseIRRF                     NUMBER;
    v_valorIRRF                    NUMBER;
    v_baseINSS                     NUMBER;
    v_valorINSS                    NUMBER;
    v_baseRetPIS                   NUMBER;
    v_valorRetPIS                  NUMBER;
    v_baseRetCOFINS                NUMBER;
    v_valorRetCOFINS               NUMBER;
    v_baseRetCSLL                  NUMBER;
    v_valorRetCSLL                 NUMBER;
    v_baseII                       NUMBER;
    v_valorII                      NUMBER;
    v_baseIOF                      NUMBER;
    v_valorIOF                     NUMBER;
    v_baseIPI                      NUMBER;
    v_valorIPI                     NUMBER;
    v_basePIS                      NUMBER;
    v_valorPIS                     NUMBER;
    v_basePISST                    NUMBER;
    v_valorPISST                   NUMBER;
    v_baseCOFINS                   NUMBER;
    v_valorCOFINS                  NUMBER;
    v_baseCOFINSST                 NUMBER;
    v_valorCOFINSST                NUMBER;
    v_baseCreditoSimplesNacional   NUMBER;
    v_valorCreditoSimplesNacional  NUMBER;
    v_baseICMS                     NUMBER;
    v_valorICMSOperacao            NUMBER;
    v_valorICMSDiferido            NUMBER;
    v_valorICMS                    NUMBER;
    v_valorICMSDesoneracao         NUMBER;
    v_baseICMSST                   NUMBER;
    v_valorICMSST                  NUMBER;
    v_baseICMSSTAnteriormente      NUMBER;
    v_valorICMSSTAnteriormente     NUMBER;
    v_valorICMSProprioSubstituto   NUMBER;
    v_baseICMSEfetivo              NUMBER;
    v_valorICMSEfetivo             NUMBER;
    v_baseICMSEscrituracao         NUMBER;
    v_valorICMSEscrituracao        NUMBER;
    v_valorICMSDesonEscrituracao   NUMBER;
    v_baseICMSSTEscrituracao       NUMBER;
    v_valorICMSSTEscrituracao      NUMBER;
    v_baseICMSUFDestinatario       NUMBER;
    v_valorICMSUFDestinatario      NUMBER;
    v_baseICMSUFRemetente          NUMBER;
    v_valorICMSUFRemetente         NUMBER;
    v_baseFCP                      NUMBER;
    v_valorFCP                     NUMBER;
    v_baseFCPST                    NUMBER;
    v_valorFCPST                   NUMBER;
    v_baseFCPSTAnteriormente       NUMBER;
    v_valorFCPSTAnteriormente      NUMBER;
    v_baseFCPUFDestinatario        NUMBER;
    v_valorFCPUFDestinatario       NUMBER;
    v_baseEstimadaImpostos         NUMBER;
    v_valorEstimadoImpFederais     NUMBER;
    v_valorEstimadoImpEstaduais    NUMBER;
    v_valorEstimadoImpMunicipais   NUMBER;
    v_valorImpSomaPagamento        NUMBER;
    v_valorImpDiminuiPagamento     NUMBER;
    v_valorLiquidoItem             NUMBER;
    v_valorDescontoCustoOpTotal    NUMBER;
    v_valorAcrescimoCustoOpTotal   NUMBER;
    v_precoCustoOperacao           NUMBER;
    v_valorCustoOperacao           NUMBER;
    v_precoCMV                     NUMBER;
    v_valorCMV                     NUMBER;
    v_valorAcrescimoExtempSubtotal NUMBER;
    v_valorAcrescimoExtempTotal    NUMBER;
    CURSOR c_item IS
      SELECT
        a.*,
        gradProd.produto,
        gradProd.cor,
        gradProd.tamanho,
        prod.controleEstoque,
        prod.tipoProduto
      FROM MODOCFISCALXITENS a
      JOIN CAGRADESPRODUTO gradProd ON gradProd.gradeProduto = a.gradeProduto
      JOIN CAPRODUTOS prod ON prod.produto = gradProd.produto
      WHERE a.idDocumentoFiscal = p_cab_idDocumentoFiscal
      AND a.cancelado = 0
      ORDER BY a.sequencia;
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;
  FOR item IN c_item LOOP
    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_baseISSQN                    := item.baseISSQN;
    v_valorISSQN                   := item.valorISSQN;
    v_baseIRRF                     := item.baseIRRF;
    v_valorIRRF                    := item.valorIRRF;
    v_baseINSS                     := item.baseINSS;
    v_valorINSS                    := item.valorINSS;
    v_baseRetPIS                   := item.baseRetPIS;
    v_valorRetPIS                  := item.valorRetPIS;
    v_baseRetCOFINS                := item.baseRetCOFINS;
    v_valorRetCOFINS               := item.valorRetCOFINS;
    v_baseRetCSLL                  := item.baseRetCSLL;
    v_valorRetCSLL                 := item.valorRetCSLL;
    v_baseII                       := item.baseII;
    v_valorII                      := item.valorII;
    v_baseIOF                      := item.baseIOF;
    v_valorIOF                     := item.valorIOF;
    v_baseIPI                      := item.baseIPI;
    v_valorIPI                     := item.valorIPI;
    v_basePIS                      := item.basePIS;
    v_valorPIS                     := item.valorPIS;
    v_basePISST                    := item.basePISST;
    v_valorPISST                   := item.valorPISST;
    v_baseCOFINS                   := item.baseCOFINS;
    v_valorCOFINS                  := item.valorCOFINS;
    v_baseCOFINSST                 := item.baseCOFINSST;
    v_valorCOFINSST                := item.valorCOFINSST;
    v_baseCreditoSimplesNacional   := item.baseCreditoSimplesNacional;
    v_valorCreditoSimplesNacional  := item.valorCreditoSimplesNacional;
    v_baseICMS                     := item.baseICMS;
    v_valorICMSOperacao            := item.valorICMSOperacao;
    v_valorICMSDiferido            := item.valorICMSDiferido;
    v_valorICMS                    := item.valorICMS;
    v_valorICMSDesoneracao         := item.valorICMSDesoneracao;
    v_baseICMSST                   := item.baseICMSST;
    v_valorICMSST                  := item.valorICMSST;
    v_baseICMSSTAnteriormente      := item.baseICMSSTAnteriormente;
    v_valorICMSSTAnteriormente     := item.valorICMSSTAnteriormente;
    v_valorICMSProprioSubstituto   := item.valorICMSProprioSubstituto;
    v_baseICMSEfetivo              := item.baseICMSEfetivo;
    v_valorICMSEfetivo             := item.valorICMSEfetivo;
    v_baseICMSEscrituracao         := item.baseICMSEscrituracao;
    v_valorICMSEscrituracao        := item.valorICMSEscrituracao;
    v_valorICMSDesonEscrituracao   := item.valorICMSDesonEscrituracao;
    v_baseICMSSTEscrituracao       := item.baseICMSSTEscrituracao;
    v_valorICMSSTEscrituracao      := item.valorICMSSTEscrituracao;
    v_baseICMSUFDestinatario       := item.baseICMSUFDestinatario;
    v_valorICMSUFDestinatario      := item.valorICMSUFDestinatario;
    v_baseICMSUFRemetente          := item.baseICMSUFRemetente;
    v_valorICMSUFRemetente         := item.valorICMSUFRemetente;
    v_baseFCP                      := item.baseFCP;
    v_valorFCP                     := item.valorFCP;
    v_baseFCPST                    := item.baseFCPST;
    v_valorFCPST                   := item.valorFCPST;
    v_baseFCPSTAnteriormente       := item.baseFCPSTAnteriormente;
    v_valorFCPSTAnteriormente      := item.valorFCPSTAnteriormente;
    v_baseFCPUFDestinatario        := item.baseFCPUFDestinatario;
    v_valorFCPUFDestinatario       := item.valorFCPUFDestinatario;
    v_baseEstimadaImpostos         := item.baseEstimadaImpostos;
    v_valorEstimadoImpFederais     := item.valorEstimadoImpFederais;
    v_valorEstimadoImpEstaduais    := item.valorEstimadoImpEstaduais;
    v_valorEstimadoImpMunicipais   := item.valorEstimadoImpMunicipais;
    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;
    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,
      item.valorFreteGeral,
      item.valorSeguroGeral,
      item.valorDescontoGeral,
      item.valorOutrasDespesasGeral,
      item.valorAdicFreteMarinhaMerGeral,
      item.valorDespesasAduaneirasGeral,
      item.valorDescontoPagamento,
      item.valorOutrasDespesasPagamento,
      item.valorJurosPagamento,
      item.quantidadeExtemporanea,
      item.acrescimoUnitarioExtemporaneo,
      item.valorAcrescimoExtempItem,
      item.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);
    ADD_CALCULA_IMPOSTOS_ITEM (
      p_config_64_casasDecSaidas,
      p_config_209_filtrarGrupoEcon,
      p_config_330_redIcmsBasePisCof,
      p_config_362_calcCustoPorGrade,
      p_cab_entradaSaida,
      p_cab_devolucaoAnulacaoRetorno,
      p_cab_estabelecimento,
      p_cab_nfFornecedor,
      p_cab_dataEntradaSaida,
      p_cab_pessoa,
      p_cab_localDestinoOperacao,
      p_cab_indicadorConsumidorFinal,
      p_cab_tipoPagamentoFrete,
      p_pess_indicadorInscricaoEstad,
      item.personalizacao,
      item.quantidade,
      item.precoPautaTabelado,
      v_valorProdutoServico,
      v_valorFreteTotal,
      v_valorSeguroTotal,
      v_valorDescontoTotal,
      v_valorOutrasDespesasTotal,
      v_valorAdicFreteMarinMerTotal,
      v_valorDespesasAduaneirasTotal,
      item.cfop,
      1,
      item.indicadorISSQN,
      item.aliquotaISSQN,
      v_baseISSQN,
      v_valorISSQN,
      1,
      item.aliquotaIRRF,
      v_baseIRRF,
      v_valorIRRF,
      1,
      item.aliquotaINSS,
      v_baseINSS,
      v_valorINSS,
      1,
      item.retencaoPIS,
      v_baseRetPIS,
      v_valorRetPIS,
      1,
      item.retencaoCOFINS,
      v_baseRetCOFINS,
      v_valorRetCOFINS,
      1,
      item.retencaoCSLL,
      v_baseRetCSLL,
      v_valorRetCSLL,
      1,
      item.aliquotaII,
      v_baseII,
      v_valorII,
      1,
      item.aliquotaIOF,
      v_baseIOF,
      v_valorIOF,
      1,
      item.aliquotaIPI,
      item.valorAliquotaIPI,
      v_baseIPI,
      v_valorIPI,
      item.valorIPIDevolucao,
      1,
      item.aliquotaPIS,
      item.valorAliquotaPIS,
      v_basePIS,
      v_valorPIS,
      1,
      item.aliquotaPISST,
      item.valorAliquotaPISST,
      v_basePISST,
      v_valorPISST,
      1,
      item.aliquotaCOFINS,
      item.valorAliquotaCOFINS,
      v_baseCOFINS,
      v_valorCOFINS,
      1,
      item.aliquotaCOFINSST,
      item.valorAliquotaCOFINSST,
      v_baseCOFINSST,
      v_valorCOFINSST,
      1,
      item.stSimplesNacional,
      item.creditoSimplesNacional,
      v_baseCreditoSimplesNacional,
      v_valorCreditoSimplesNacional,
      1,
      item.stICMS,
      item.modalidadeBaseCalcICMS,
      item.reducaoBaseICMS,
      item.aliquotaICMS,
      item.diferimentoICMS,
      v_baseICMS,
      v_valorICMSOperacao,
      v_valorICMSDiferido,
      v_valorICMS,
      v_valorICMSDesoneracao,
      1,
      item.modalidadeBaseCalcICMSST,
      item.margemValorAdicionadoST,
      item.reducaoBaseST,
      item.aliquotaICMSST,
      v_baseICMSST,
      v_valorICMSST,
      1,
      v_baseICMSSTAnteriormente,
      v_valorICMSSTAnteriormente,
      v_valorICMSProprioSubstituto,
      item.reducaoBaseICMSEfetivo,
      item.aliquotaICMSEfetivo,
      v_baseICMSEfetivo,
      v_valorICMSEfetivo,
      1,
      item.stICMSEscrituracao,
      item.reducaoBaseICMSEscrituracao,
      item.aliquotaICMSEscrituracao,
      v_baseICMSEscrituracao,
      v_valorICMSEscrituracao,
      v_valorICMSDesonEscrituracao,
      1,
      item.margemValorAdicSTEscrituracao,
      item.reducaoBaseSTEscrituracao,
      item.aliquotaICMSSTEscrituracao,
      v_baseICMSSTEscrituracao,
      v_valorICMSSTEscrituracao,
      1,
      item.aliquotaICMSUFDestinatario,
      item.aliquotaICMSInterestadual,
      item.partilhaICMSInterestadual,
      v_baseICMSUFDestinatario,
      v_valorICMSUFDestinatario,
      v_baseICMSUFRemetente,
      v_valorICMSUFRemetente,
      1,
      item.aliquotaFCP,
      v_baseFCP,
      v_valorFCP,
      item.aliquotaFCPST,
      v_baseFCPST,
      v_valorFCPST,
      item.aliquotaFCPSTAnteriormente,
      v_baseFCPSTAnteriormente,
      v_valorFCPSTAnteriormente,
      item.aliquotaFCPUFDestinatario,
      v_baseFCPUFDestinatario,
      v_valorFCPUFDestinatario,
      1,
      item.aliquotaEstimadaImpFederais,
      item.aliquotaEstimadaImpEstaduais,
      item.aliquotaEstimadaImpMunicipais,
      v_baseEstimadaImpostos,
      v_valorEstimadoImpFederais,
      v_valorEstimadoImpEstaduais,
      v_valorEstimadoImpMunicipais,
      item.produto,
      item.cor,
      item.tamanho,
      item.controleEstoque,
      item.tipoProduto,
      /* Retornos */
      v_baseISSQN,
      v_valorISSQN,
      v_baseIRRF,
      v_valorIRRF,
      v_baseINSS,
      v_valorINSS,
      v_baseRetPIS,
      v_valorRetPIS,
      v_baseRetCOFINS,
      v_valorRetCOFINS,
      v_baseRetCSLL,
      v_valorRetCSLL,
      v_baseII,
      v_valorII,
      v_baseIOF,
      v_valorIOF,
      v_baseIPI,
      v_valorIPI,
      v_basePIS,
      v_valorPIS,
      v_basePISST,
      v_valorPISST,
      v_baseCOFINS,
      v_valorCOFINS,
      v_baseCOFINSST,
      v_valorCOFINSST,
      v_baseCreditoSimplesNacional,
      v_valorCreditoSimplesNacional,
      v_baseICMS,
      v_valorICMSOperacao,
      v_valorICMSDiferido,
      v_valorICMS,
      v_valorICMSDesoneracao,
      v_baseICMSST,
      v_valorICMSST,
      v_baseICMSSTAnteriormente,
      v_valorICMSSTAnteriormente,
      v_valorICMSProprioSubstituto,
      v_baseICMSEfetivo,
      v_valorICMSEfetivo,
      v_baseICMSEscrituracao,
      v_valorICMSEscrituracao,
      v_valorICMSDesonEscrituracao,
      v_baseICMSSTEscrituracao,
      v_valorICMSSTEscrituracao,
      v_baseICMSUFDestinatario,
      v_valorICMSUFDestinatario,
      v_baseICMSUFRemetente,
      v_valorICMSUFRemetente,
      v_baseFCP,
      v_valorFCP,
      v_baseFCPST,
      v_valorFCPST,
      v_baseFCPSTAnteriormente,
      v_valorFCPSTAnteriormente,
      v_baseFCPUFDestinatario,
      v_valorFCPUFDestinatario,
      v_baseEstimadaImpostos,
      v_valorEstimadoImpFederais,
      v_valorEstimadoImpEstaduais,
      v_valorEstimadoImpMunicipais);    
    ADD_CALCULA_VALOR_LIQUIDO (
      p_cab_origemDocumento,
      p_cab_nfFornecedor,
      p_cab_tipoPagamentoFrete,
      item.geraFinanceiro,
      v_valorProdutoServico,
      item.valorDescontoPagamento,
      item.valorOutrasDespesasPagamento,
      item.valorJurosPagamento,
      v_valorFreteTotal,
      v_valorSeguroTotal,
      v_valorDescontoTotal,
      v_valorOutrasDespesasTotal,
      v_valorIRRF,
      v_valorINSS,
      v_valorRetPIS,
      v_valorRetCOFINS,
      v_valorRetCSLL,
      v_valorII,
      v_valorIOF,
      v_valorIPI,
      item.valorIPIDevolucao,
      v_valorICMSST,
      v_valorICMSSTEscrituracao,
      item.somarICMSST,
      v_valorAcrescimoExtempTotal,
      /* Retornos */
      v_valorBasePagamento,
      v_valorImpSomaPagamento,
      v_valorImpDiminuiPagamento,
      v_valorLiquidoItem);
    ADD_CALCULA_CUSTO_CMV (
      p_cab_atualizaCustoMedio,
      p_cab_nfFornecedor,
      item.modeloDocumento,
      item.quantidade,
      v_valorII,
      v_valorIOF,
      v_valorIPI,
      item.valorIPIDevolucao,
      v_valorPIS,
      v_valorPISST,
      v_valorCOFINS,
      v_valorCOFINSST,
      v_valorCreditoSimplesNacional,
      v_valorICMS,
      v_valorICMSST,
      v_valorICMSSTEscrituracao,
      v_valorLiquidoItem,
      item.valorDescontoCustoOpItem,
      item.valorDescontoCustoOpGeral,
      item.valorAcrescimoCustoOpItem,
      item.valorAcrescimoCustoOpGeral,
      v_valorAcrescimoExtempTotal,
      /* Retornos */
      v_valorDescontoCustoOpTotal,
      v_valorAcrescimoCustoOpTotal,
      v_precoCustoOperacao,
      v_valorCustoOperacao,
      v_precoCMV,
      v_valorCMV);
    UPDATE MODOCFISCALXITENS SET
      precoUnitario                 = v_precoUnitario,
      precoUnitarioConvertido       = v_precoUnitarioConvertido,
      valorProdutoServico           = v_valorProdutoServico,
      valorBasePagamento            = v_valorBasePagamento,
      valorFreteTotal               = v_valorFreteTotal,
      valorSeguroTotal              = v_valorSeguroTotal,
      valorDescontoTotal            = v_valorDescontoTotal,
      valorOutrasDespesasTotal      = v_valorOutrasDespesasTotal,
      valorAdicFreteMarinhaMerTotal = v_valorAdicFreteMarinMerTotal,
      valorDespesasAduaneirasTotal  = v_valorDespesasAduaneirasTotal,
      baseISSQN                     = v_baseISSQN,
      valorISSQN                    = v_valorISSQN,
      baseIRRF                      = v_baseIRRF,
      valorIRRF                     = v_valorIRRF,
      baseINSS                      = v_baseINSS,
      valorINSS                     = v_valorINSS,
      baseRetPIS                    = v_baseRetPIS,
      valorRetPIS                   = v_valorRetPIS,
      baseRetCOFINS                 = v_baseRetCOFINS,
      valorRetCOFINS                = v_valorRetCOFINS,
      baseRetCSLL                   = v_baseRetCSLL,
      valorRetCSLL                  = v_valorRetCSLL,
      baseII                        = v_baseII,
      valorII                       = v_valorII,
      baseIOF                       = v_baseIOF,
      valorIOF                      = v_valorIOF,
      baseIPI                       = v_baseIPI,
      valorIPI                      = v_valorIPI,
      basePIS                       = v_basePIS,
      valorPIS                      = v_valorPIS,
      basePISST                     = v_basePISST,
      valorPISST                    = v_valorPISST,
      baseCOFINS                    = v_baseCOFINS,
      valorCOFINS                   = v_valorCOFINS,
      baseCOFINSST                  = v_baseCOFINSST,
      valorCOFINSST                 = v_valorCOFINSST,
      baseCreditoSimplesNacional    = v_baseCreditoSimplesNacional,
      valorCreditoSimplesNacional   = v_valorCreditoSimplesNacional,
      baseICMS                      = v_baseICMS,
      valorICMSOperacao             = v_valorICMSOperacao,
      valorICMSDiferido             = v_valorICMSDiferido,
      valorICMS                     = v_valorICMS,
      valorICMSDesoneracao          = v_valorICMSDesoneracao,
      baseICMSST                    = v_baseICMSST,
      valorICMSST                   = v_valorICMSST,
      baseICMSSTAnteriormente       = v_baseICMSSTAnteriormente,
      valorICMSSTAnteriormente      = v_valorICMSSTAnteriormente,
      valorICMSProprioSubstituto    = v_valorICMSProprioSubstituto,
      baseICMSEfetivo               = v_baseICMSEfetivo,
      valorICMSEfetivo              = v_valorICMSEfetivo,
      baseICMSEscrituracao          = v_baseICMSEscrituracao,
      valorICMSEscrituracao         = v_valorICMSEscrituracao,
      valorICMSDesonEscrituracao    = v_valorICMSDesonEscrituracao,
      baseICMSSTEscrituracao        = v_baseICMSSTEscrituracao,
      valorICMSSTEscrituracao       = v_valorICMSSTEscrituracao,
      baseICMSUFDestinatario        = v_baseICMSUFDestinatario,
      valorICMSUFDestinatario       = v_valorICMSUFDestinatario,
      baseICMSUFRemetente           = v_baseICMSUFRemetente,
      valorICMSUFRemetente          = v_valorICMSUFRemetente,
      baseFCP                       = v_baseFCP,
      valorFCP                      = v_valorFCP,
      baseFCPST                     = v_baseFCPST,
      valorFCPST                    = v_valorFCPST,
      baseFCPSTAnteriormente        = v_baseFCPSTAnteriormente,
      valorFCPSTAnteriormente       = v_valorFCPSTAnteriormente,
      baseFCPUFDestinatario         = v_baseFCPUFDestinatario,
      valorFCPUFDestinatario        = v_valorFCPUFDestinatario,
      baseEstimadaImpostos          = v_baseEstimadaImpostos,
      valorEstimadoImpFederais      = v_valorEstimadoImpFederais,
      valorEstimadoImpEstaduais     = v_valorEstimadoImpEstaduais,
      valorEstimadoImpMunicipais    = v_valorEstimadoImpMunicipais,
      valorImpostosSomaPagamento    = v_valorImpSomaPagamento,
      valorImpostosDiminuiPagamento = v_valorImpDiminuiPagamento,
      valorLiquidoItem              = v_valorLiquidoItem,
      valorDescontoCustoOpTotal     = v_valorDescontoCustoOpTotal,
      valorAcrescimoCustoOpTotal    = v_valorAcrescimoCustoOpTotal,
      precoCustoOperacao            = v_precoCustoOperacao,
      valorCustoOperacao            = v_valorCustoOperacao,
      precoCMV                      = v_precoCMV,
      valorCMV                      = v_valorCMV,
      valorAcrescimoExtempSubtotal  = v_valorAcrescimoExtempSubtotal,
      valorAcrescimoExtempTotal     = v_valorAcrescimoExtempTotal
    WHERE idItemDocFiscal           = 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 + item.valorDescontoPagamento - item.valorOutrasDespesasPagamento - item.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;
END ADD_DOC_FISC_CALC_IMP_ITENS;

/

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

/

create or replace PROCEDURE ADD_DOC_FISC_INFO_SISTEMA_CRIA (
  p_exclusivo                    IN VARCHAR2,
  p_paf                          IN NUMBER,
  p_perfilUsuarioLogado          IN NUMBER,
  p_usuarioLogado                IN NUMBER,
  p_estabelecimentoAtivo         IN NUMBER,
  p_cab_idDocumentoFiscal        IN NUMBER)
IS
  v_modeloDocumentoFiscal        CHAR(2);
  v_indicadorConsumidorFinal     CHAR(1);
  v_regimeTributario             CHAR(1);
  v_md5                          VARCHAR(32);
  v_documentoFiscalRef           NUMBER;
  v_dataEmissaoRef               DATE;
  v_valorPagamentoBruto          NUMBER;
  v_creditoSimplesNacional       NUMBER;
  v_valorCreditoSimplesNacional  NUMBER;
  v_valorFCP                     NUMBER;
  v_valorICMSUFDestinatario      NUMBER;
  v_valorICMSUFRemetente         NUMBER;
  v_baseEstimadaImpostos         NUMBER;
  v_valorEstimadoImpostos        NUMBER;
  v_possui_1913                  NUMBER;
  v_possui_5912                  NUMBER;
  v_motorista                    NUMBER;
  v_motoristaNomeRazaoSocial     VARCHAR2(60);
  v_sequenciaMD5                 NUMBER;
  v_sequenciaFCP                 NUMBER;
  v_sequenciaDestino             NUMBER;
  v_sequenciaRemetente           NUMBER;
  v_sequenciaTributosAprox       NUMBER;
  v_sequenciaVendaConsumidor     NUMBER;
  v_sequenciaNfTransporte        NUMBER;
  v_sequenciaAproveitamentoCred  NUMBER;
  v_sequenciaCreditoIPI          NUMBER;
  v_sequenciaMercadoriaDemo      NUMBER;
  v_sequenciaSuspensoSINIEF      NUMBER;
  v_sequenciaMotorista           NUMBER;
  CURSOR c_obs IS
    SELECT
      a.informacaoComplementar,
      a.descInformacaoComplementar
    FROM PAINFORMACOESCOMPLEMENTAR a
    WHERE a.informacaoComplementar > 0
    AND (
      EXISTS (
        SELECT 1
        FROM MODOCFISCALXITENS item
        JOIN PAOPERFISCALXINFOCOMPLEM opXInfo ON opXInfo.operacaoFiscal = item.operacaoFiscal
        WHERE item.idDocumentoFiscal = p_cab_idDocumentoFiscal
        AND item.cancelado = 0
        AND item.operacaoFiscal > 0
        AND opXInfo.informacaoComplementar = a.informacaoComplementar)
      OR EXISTS (
        SELECT 1
        FROM MODOCUMENTOSFISCAIS cab
        JOIN MODOCFISCALXITENS item ON item.idDocumentoFiscal = cab.idDocumentoFiscal
        JOIN CAGRADESPRODUTO gradProd ON gradProd.gradeProduto = item.gradeProduto
        JOIN CAPRODUTOS prod ON prod.produto = gradProd.produto
        JOIN PAESTABELECIMENTOS est ON est.estabelecimento = cab.idDocumentoFiscal
        LEFT JOIN CAENDERECOSPESSOA endEst ON endEst.pessoa = est.pessoaEstabelecimento AND endEst.ativo = 1 AND endEst.principal = 1
        JOIN SIMUNICIPIOS munEst ON munEst.municipio = COALESCE(endEst.municipio,0)
        LEFT JOIN CAENDERECOSPESSOA endPess ON endPess.pessoa = cab.pessoa AND endPess.ativo = 1 AND endPess.principal = 1
        JOIN SIMUNICIPIOS munPess ON munPess.municipio = COALESCE(endPess.municipio,0)
        WHERE cab.idDocumentoFiscal = p_cab_idDocumentoFiscal
        AND item.cancelado = 0
        AND a.informacaoComplementar = 
          FUNC_ADD_BUSCA_INFO_DESON (
            cab.tipoDocumento,
            cab.entradaSaida,
            cab.estabelecimento,
            cab.pessoa,
            cab.vendaConsumidor,
            munEst.uf,
            munPess.uf,
            item.stICMS,
            gradProd.produto,
            prod.origemMercadoria,
            prod.idNcm)))
    ORDER BY a.informacaoComplementar;
  CURSOR c_nfe IS
    SELECT chaveNfe
    FROM MODOCFISCALXNFREF
    WHERE idDocumentoFiscal = p_cab_idDocumentoFiscal;
BEGIN
  SELECT
    cab.modeloDocumentoFiscal,
    cab.indicadorConsumidorFinal,
    cab.valorPagamentoBruto,
    pess.regimeTributario
  INTO
    v_modeloDocumentoFiscal,
    v_indicadorConsumidorFinal,
    v_valorPagamentoBruto,
    v_regimeTributario
  FROM MODOCUMENTOSFISCAIS cab
  JOIN PAESTABELECIMENTOS est ON est.estabelecimento = cab.estabelecimento
  JOIN CAPESSOAS pess ON pess.pessoa = est.pessoaEstabelecimento
  WHERE cab.idDocumentoFiscal = p_cab_idDocumentoFiscal;
  IF p_paf = 1 AND FUNC_ADD_BUSCA_CONFIG (322, p_perfilUsuarioLogado, p_usuarioLogado, p_estabelecimentoAtivo) = 'S' THEN
    SELECT COALESCE (MAX (md5PAFECF), ' ') INTO v_md5
    FROM SIPAFLAUDO
    WHERE idLaudo = 1;
    IF v_md5 <> ' ' THEN
      SELECT COALESCE (MAX (sequencia), 0) INTO v_sequenciaMD5
      FROM MODOCFISCALXINFOCOMPLEMEN
      WHERE idDocumentoFiscal = p_cab_idDocumentoFiscal
      AND geradoPeloSistema = 1
      AND descInformacaoComplementar LIKE 'MD5:%';
      
      DELETE FROM MODOCFISCALXINFOCOMPLEMEN
      WHERE idDocumentoFiscal = p_cab_idDocumentoFiscal
      AND geradoPeloSistema = 1
      AND descInformacaoComplementar LIKE 'MD5:%';
    ELSE
      v_sequenciaMD5 := 0;
    END IF;  
  ELSE
    v_md5 := ' ';
    v_sequenciaMD5 := 0;
  END IF;
  SELECT
    COALESCE(MAX(docRef.documentoFiscal),0),
    MAX(TRUNC(doc.dataEmissao))
  INTO
    v_documentoFiscalRef,
    v_dataEmissaoRef
  FROM MODOCFISCALXITENS item
  JOIN MODOCUMENTOSFISCAIS doc ON doc.idDocumentoFiscal = item.idDocumentoFiscal
  JOIN MOENTREGAS entr ON entr.idItemDocFiscalRemessa = item.idItemDocFiscal
  JOIN MODOCFISCALXDOCFISCAL docXDoc ON docXDoc.idItemDocFiscal = item.idItemDocFiscal
  JOIN MODOCFISCALXITENS itemRef ON itemRef.idItemDocFiscal = docXDoc.idItemDocFiscalReferenciado
  JOIN MODOCUMENTOSFISCAIS docRef ON docRef.idDocumentoFiscal = itemRef.idDocumentoFiscal
  WHERE item.idDocumentoFiscal = p_cab_idDocumentoFiscal
  AND doc.entradaSaida ='S'
  AND doc.devolucaoAnulacaoRetorno = 0
  AND docRef.entradaSaida ='S'
  AND docRef.devolucaoAnulacaoRetorno = 0;
  SELECT
    COALESCE (MAX (item.creditoSimplesNacional), 0),
    COALESCE (SUM (item.valorCreditoSimplesNacional), 0),
    COALESCE (SUM (item.valorFCP), 0),
    COALESCE (SUM (item.valorICMSUFDestinatario), 0),
    COALESCE (SUM (item.valorICMSUFRemetente), 0),
    COALESCE (SUM (item.baseEstimadaImpostos), 0),
    COALESCE (SUM (item.valorEstimadoImpFederais + item.valorEstimadoImpEstaduais + item.valorEstimadoImpMunicipais), 0),
    COALESCE (MAX (CASE WHEN cfop IN (1913,2913) THEN 1 ELSE 0 END), 0),
    COALESCE (MAX (CASE WHEN cfop IN (5912,6912) THEN 1 ELSE 0 END), 0),
    COALESCE (MAX (entr.motorista), 0)
  INTO
    v_creditoSimplesNacional,
    v_valorCreditoSimplesNacional,
    v_valorFCP,
    v_valorICMSUFDestinatario,
    v_valorICMSUFRemetente,
    v_baseEstimadaImpostos,
    v_valorEstimadoImpostos,
    v_possui_1913,
    v_possui_5912,
    v_motorista
  FROM MODOCFISCALXITENS item
  LEFT JOIN MOENTREGAS entr ON entr.idItemDocFiscalRemessa = item.idItemDocFiscal
  WHERE item.idDocumentoFiscal = p_cab_idDocumentoFiscal
  AND item.cancelado = 0;
  
  DELETE FROM MODOCFISCALXINFOCOMPLEMEN
  WHERE idDocumentoFiscal = p_cab_idDocumentoFiscal
  AND geradoPeloSistema = 1
  AND descInformacaoComplementar LIKE 'NF-e Ref.:%';
  
  SELECT COALESCE (MAX (sequencia), 0) INTO v_sequenciaFCP
  FROM MODOCFISCALXINFOCOMPLEMEN
  WHERE idDocumentoFiscal = p_cab_idDocumentoFiscal
  AND geradoPeloSistema = 1
  AND descInformacaoComplementar LIKE 'Valor do ICMS relativo ao Fundo de Combate a Pobreza - FCP da UF de destino: R$%';
  
  DELETE FROM MODOCFISCALXINFOCOMPLEMEN
  WHERE idDocumentoFiscal = p_cab_idDocumentoFiscal
  AND geradoPeloSistema = 1
  AND descInformacaoComplementar LIKE 'Valor do ICMS relativo ao Fundo de Combate a Pobreza - FCP da UF de destino: R$%';
  
  SELECT COALESCE (MAX (sequencia), 0) INTO v_sequenciaDestino
  FROM MODOCFISCALXINFOCOMPLEMEN
  WHERE idDocumentoFiscal = p_cab_idDocumentoFiscal
  AND geradoPeloSistema = 1
  AND descInformacaoComplementar LIKE 'Valor do ICMS  Interestadual para a UF de destino: R$%';
  
  DELETE FROM MODOCFISCALXINFOCOMPLEMEN
  WHERE idDocumentoFiscal = p_cab_idDocumentoFiscal
  AND geradoPeloSistema = 1
  AND descInformacaoComplementar LIKE 'Valor do ICMS  Interestadual para a UF de destino: R$%';
  
  SELECT COALESCE (MAX (sequencia), 0) INTO v_sequenciaRemetente
  FROM MODOCFISCALXINFOCOMPLEMEN
  WHERE idDocumentoFiscal = p_cab_idDocumentoFiscal
  AND geradoPeloSistema = 1
  AND descInformacaoComplementar LIKE 'Valor do ICMS Interestadual para a UF do remetente: R$%';
  
  DELETE FROM MODOCFISCALXINFOCOMPLEMEN
  WHERE idDocumentoFiscal = p_cab_idDocumentoFiscal
  AND geradoPeloSistema = 1
  AND descInformacaoComplementar LIKE 'Valor do ICMS Interestadual para a UF do remetente: R$%';
  
  SELECT COALESCE (MAX (sequencia), 0) INTO v_sequenciaTributosAprox
  FROM MODOCFISCALXINFOCOMPLEMEN
  WHERE idDocumentoFiscal = p_cab_idDocumentoFiscal
  AND geradoPeloSistema = 1
  AND descInformacaoComplementar LIKE 'Valor Aproximado Tributos: R$%';
  
  DELETE FROM MODOCFISCALXINFOCOMPLEMEN
  WHERE idDocumentoFiscal = p_cab_idDocumentoFiscal
  AND geradoPeloSistema = 1
  AND descInformacaoComplementar LIKE 'Valor Aproximado Tributos: R$%';
  
  SELECT COALESCE (MAX (sequencia), 0) INTO v_sequenciaVendaConsumidor
  FROM MODOCFISCALXINFOCOMPLEMEN
  WHERE idDocumentoFiscal = p_cab_idDocumentoFiscal
  AND geradoPeloSistema = 1
  AND descInformacaoComplementar = 'Venda destinada a consumidor final sem fins comerciais.';
  
  DELETE FROM MODOCFISCALXINFOCOMPLEMEN
  WHERE idDocumentoFiscal = p_cab_idDocumentoFiscal
  AND geradoPeloSistema = 1
  AND descInformacaoComplementar = 'Venda destinada a consumidor final sem fins comerciais.';
  
  SELECT COALESCE (MAX (sequencia), 0) INTO v_sequenciaNfTransporte
  FROM MODOCFISCALXINFOCOMPLEMEN
  WHERE idDocumentoFiscal = p_cab_idDocumentoFiscal
  AND geradoPeloSistema = 1
  AND descInformacaoComplementar LIKE 'Nota de transporte referente a nota de antecipação de faturamento%';
  
  DELETE FROM MODOCFISCALXINFOCOMPLEMEN
  WHERE idDocumentoFiscal = p_cab_idDocumentoFiscal
  AND geradoPeloSistema = 1
  AND descInformacaoComplementar LIKE 'Nota de transporte referente a nota de antecipação de faturamento%';
  
  SELECT COALESCE (MAX (sequencia), 0) INTO v_sequenciaAproveitamentoCred
  FROM MODOCFISCALXINFOCOMPLEMEN
  WHERE idDocumentoFiscal = p_cab_idDocumentoFiscal
  AND geradoPeloSistema = 1
  AND descInformacaoComplementar LIKE 'Permite aproveitamento de credito de ICMS no valor de R$%';
  
  DELETE FROM MODOCFISCALXINFOCOMPLEMEN
  WHERE idDocumentoFiscal = p_cab_idDocumentoFiscal
  AND geradoPeloSistema = 1
  AND descInformacaoComplementar LIKE 'Permite aproveitamento de credito de ICMS no valor de R$%';
  
  SELECT COALESCE (MAX (sequencia), 0) INTO v_sequenciaCreditoIPI
  FROM MODOCFISCALXINFOCOMPLEMEN
  WHERE idDocumentoFiscal = p_cab_idDocumentoFiscal
  AND geradoPeloSistema = 1
  AND descInformacaoComplementar = 'Documento emitido por ME ou EPP optante pelo Simples Nacional; Nao gera direito a credito fiscal de IPI.';
  
  DELETE FROM MODOCFISCALXINFOCOMPLEMEN
  WHERE idDocumentoFiscal = p_cab_idDocumentoFiscal
  AND geradoPeloSistema = 1
  AND descInformacaoComplementar = 'Documento emitido por ME ou EPP optante pelo Simples Nacional; Nao gera direito a credito fiscal de IPI.';
  
  SELECT COALESCE (MAX (sequencia), 0) INTO v_sequenciaMercadoriaDemo
  FROM MODOCFISCALXINFOCOMPLEMEN
  WHERE idDocumentoFiscal = p_cab_idDocumentoFiscal
  AND geradoPeloSistema = 1
  AND descInformacaoComplementar = 'Mercadoria remetida para demonstracao.';
  
  DELETE FROM MODOCFISCALXINFOCOMPLEMEN
  WHERE idDocumentoFiscal = p_cab_idDocumentoFiscal
  AND geradoPeloSistema = 1
  AND descInformacaoComplementar = 'Mercadoria remetida para demonstracao.';
  
  SELECT COALESCE (MAX (sequencia), 0) INTO v_sequenciaSuspensoSINIEF
  FROM MODOCFISCALXINFOCOMPLEMEN
  WHERE idDocumentoFiscal = p_cab_idDocumentoFiscal
  AND geradoPeloSistema = 1
  AND descInformacaoComplementar = 'Imposto suspenso nos termos do Ajuste SINIEF 02/18.';
  
  DELETE FROM MODOCFISCALXINFOCOMPLEMEN
  WHERE idDocumentoFiscal = p_cab_idDocumentoFiscal
  AND geradoPeloSistema = 1
  AND descInformacaoComplementar = 'Imposto suspenso nos termos do Ajuste SINIEF 02/18.';
  
  SELECT COALESCE (MAX (sequencia), 0) INTO v_sequenciaMotorista
  FROM MODOCFISCALXINFOCOMPLEMEN
  WHERE idDocumentoFiscal = p_cab_idDocumentoFiscal
  AND geradoPeloSistema = 1
  AND descInformacaoComplementar LIKE 'Motorista:%';
  
  DELETE FROM MODOCFISCALXINFOCOMPLEMEN
  WHERE idDocumentoFiscal = p_cab_idDocumentoFiscal
  AND geradoPeloSistema = 1
  AND descInformacaoComplementar LIKE 'Motorista:%';
  
  DELETE FROM MODOCFISCALXINFOCOMPLEMEN
  WHERE idDocumentoFiscal = p_cab_idDocumentoFiscal
  AND informacaoComplementar > 0;

  IF v_md5 <> ' ' THEN  
    IF v_sequenciaMD5 > 0 THEN
      ADD_DOC_FISC_INFO_GRAVA_SEQ (
        p_estabelecimentoAtivo,
        p_cab_idDocumentoFiscal,
        v_sequenciaMD5,
        1,
        1,
        0,
        0,
        'MD5: ' || RTRIM(v_md5)
      );
    ELSE
      ADD_DOC_FISC_INFO_CRIA (
        p_estabelecimentoAtivo,
        p_cab_idDocumentoFiscal,
        1,
        1,
        0,
        0,
        'MD5: ' || RTRIM(v_md5)
      );
    END IF;
  END IF;
  IF v_modeloDocumentoFiscal <> '58' THEN
    FOR nfe IN c_nfe LOOP      
      ADD_DOC_FISC_INFO_GRAVA_DESCR (
        p_estabelecimentoAtivo,
        p_cab_idDocumentoFiscal,
        1,
        1,
        0,
        0,
        'NF-e Ref.: '
        || SUBSTR(nfe.chaveNfe,1,2)
        || '-' || SUBSTR(nfe.chaveNfe,3,4)
        || '-' || SUBSTR(nfe.chaveNfe,7,2)
        || '.' || SUBSTR(nfe.chaveNfe,9,3)
        || '.' || SUBSTR(nfe.chaveNfe,12,3)
        || '/' || SUBSTR(nfe.chaveNfe,15,4)
        || '-' || SUBSTR(nfe.chaveNfe,19,2)
        || '-' || SUBSTR(nfe.chaveNfe,21,2)
        || '-' || SUBSTR(nfe.chaveNfe,23,3)
        || '-' || SUBSTR(nfe.chaveNfe,26,3)
        || '.' || SUBSTR(nfe.chaveNfe,29,3)
        || '.' || SUBSTR(nfe.chaveNfe,32,3)
        || '-' || SUBSTR(nfe.chaveNfe,35,3)
        || '.' || SUBSTR(nfe.chaveNfe,38,3)
        || '.' || SUBSTR(nfe.chaveNfe,41,3)
        || '-' || SUBSTR(nfe.chaveNfe,44,1)
      );
    END LOOP;
  END IF;
  IF v_valorFCP > 0 THEN  
    IF v_sequenciaFCP > 0 THEN
      ADD_DOC_FISC_INFO_GRAVA_SEQ (
        p_estabelecimentoAtivo,
        p_cab_idDocumentoFiscal,
        v_sequenciaFCP,
        1,
        1,
        0,
        0,
        'Valor do ICMS relativo ao Fundo de Combate a Pobreza - FCP da UF de destino: R$ ' || TRIM (TO_CHAR (v_valorFCP, 'FM999G999G999G999G999G990D00')) || '.'
      );
    ELSE
      ADD_DOC_FISC_INFO_CRIA (
        p_estabelecimentoAtivo,
        p_cab_idDocumentoFiscal,
        1,
        1,
        0,
        0,
        'Valor do ICMS relativo ao Fundo de Combate a Pobreza - FCP da UF de destino: R$ ' || TRIM (TO_CHAR (v_valorFCP, 'FM999G999G999G999G999G990D00')) || '.'
      );
    END IF;
  END IF;
    
  IF v_valorICMSUFDestinatario > 0 OR v_valorICMSUFRemetente > 0 THEN
    IF v_sequenciaDestino > 0 THEN
      ADD_DOC_FISC_INFO_GRAVA_SEQ (
        p_estabelecimentoAtivo,
        p_cab_idDocumentoFiscal,
        v_sequenciaDestino,
        1,
        1,
        0,
        0,
        'Valor do ICMS  Interestadual para a UF de destino: R$ ' || TRIM (TO_CHAR (v_valorICMSUFDestinatario, 'FM999G999G999G999G999G990D00')) || '.'
      );
    ELSE
      ADD_DOC_FISC_INFO_CRIA (
        p_estabelecimentoAtivo,
        p_cab_idDocumentoFiscal,
        1,
        1,
        0,
        0,
        'Valor do ICMS  Interestadual para a UF de destino: R$ ' || TRIM (TO_CHAR (v_valorICMSUFDestinatario, 'FM999G999G999G999G999G990D00')) || '.'
      );
    END IF;
  END IF;
    
  IF v_valorICMSUFDestinatario > 0 OR v_valorICMSUFRemetente > 0 THEN
    IF v_sequenciaRemetente > 0 THEN
      ADD_DOC_FISC_INFO_GRAVA_SEQ (
        p_estabelecimentoAtivo,
        p_cab_idDocumentoFiscal,
        v_sequenciaRemetente,
        1,
        1,
        0,
        0,
        'Valor do ICMS Interestadual para a UF do remetente: R$ ' || TRIM (TO_CHAR (v_valorICMSUFRemetente, 'FM999G999G999G999G999G990D00')) || '.'
      );
    ELSE
      ADD_DOC_FISC_INFO_CRIA (
        p_estabelecimentoAtivo,
        p_cab_idDocumentoFiscal,
        1,
        1,
        0,
        0,
        'Valor do ICMS Interestadual para a UF do remetente: R$ ' || TRIM (TO_CHAR (v_valorICMSUFRemetente, 'FM999G999G999G999G999G990D00')) || '.'
      );
    END IF;
  END IF;
    
  IF v_valorEstimadoImpostos > 0 THEN
    IF v_sequenciaTributosAprox > 0 THEN
      ADD_DOC_FISC_INFO_GRAVA_SEQ (
        p_estabelecimentoAtivo,
        p_cab_idDocumentoFiscal,
        v_sequenciaTributosAprox,
        1,
        1,
        0,
        0,
        'Valor Aproximado Tributos: R$ ' || TRIM (TO_CHAR (v_valorEstimadoImpostos, 'FM999G999G999G999G999G990D00')) || ' (' || CASE WHEN v_baseEstimadaImpostos = 0 THEN '0,00' ELSE TRIM (TO_CHAR (100* ROUND(v_valorEstimadoImpostos / v_baseEstimadaImpostos,2), 'FM999G999G999G999G999G990D00')) END || '%) Fonte: IBPT.'
      );
    ELSE
      ADD_DOC_FISC_INFO_CRIA (
        p_estabelecimentoAtivo,
        p_cab_idDocumentoFiscal,
        1,
        1,
        0,
        0,
        'Valor Aproximado Tributos: R$ ' || TRIM (TO_CHAR (v_valorEstimadoImpostos, 'FM999G999G999G999G999G990D00')) || ' (' || CASE WHEN v_baseEstimadaImpostos = 0 THEN '0,00' ELSE TRIM (TO_CHAR (100* ROUND(v_valorEstimadoImpostos / v_baseEstimadaImpostos,2), 'FM999G999G999G999G999G990D00')) END || '%) Fonte: IBPT.'
      );
    END IF;
  END IF;
    
  IF v_indicadorConsumidorFinal = '1' THEN
    IF v_sequenciaVendaConsumidor > 0 THEN
      ADD_DOC_FISC_INFO_GRAVA_SEQ (
        p_estabelecimentoAtivo,
        p_cab_idDocumentoFiscal,
        v_sequenciaVendaConsumidor,
        1,
        1,
        0,
        0,
        'Venda destinada a consumidor final sem fins comerciais.'
      );
    ELSE
      ADD_DOC_FISC_INFO_CRIA (
        p_estabelecimentoAtivo,
        p_cab_idDocumentoFiscal,
        1,
        1,
        0,
        0,
        'Venda destinada a consumidor final sem fins comerciais.'
      );
    END IF;
  END IF;
    
  IF v_documentoFiscalRef > 0 THEN
    IF v_sequenciaNfTransporte > 0 THEN
      ADD_DOC_FISC_INFO_GRAVA_SEQ (
        p_estabelecimentoAtivo,
        p_cab_idDocumentoFiscal,
        v_sequenciaNfTransporte,
        1,
        1,
        0,
        0,
        'Nota de transporte referente a nota de antecipação de faturamento ' || TRIM (TO_CHAR (v_documentoFiscalRef)) || CASE WHEN v_dataEmissaoRef IS NULL THEN '' ELSE ' gerada na data ' || TO_CHAR(v_dataEmissaoRef,'DD/MM/YYYY') END || '.'
      );
    ELSE
      ADD_DOC_FISC_INFO_CRIA (
        p_estabelecimentoAtivo,
        p_cab_idDocumentoFiscal,
        1,
        1,
        0,
        0,
        'Nota de transporte referente a nota de antecipação de faturamento ' || TRIM (TO_CHAR (v_documentoFiscalRef)) || CASE WHEN v_dataEmissaoRef IS NULL THEN '' ELSE ' gerada na data ' || TO_CHAR(v_dataEmissaoRef,'DD/MM/YYYY') END || '.'
      );
    END IF;
  END IF;
    
  IF v_regimeTributario IN ('1','2') AND v_valorCreditoSimplesNacional > 0 THEN
    IF v_sequenciaAproveitamentoCred > 0 THEN
      ADD_DOC_FISC_INFO_GRAVA_SEQ (
        p_estabelecimentoAtivo,
        p_cab_idDocumentoFiscal,
        v_sequenciaAproveitamentoCred,
        1,
        1,
        0,
        0,
        'Permite aproveitamento de credito de ICMS no valor de R$ ' || TRIM (TO_CHAR (v_valorCreditoSimplesNacional, 'FM999G999G999G999G999G990D00')) || ', correspondente a aliquota de ' || TRIM (TO_CHAR (v_creditoSimplesNacional, 'FM999G999G999G999G999G990D00')) || '%, nos termos do art. 23 da LC. 123, de 2006.'
      );
    ELSE
      ADD_DOC_FISC_INFO_CRIA (
        p_estabelecimentoAtivo,
        p_cab_idDocumentoFiscal,
        1,
        1,
        0,
        0,
        'Permite aproveitamento de credito de ICMS no valor de R$ ' || TRIM (TO_CHAR (v_valorCreditoSimplesNacional, 'FM999G999G999G999G999G990D00')) || ', correspondente a aliquota de ' || TRIM (TO_CHAR (v_creditoSimplesNacional, 'FM999G999G999G999G999G990D00')) || '%, nos termos do art. 23 da LC. 123, de 2006.'
      );
    END IF;
  END IF;
    
  IF v_regimeTributario IN ('1','2') THEN
    IF v_sequenciaCreditoIPI > 0 THEN
      ADD_DOC_FISC_INFO_GRAVA_SEQ (
        p_estabelecimentoAtivo,
        p_cab_idDocumentoFiscal,
        v_sequenciaCreditoIPI,
        1,
        1,
        0,
        0,
        'Documento emitido por ME ou EPP optante pelo Simples Nacional; Nao gera direito a credito fiscal de IPI.'
      );
    ELSE
      ADD_DOC_FISC_INFO_CRIA (
        p_estabelecimentoAtivo,
        p_cab_idDocumentoFiscal,
        1,
        1,
        0,
        0,
        'Documento emitido por ME ou EPP optante pelo Simples Nacional; Nao gera direito a credito fiscal de IPI.'
      );
    END IF;
  END IF;
  
  FOR obs IN c_obs LOOP
    
    ADD_DOC_FISC_INFO_GRAVA_DESCR (
      p_estabelecimentoAtivo,
      p_cab_idDocumentoFiscal,
      1,
      1,
      0,
      obs.informacaoComplementar,
      obs.descInformacaoComplementar
    );
    
  END LOOP;
  
  IF v_possui_5912 = 1 THEN
  
    ADD_DOC_FISC_INFO_GRAVA_DESCR (
      p_estabelecimentoAtivo,
      p_cab_idDocumentoFiscal,
      1,
      1,
      0,
      0,
      'Mercadoria remetida para demonstracao.'
    );

  END IF;
  
  IF v_possui_5912 = 1 OR v_possui_1913 = 1 THEN

    ADD_DOC_FISC_INFO_GRAVA_DESCR (
      p_estabelecimentoAtivo,
      p_cab_idDocumentoFiscal,
      1,
      1,
      0,
      0,
      'Imposto suspenso nos termos do Ajuste SINIEF 02/18.'
    );
    
  END IF;
   
  IF v_motorista <> 0 THEN
   
    SELECT COALESCE (MAX (nomeRazaoSocial), ' ') INTO v_motoristaNomeRazaoSocial
    FROM CAPESSOAS
    WHERE pessoa = v_motorista;
  
    ADD_DOC_FISC_INFO_GRAVA_DESCR (
      p_estabelecimentoAtivo,
      p_cab_idDocumentoFiscal,
      1,
      1,
      0,
      0,
      'Motorista: ' || TRIM (v_motoristaNomeRazaoSocial)
    );
  END IF;

  IF p_exclusivo = 'BITELO' THEN
    ADD_DOC_FISC_INFO_GRAVA_DESCR (
      p_estabelecimentoAtivo,
      p_cab_idDocumentoFiscal,
      1,
      1,
      0,
      0,
      'ATENÇÃO: 
CONFIRA A MERCADORIA NO ATO DA ENTREGA, OS MATERIAIS SERÃO DESCARREGADOS AO LADO DO CAMINHÃO. 
DÚVIDAS E RECLAMAÇÕES SOBRE ENTREGAS LIGAR PARA (51) 3497-7589.'
    );
  END IF;

  IF p_exclusivo = 'DC' THEN
    ADD_DOC_FISC_INFO_GRAVA_DESCR (
      p_estabelecimentoAtivo,
      p_cab_idDocumentoFiscal,
      1,
      1,
      0,
      0,
      'Declaro que o produto acima se encontra em perfeito estado, não constando nenhum dano físico, ou avarias, e, sobretudo com número de série idêntico ao da embalagem e com todos os acessórios e itens que o acompanham, bem como sua embalagem também em perfeito estado.

______________________________
    Assinatura do Recebido
    CPF/RG:'
    );
  END IF;
  
  IF v_modeloDocumentoFiscal = '55'
    AND v_valorPagamentoBruto > 0
    AND FUNC_ADD_BUSCA_CONFIG (110, p_perfilUsuarioLogado, p_usuarioLogado, p_estabelecimentoAtivo) = 'S' THEN
    DELETE MODOCFISCALXINFOCOMPLEMEN
    WHERE IdDocumentoFiscal = p_cab_idDocumentoFiscal
    AND geradoPeloSistema = 1
    AND imprimir = 1
    AND informacaoComplementar = 0
    AND (descInformacaoComplementar LIKE 'P%R$%'
      OR descInformacaoComplementar LIKE 'T%R$%')
    AND SUBSTR(descInformacaoComplementar,2,1) BETWEEN '1' AND '9';
    ADD_DOC_FISC_INFO_PAG_DOC_FISC (
      p_perfilUsuarioLogado,
      p_usuarioLogado,
      p_estabelecimentoAtivo,
      p_cab_idDocumentoFiscal,
      p_cab_idDocumentoFiscal,
      0
    );
  END IF;
END ADD_DOC_FISC_INFO_SISTEMA_CRIA;

/

create or replace PROCEDURE ADD_DOC_FISC_ITEM_EST_N_SERIE(
    p_bufferIdEstoque              IN VARCHAR2,
    p_estabelecimentoAtivo         IN NUMBER,
    p_cab_modeloDocumento          IN NUMBER,
    p_cab_atualizaCustoMedio       IN NUMBER,
    p_cab_atualizaUltimaCompra     IN NUMBER,
    p_cab_entradaSaida             IN CHAR,
    p_cab_estabelecimento          IN NUMBER,
    p_cab_dataEmissao              IN DATE,
    p_cab_dataEntradaSaida         IN DATE,
    p_modDoc_geraTransferencia     IN NUMBER,
    p_modDoc_geraOperacaoEmTransit IN NUMBER,
    p_modDoc_transitoLocalEstoque  IN NUMBER,
    p_locEstTransito_indicProprPos IN CHAR,
    p_item_idItemDocFiscal         IN NUMBER,
    p_item_gradeProduto            IN NUMBER,
    p_item_personalizacao          IN NUMBER,
    p_item_idLoteEstoque           IN NUMBER,
    p_item_localEstoque            IN NUMBER,
    p_item_pessoaParticipante      IN NUMBER,
    p_item_precoCustoOperacao      IN NUMBER,
    p_item_precoCMV                IN NUMBER,
    p_item_observacoes             IN VARCHAR2,
    p_endEst_idEnderecoEstoqueDocF IN NUMBER,
    p_idEnderecoEstoque            IN NUMBER,
    p_locEst_indicProprPosseItem   IN CHAR,
    p_docTransf_estabelecEntrada   IN NUMBER,
    p_docTransf_estabelecSaida     IN NUMBER,
    r_bufferIdEstoque              OUT VARCHAR2,
    r_quantidadeNumerosSerie       OUT NUMBER)
IS
  CURSOR c_numSerie
  IS 
    SELECT idNumeroSerie
    FROM MODOCFISCALXNUMEROSSERIE
    WHERE idItemDocFiscal = p_item_idItemDocFiscal
    AND idEnderecoEstoqueDocFiscal = p_endEst_idEnderecoEstoqueDocF
    AND gradeProduto = p_item_gradeProduto;
BEGIN
  r_bufferIdEstoque        := p_bufferIdEstoque;
  r_quantidadeNumerosSerie := 0;
  FOR numSerie IN c_numSerie
  LOOP
    r_quantidadeNumerosSerie := r_quantidadeNumerosSerie + 1;
    ADD_ESTOQUE_INSERE(
      r_bufferIdEstoque, 
      p_estabelecimentoAtivo, 
      p_cab_estabelecimento,
      CASE WHEN p_cab_dataEntradaSaida IS NULL OR p_cab_dataEntradaSaida < p_cab_dataEmissao THEN p_cab_dataEmissao ELSE p_cab_dataEntradaSaida END, -- p_data
      p_item_gradeProduto,
      p_cab_modeloDocumento,
      100,
      p_cab_atualizaCustoMedio,
      p_cab_atualizaUltimaCompra,
      p_cab_entradaSaida,
      p_locEst_indicProprPosseItem,
      p_item_pessoaParticipante,
      p_item_localEstoque,
      p_item_personalizacao,
      p_item_idLoteEstoque,
      p_idEnderecoEstoque,
      numSerie.idNumeroSerie,
      1,
      p_item_precoCustoOperacao,
      ROUND (p_item_precoCustoOperacao, 2),
      p_item_precoCMV,
      ROUND (p_item_precoCMV, 2),
      p_item_observacoes,
      0,
      p_item_idItemDocFiscal,
      0,
      0,
      0,
      r_bufferIdEstoque);    
    IF p_modDoc_geraTransferencia = 1 AND p_modDoc_geraOperacaoEmTransit = 1 AND p_modDoc_transitoLocalEstoque > 0 AND p_docTransf_estabelecEntrada > 0 AND p_docTransf_estabelecSaida > 0 THEN
      ADD_ESTOQUE_INSERE(
        r_bufferIdEstoque, 
        p_estabelecimentoAtivo, 
        p_docTransf_estabelecSaida,
        CASE WHEN p_cab_dataEntradaSaida IS NULL OR p_cab_dataEntradaSaida < p_cab_dataEmissao THEN p_cab_dataEmissao ELSE p_cab_dataEntradaSaida END, -- p_data
        p_item_gradeProduto,
        p_cab_modeloDocumento,
        900,
        0,
        0,
        CASE WHEN p_cab_entradaSaida='S' THEN 'E' ELSE 'S' END,
        p_locEstTransito_indicProprPos,
        p_item_pessoaParticipante,
        p_modDoc_transitoLocalEstoque,
        p_item_personalizacao,
        p_item_idLoteEstoque,
        p_idEnderecoEstoque,
        numSerie.idNumeroSerie,
        1,
        p_item_precoCustoOperacao,
        ROUND (p_item_precoCustoOperacao, 2),
        p_item_precoCMV,
        ROUND (p_item_precoCMV, 2),
        p_item_observacoes,
        0,
        p_item_idItemDocFiscal,
        0,
        0,
        0,
        r_bufferIdEstoque);
    END IF;
  END LOOP;
END ADD_DOC_FISC_ITEM_EST_N_SERIE;

/

create or replace PROCEDURE ADD_DOC_FISC_ITEM_EST_KIT(
    p_config_209_filtrarGrupoEcon  IN NUMBER,
    p_config_362_calcCustoPorGrade IN NUMBER,
    p_bufferIdEstoque              IN VARCHAR2,
    p_estabelecimentoAtivo         IN NUMBER,
    p_cab_modeloDocumento          IN NUMBER,
    p_cab_atualizaCustoMedio       IN NUMBER,
    p_cab_atualizaUltimaCompra     IN NUMBER,
    p_cab_entradaSaida             IN CHAR,
    p_cab_estabelecimento          IN NUMBER,
    p_cab_dataEmissao              IN DATE,
    p_cab_dataEntradaSaida         IN DATE,
    p_modDoc_geraTransferencia     IN NUMBER,
    p_modDoc_geraOperacaoEmTransit IN NUMBER,
    p_modDoc_transitoLocalEstoque  IN NUMBER,
    p_locEstTransito_indicProprPos IN CHAR,
    p_item_idItemDocFiscal         IN NUMBER,
    p_item_gradeProduto            IN NUMBER,
    p_item_localEstoque            IN NUMBER,
    p_item_pessoaParticipante      IN NUMBER,
    p_item_quantidade              IN NUMBER,
    p_item_valorCustoOperacao      IN NUMBER,
    p_item_observacoes             IN VARCHAR2,
    p_endEst_idEnderecoEstoqueDocF IN NUMBER,
    p_idEnderecoEstoque            IN NUMBER,
    p_locEst_indicProprPosseItem   IN CHAR,
    p_docTransf_estabelecEntrada   IN NUMBER,
    p_docTransf_estabelecSaida     IN NUMBER,
    r_bufferIdEstoque              OUT VARCHAR2)
IS  
  v_quantidadeNumerosSerie NUMBER;
  v_quantidadeRateioTotal  NUMBER;
  v_quantSaldoRateioTotal  NUMBER;
  v_valorSaldoRateioTotal  NUMBER;
  v_valorCustoManter       NUMBER;
  v_precoCustoKit          NUMBER;
  v_valorCustoKit          NUMBER;
  CURSOR c_kit IS 
    SELECT 
      kit.gradeProdutoFilho,
      kit.manterUltimoCusto,
      gradProdFilho.produto,
      prodFilho.controleEstoque,
      prodFilho.controlaNumeroSerie,
      ROUND(p_item_quantidade * kit.quantidade, uniFilho.casasDecimaisUnidadeMedida) quantidade
    FROM CAGRADEPRODUTOXKITSCOMBOS kit
    JOIN CAGRADESPRODUTO gradProdFilho
    ON gradProdFilho.gradeProduto = kit.gradeProdutoFilho
    JOIN CAPRODUTOS prodFilho
    ON prodFilho.produto = gradProdFilho.produto
    JOIN SIUNIDADESMEDIDA uniFilho
    ON uniFilho.unidadeMedida = prodFilho.unidadeMedida
    WHERE kit.gradeProduto = p_item_gradeProduto
    AND kit.ativo = 1
    AND kit.gradeProduto <> kit.gradeProdutoFilho
    AND ROUND(p_item_quantidade * kit.quantidade, uniFilho.casasDecimaisUnidadeMedida) > 0;
BEGIN
  r_bufferIdEstoque := p_bufferIdEstoque;
  IF p_cab_atualizaCustoMedio = 1 THEN
    SELECT COALESCE(SUM(ROUND(p_item_quantidade * kit.quantidade, uniFilho.casasDecimaisUnidadeMedida)),0)
    INTO v_quantidadeRateioTotal
    FROM CAGRADEPRODUTOXKITSCOMBOS kit
    JOIN CAGRADESPRODUTO gradProdFilho
    ON gradProdFilho.gradeProduto = kit.gradeProdutoFilho
    JOIN CAPRODUTOS prodFilho
    ON prodFilho.produto = gradProdFilho.produto
    JOIN SIUNIDADESMEDIDA uniFilho
    ON uniFilho.unidadeMedida = prodFilho.unidadeMedida
    WHERE kit.gradeProduto = p_item_gradeProduto
    AND kit.ativo = 1
    AND kit.manterUltimoCusto = 0
    AND kit.gradeProduto <> kit.gradeProdutoFilho;
    SELECT ROUND((COALESCE(SUM(ROUND(p_item_quantidade * kit.quantidade, uniFilho.casasDecimaisUnidadeMedida)
      * FUNC_ADD_BUSCA_PRECO_ULT_CUSTO(
          p_config_209_filtrarGrupoEcon,
          p_config_362_calcCustoPorGrade,
          p_cab_estabelecimento,
          TO_DATE ('01/01/1900','DD/MM/YYYY'),
          CASE WHEN p_cab_dataEntradaSaida IS NULL OR p_cab_dataEntradaSaida < p_cab_dataEmissao THEN p_cab_dataEmissao ELSE p_cab_dataEntradaSaida END - 1,
          0,
          gradProdFilho.produto,
          0,
          ' ',
          p_locEst_indicProprPosseItem,
          p_item_pessoaParticipante,
          0)),0)),2)
    INTO v_valorCustoManter
    FROM CAGRADEPRODUTOXKITSCOMBOS kit 
    JOIN CAGRADESPRODUTO gradProdFilho
    ON gradProdFilho.gradeProduto = kit.gradeProdutoFilho
    JOIN CAPRODUTOS prodFilho
    ON prodFilho.produto = gradProdFilho.produto
    JOIN SIUNIDADESMEDIDA uniFilho
    ON uniFilho.unidadeMedida = prodFilho.unidadeMedida
    WHERE kit.gradeProduto = p_item_gradeProduto
    AND kit.ativo = 1
    AND kit.manterUltimoCusto = 1
    AND kit.gradeProduto <> kit.gradeProdutoFilho;
  ELSE
    v_quantidadeRateioTotal := 0;
    v_valorCustoManter      := 0;
  END IF;
  v_quantSaldoRateioTotal := v_quantidadeRateioTotal;
  v_valorSaldoRateioTotal := p_item_valorCustoOperacao - v_valorCustoManter;
  FOR kit IN c_kit
  LOOP  
    IF p_cab_atualizaCustoMedio = 1 AND kit.manterUltimoCusto = 1 THEN
      v_precoCustoKit := FUNC_ADD_BUSCA_PRECO_ULT_CUSTO(
          p_config_209_filtrarGrupoEcon,
          p_config_362_calcCustoPorGrade,
          p_cab_estabelecimento,
          TO_DATE ('01/01/1900','DD/MM/YYYY'),
          CASE WHEN p_cab_dataEntradaSaida IS NULL OR p_cab_dataEntradaSaida < p_cab_dataEmissao THEN p_cab_dataEmissao ELSE p_cab_dataEntradaSaida END - 1,
          0,
          kit.produto,
          0,
          ' ',
          p_locEst_indicProprPosseItem,
          p_item_pessoaParticipante,
          0);
      v_valorCustoKit := ROUND (kit.quantidade * v_precoCustoKit,2);
    ELSIF p_cab_atualizaCustoMedio = 1 AND p_item_valorCustoOperacao > v_valorCustoManter AND v_quantSaldoRateioTotal > kit.quantidade THEN
      v_valorCustoKit := ROUND((p_item_valorCustoOperacao - v_valorCustoManter) * kit.quantidade / v_quantidadeRateioTotal,2);
      v_precoCustoKit := ROUND(v_valorCustoKit / kit.quantidade,7);
      v_quantSaldoRateioTotal := v_quantSaldoRateioTotal - kit.quantidade;
      v_valorSaldoRateioTotal := v_valorSaldoRateioTotal - v_valorCustoKit;
    ELSIF p_cab_atualizaCustoMedio = 1 AND v_valorSaldoRateioTotal > 0 THEN
      v_valorCustoKit := v_valorSaldoRateioTotal;
      v_precoCustoKit := ROUND(v_valorCustoKit / kit.quantidade,7);
      v_quantSaldoRateioTotal := 0;
      v_valorSaldoRateioTotal := 0;
    ELSE
      v_precoCustoKit := 0;
      v_valorCustoKit := 0;
    END IF;
    IF kit.controleEstoque IN (3,4) THEN
      ADD_DOC_FISC_ITEM_EST_KIT(
        p_config_209_filtrarGrupoEcon,
        p_config_362_calcCustoPorGrade,
        r_bufferIdEstoque,
        p_estabelecimentoAtivo,
        p_cab_modeloDocumento,
        p_cab_atualizaCustoMedio,
        p_cab_atualizaUltimaCompra,
        p_cab_entradaSaida,
        p_cab_estabelecimento,
        p_cab_dataEmissao,
        p_cab_dataEntradaSaida,
        p_modDoc_geraTransferencia,
        p_modDoc_geraOperacaoEmTransit,
        p_modDoc_transitoLocalEstoque,
        p_locEstTransito_indicProprPos,
        p_item_idItemDocFiscal,
        kit.gradeProdutoFilho,
        p_item_localEstoque,
        p_item_pessoaParticipante,
        kit.quantidade,
        v_valorCustoKit,
        p_item_observacoes,
        p_endEst_idEnderecoEstoqueDocF,
        p_idEnderecoEstoque,
        p_locEst_indicProprPosseItem,
        p_docTransf_estabelecEntrada,
        p_docTransf_estabelecSaida,
        r_bufferIdEstoque);
    ELSIF kit.controleEstoque IN(1,5,11,12) THEN
      v_quantidadeNumerosSerie := 0;
      IF kit.controlaNumeroSerie > 0 THEN
        ADD_DOC_FISC_ITEM_EST_N_SERIE(
          r_bufferIdEstoque,
          p_estabelecimentoAtivo,
          p_cab_modeloDocumento,
          p_cab_atualizaCustoMedio,
          p_cab_atualizaUltimaCompra,
          p_cab_entradaSaida,
          p_cab_estabelecimento,
          p_cab_dataEmissao,
          p_cab_dataEntradaSaida,
          p_modDoc_geraTransferencia,
          p_modDoc_geraOperacaoEmTransit,
          p_modDoc_transitoLocalEstoque,
          p_locEstTransito_indicProprPos,
          p_item_idItemDocFiscal,
          kit.gradeProdutoFilho,
          0, -- p_item_personalizacao
          0, -- p_item_idLoteEstoque
          p_item_localEstoque,
          p_item_pessoaParticipante,
          v_precoCustoKit, -- p_item_precoCustoOperacao,
          0, -- p_item_precoCMV,
          p_item_observacoes,
          p_endEst_idEnderecoEstoqueDocF,
          p_idEnderecoEstoque,
          p_locEst_indicProprPosseItem,
          p_docTransf_estabelecEntrada,
          p_docTransf_estabelecSaida,
          r_bufferIdEstoque,
          v_quantidadeNumerosSerie);
      END IF;    
      IF kit.quantidade > v_quantidadeNumerosSerie THEN
        ADD_ESTOQUE_INSERE(
          r_bufferIdEstoque,
          p_estabelecimentoAtivo,
          p_cab_estabelecimento,
          CASE WHEN p_cab_dataEntradaSaida IS NULL OR p_cab_dataEntradaSaida < p_cab_dataEmissao THEN p_cab_dataEmissao ELSE p_cab_dataEntradaSaida END, --p_data
          kit.gradeProdutoFilho,
          p_cab_modeloDocumento,
          100, --p_cab_operacaoInternaEstoque
          p_cab_atualizaCustoMedio,
          p_cab_atualizaUltimaCompra,
          p_cab_entradaSaida,
          p_locEst_indicProprPosseItem,
          p_item_pessoaParticipante,
          p_item_localEstoque,
          0, -- p_personalizacao
          0, -- p_idLoteEstoque
          p_idEnderecoEstoque,
          0, -- p_idNumeroSerie
          kit.quantidade - v_quantidadeNumerosSerie,
          v_precoCustoKit, -- p_precoCustoOperacao
          CASE WHEN v_quantidadeNumerosSerie = 0 THEN v_valorCustoKit WHEN kit.quantidade = 0 THEN 0 ELSE ROUND ((v_valorCustoKit * (kit.quantidade - v_quantidadeNumerosSerie) / kit.quantidade), 2) END, -- p_totalCustoOperacao
          0, -- p_precoCMV
          0, -- p_valorCMV
          p_item_observacoes,
          0, -- p_idItemPreDocumento,
          p_item_idItemDocFiscal,
          0, -- p_idItemSeparacao,
          0, -- p_divergenciaBalanco,
          0, -- p_idItemDocTransferencia,
          r_bufferIdEstoque);
        IF p_modDoc_geraTransferencia = 1 AND p_modDoc_geraOperacaoEmTransit = 1 AND p_modDoc_transitoLocalEstoque > 0 AND p_docTransf_estabelecEntrada > 0 AND p_docTransf_estabelecSaida > 0 THEN
          ADD_ESTOQUE_INSERE(
            r_bufferIdEstoque, 
            p_estabelecimentoAtivo, 
            p_docTransf_estabelecSaida,
            CASE WHEN p_cab_dataEntradaSaida IS NULL OR p_cab_dataEntradaSaida < p_cab_dataEmissao THEN p_cab_dataEmissao ELSE p_cab_dataEntradaSaida END, --p_data
            kit.gradeProdutoFilho,
            p_cab_modeloDocumento,
            900,
            0,
            0,
            CASE WHEN p_cab_entradaSaida='S' THEN 'E' ELSE 'S' END,
            p_locEstTransito_indicProprPos,
            p_item_pessoaParticipante,
            p_modDoc_transitoLocalEstoque,
            0, -- p_personalizacao
            0, -- p_idLoteEstoque
            p_idEnderecoEstoque,
            0, -- p_idNumeroSerie
            kit.quantidade - v_quantidadeNumerosSerie,
            v_precoCustoKit, -- p_precoCustoOperacao
            CASE WHEN v_quantidadeNumerosSerie = 0 THEN v_valorCustoKit WHEN kit.quantidade = 0 THEN 0 ELSE ROUND ((v_valorCustoKit * (kit.quantidade - v_quantidadeNumerosSerie) / kit.quantidade), 2) END, -- p_totalCustoOperacao
            0, -- p_precoCMV
            0, -- p_valorCMV
            p_item_observacoes,
            0, -- p_idItemPreDocumento,
            p_item_idItemDocFiscal,
            0, -- p_idItemSeparacao,
            0, -- p_divergenciaBalanco,
            0, -- p_idItemDocTransferencia,
            r_bufferIdEstoque);
        END IF;    
      END IF;    
    END IF;
  END LOOP;
END ADD_DOC_FISC_ITEM_EST_KIT;

/

create or replace PROCEDURE ADD_DOC_FISC_ITEM_EST_ENDERECO(
    p_config_209_filtrarGrupoEcon  IN NUMBER,
    p_config_362_calcCustoPorGrade IN NUMBER,
    p_bufferIdEstoque              IN VARCHAR2,
    p_estabelecimentoAtivo         IN NUMBER,
    p_cab_modeloDocumento          IN NUMBER,
    p_cab_atualizaCustoMedio       IN NUMBER,
    p_cab_atualizaUltimaCompra     IN NUMBER,
    p_cab_entradaSaida             IN CHAR,
    p_cab_estabelecimento          IN NUMBER,
    p_cab_dataEmissao              IN DATE,
    p_cab_dataEntradaSaida         IN DATE,
    p_modDoc_geraTransferencia     IN NUMBER,
    p_modDoc_geraOperacaoEmTransit IN NUMBER,
    p_modDoc_transitoLocalEstoque  IN NUMBER,
    p_locEstTransito_indicProprPos IN CHAR,
    p_item_idItemDocFiscal         IN NUMBER,
    p_item_gradeProduto            IN NUMBER,
    p_item_idFormulaTinta          IN NUMBER,
    p_item_personalizacao          IN NUMBER,
    p_item_idLoteEstoque           IN NUMBER,
    p_item_localEstoque            IN NUMBER,
    p_item_pessoaParticipante      IN NUMBER,
    p_item_quantidade              IN NUMBER,
    p_item_precoCustoOperacao      IN NUMBER,
    p_item_valorCustoOperacao      IN NUMBER,
    p_item_precoCMV                IN NUMBER,
    p_item_valorCMV                IN NUMBER,
    p_item_quantidadeExtemporanea  IN NUMBER,
    p_item_valorAcrescimoExtempTot IN NUMBER,
    p_item_observacoes             IN VARCHAR2,
    p_prod_controlaNumeroSerie     IN NUMBER,
    p_prod_controleEstoque         IN NUMBER,
    p_uniMed_casasDecimaisUnidadeM IN VARCHAR2,
    p_locEst_indicProprPosseItem   IN CHAR,
    p_docTransf_estabelecEntrada   IN NUMBER,
    p_docTransf_estabelecSaida     IN NUMBER,
    r_bufferIdEstoque              OUT VARCHAR2,
    r_quantidadeEnderecoEstoque    OUT NUMBER)
IS
  v_quantidadeNumerosSerie NUMBER (14,0);
  CURSOR c_endEst
  IS 
    SELECT idEnderecoEstoque,
      idEnderecoEstoqueDocFiscal,
      CASE
        WHEN p_item_quantidade = 0
          OR p_item_quantidadeExtemporanea = 0
          OR p_item_quantidade + p_item_quantidadeExtemporanea = 0
        THEN quantidade
        ELSE ROUND(quantidade * (p_item_quantidade + p_item_quantidadeExtemporanea) / p_item_quantidade, TO_NUMBER(p_uniMed_casasDecimaisUnidadeM))
      END quantidade
    FROM MODOCFISCALXENDERECOESTOQ
    WHERE idItemDocFiscal = p_item_idItemDocFiscal
    AND quantidade        > 0;
BEGIN
  r_bufferIdEstoque           := p_bufferIdEstoque;
  r_quantidadeEnderecoEstoque := 0;
  FOR endEst IN c_endEst
  LOOP
    r_quantidadeEnderecoEstoque := r_quantidadeEnderecoEstoque + endEst.quantidade;
    IF p_prod_controleEstoque = 12 AND p_item_idFormulaTinta > 0 THEN
      ADD_ESTOQUE_FORMULA_TINTA(
        p_config_209_filtrarGrupoEcon,
        p_config_362_calcCustoPorGrade,
        r_bufferIdEstoque, 
        p_estabelecimentoAtivo, 
        p_cab_modeloDocumento,
        100,
        p_cab_atualizaCustoMedio,
        p_cab_atualizaUltimaCompra,
        p_cab_entradaSaida,
        p_cab_estabelecimento,
        p_cab_dataEmissao,
        p_cab_dataEntradaSaida,
        p_modDoc_geraTransferencia,
        p_modDoc_geraOperacaoEmTransit,
        p_modDoc_transitoLocalEstoque,
        p_locEstTransito_indicProprPos,
        p_item_idFormulaTinta,
        p_item_localEstoque,
        p_item_pessoaParticipante,
        endEst.quantidade,
        p_item_observacoes,
        endEst.idEnderecoEstoque,
        p_locEst_indicProprPosseItem,
        0, -- p_idItemPreDocumento,
        p_item_idItemDocFiscal,
        0, -- p_idItemSeparacao,
        0, -- p_divergenciaBalanco,
        0, -- p_idItemDocTransferencia,
        p_docTransf_estabelecEntrada,
        p_docTransf_estabelecSaida,
        r_bufferIdEstoque);
    ELSIF p_prod_controleEstoque IN (3,4) THEN
      ADD_DOC_FISC_ITEM_EST_KIT(
        p_config_209_filtrarGrupoEcon,
        p_config_362_calcCustoPorGrade,
        r_bufferIdEstoque, 
        p_estabelecimentoAtivo, 
        p_cab_modeloDocumento,
        p_cab_atualizaCustoMedio,
        p_cab_atualizaUltimaCompra,
        p_cab_entradaSaida,
        p_cab_estabelecimento,
        p_cab_dataEmissao,
        p_cab_dataEntradaSaida,
        p_modDoc_geraTransferencia,
        p_modDoc_geraOperacaoEmTransit,
        p_modDoc_transitoLocalEstoque,
        p_locEstTransito_indicProprPos,
        p_item_idItemDocFiscal,
        p_item_gradeProduto,
        p_item_localEstoque,
        p_item_pessoaParticipante,
        endEst.quantidade,
        CASE WHEN p_item_quantidade = 0 THEN 0 ELSE ROUND (((p_item_valorCustoOperacao + p_item_valorAcrescimoExtempTot) * (endEst.quantidade - v_quantidadeNumerosSerie) / p_item_quantidade), 2) END,
        p_item_observacoes,
        endEst.idEnderecoEstoqueDocFiscal,
        endEst.idEnderecoEstoque,
        p_locEst_indicProprPosseItem,
        p_docTransf_estabelecEntrada,
        p_docTransf_estabelecSaida,
        r_bufferIdEstoque);
    ELSIF p_prod_controleEstoque IN (1,5,11,12) THEN
      v_quantidadeNumerosSerie := 0;
      IF p_prod_controlaNumeroSerie > 0 THEN
        ADD_DOC_FISC_ITEM_EST_N_SERIE(
          r_bufferIdEstoque,
          p_estabelecimentoAtivo,
          p_cab_modeloDocumento,
          p_cab_atualizaCustoMedio,
          p_cab_atualizaUltimaCompra,
          p_cab_entradaSaida,
          p_cab_estabelecimento,
          p_cab_dataEmissao,
          p_cab_dataEntradaSaida,
          p_modDoc_geraTransferencia,
          p_modDoc_geraOperacaoEmTransit,
          p_modDoc_transitoLocalEstoque,
          p_locEstTransito_indicProprPos,
          p_item_idItemDocFiscal,
          p_item_gradeProduto,
          p_item_personalizacao,
          p_item_idLoteEstoque,
          p_item_localEstoque,
          p_item_pessoaParticipante,
          CASE
            WHEN p_item_valorCustoOperacao = 0
              OR p_item_valorAcrescimoExtempTot = 0
              OR p_item_valorCustoOperacao + p_item_valorAcrescimoExtempTot = 0
            THEN p_item_precoCustoOperacao
            ELSE ROUND(p_item_precoCustoOperacao * (p_item_valorCustoOperacao + p_item_valorAcrescimoExtempTot) / p_item_valorCustoOperacao,7)
          END,
          p_item_precoCMV,
          p_item_observacoes,
          endEst.idEnderecoEstoqueDocFiscal,
          endEst.idEnderecoEstoque,
          p_locEst_indicProprPosseItem,
          p_docTransf_estabelecEntrada,
          p_docTransf_estabelecSaida,
          r_bufferIdEstoque,
          v_quantidadeNumerosSerie);
      END IF;
      IF endEst.quantidade > v_quantidadeNumerosSerie THEN
        ADD_ESTOQUE_INSERE(
          r_bufferIdEstoque, 
          p_estabelecimentoAtivo, 
          p_cab_estabelecimento,
          CASE WHEN p_cab_dataEntradaSaida IS NULL OR p_cab_dataEntradaSaida < p_cab_dataEmissao THEN p_cab_dataEmissao ELSE p_cab_dataEntradaSaida END, -- p_data
          p_item_gradeProduto,
          p_cab_modeloDocumento,
          100,
          p_cab_atualizaCustoMedio,
          p_cab_atualizaUltimaCompra,
          p_cab_entradaSaida,
          p_locEst_indicProprPosseItem,
          p_item_pessoaParticipante,
          p_item_localEstoque,
          p_item_personalizacao,
          p_item_idLoteEstoque,
          endEst.idEnderecoEstoque,
          0, -- p_idNumeroSerie
          endEst.quantidade - v_quantidadeNumerosSerie,
          CASE
            WHEN p_item_valorCustoOperacao = 0
              OR p_item_valorAcrescimoExtempTot = 0
              OR p_item_valorCustoOperacao + p_item_valorAcrescimoExtempTot = 0
            THEN p_item_precoCustoOperacao
            ELSE ROUND(p_item_precoCustoOperacao * (p_item_valorCustoOperacao + p_item_valorAcrescimoExtempTot) / p_item_valorCustoOperacao,7)
          END,
          CASE WHEN p_item_quantidade = 0 THEN 0 ELSE ROUND (((p_item_valorCustoOperacao + p_item_valorAcrescimoExtempTot) * (endEst.quantidade - v_quantidadeNumerosSerie) / p_item_quantidadeExtemporanea), 2) END,
          p_item_precoCMV,
          CASE WHEN p_item_quantidade = 0 THEN 0 ELSE ROUND ((p_item_valorCMV * (endEst.quantidade - v_quantidadeNumerosSerie) / p_item_quantidade), 2) END,
          p_item_observacoes,
          0, -- p_idItemPreDocumento,
          p_item_idItemDocFiscal,
          0, -- p_idItemSeparacao,
          0, -- p_divergenciaBalanco,
          0, -- p_idItemDocTransferencia,
          r_bufferIdEstoque);
        IF p_modDoc_geraTransferencia = 1 AND p_modDoc_geraOperacaoEmTransit = 1 AND p_modDoc_transitoLocalEstoque > 0 AND p_docTransf_estabelecEntrada > 0 AND p_docTransf_estabelecSaida > 0 THEN
          ADD_ESTOQUE_INSERE(
            r_bufferIdEstoque, 
            p_estabelecimentoAtivo, 
            p_docTransf_estabelecSaida,
            CASE WHEN p_cab_dataEntradaSaida IS NULL OR p_cab_dataEntradaSaida < p_cab_dataEmissao THEN p_cab_dataEmissao ELSE p_cab_dataEntradaSaida END, -- p_data
            p_item_gradeProduto,
            p_cab_modeloDocumento,
            900,
            0,
            0,
            CASE WHEN p_cab_entradaSaida='S' THEN 'E' ELSE 'S' END,
            p_locEstTransito_indicProprPos,
            p_item_pessoaParticipante,
            p_modDoc_transitoLocalEstoque,
            p_item_personalizacao,
            p_item_idLoteEstoque,
            endEst.idEnderecoEstoque,
            0, -- p_idNumeroSerie
            endEst.quantidade - v_quantidadeNumerosSerie,
            CASE
              WHEN p_item_valorCustoOperacao = 0
                OR p_item_valorAcrescimoExtempTot = 0
                OR p_item_valorCustoOperacao + p_item_valorAcrescimoExtempTot = 0
              THEN p_item_precoCustoOperacao
              ELSE ROUND(p_item_precoCustoOperacao * (p_item_valorCustoOperacao + p_item_valorAcrescimoExtempTot) / p_item_valorCustoOperacao,7)
            END,
            CASE WHEN p_item_quantidade = 0 THEN 0 ELSE ROUND (((p_item_valorCustoOperacao + p_item_valorAcrescimoExtempTot) * (endEst.quantidade - v_quantidadeNumerosSerie) / p_item_quantidade), 2) END,
            p_item_precoCMV,
            CASE WHEN p_item_quantidade = 0 THEN 0 ELSE ROUND ((p_item_valorCMV * (endEst.quantidade - v_quantidadeNumerosSerie) / p_item_quantidade), 2) END,
            p_item_observacoes,
            0, -- p_idItemPreDocumento,
            p_item_idItemDocFiscal,
            0, -- p_idItemSeparacao,
            0, -- p_divergenciaBalanco,
            0, -- p_idItemDocTransferencia,
            r_bufferIdEstoque);
        END IF;
      END IF;
    END IF;
  END LOOP;
END ADD_DOC_FISC_ITEM_EST_ENDERECO;

/

create or replace PROCEDURE ADD_DOC_FISC_ITEM_EST_GRAVA(
    p_config_209_filtrarGrupoEcon  IN NUMBER,
    p_config_362_calcCustoPorGrade IN NUMBER,
    p_bufferIdEstoque              IN VARCHAR2,
    p_estabelecimentoAtivo         IN NUMBER,
    p_cab_modeloDocumento          IN NUMBER,
    p_cab_atualizaCustoMedio       IN NUMBER,
    p_cab_atualizaUltimaCompra     IN NUMBER,
    p_cab_entradaSaida             IN CHAR,
    p_cab_estabelecimento          IN NUMBER,
    p_cab_dataEmissao              IN DATE,
    p_cab_dataEntradaSaida         IN DATE,
    p_modDoc_geraTransferencia     IN NUMBER,
    p_modDoc_geraOperacaoEmTransit IN NUMBER,
    p_modDoc_transitoLocalEstoque  IN NUMBER,
    p_locEstTransito_indicProprPos IN CHAR,
    p_item_idItemDocFiscal         IN NUMBER,
    p_item_gradeProduto            IN NUMBER,
    p_item_idFormulaTinta          IN NUMBER,
    p_item_personalizacao          IN NUMBER,
    p_item_idLoteEstoque           IN NUMBER,
    p_item_localEstoque            IN NUMBER,
    p_item_pessoaParticipante      IN NUMBER,
    p_item_quantidade              IN NUMBER,
    p_item_precoCustoOperacao      IN NUMBER,
    p_item_valorCustoOperacao      IN NUMBER,
    p_item_precoCMV                IN NUMBER,
    p_item_valorCMV                IN NUMBER,
    p_item_quantidadeExtemporanea  IN NUMBER,
    p_item_valorAcrescimoExtempTot IN NUMBER,
    p_item_observacoes             IN VARCHAR2,
    p_prod_controlaNumeroSerie     IN NUMBER,
    p_prod_controleEstoque         IN NUMBER,
    p_uniMed_casasDecimaisUnidadeM IN VARCHAR2,
    p_locEst_indicProprPosseItem   IN CHAR,
    p_estXLoc_solicitaEnderecoEst  IN NUMBER,
    p_docTransf_estabelecEntrada   IN NUMBER,
    p_docTransf_estabelecSaida     IN NUMBER,
    r_bufferIdEstoque              OUT VARCHAR2)
IS
  v_quantidadeEnderecoEstoque NUMBER (14,0);
  v_quantidadeNumerosSerie    NUMBER (14,0);
BEGIN
  r_bufferIdEstoque := p_bufferIdEstoque;
  v_quantidadeEnderecoEstoque := 0;
  v_quantidadeNumerosSerie    := 0;
  IF p_estXLoc_solicitaEnderecoEst = 1 AND p_prod_controleEstoque IN (1,3,4,5,11,12) THEN
    ADD_DOC_FISC_ITEM_EST_ENDERECO(
      p_config_209_filtrarGrupoEcon,
      p_config_362_calcCustoPorGrade,
      r_bufferIdEstoque,
      p_estabelecimentoAtivo,
      p_cab_modeloDocumento,
      p_cab_atualizaCustoMedio,
      p_cab_atualizaUltimaCompra,
      p_cab_entradaSaida,
      p_cab_estabelecimento,
      p_cab_dataEmissao,
      p_cab_dataEntradaSaida,
      p_modDoc_geraTransferencia,
      p_modDoc_geraOperacaoEmTransit,
      p_modDoc_transitoLocalEstoque,
      p_locEstTransito_indicProprPos,
      p_item_idItemDocFiscal,
      p_item_gradeProduto,
      p_item_idFormulaTinta,
      p_item_personalizacao,
      p_item_idLoteEstoque,
      p_item_localEstoque,
      p_item_pessoaParticipante,
      p_item_quantidade,
      p_item_precoCustoOperacao,
      p_item_valorCustoOperacao,
      p_item_precoCMV,
      p_item_valorCMV,
      p_item_quantidadeExtemporanea,
      p_item_valorAcrescimoExtempTot,
      p_item_observacoes,
      p_prod_controlaNumeroSerie,
      p_prod_controleEstoque,
      p_uniMed_casasDecimaisUnidadeM,
      p_locEst_indicProprPosseItem,
      p_docTransf_estabelecEntrada,
      p_docTransf_estabelecSaida,
      r_bufferIdEstoque,
      v_quantidadeEnderecoEstoque);
  END IF;
  IF p_item_quantidade + p_item_quantidadeExtemporanea > v_quantidadeEnderecoEstoque THEN
    IF p_prod_controleEstoque = 12 AND p_item_idFormulaTinta > 0 THEN
      ADD_ESTOQUE_FORMULA_TINTA(
        p_config_209_filtrarGrupoEcon,
        p_config_362_calcCustoPorGrade,
        r_bufferIdEstoque, 
        p_estabelecimentoAtivo, 
        p_cab_modeloDocumento,
        100,
        p_cab_atualizaCustoMedio,
        p_cab_atualizaUltimaCompra,
        p_cab_entradaSaida,
        p_cab_estabelecimento,
        p_cab_dataEmissao,
        p_cab_dataEntradaSaida,
        p_modDoc_geraTransferencia,
        p_modDoc_geraOperacaoEmTransit,
        p_modDoc_transitoLocalEstoque,
        p_locEstTransito_indicProprPos,
        p_item_idFormulaTinta,
        p_item_localEstoque,
        p_item_pessoaParticipante,
        p_item_quantidade + p_item_quantidadeExtemporanea - v_quantidadeEnderecoEstoque,
        p_item_observacoes,
        0, -- p_idEnderecoEstoque,
        p_locEst_indicProprPosseItem,
        0, -- p_idItemPreDocumento,
        p_item_idItemDocFiscal,
        0, -- p_idItemSeparacao,
        0, -- p_divergenciaBalanco,
        0, -- p_idItemDocTransferencia,
        p_docTransf_estabelecEntrada,
        p_docTransf_estabelecSaida,
        r_bufferIdEstoque);
    ELSIF p_prod_controleEstoque IN (3,4) THEN
      ADD_DOC_FISC_ITEM_EST_KIT(
        p_config_209_filtrarGrupoEcon,
        p_config_362_calcCustoPorGrade,
        r_bufferIdEstoque,
        p_estabelecimentoAtivo, 
        p_cab_modeloDocumento,
        p_cab_atualizaCustoMedio,
        p_cab_atualizaUltimaCompra,
        p_cab_entradaSaida,
        p_cab_estabelecimento,
        p_cab_dataEmissao,
        p_cab_dataEntradaSaida,
        p_modDoc_geraTransferencia,
        p_modDoc_geraOperacaoEmTransit,
        p_modDoc_transitoLocalEstoque,
        p_locEstTransito_indicProprPos,
        p_item_idItemDocFiscal,
        p_item_gradeProduto,
        p_item_localEstoque,
        p_item_pessoaParticipante,
        p_item_quantidade + p_item_quantidadeExtemporanea - v_quantidadeEnderecoEstoque,
        CASE WHEN v_quantidadeEnderecoEstoque = 0 THEN (p_item_valorCustoOperacao + p_item_valorAcrescimoExtempTot) WHEN p_item_quantidade = 0 THEN 0 ELSE ROUND (((p_item_valorCustoOperacao + p_item_valorAcrescimoExtempTot) * (p_item_quantidade + p_item_quantidadeExtemporanea - v_quantidadeEnderecoEstoque) / p_item_quantidade), 2) END,
        p_item_observacoes,
        0, -- p_idEnderecoEstoqueDocFiscal,
        0, -- p_idEnderecoEstoque,
        p_locEst_indicProprPosseItem,
        p_docTransf_estabelecEntrada,
        p_docTransf_estabelecSaida,
        r_bufferIdEstoque);
    ELSIF p_prod_controleEstoque IN (1,5,11,12) THEN
      v_quantidadeNumerosSerie := 0;
      IF p_prod_controlaNumeroSerie > 0 THEN
        ADD_DOC_FISC_ITEM_EST_N_SERIE(
          r_bufferIdEstoque,
          p_estabelecimentoAtivo,
          p_cab_modeloDocumento,
          p_cab_atualizaCustoMedio,
          p_cab_atualizaUltimaCompra,
          p_cab_entradaSaida,
          p_cab_estabelecimento,
          p_cab_dataEmissao,
          p_cab_dataEntradaSaida,
          p_modDoc_geraTransferencia,
          p_modDoc_geraOperacaoEmTransit,
          p_modDoc_transitoLocalEstoque,
          p_locEstTransito_indicProprPos,
          p_item_idItemDocFiscal,
          p_item_gradeProduto,
          p_item_personalizacao,
          p_item_idLoteEstoque,
          p_item_localEstoque,
          p_item_pessoaParticipante,
          CASE
            WHEN p_item_valorCustoOperacao = 0
              OR p_item_valorAcrescimoExtempTot = 0
              OR p_item_valorCustoOperacao + p_item_valorAcrescimoExtempTot = 0
            THEN p_item_precoCustoOperacao
            ELSE ROUND(p_item_precoCustoOperacao * (p_item_valorCustoOperacao + p_item_valorAcrescimoExtempTot) / p_item_valorCustoOperacao,7)
          END,
          p_item_precoCMV,
          p_item_observacoes,
          0, -- p_idEnderecoEstoqueDocFiscal,
          0, -- p_idEnderecoEstoque,
          p_locEst_indicProprPosseItem,
          p_docTransf_estabelecEntrada,
          p_docTransf_estabelecSaida,
          r_bufferIdEstoque,
          v_quantidadeNumerosSerie);
      END IF;
      IF p_item_quantidade + p_item_quantidadeExtemporanea - v_quantidadeEnderecoEstoque > v_quantidadeNumerosSerie THEN
        ADD_ESTOQUE_INSERE(
          r_bufferIdEstoque, 
          p_estabelecimentoAtivo, 
          p_cab_estabelecimento,
          CASE WHEN p_cab_dataEntradaSaida IS NULL OR p_cab_dataEntradaSaida < p_cab_dataEmissao THEN p_cab_dataEmissao ELSE p_cab_dataEntradaSaida END, -- p_data
          p_item_gradeProduto,
          p_cab_modeloDocumento,
          100,
          p_cab_atualizaCustoMedio,
          p_cab_atualizaUltimaCompra,
          p_cab_entradaSaida,
          p_locEst_indicProprPosseItem,
          p_item_pessoaParticipante,
          p_item_localEstoque,
          p_item_personalizacao,
          p_item_idLoteEstoque,
          0, -- p_idEnderecoEstoque,
          0, -- p_idNumeroSerie
          p_item_quantidade + p_item_quantidadeExtemporanea - v_quantidadeEnderecoEstoque - v_quantidadeNumerosSerie,
          CASE
            WHEN p_item_valorCustoOperacao = 0
              OR p_item_valorAcrescimoExtempTot = 0
              OR p_item_valorCustoOperacao + p_item_valorAcrescimoExtempTot = 0
            THEN p_item_precoCustoOperacao
            ELSE ROUND(p_item_precoCustoOperacao * (p_item_valorCustoOperacao + p_item_valorAcrescimoExtempTot) / p_item_valorCustoOperacao,7)
          END,
          CASE WHEN p_item_quantidade = 0 THEN 0 ELSE ROUND (((p_item_valorCustoOperacao + p_item_valorAcrescimoExtempTot) * (p_item_quantidade + p_item_quantidadeExtemporanea - v_quantidadeEnderecoEstoque - v_quantidadeNumerosSerie) / p_item_quantidade), 2) END,
          p_item_precoCMV,
          CASE WHEN p_item_quantidade = 0 THEN 0 ELSE ROUND ((p_item_valorCMV * (p_item_quantidade + p_item_quantidadeExtemporanea - v_quantidadeEnderecoEstoque - v_quantidadeNumerosSerie) / p_item_quantidade), 2) END,
          p_item_observacoes,
          0, -- p_idItemPreDocumento,
          p_item_idItemDocFiscal,
          0, -- p_idItemSeparacao,
          0, -- p_divergenciaBalanco,
          0, -- p_idItemDocTransferencia,
          r_bufferIdEstoque);
        IF p_modDoc_geraTransferencia = 1 AND p_modDoc_geraOperacaoEmTransit = 1 AND p_modDoc_transitoLocalEstoque > 0 AND p_docTransf_estabelecEntrada > 0 AND p_docTransf_estabelecSaida > 0 THEN
          ADD_ESTOQUE_INSERE(
            r_bufferIdEstoque, 
            p_estabelecimentoAtivo, 
            p_docTransf_estabelecSaida,
            CASE WHEN p_cab_dataEntradaSaida IS NULL OR p_cab_dataEntradaSaida < p_cab_dataEmissao THEN p_cab_dataEmissao ELSE p_cab_dataEntradaSaida END, -- p_data
            p_item_gradeProduto,
            p_cab_modeloDocumento,
            900,
            0,
            0,
            CASE WHEN p_cab_entradaSaida='S' THEN 'E' ELSE 'S' END,
            p_locEstTransito_indicProprPos,
            p_item_pessoaParticipante,
            p_modDoc_transitoLocalEstoque,
            p_item_personalizacao,
            p_item_idLoteEstoque,
            0, -- p_idEnderecoEstoque,
            0, -- p_idNumeroSerie
            p_item_quantidade + p_item_quantidadeExtemporanea - v_quantidadeEnderecoEstoque - v_quantidadeNumerosSerie,
            CASE
              WHEN p_item_valorCustoOperacao = 0
                OR p_item_valorAcrescimoExtempTot = 0
                OR p_item_valorCustoOperacao + p_item_valorAcrescimoExtempTot = 0
              THEN p_item_precoCustoOperacao
              ELSE ROUND(p_item_precoCustoOperacao * (p_item_valorCustoOperacao + p_item_valorAcrescimoExtempTot) / p_item_valorCustoOperacao,7)
            END,
            CASE WHEN p_item_quantidade = 0 THEN 0 ELSE ROUND (((p_item_valorCustoOperacao + p_item_valorAcrescimoExtempTot) * (p_item_quantidade + p_item_quantidadeExtemporanea - v_quantidadeEnderecoEstoque - v_quantidadeNumerosSerie) / p_item_quantidade), 2) END,
            p_item_precoCMV,
            CASE WHEN p_item_quantidade = 0 THEN 0 ELSE ROUND ((p_item_valorCMV * (p_item_quantidade + p_item_quantidadeExtemporanea - v_quantidadeEnderecoEstoque - v_quantidadeNumerosSerie) / p_item_quantidade), 2) END,
            p_item_observacoes,
            0, -- p_idItemPreDocumento,
            p_item_idItemDocFiscal,
            0, -- p_idItemSeparacao,
            0, -- p_divergenciaBalanco,
            0, -- p_idItemDocTransferencia,
            r_bufferIdEstoque);
        END IF;
      END IF;
    END IF;
  END IF;
END ADD_DOC_FISC_ITEM_EST_GRAVA;

/

create or replace PROCEDURE ADD_DOC_FISC_ITEM_EST_ATUALIZA(
    p_config_209_filtrarGrupoEcon  IN NUMBER,
    p_config_362_calcCustoPorGrade IN NUMBER,
    p_idItemDocFiscal              IN NUMBER,
    p_estabelecimentoAtivo         IN NUMBER
  )
IS
  v_bufferIdEstoque        VARCHAR2 (32000);
  CURSOR c_estoqueExcluir
  IS 
    SELECT a.idEstoque
    FROM MOESTOQUES a
    JOIN MODOCFISCALXESTOQUE b ON b.idEstoque = a.idEstoque
    WHERE b.idItemDocFiscal = p_idItemDocFiscal
    ORDER BY a.idEstoque;
  CURSOR c_item
  IS 
    SELECT 
      cab.modeloDocumento,
      cab.entradaSaida,
      cab.atualizaCustoMedio,
      cab.atualizaUltimaCompra,
      cab.estabelecimento,
      cab.dataEmissao,
      cab.dataEntradaSaida,
      modDoc.geraTransferencia,
      modDoc.geraOperacaoEmTransito,
      modDoc.transitoLocalEstoque,
      locEstTransito.indicadorPropriedadePosseItem locEstTransito_indicProprPos,
      item.idItemDocFiscal,
      item.gradeProduto,
      item.idFormulaTinta,
      item.personalizacao,
      item.idLoteEstoque,
      item.localEstoque,
      item.pessoaParticipante,
      item.quantidade,
      item.precoCustoOperacao,
      item.valorCustoOperacao,
      item.precoCMV,
      item.valorCMV,
      item.quantidadeExtemporanea,
      item.valorAcrescimoExtempTotal,
      item.observacoes,
      prod.controlaNumeroSerie,
      prod.controleEstoque,
      uniMed.casasDecimaisUnidadeMedida,
      locEst.indicadorPropriedadePosseItem locEst_indicProprPosseItem,
      COALESCE (estXLoc.solicitaEnderecoEstoque,0) estXLoc_solicitaEnderecoEst,
      COALESCE (cabTransf.estabelecimentoEntrada,0) docTransf_estabelecEntrada,
      COALESCE (cabTransf.estabelecimentoSaida,0) docTransf_estabelecSaida
    FROM MODOCFISCALXITENS item
    JOIN MODOCUMENTOSFISCAIS cab
    ON cab.idDocumentoFiscal = item.idDocumentoFiscal
    JOIN CAGRADESPRODUTO gradProd
    ON gradProd.gradeProduto = item.gradeProduto
    JOIN CAPRODUTOS prod
    ON prod.produto = gradProd.produto
    JOIN SIUNIDADESMEDIDA uniMed
    ON uniMed.unidadeMedida = prod.unidadeMedida
    JOIN PAMODELOSDOCUMENTO modDoc
    ON modDoc.modeloDocumento = cab.modeloDocumento
    JOIN PALOCAISESTOQUE locEstTransito
    ON locEstTransito.localEstoque = modDoc.transitoLocalEstoque 
    JOIN PALOCAISESTOQUE locEst
    ON locEst.localEstoque = item.localEstoque
    LEFT JOIN PAESTABELECIMENTOXLOCAISE estXLoc
    ON estXLoc.estabelecimento = cab.estabelecimento
    AND estXLoc.localEstoque = item.localEstoque
    LEFT JOIN MODOCTRANSFXDOCFISCAL transfXDoc
    ON transfXDoc.idItemDocFiscal = item.idItemDocFiscal
    AND transfXDoc.entradaSaidaOriginal IN ('E','S')
    LEFT JOIN MODOCUMENTOTRANSFXITENS itemTransf
    ON itemTransf.idItemDocTransferencia = transfXDoc.idItemDocTransferencia
    LEFT JOIN MODOCUMENTOSTRANSFERENCIA cabTransf
    ON cabTransf.documentoTransferencia = itemTransf.documentoTransferencia
    WHERE item.idItemDocFiscal = p_idItemDocFiscal
    AND item.cancelado = 0
    AND item.quantidade+item.quantidadeExtemporanea > 0
    AND item.movimentaEstoque = 1
    AND cab.situacaoDocumentoFiscal BETWEEN 21 AND 23;
BEGIN
  v_bufferIdEstoque := '';
  FOR estoqueExcluir IN c_estoqueExcluir
  LOOP
    v_bufferIdEstoque := CASE WHEN (v_bufferIdEstoque IS NULL OR v_bufferIdEstoque = '' OR v_bufferIdEstoque = ' ') THEN '' ELSE RTRIM (v_bufferIdEstoque) || ';' END || TO_CHAR (LPAD(estoqueExcluir.idEstoque,14,'0'));
    ADD_MOESTOQUES_EXCLUI (estoqueExcluir.idEstoque);
  END LOOP;
  FOR item IN c_item
  LOOP
    ADD_DOC_FISC_ITEM_EST_GRAVA(
      p_config_209_filtrarGrupoEcon,
      p_config_362_calcCustoPorGrade,
      v_bufferIdEstoque,
      p_estabelecimentoAtivo,
      item.modeloDocumento,
      item.atualizaCustoMedio,
      item.atualizaUltimaCompra,
      item.entradaSaida,
      item.estabelecimento,
      item.dataEmissao,
      item.dataEntradaSaida,
      item.geraTransferencia,
      item.geraOperacaoEmTransito,
      item.transitoLocalEstoque,
      item.locEstTransito_indicProprPos,
      item.idItemDocFiscal,
      item.gradeProduto,
      item.idFormulaTinta,
      item.personalizacao,
      item.idLoteEstoque,
      item.localEstoque,
      item.pessoaParticipante,
      item.quantidade,
      item.precoCustoOperacao,
      item.valorCustoOperacao,
      item.precoCMV,
      item.valorCMV,
      item.quantidadeExtemporanea,
      item.valorAcrescimoExtempTotal,
      item.observacoes,
      item.controlaNumeroSerie,
      item.controleEstoque,
      item.casasDecimaisUnidadeMedida,
      item.locEst_indicProprPosseItem,
      item.estXLoc_solicitaEnderecoEst,
      item.docTransf_estabelecEntrada,
      item.docTransf_estabelecSaida,
      v_bufferIdEstoque);
  END LOOP;
END ADD_DOC_FISC_ITEM_EST_ATUALIZA;

/

create or replace PROCEDURE ADD_DOC_FISC_CAB_EST_ATUALIZA(
    p_config_209_filtrarGrupoEcon  IN NUMBER,
    p_config_362_calcCustoPorGrade IN NUMBER,
    p_idDocumentoFiscal            IN NUMBER,
    p_estabelecimentoAtivo         IN NUMBER
  )
IS
  v_bufferIdEstoque        VARCHAR2 (32000);
  CURSOR c_estoqueExcluir
  IS 
    SELECT a.idEstoque
    FROM MOESTOQUES a
    JOIN MODOCFISCALXESTOQUE b ON b.idEstoque = a.idEstoque
    JOIN MODOCFISCALXITENS c ON c.idItemDocFiscal = b.idItemDocFiscal
    WHERE c.idDocumentoFiscal = p_idDocumentoFiscal
    ORDER BY a.idEstoque;
  CURSOR c_item
  IS 
    SELECT 
      cab.modeloDocumento,
      cab.entradaSaida,
      cab.atualizaCustoMedio,
      cab.atualizaUltimaCompra,
      cab.estabelecimento,
      cab.dataEmissao,
      cab.dataEntradaSaida,
      modDoc.geraTransferencia,
      modDoc.geraOperacaoEmTransito,
      modDoc.transitoLocalEstoque,
      locEstTransito.indicadorPropriedadePosseItem locEstTransito_indicProprPos,
      item.idItemDocFiscal,
      item.gradeProduto,
      item.idFormulaTinta,
      item.personalizacao,
      item.idLoteEstoque,
      item.localEstoque,
      item.pessoaParticipante,
      item.quantidade,
      item.precoCustoOperacao,
      item.valorCustoOperacao,
      item.precoCMV,
      item.valorCMV,
      item.quantidadeExtemporanea,
      item.valorAcrescimoExtempTotal,
      item.observacoes,
      prod.controlaNumeroSerie,
      prod.controleEstoque,
      uniMed.casasDecimaisUnidadeMedida,
      locEst.indicadorPropriedadePosseItem locEst_indicProprPosseItem,
      COALESCE (estXLoc.solicitaEnderecoEstoque,0) estXLoc_solicitaEnderecoEst,
      COALESCE (cabTransf.estabelecimentoEntrada,0) docTransf_estabelecEntrada,
      COALESCE (cabTransf.estabelecimentoSaida,0) docTransf_estabelecSaida
    FROM MODOCFISCALXITENS item
    JOIN MODOCUMENTOSFISCAIS cab
    ON cab.idDocumentoFiscal = item.idDocumentoFiscal
    JOIN CAGRADESPRODUTO gradProd
    ON gradProd.gradeProduto = item.gradeProduto
    JOIN CAPRODUTOS prod
    ON prod.produto = gradProd.produto
    JOIN SIUNIDADESMEDIDA uniMed
    ON uniMed.unidadeMedida = prod.unidadeMedida
    JOIN PAMODELOSDOCUMENTO modDoc
    ON modDoc.modeloDocumento = cab.modeloDocumento
    JOIN PALOCAISESTOQUE locEstTransito
    ON locEstTransito.localEstoque = modDoc.transitoLocalEstoque 
    JOIN PALOCAISESTOQUE locEst
    ON locEst.localEstoque = item.localEstoque
    LEFT JOIN PAESTABELECIMENTOXLOCAISE estXLoc
    ON estXLoc.estabelecimento = cab.estabelecimento
    AND estXLoc.localEstoque = item.localEstoque
    LEFT JOIN MODOCTRANSFXDOCFISCAL transfXDoc
    ON transfXDoc.idItemDocFiscal = item.idItemDocFiscal
    AND transfXDoc.entradaSaidaOriginal IN('E','S')
    LEFT JOIN MODOCUMENTOTRANSFXITENS itemTransf
    ON itemTransf.idItemDocTransferencia = transfXDoc.idItemDocTransferencia
    LEFT JOIN MODOCUMENTOSTRANSFERENCIA cabTransf
    ON cabTransf.documentoTransferencia = itemTransf.documentoTransferencia
    WHERE item.idDocumentoFiscal = p_idDocumentoFiscal
    AND item.cancelado = 0
    AND item.quantidade+item.quantidadeExtemporanea > 0
    AND item.movimentaEstoque = 1
    AND cab.situacaoDocumentoFiscal BETWEEN 21 AND 23;
BEGIN
  v_bufferIdEstoque := '';
  FOR estoqueExcluir IN c_estoqueExcluir
  LOOP
    v_bufferIdEstoque := CASE WHEN (v_bufferIdEstoque IS NULL OR v_bufferIdEstoque = '' OR v_bufferIdEstoque = ' ') THEN '' ELSE RTRIM (v_bufferIdEstoque) || ';' END || TO_CHAR (LPAD(estoqueExcluir.idEstoque,14,'0'));
    ADD_MOESTOQUES_EXCLUI (estoqueExcluir.idEstoque);
  END LOOP;
  FOR item IN c_item
  LOOP
    ADD_DOC_FISC_ITEM_EST_GRAVA(
      p_config_209_filtrarGrupoEcon,
      p_config_362_calcCustoPorGrade,
      v_bufferIdEstoque,
      p_estabelecimentoAtivo,
      item.modeloDocumento,
      item.atualizaCustoMedio,
      item.atualizaUltimaCompra,
      item.entradaSaida,
      item.estabelecimento,
      item.dataEmissao,
      item.dataEntradaSaida,
      item.geraTransferencia,
      item.geraOperacaoEmTransito,
      item.transitoLocalEstoque,
      item.locEstTransito_indicProprPos,
      item.idItemDocFiscal,
      item.gradeProduto,
      item.idFormulaTinta,
      item.personalizacao,
      item.idLoteEstoque,
      item.localEstoque,
      item.pessoaParticipante,
      item.quantidade,
      item.precoCustoOperacao,
      item.valorCustoOperacao,
      item.precoCMV,
      item.valorCMV,
      item.quantidadeExtemporanea,
      item.valorAcrescimoExtempTotal,
      item.observacoes,
      item.controlaNumeroSerie,
      item.controleEstoque,
      item.casasDecimaisUnidadeMedida,
      item.locEst_indicProprPosseItem,
      item.estXLoc_solicitaEnderecoEst,
      item.docTransf_estabelecEntrada,
      item.docTransf_estabelecSaida,
      v_bufferIdEstoque);
  END LOOP;
END ADD_DOC_FISC_CAB_EST_ATUALIZA;

/

create or replace PROCEDURE ADD_PRE_DOC_ITEM_EST_N_SERIE(
    p_bufferIdEstoque              IN VARCHAR2,
    p_estabelecimentoAtivo         IN NUMBER,
    p_cab_modeloDocumento          IN NUMBER,
    p_cab_atualizaCustoMedio       IN NUMBER,
    p_cab_atualizaUltimaCompra     IN NUMBER,
    p_cab_entradaSaida             IN CHAR,
    p_cab_estabelecimento          IN NUMBER,
    p_cab_dataEmissao              IN DATE,
    p_cab_dataEntradaSaida         IN DATE,
    p_modDoc_geraTransferencia     IN NUMBER,
    p_modDoc_geraOperacaoEmTransit IN NUMBER,
    p_modDoc_transitoLocalEstoque  IN NUMBER,
    p_locEstTransito_indicProprPos IN CHAR,
    p_item_idItemPreDocumento      IN NUMBER,
    p_item_gradeProduto            IN NUMBER,
    p_item_personalizacao          IN NUMBER,
    p_item_idLoteEstoque           IN NUMBER,
    p_item_localEstoque            IN NUMBER,
    p_item_pessoaParticipante      IN NUMBER,
    p_item_precoCustoOperacao      IN NUMBER,
    p_item_precoCMV                IN NUMBER,
    p_item_observacoes             IN VARCHAR2,
    p_endEst_idEnderecoEstoquePreD IN NUMBER,
    p_idEnderecoEstoque            IN NUMBER,
    p_locEst_indicProprPosseItem   IN CHAR,
    p_docTransf_estabelecEntrada   IN NUMBER,
    p_docTransf_estabelecSaida     IN NUMBER,
    r_bufferIdEstoque              OUT VARCHAR2,
    r_quantidadeNumerosSerie       OUT NUMBER)
IS
  CURSOR c_numSerie
  IS 
    SELECT idNumeroSerie
    FROM MOPREDOCUMXNUMEROSSERIE
    WHERE idItemPreDocumento = p_item_idItemPreDocumento
    AND idEnderecoEstoquePreDocumento = p_endEst_idEnderecoEstoquePreD
    AND gradeProduto = p_item_gradeProduto;
BEGIN
  r_bufferIdEstoque        := p_bufferIdEstoque;
  r_quantidadeNumerosSerie := 0;
  FOR numSerie IN c_numSerie
  LOOP
    r_quantidadeNumerosSerie := r_quantidadeNumerosSerie + 1;
    ADD_ESTOQUE_INSERE(
      r_bufferIdEstoque, 
      p_estabelecimentoAtivo, 
      p_cab_estabelecimento,
      CASE WHEN p_cab_dataEntradaSaida IS NULL OR p_cab_dataEntradaSaida < p_cab_dataEmissao THEN p_cab_dataEmissao ELSE p_cab_dataEntradaSaida END, -- p_data
      p_item_gradeProduto,
      p_cab_modeloDocumento,
      101,
      p_cab_atualizaCustoMedio,
      p_cab_atualizaUltimaCompra,
      p_cab_entradaSaida,
      p_locEst_indicProprPosseItem,
      p_item_pessoaParticipante,
      p_item_localEstoque,
      p_item_personalizacao,
      p_item_idLoteEstoque,
      p_idEnderecoEstoque,
      numSerie.idNumeroSerie,
      1,
      p_item_precoCustoOperacao,
      ROUND (p_item_precoCustoOperacao, 2),
      p_item_precoCMV,
      ROUND (p_item_precoCMV, 2),
      p_item_observacoes,
      p_item_idItemPreDocumento,
      0,
      0,
      0,
      0,
      r_bufferIdEstoque);    
    IF p_modDoc_geraTransferencia = 1 AND p_modDoc_geraOperacaoEmTransit = 1 AND p_modDoc_transitoLocalEstoque > 0 AND p_docTransf_estabelecEntrada > 0 AND p_docTransf_estabelecSaida > 0 THEN
      ADD_ESTOQUE_INSERE(
        r_bufferIdEstoque, 
        p_estabelecimentoAtivo, 
        p_docTransf_estabelecSaida,
        CASE WHEN p_cab_dataEntradaSaida IS NULL OR p_cab_dataEntradaSaida < p_cab_dataEmissao THEN p_cab_dataEmissao ELSE p_cab_dataEntradaSaida END, -- p_data
        p_item_gradeProduto,
        p_cab_modeloDocumento,
        900,
        0,
        0,
        CASE WHEN p_cab_entradaSaida='S' THEN 'E' ELSE 'S' END,
        p_locEstTransito_indicProprPos,
        p_item_pessoaParticipante,
        p_modDoc_transitoLocalEstoque,
        p_item_personalizacao,
        p_item_idLoteEstoque,
        p_idEnderecoEstoque,
        numSerie.idNumeroSerie,
        1,
        p_item_precoCustoOperacao,
        ROUND (p_item_precoCustoOperacao, 2),
        p_item_precoCMV,
        ROUND (p_item_precoCMV, 2),
        p_item_observacoes,
        p_item_idItemPreDocumento,
        0,
        0,
        0,
        0,
        r_bufferIdEstoque);
    END IF;
  END LOOP;
END ADD_PRE_DOC_ITEM_EST_N_SERIE;

/

create or replace PROCEDURE ADD_PRE_DOC_ITEM_EST_KIT(
    p_config_209_filtrarGrupoEcon  IN NUMBER,
    p_config_362_calcCustoPorGrade IN NUMBER,
    p_bufferIdEstoque              IN VARCHAR2,
    p_estabelecimentoAtivo         IN NUMBER,
    p_cab_modeloDocumento          IN NUMBER,
    p_cab_atualizaCustoMedio       IN NUMBER,
    p_cab_atualizaUltimaCompra     IN NUMBER,
    p_cab_entradaSaida             IN CHAR,
    p_cab_estabelecimento          IN NUMBER,
    p_cab_dataEmissao              IN DATE,
    p_cab_dataEntradaSaida         IN DATE,
    p_modDoc_geraTransferencia     IN NUMBER,
    p_modDoc_geraOperacaoEmTransit IN NUMBER,
    p_modDoc_transitoLocalEstoque  IN NUMBER,
    p_locEstTransito_indicProprPos IN CHAR,
    p_item_idItemPreDocumento      IN NUMBER,
    p_item_gradeProduto            IN NUMBER,
    p_item_localEstoque            IN NUMBER,
    p_item_pessoaParticipante      IN NUMBER,
    p_item_quantidade              IN NUMBER,
    p_item_valorCustoOperacao      IN NUMBER,
    p_item_observacoes             IN VARCHAR2,
    p_endEst_idEnderecoEstoquePreD IN NUMBER,
    p_idEnderecoEstoque            IN NUMBER,
    p_locEst_indicProprPosseItem   IN CHAR,
    p_docTransf_estabelecEntrada   IN NUMBER,
    p_docTransf_estabelecSaida     IN NUMBER,
    r_bufferIdEstoque              OUT VARCHAR2)
IS  
  v_quantidadeNumerosSerie NUMBER;
  v_quantidadeRateioTotal  NUMBER;
  v_quantSaldoRateioTotal  NUMBER;
  v_valorSaldoRateioTotal  NUMBER;
  v_valorCustoManter       NUMBER;
  v_precoCustoKit          NUMBER;
  v_valorCustoKit          NUMBER;
  CURSOR c_kit
  IS 
    SELECT 
      kit.gradeProdutoFilho,
      kit.manterUltimoCusto,
      gradProdFilho.produto,
      prodFilho.controleEstoque,
      prodFilho.controlaNumeroSerie,
      ROUND(p_item_quantidade * kit.quantidade, uniFilho.casasDecimaisUnidadeMedida) quantidade
    FROM CAGRADEPRODUTOXKITSCOMBOS kit
    JOIN CAGRADESPRODUTO gradProdFilho
    ON gradProdFilho.gradeProduto = kit.gradeProdutoFilho
    JOIN CAPRODUTOS prodFilho
    ON prodFilho.produto = gradProdFilho.produto
    JOIN SIUNIDADESMEDIDA uniFilho
    ON uniFilho.unidadeMedida = prodFilho.unidadeMedida
    WHERE kit.gradeProduto = p_item_gradeProduto
    AND kit.ativo = 1
    AND kit.gradeProduto <> kit.gradeProdutoFilho
    AND ROUND(p_item_quantidade * kit.quantidade, uniFilho.casasDecimaisUnidadeMedida) > 0;
BEGIN
  r_bufferIdEstoque := p_bufferIdEstoque;
  IF p_cab_atualizaCustoMedio = 1 THEN
    SELECT COALESCE(SUM(ROUND(p_item_quantidade * kit.quantidade, uniFilho.casasDecimaisUnidadeMedida)),0)
    INTO v_quantidadeRateioTotal
    FROM CAGRADEPRODUTOXKITSCOMBOS kit 
    JOIN CAGRADESPRODUTO gradProdFilho ON gradProdFilho.gradeProduto = kit.gradeProdutoFilho
    JOIN CAPRODUTOS prodFilho ON prodFilho.produto = gradProdFilho.produto
    JOIN SIUNIDADESMEDIDA uniFilho ON uniFilho.unidadeMedida = prodFilho.unidadeMedida
    WHERE kit.gradeProduto = p_item_gradeProduto
    AND kit.ativo = 1
    AND kit.manterUltimoCusto = 0
    AND kit.gradeProduto <> kit.gradeProdutoFilho;
    SELECT ROUND((COALESCE(SUM(ROUND(p_item_quantidade * kit.quantidade, uniFilho.casasDecimaisUnidadeMedida)
      * FUNC_ADD_BUSCA_PRECO_ULT_CUSTO(
          p_config_209_filtrarGrupoEcon,
          p_config_362_calcCustoPorGrade,
          p_cab_estabelecimento,
          TO_DATE ('01/01/1900','DD/MM/YYYY'),
          CASE WHEN p_cab_dataEntradaSaida IS NULL OR p_cab_dataEntradaSaida < p_cab_dataEmissao THEN p_cab_dataEmissao ELSE p_cab_dataEntradaSaida END - 1,
          0,
          gradProdFilho.produto,
          0,
          ' ',
          p_locEst_indicProprPosseItem,
          p_item_pessoaParticipante,
          0)),0)),2)
    INTO v_valorCustoManter
    FROM CAGRADEPRODUTOXKITSCOMBOS kit
    JOIN CAGRADESPRODUTO gradProdFilho
    ON gradProdFilho.gradeProduto = kit.gradeProdutoFilho
    JOIN CAPRODUTOS prodFilho
    ON prodFilho.produto = gradProdFilho.produto
    JOIN SIUNIDADESMEDIDA uniFilho
    ON uniFilho.unidadeMedida = prodFilho.unidadeMedida
    WHERE kit.gradeProduto = p_item_gradeProduto
    AND kit.ativo = 1
    AND kit.manterUltimoCusto = 1
    AND kit.gradeProduto <> kit.gradeProdutoFilho;
  ELSE
    v_quantidadeRateioTotal := 0;
    v_valorCustoManter      := 0;
  END IF;
  v_quantSaldoRateioTotal := v_quantidadeRateioTotal;
  v_valorSaldoRateioTotal := p_item_valorCustoOperacao - v_valorCustoManter;
  FOR kit IN c_kit
  LOOP  
    IF p_cab_atualizaCustoMedio = 1 AND kit.manterUltimoCusto = 1 THEN
      v_precoCustoKit := FUNC_ADD_BUSCA_PRECO_ULT_CUSTO(
          p_config_209_filtrarGrupoEcon,
          p_config_362_calcCustoPorGrade,
          p_cab_estabelecimento,
          TO_DATE ('01/01/1900','DD/MM/YYYY'),
          CASE WHEN p_cab_dataEntradaSaida IS NULL OR p_cab_dataEntradaSaida < p_cab_dataEmissao THEN p_cab_dataEmissao ELSE p_cab_dataEntradaSaida END - 1,
          0,
          kit.produto,
          0,
          ' ',
          p_locEst_indicProprPosseItem,
          p_item_pessoaParticipante,
          0);
      v_valorCustoKit := ROUND (kit.quantidade * v_precoCustoKit,2);
    ELSIF p_cab_atualizaCustoMedio = 1 AND p_item_valorCustoOperacao > v_valorCustoManter AND v_quantSaldoRateioTotal > kit.quantidade THEN
      v_valorCustoKit := ROUND((p_item_valorCustoOperacao - v_valorCustoManter) * kit.quantidade / v_quantidadeRateioTotal,2);
      v_precoCustoKit := ROUND(v_valorCustoKit / kit.quantidade,7);
      v_quantSaldoRateioTotal := v_quantSaldoRateioTotal - kit.quantidade;
      v_valorSaldoRateioTotal := v_valorSaldoRateioTotal - v_valorCustoKit;
    ELSIF p_cab_atualizaCustoMedio = 1 AND v_valorSaldoRateioTotal > 0 THEN
      v_valorCustoKit := v_valorSaldoRateioTotal;
      v_precoCustoKit := ROUND(v_valorCustoKit / kit.quantidade,7);
      v_quantSaldoRateioTotal := 0;
      v_valorSaldoRateioTotal := 0;
    ELSE
      v_precoCustoKit := 0;
      v_valorCustoKit := 0;
    END IF;
    IF kit.controleEstoque IN (3,4) THEN
      ADD_PRE_DOC_ITEM_EST_KIT(
        p_config_209_filtrarGrupoEcon,
        p_config_362_calcCustoPorGrade,
        r_bufferIdEstoque,
        p_estabelecimentoAtivo,
        p_cab_modeloDocumento,
        p_cab_atualizaCustoMedio,
        p_cab_atualizaUltimaCompra,
        p_cab_entradaSaida,
        p_cab_estabelecimento,
        p_cab_dataEmissao,
        p_cab_dataEntradaSaida,
        p_modDoc_geraTransferencia,
        p_modDoc_geraOperacaoEmTransit,
        p_modDoc_transitoLocalEstoque,
        p_locEstTransito_indicProprPos,
        p_item_idItemPreDocumento,
        kit.gradeProdutoFilho,
        p_item_localEstoque,
        p_item_pessoaParticipante,
        kit.quantidade,
        v_valorCustoKit,
        p_item_observacoes,
        p_endEst_idEnderecoEstoquePreD,
        p_idEnderecoEstoque,
        p_locEst_indicProprPosseItem,
        p_docTransf_estabelecEntrada,
        p_docTransf_estabelecSaida,
        r_bufferIdEstoque);
    ELSIF kit.controleEstoque IN(1,5,11,12) THEN
      v_quantidadeNumerosSerie := 0;
      IF kit.controlaNumeroSerie > 0 THEN
        ADD_PRE_DOC_ITEM_EST_N_SERIE(
          r_bufferIdEstoque,
          p_estabelecimentoAtivo,
          p_cab_modeloDocumento,
          p_cab_atualizaCustoMedio,
          p_cab_atualizaUltimaCompra,
          p_cab_entradaSaida,
          p_cab_estabelecimento,
          p_cab_dataEmissao,
          p_cab_dataEntradaSaida,
          p_modDoc_geraTransferencia,
          p_modDoc_geraOperacaoEmTransit,
          p_modDoc_transitoLocalEstoque,
          p_locEstTransito_indicProprPos,
          p_item_idItemPreDocumento,
          kit.gradeProdutoFilho,
          0, -- p_item_personalizacao
          0, -- p_item_idLoteEstoque
          p_item_localEstoque,
          p_item_pessoaParticipante,
          v_precoCustoKit, -- p_item_precoCustoOperacao,
          0, -- p_item_precoCMV,
          p_item_observacoes,
          p_endEst_idEnderecoEstoquePreD,
          p_idEnderecoEstoque,
          p_locEst_indicProprPosseItem,
          p_docTransf_estabelecEntrada,
          p_docTransf_estabelecSaida,
          r_bufferIdEstoque,
          v_quantidadeNumerosSerie);
      END IF;    
      IF kit.quantidade > v_quantidadeNumerosSerie THEN
        ADD_ESTOQUE_INSERE(
          r_bufferIdEstoque,
          p_estabelecimentoAtivo,
          p_cab_estabelecimento,
          CASE WHEN p_cab_dataEntradaSaida IS NULL OR p_cab_dataEntradaSaida < p_cab_dataEmissao THEN p_cab_dataEmissao ELSE p_cab_dataEntradaSaida END, --p_data
          kit.gradeProdutoFilho,
          p_cab_modeloDocumento,
          101, --p_cab_operacaoInternaEstoque
          p_cab_atualizaCustoMedio,
          p_cab_atualizaUltimaCompra,
          p_cab_entradaSaida,
          p_locEst_indicProprPosseItem,
          p_item_pessoaParticipante,
          p_item_localEstoque,
          0, -- p_personalizacao
          0, -- p_idLoteEstoque
          p_idEnderecoEstoque,
          0, -- p_idNumeroSerie
          kit.quantidade - v_quantidadeNumerosSerie,
          v_precoCustoKit, -- p_precoCustoOperacao
          CASE WHEN v_quantidadeNumerosSerie = 0 THEN v_valorCustoKit WHEN kit.quantidade = 0 THEN 0 ELSE ROUND ((v_valorCustoKit * (kit.quantidade - v_quantidadeNumerosSerie) / kit.quantidade), 2) END, -- p_totalCustoOperacao
          0, -- p_precoCMV
          0, -- p_valorCMV
          p_item_observacoes,
          p_item_idItemPreDocumento,
          0, -- p_idItemDocFiscal,
          0, -- p_idItemSeparacao,
          0, -- p_divergenciaBalanco,
          0, -- p_idItemDocTransferencia,
          r_bufferIdEstoque);
        IF p_modDoc_geraTransferencia = 1 AND p_modDoc_geraOperacaoEmTransit = 1 AND p_modDoc_transitoLocalEstoque > 0 AND p_docTransf_estabelecEntrada > 0 AND p_docTransf_estabelecSaida > 0 THEN
          ADD_ESTOQUE_INSERE(
            r_bufferIdEstoque, 
            p_estabelecimentoAtivo, 
            p_docTransf_estabelecSaida,
            CASE WHEN p_cab_dataEntradaSaida IS NULL OR p_cab_dataEntradaSaida < p_cab_dataEmissao THEN p_cab_dataEmissao ELSE p_cab_dataEntradaSaida END, --p_data
            kit.gradeProdutoFilho,
            p_cab_modeloDocumento,
            900,
            0,
            0,
            CASE WHEN p_cab_entradaSaida='S' THEN 'E' ELSE 'S' END,
            p_locEstTransito_indicProprPos,
            p_item_pessoaParticipante,
            p_modDoc_transitoLocalEstoque,
            0, -- p_personalizacao
            0, -- p_idLoteEstoque
            p_idEnderecoEstoque,
            0, -- p_idNumeroSerie
            kit.quantidade - v_quantidadeNumerosSerie,
            v_precoCustoKit, -- p_precoCustoOperacao
            CASE WHEN v_quantidadeNumerosSerie = 0 THEN v_valorCustoKit WHEN kit.quantidade = 0 THEN 0 ELSE ROUND ((v_valorCustoKit * (kit.quantidade - v_quantidadeNumerosSerie) / kit.quantidade), 2) END, -- p_totalCustoOperacao
            0, -- p_precoCMV
            0, -- p_valorCMV
            p_item_observacoes,
            p_item_idItemPreDocumento,
            0, -- p_idItemDocFiscal,
            0, -- p_idItemSeparacao,
            0, -- p_divergenciaBalanco,
            0, -- p_idItemDocTransferencia,
            r_bufferIdEstoque);
        END IF;    
      END IF;    
    END IF;
  END LOOP;
END ADD_PRE_DOC_ITEM_EST_KIT;

/

create or replace PROCEDURE ADD_PRE_DOC_ITEM_EST_ENDERECO(
    p_config_209_filtrarGrupoEcon  IN NUMBER,
    p_config_362_calcCustoPorGrade IN NUMBER,
    p_bufferIdEstoque              IN VARCHAR2,
    p_estabelecimentoAtivo         IN NUMBER,
    p_cab_modeloDocumento          IN NUMBER,
    p_cab_atualizaCustoMedio       IN NUMBER,
    p_cab_atualizaUltimaCompra     IN NUMBER,
    p_cab_entradaSaida             IN CHAR,
    p_cab_estabelecimento          IN NUMBER,
    p_cab_dataEmissao              IN DATE,
    p_cab_dataEntradaSaida         IN DATE,
    p_modDoc_geraTransferencia     IN NUMBER,
    p_modDoc_geraOperacaoEmTransit IN NUMBER,
    p_modDoc_transitoLocalEstoque  IN NUMBER,
    p_locEstTransito_indicProprPos IN CHAR,
    p_item_idItemPreDocumento      IN NUMBER,
    p_item_gradeProduto            IN NUMBER,
    p_item_idFormulaTinta          IN NUMBER,
    p_item_personalizacao          IN NUMBER,
    p_item_idLoteEstoque           IN NUMBER,
    p_item_localEstoque            IN NUMBER,
    p_item_pessoaParticipante      IN NUMBER,
    p_item_quantidade              IN NUMBER,
    p_item_precoCustoOperacao      IN NUMBER,
    p_item_valorCustoOperacao      IN NUMBER,
    p_item_precoCMV                IN NUMBER,
    p_item_valorCMV                IN NUMBER,
    p_item_quantidadeExtemporanea  IN NUMBER,
    p_item_valorAcrescimoExtempTot IN NUMBER,
    p_item_observacoes             IN VARCHAR2,
    p_prod_controlaNumeroSerie     IN NUMBER,
    p_prod_controleEstoque         IN NUMBER,
    p_uniMed_casasDecimaisUnidadeM IN VARCHAR2,
    p_locEst_indicProprPosseItem   IN CHAR,
    p_docTransf_estabelecEntrada   IN NUMBER,
    p_docTransf_estabelecSaida     IN NUMBER,
    r_bufferIdEstoque              OUT VARCHAR2,
    r_quantidadeEnderecoEstoque    OUT NUMBER)
IS
  v_quantidadeNumerosSerie NUMBER;
  CURSOR c_endEst
  IS 
    SELECT idEnderecoEstoque,
      idEnderecoEstoquePreDocumento,
      CASE
        WHEN p_item_quantidade = 0
          OR p_item_quantidadeExtemporanea = 0
          OR p_item_quantidade + p_item_quantidadeExtemporanea = 0
        THEN quantidade
        ELSE ROUND(quantidade * (p_item_quantidade + p_item_quantidadeExtemporanea) / p_item_quantidade, TO_NUMBER(p_uniMed_casasDecimaisUnidadeM))
      END quantidade
    FROM MOPREDOCUMXENDERECOESTOQ
    WHERE idItemPreDocumento = p_item_idItemPreDocumento
    AND quantidade           > 0;
BEGIN
  r_bufferIdEstoque           := p_bufferIdEstoque;
  r_quantidadeEnderecoEstoque := 0;
  FOR endEst IN c_endEst
  LOOP
    r_quantidadeEnderecoEstoque := r_quantidadeEnderecoEstoque + endEst.quantidade;
    IF p_prod_controleEstoque = 12 AND p_item_idFormulaTinta > 0 THEN
      ADD_ESTOQUE_FORMULA_TINTA(
        p_config_209_filtrarGrupoEcon,
        p_config_362_calcCustoPorGrade,
        r_bufferIdEstoque, 
        p_estabelecimentoAtivo, 
        p_cab_modeloDocumento,
        101,
        p_cab_atualizaCustoMedio,
        p_cab_atualizaUltimaCompra,
        p_cab_entradaSaida,
        p_cab_estabelecimento,
        p_cab_dataEmissao,
        p_cab_dataEntradaSaida,
        p_modDoc_geraTransferencia,
        p_modDoc_geraOperacaoEmTransit,
        p_modDoc_transitoLocalEstoque,
        p_locEstTransito_indicProprPos,
        p_item_idFormulaTinta,
        p_item_localEstoque,
        p_item_pessoaParticipante,
        endEst.quantidade,
        p_item_observacoes,
        endEst.idEnderecoEstoque,
        p_locEst_indicProprPosseItem,
        p_item_idItemPreDocumento,
        0, -- p_idItemDocFiscal,
        0, -- p_idItemSeparacao,
        0, -- p_divergenciaBalanco,
        0, -- p_idItemDocTransferencia,
        p_docTransf_estabelecEntrada,
        p_docTransf_estabelecSaida,
        r_bufferIdEstoque);
    ELSIF p_prod_controleEstoque IN (3,4) THEN
      ADD_PRE_DOC_ITEM_EST_KIT(
        p_config_209_filtrarGrupoEcon,
        p_config_362_calcCustoPorGrade,
        r_bufferIdEstoque, 
        p_estabelecimentoAtivo, 
        p_cab_modeloDocumento,
        p_cab_atualizaCustoMedio,
        p_cab_atualizaUltimaCompra,
        p_cab_entradaSaida,
        p_cab_estabelecimento,
        p_cab_dataEmissao,
        p_cab_dataEntradaSaida,
        p_modDoc_geraTransferencia,
        p_modDoc_geraOperacaoEmTransit,
        p_modDoc_transitoLocalEstoque,
        p_locEstTransito_indicProprPos,
        p_item_idItemPreDocumento,
        p_item_gradeProduto,
        p_item_localEstoque,
        p_item_pessoaParticipante,
        endEst.quantidade,
        CASE WHEN p_item_quantidade = 0 THEN 0 ELSE ROUND (((p_item_valorCustoOperacao + p_item_valorAcrescimoExtempTot) * (endEst.quantidade - v_quantidadeNumerosSerie) / p_item_quantidade), 2) END,
        p_item_observacoes,
        endEst.idEnderecoEstoquePreDocumento,
        endEst.idEnderecoEstoque,
        p_locEst_indicProprPosseItem,
        p_docTransf_estabelecEntrada,
        p_docTransf_estabelecSaida,
        r_bufferIdEstoque);
    ELSIF p_prod_controleEstoque IN (1,5,11,12) THEN
      v_quantidadeNumerosSerie := 0;
      IF p_prod_controlaNumeroSerie > 0 THEN
        ADD_PRE_DOC_ITEM_EST_N_SERIE(
          r_bufferIdEstoque,
          p_estabelecimentoAtivo,
          p_cab_modeloDocumento,
          p_cab_atualizaCustoMedio,
          p_cab_atualizaUltimaCompra,
          p_cab_entradaSaida,
          p_cab_estabelecimento,
          p_cab_dataEmissao,
          p_cab_dataEntradaSaida,
          p_modDoc_geraTransferencia,
          p_modDoc_geraOperacaoEmTransit,
          p_modDoc_transitoLocalEstoque,
          p_locEstTransito_indicProprPos,
          p_item_idItemPreDocumento,
          p_item_gradeProduto,
          p_item_personalizacao,
          p_item_idLoteEstoque,
          p_item_localEstoque,
          p_item_pessoaParticipante,
          CASE
            WHEN p_item_valorCustoOperacao = 0
              OR p_item_valorAcrescimoExtempTot = 0
              OR p_item_valorCustoOperacao + p_item_valorAcrescimoExtempTot = 0
            THEN p_item_precoCustoOperacao
            ELSE ROUND(p_item_precoCustoOperacao * (p_item_valorCustoOperacao + p_item_valorAcrescimoExtempTot) / p_item_valorCustoOperacao,7)
          END,
          p_item_precoCMV,
          p_item_observacoes,
          endEst.idEnderecoEstoquePreDocumento,
          endEst.idEnderecoEstoque,
          p_locEst_indicProprPosseItem,
          p_docTransf_estabelecEntrada,
          p_docTransf_estabelecSaida,
          r_bufferIdEstoque,
          v_quantidadeNumerosSerie);
      END IF;
      IF endEst.quantidade > v_quantidadeNumerosSerie THEN
        ADD_ESTOQUE_INSERE(
          r_bufferIdEstoque, 
          p_estabelecimentoAtivo, 
          p_cab_estabelecimento,
          CASE WHEN p_cab_dataEntradaSaida IS NULL OR p_cab_dataEntradaSaida < p_cab_dataEmissao THEN p_cab_dataEmissao ELSE p_cab_dataEntradaSaida END, -- p_data
          p_item_gradeProduto,
          p_cab_modeloDocumento,
          101,
          p_cab_atualizaCustoMedio,
          p_cab_atualizaUltimaCompra,
          p_cab_entradaSaida,
          p_locEst_indicProprPosseItem,
          p_item_pessoaParticipante,
          p_item_localEstoque,
          p_item_personalizacao,
          p_item_idLoteEstoque,
          endEst.idEnderecoEstoque,
          0, -- p_idNumeroSerie
          endEst.quantidade - v_quantidadeNumerosSerie,
          CASE
            WHEN p_item_valorCustoOperacao = 0
              OR p_item_valorAcrescimoExtempTot = 0
              OR p_item_valorCustoOperacao + p_item_valorAcrescimoExtempTot = 0
            THEN p_item_precoCustoOperacao
            ELSE ROUND(p_item_precoCustoOperacao * (p_item_valorCustoOperacao + p_item_valorAcrescimoExtempTot) / p_item_valorCustoOperacao,7)
          END,
          CASE WHEN p_item_quantidade = 0 THEN 0 ELSE ROUND (((p_item_valorCustoOperacao + p_item_valorAcrescimoExtempTot) * (endEst.quantidade - v_quantidadeNumerosSerie) / p_item_quantidadeExtemporanea), 2) END,
          p_item_precoCMV,
          CASE WHEN p_item_quantidade = 0 THEN 0 ELSE ROUND ((p_item_valorCMV * (endEst.quantidade - v_quantidadeNumerosSerie) / p_item_quantidade), 2) END,
          p_item_observacoes,
          p_item_idItemPreDocumento,
          0, -- p_idItemDocFiscal,
          0, -- p_idItemSeparacao,
          0, -- p_divergenciaBalanco,
          0, -- p_idItemDocTransferencia,
          r_bufferIdEstoque);
        IF p_modDoc_geraTransferencia = 1 AND p_modDoc_geraOperacaoEmTransit = 1 AND p_modDoc_transitoLocalEstoque > 0 AND p_docTransf_estabelecEntrada > 0 AND p_docTransf_estabelecSaida > 0 THEN
          ADD_ESTOQUE_INSERE(
            r_bufferIdEstoque, 
            p_estabelecimentoAtivo, 
            p_docTransf_estabelecSaida,
            CASE WHEN p_cab_dataEntradaSaida IS NULL OR p_cab_dataEntradaSaida < p_cab_dataEmissao THEN p_cab_dataEmissao ELSE p_cab_dataEntradaSaida END, -- p_data
            p_item_gradeProduto,
            p_cab_modeloDocumento,
            900,
            0,
            0,
            CASE WHEN p_cab_entradaSaida='S' THEN 'E' ELSE 'S' END,
            p_locEstTransito_indicProprPos,
            p_item_pessoaParticipante,
            p_modDoc_transitoLocalEstoque,
            p_item_personalizacao,
            p_item_idLoteEstoque,
            endEst.idEnderecoEstoque,
            0, -- p_idNumeroSerie
            endEst.quantidade - v_quantidadeNumerosSerie,
            CASE
              WHEN p_item_valorCustoOperacao = 0
                OR p_item_valorAcrescimoExtempTot = 0
                OR p_item_valorCustoOperacao + p_item_valorAcrescimoExtempTot = 0
              THEN p_item_precoCustoOperacao
              ELSE ROUND(p_item_precoCustoOperacao * (p_item_valorCustoOperacao + p_item_valorAcrescimoExtempTot) / p_item_valorCustoOperacao,7)
            END,
            CASE WHEN p_item_quantidade = 0 THEN 0 ELSE ROUND (((p_item_valorCustoOperacao + p_item_valorAcrescimoExtempTot) * (endEst.quantidade - v_quantidadeNumerosSerie) / p_item_quantidade), 2) END,
            p_item_precoCMV,
            CASE WHEN p_item_quantidade = 0 THEN 0 ELSE ROUND ((p_item_valorCMV * (endEst.quantidade - v_quantidadeNumerosSerie) / p_item_quantidade), 2) END,
            p_item_observacoes,
            p_item_idItemPreDocumento,
            0, -- p_idItemDocFiscal,
            0, -- p_idItemSeparacao,
            0, -- p_divergenciaBalanco,
            0, -- p_idItemDocTransferencia,
            r_bufferIdEstoque);
        END IF;
      END IF;
    END IF;
  END LOOP;
END ADD_PRE_DOC_ITEM_EST_ENDERECO;

/

create or replace PROCEDURE ADD_PRE_DOC_ITEM_EST_GRAVA(
    p_config_209_filtrarGrupoEcon  IN NUMBER,
    p_config_362_calcCustoPorGrade IN NUMBER,
    p_bufferIdEstoque              IN VARCHAR2,
    p_estabelecimentoAtivo         IN NUMBER,
    p_cab_modeloDocumento          IN NUMBER,
    p_cab_atualizaCustoMedio       IN NUMBER,
    p_cab_atualizaUltimaCompra     IN NUMBER,
    p_cab_entradaSaida             IN CHAR,
    p_cab_estabelecimento          IN NUMBER,
    p_cab_dataEmissao              IN DATE,
    p_cab_dataEntradaSaida         IN DATE,
    p_modDoc_geraTransferencia     IN NUMBER,
    p_modDoc_geraOperacaoEmTransit IN NUMBER,
    p_modDoc_transitoLocalEstoque  IN NUMBER,
    p_locEstTransito_indicProprPos IN CHAR,
    p_item_idItemPreDocumento      IN NUMBER,
    p_item_gradeProduto            IN NUMBER,
    p_item_idFormulaTinta          IN NUMBER,
    p_item_personalizacao          IN NUMBER,
    p_item_idLoteEstoque           IN NUMBER,
    p_item_localEstoque            IN NUMBER,
    p_item_pessoaParticipante      IN NUMBER,
    p_item_quantidade              IN NUMBER,
    p_item_precoCustoOperacao      IN NUMBER,
    p_item_valorCustoOperacao      IN NUMBER,
    p_item_precoCMV                IN NUMBER,
    p_item_valorCMV                IN NUMBER,
    p_item_quantidadeExtemporanea  IN NUMBER,
    p_item_valorAcrescimoExtempTot IN NUMBER,
    p_item_observacoes             IN VARCHAR2,
    p_prod_controlaNumeroSerie     IN NUMBER,
    p_prod_controleEstoque         IN NUMBER,
    p_uniMed_casasDecimaisUnidadeM IN VARCHAR2,
    p_locEst_indicProprPosseItem   IN CHAR,
    p_estXLoc_solicitaEnderecoEst  IN NUMBER,
    p_docTransf_estabelecEntrada   IN NUMBER,
    p_docTransf_estabelecSaida     IN NUMBER,
    r_bufferIdEstoque              OUT VARCHAR2)
IS
  v_quantidadeEnderecoEstoque NUMBER (14,0);
  v_quantidadeNumerosSerie    NUMBER (14,0);
BEGIN
  r_bufferIdEstoque := p_bufferIdEstoque;
  v_quantidadeEnderecoEstoque := 0;
  v_quantidadeNumerosSerie    := 0;
  IF p_estXLoc_solicitaEnderecoEst = 1 AND p_prod_controleEstoque IN (1,3,4,5,11,12) THEN
    ADD_PRE_DOC_ITEM_EST_ENDERECO(
      p_config_209_filtrarGrupoEcon,
      p_config_362_calcCustoPorGrade,
      r_bufferIdEstoque,
      p_estabelecimentoAtivo,
      p_cab_modeloDocumento,
      p_cab_atualizaCustoMedio,
      p_cab_atualizaUltimaCompra,
      p_cab_entradaSaida,
      p_cab_estabelecimento,
      p_cab_dataEmissao,
      p_cab_dataEntradaSaida,
      p_modDoc_geraTransferencia,
      p_modDoc_geraOperacaoEmTransit,
      p_modDoc_transitoLocalEstoque,
      p_locEstTransito_indicProprPos,
      p_item_idItemPreDocumento,
      p_item_gradeProduto,
      p_item_idFormulaTinta,
      p_item_personalizacao,
      p_item_idLoteEstoque,
      p_item_localEstoque,
      p_item_pessoaParticipante,
      p_item_quantidade,
      p_item_precoCustoOperacao,
      p_item_valorCustoOperacao,
      p_item_precoCMV,
      p_item_valorCMV,
      p_item_quantidadeExtemporanea,
      p_item_valorAcrescimoExtempTot,
      p_item_observacoes,
      p_prod_controlaNumeroSerie,
      p_prod_controleEstoque,
      p_uniMed_casasDecimaisUnidadeM,
      p_locEst_indicProprPosseItem,
      p_docTransf_estabelecEntrada,
      p_docTransf_estabelecSaida,
      r_bufferIdEstoque,
      v_quantidadeEnderecoEstoque);
  END IF;
  IF p_item_quantidade + p_item_quantidadeExtemporanea > v_quantidadeEnderecoEstoque THEN
    IF p_prod_controleEstoque = 12 AND p_item_idFormulaTinta > 0 THEN
      ADD_ESTOQUE_FORMULA_TINTA(
        p_config_209_filtrarGrupoEcon,
        p_config_362_calcCustoPorGrade,
        r_bufferIdEstoque, 
        p_estabelecimentoAtivo, 
        p_cab_modeloDocumento,
        101,
        p_cab_atualizaCustoMedio,
        p_cab_atualizaUltimaCompra,
        p_cab_entradaSaida,
        p_cab_estabelecimento,
        p_cab_dataEmissao,
        p_cab_dataEntradaSaida,
        p_modDoc_geraTransferencia,
        p_modDoc_geraOperacaoEmTransit,
        p_modDoc_transitoLocalEstoque,
        p_locEstTransito_indicProprPos,
        p_item_idFormulaTinta,
        p_item_localEstoque,
        p_item_pessoaParticipante,
        p_item_quantidade + p_item_quantidadeExtemporanea - v_quantidadeEnderecoEstoque,
        p_item_observacoes,
        0, -- p_idEnderecoEstoque,
        p_locEst_indicProprPosseItem,
        p_item_idItemPreDocumento,
        0, -- p_idItemDocFiscal,
        0, -- p_idItemSeparacao,
        0, -- p_divergenciaBalanco,
        0, -- p_idItemDocTransferencia,
        p_docTransf_estabelecEntrada,
        p_docTransf_estabelecSaida,
        r_bufferIdEstoque);
    ELSIF p_prod_controleEstoque IN (3,4) THEN
      ADD_PRE_DOC_ITEM_EST_KIT(
        p_config_209_filtrarGrupoEcon,
        p_config_362_calcCustoPorGrade,
        r_bufferIdEstoque, 
        p_estabelecimentoAtivo, 
        p_cab_modeloDocumento,
        p_cab_atualizaCustoMedio,
        p_cab_atualizaUltimaCompra,
        p_cab_entradaSaida,
        p_cab_estabelecimento,
        p_cab_dataEmissao,
        p_cab_dataEntradaSaida,
        p_modDoc_geraTransferencia,
        p_modDoc_geraOperacaoEmTransit,
        p_modDoc_transitoLocalEstoque,
        p_locEstTransito_indicProprPos,
        p_item_idItemPreDocumento,
        p_item_gradeProduto,
        p_item_localEstoque,
        p_item_pessoaParticipante,
        p_item_quantidade + p_item_quantidadeExtemporanea - v_quantidadeEnderecoEstoque,
        CASE WHEN v_quantidadeEnderecoEstoque = 0 THEN (p_item_valorCustoOperacao + p_item_valorAcrescimoExtempTot) WHEN p_item_quantidade = 0 THEN 0 ELSE ROUND (((p_item_valorCustoOperacao + p_item_valorAcrescimoExtempTot) * (p_item_quantidade + p_item_quantidadeExtemporanea - v_quantidadeEnderecoEstoque) / p_item_quantidade), 2) END,
        p_item_observacoes,
        0, -- p_idEnderecoEstoquePreDocumento,
        0, -- p_idEnderecoEstoque,
        p_locEst_indicProprPosseItem,
        p_docTransf_estabelecEntrada,
        p_docTransf_estabelecSaida,
        r_bufferIdEstoque);
    ELSIF p_prod_controleEstoque IN (1,5,11,12) THEN
      v_quantidadeNumerosSerie := 0;
      IF p_prod_controlaNumeroSerie > 0 THEN
        ADD_PRE_DOC_ITEM_EST_N_SERIE(
          r_bufferIdEstoque,
          p_estabelecimentoAtivo,
          p_cab_modeloDocumento,
          p_cab_atualizaCustoMedio,
          p_cab_atualizaUltimaCompra,
          p_cab_entradaSaida,
          p_cab_estabelecimento,
          p_cab_dataEmissao,
          p_cab_dataEntradaSaida,
          p_modDoc_geraTransferencia,
          p_modDoc_geraOperacaoEmTransit,
          p_modDoc_transitoLocalEstoque,
          p_locEstTransito_indicProprPos,
          p_item_idItemPreDocumento,
          p_item_gradeProduto,
          p_item_personalizacao,
          p_item_idLoteEstoque,
          p_item_localEstoque,
          p_item_pessoaParticipante,
          CASE
            WHEN p_item_valorCustoOperacao = 0
              OR p_item_valorAcrescimoExtempTot = 0
              OR p_item_valorCustoOperacao + p_item_valorAcrescimoExtempTot = 0
            THEN p_item_precoCustoOperacao
            ELSE ROUND(p_item_precoCustoOperacao * (p_item_valorCustoOperacao + p_item_valorAcrescimoExtempTot) / p_item_valorCustoOperacao,7)
          END,
          p_item_precoCMV,
          p_item_observacoes,
          0, -- p_idEnderecoEstoquePreDocumento,
          0, -- p_idEnderecoEstoque,
          p_locEst_indicProprPosseItem,
          p_docTransf_estabelecEntrada,
          p_docTransf_estabelecSaida,
          r_bufferIdEstoque,
          v_quantidadeNumerosSerie);
      END IF;
      IF p_item_quantidade + p_item_quantidadeExtemporanea - v_quantidadeEnderecoEstoque > v_quantidadeNumerosSerie THEN
        ADD_ESTOQUE_INSERE(
          r_bufferIdEstoque, 
          p_estabelecimentoAtivo, 
          p_cab_estabelecimento,
          CASE WHEN p_cab_dataEntradaSaida IS NULL OR p_cab_dataEntradaSaida < p_cab_dataEmissao THEN p_cab_dataEmissao ELSE p_cab_dataEntradaSaida END, -- p_data
          p_item_gradeProduto,
          p_cab_modeloDocumento,
          101,
          p_cab_atualizaCustoMedio,
          p_cab_atualizaUltimaCompra,
          p_cab_entradaSaida,
          p_locEst_indicProprPosseItem,
          p_item_pessoaParticipante,
          p_item_localEstoque,
          p_item_personalizacao,
          p_item_idLoteEstoque,
          0, -- p_idEnderecoEstoque,
          0, -- p_idNumeroSerie
          p_item_quantidade + p_item_quantidadeExtemporanea - v_quantidadeEnderecoEstoque - v_quantidadeNumerosSerie,
          CASE
            WHEN p_item_valorCustoOperacao = 0
              OR p_item_valorAcrescimoExtempTot = 0
              OR p_item_valorCustoOperacao + p_item_valorAcrescimoExtempTot = 0
            THEN p_item_precoCustoOperacao
            ELSE ROUND(p_item_precoCustoOperacao * (p_item_valorCustoOperacao + p_item_valorAcrescimoExtempTot) / p_item_valorCustoOperacao,7)
          END,
          CASE WHEN p_item_quantidade = 0 THEN 0 ELSE ROUND (((p_item_valorCustoOperacao + p_item_valorAcrescimoExtempTot) * (p_item_quantidade + p_item_quantidadeExtemporanea - v_quantidadeEnderecoEstoque - v_quantidadeNumerosSerie) / p_item_quantidade), 2) END,
          p_item_precoCMV,
          CASE WHEN p_item_quantidade = 0 THEN 0 ELSE ROUND ((p_item_valorCMV * (p_item_quantidade + p_item_quantidadeExtemporanea - v_quantidadeEnderecoEstoque - v_quantidadeNumerosSerie) / p_item_quantidade), 2) END,
          p_item_observacoes,
          p_item_idItemPreDocumento,
          0, -- p_idItemDocFiscal,
          0, -- p_idItemSeparacao,
          0, -- p_divergenciaBalanco,
          0, -- p_idItemDocTransferencia,
          r_bufferIdEstoque);
        IF p_modDoc_geraTransferencia = 1 AND p_modDoc_geraOperacaoEmTransit = 1 AND p_modDoc_transitoLocalEstoque > 0 AND p_docTransf_estabelecEntrada > 0 AND p_docTransf_estabelecSaida > 0 THEN
          ADD_ESTOQUE_INSERE(
            r_bufferIdEstoque, 
            p_estabelecimentoAtivo, 
            p_docTransf_estabelecSaida,
            CASE WHEN p_cab_dataEntradaSaida IS NULL OR p_cab_dataEntradaSaida < p_cab_dataEmissao THEN p_cab_dataEmissao ELSE p_cab_dataEntradaSaida END, -- p_data
            p_item_gradeProduto,
            p_cab_modeloDocumento,
            900,
            0,
            0,
            CASE WHEN p_cab_entradaSaida='S' THEN 'E' ELSE 'S' END,
            p_locEstTransito_indicProprPos,
            p_item_pessoaParticipante,
            p_modDoc_transitoLocalEstoque,
            p_item_personalizacao,
            p_item_idLoteEstoque,
            0, -- p_idEnderecoEstoque,
            0, -- p_idNumeroSerie
            p_item_quantidade + p_item_quantidadeExtemporanea - v_quantidadeEnderecoEstoque - v_quantidadeNumerosSerie,
            CASE
              WHEN p_item_valorCustoOperacao = 0
                OR p_item_valorAcrescimoExtempTot = 0
                OR p_item_valorCustoOperacao + p_item_valorAcrescimoExtempTot = 0
              THEN p_item_precoCustoOperacao
              ELSE ROUND(p_item_precoCustoOperacao * (p_item_valorCustoOperacao + p_item_valorAcrescimoExtempTot) / p_item_valorCustoOperacao,7)
            END,
            CASE WHEN p_item_quantidade = 0 THEN 0 ELSE ROUND (((p_item_valorCustoOperacao + p_item_valorAcrescimoExtempTot) * (p_item_quantidade + p_item_quantidadeExtemporanea - v_quantidadeEnderecoEstoque - v_quantidadeNumerosSerie) / p_item_quantidade), 2) END,
            p_item_precoCMV,
            CASE WHEN p_item_quantidade = 0 THEN 0 ELSE ROUND ((p_item_valorCMV * (p_item_quantidade + p_item_quantidadeExtemporanea - v_quantidadeEnderecoEstoque - v_quantidadeNumerosSerie) / p_item_quantidade), 2) END,
            p_item_observacoes,
            p_item_idItemPreDocumento,
            0, -- p_idItemDocFiscal,
            0, -- p_idItemSeparacao,
            0, -- p_divergenciaBalanco,
            0, -- p_idItemDocTransferencia,
            r_bufferIdEstoque);
        END IF;
      END IF;
    END IF;
  END IF;
END ADD_PRE_DOC_ITEM_EST_GRAVA;

/

create or replace PROCEDURE ADD_PRE_DOC_ITEM_EST_ATUALIZA(
    p_config_209_filtrarGrupoEcon  IN NUMBER,
    p_config_362_calcCustoPorGrade IN NUMBER,
    p_idItemPreDocumento           IN NUMBER,
    p_estabelecimentoAtivo         IN NUMBER
  )
IS
  v_bufferIdEstoque        VARCHAR2 (32000);
  CURSOR c_estoqueExcluir
  IS 
    SELECT a.idEstoque
    FROM MOESTOQUES a
    JOIN MOPREDOCUMXESTOQUE b ON b.idEstoque = a.idEstoque
    WHERE b.idItemPreDocumento = p_idItemPreDocumento
    ORDER BY a.idEstoque;
  CURSOR c_item
  IS 
    SELECT
      cab.modeloDocumento,
      cab.entradaSaida,
      cab.atualizaCustoMedio,
      cab.atualizaUltimaCompra,
      cab.estabelecimento,
      cab.dataEmissao,
      cab.dataEntradaSaida,
      modDoc.geraTransferencia,
      modDoc.geraOperacaoEmTransito,
      modDoc.transitoLocalEstoque,
      locEstTransito.indicadorPropriedadePosseItem locEstTransito_indicProprPos,
      item.idItemPreDocumento,
      item.gradeProduto,
      item.idFormulaTinta,
      item.personalizacao,
      item.idLoteEstoque,
      item.localEstoque,
      item.pessoaParticipante,
      item.quantidade,
      item.precoCustoOperacao,
      item.valorCustoOperacao,
      item.precoCMV,
      item.valorCMV,
      item.quantidadeExtemporanea,
      item.valorAcrescimoExtempTotal,
      item.observacoes,
      prod.controlaNumeroSerie,
      prod.controleEstoque,
      uniMed.casasDecimaisUnidadeMedida,
      locEst.indicadorPropriedadePosseItem locEst_indicProprPosseItem,
      COALESCE (estXLoc.solicitaEnderecoEstoque,0) estXLoc_solicitaEnderecoEst,
      COALESCE (cabTransf.estabelecimentoEntrada,0) docTransf_estabelecEntrada,
      COALESCE (cabTransf.estabelecimentoSaida,0) docTransf_estabelecSaida
    FROM MOPREDOCUMXITENS item
    JOIN MOPREDOCUMENTOS cab
    ON cab.preDocumento = item.preDocumento
    JOIN CAGRADESPRODUTO gradProd
    ON gradProd.gradeProduto = item.gradeProduto
    JOIN CAPRODUTOS prod
    ON prod.produto = gradProd.produto
    JOIN SIUNIDADESMEDIDA uniMed
    ON uniMed.unidadeMedida = prod.unidadeMedida
    JOIN PAMODELOSDOCUMENTO modDoc
    ON modDoc.modeloDocumento = cab.modeloDocumento
    JOIN PALOCAISESTOQUE locEstTransito
    ON locEstTransito.localEstoque = modDoc.transitoLocalEstoque 
    JOIN PALOCAISESTOQUE locEst
    ON locEst.localEstoque = item.localEstoque
    LEFT JOIN PAESTABELECIMENTOXLOCAISE estXLoc
    ON estXLoc.estabelecimento = cab.estabelecimento
    AND estXLoc.localEstoque = item.localEstoque
    LEFT JOIN MODOCTRANSFXPREDOCUM transfXDoc
    ON transfXDoc.idItemPreDocumento = item.idItemPreDocumento
    AND transfXDoc.entradaSaidaOriginal IN ('E','S')
    LEFT JOIN MODOCUMENTOTRANSFXITENS itemTransf
    ON itemTransf.idItemDocTransferencia = transfXDoc.idItemDocTransferencia
    LEFT JOIN MODOCUMENTOSTRANSFERENCIA cabTransf
    ON cabTransf.documentoTransferencia = itemTransf.documentoTransferencia
    WHERE item.idItemPreDocumento = p_idItemPreDocumento
    AND item.cancelado = 0
    AND item.quantidade+item.quantidadeExtemporanea > 0
    AND item.movimentaEstoque = 1
    AND cab.statusPreDocumento = 'A';
BEGIN
  v_bufferIdEstoque := '';
  FOR estoqueExcluir IN c_estoqueExcluir
  LOOP
    v_bufferIdEstoque := CASE WHEN (v_bufferIdEstoque IS NULL OR v_bufferIdEstoque = '' OR v_bufferIdEstoque = ' ') THEN '' ELSE RTRIM (v_bufferIdEstoque) || ';' END || TO_CHAR (LPAD(estoqueExcluir.idEstoque,14,'0'));
    ADD_MOESTOQUES_EXCLUI (estoqueExcluir.idEstoque);
  END LOOP;
  FOR item IN c_item
  LOOP
    ADD_PRE_DOC_ITEM_EST_GRAVA(
      p_config_209_filtrarGrupoEcon,
      p_config_362_calcCustoPorGrade,
      v_bufferIdEstoque,
      p_estabelecimentoAtivo,
      item.modeloDocumento,
      item.atualizaCustoMedio,
      item.atualizaUltimaCompra,
      item.entradaSaida,
      item.estabelecimento,
      item.dataEmissao,
      item.dataEntradaSaida,
      item.geraTransferencia,
      item.geraOperacaoEmTransito,
      item.transitoLocalEstoque,
      item.locEstTransito_indicProprPos,
      item.idItemPreDocumento,
      item.gradeProduto,
      item.idFormulaTinta,
      item.personalizacao,
      item.idLoteEstoque,
      item.localEstoque,
      item.pessoaParticipante,
      item.quantidade,
      item.precoCustoOperacao,
      item.valorCustoOperacao,
      item.precoCMV,
      item.valorCMV,
      item.quantidadeExtemporanea,
      item.valorAcrescimoExtempTotal,
      item.observacoes,
      item.controlaNumeroSerie,
      item.controleEstoque,
      item.casasDecimaisUnidadeMedida,
      item.locEst_indicProprPosseItem,
      item.estXLoc_solicitaEnderecoEst,
      item.docTransf_estabelecEntrada,
      item.docTransf_estabelecSaida,
      v_bufferIdEstoque);
  END LOOP;  
END ADD_PRE_DOC_ITEM_EST_ATUALIZA;

/

create or replace PROCEDURE ADD_PRE_DOC_CAB_EST_ATUALIZA(
    p_config_209_filtrarGrupoEcon  IN NUMBER,
    p_config_362_calcCustoPorGrade IN NUMBER,
    p_preDocumento                 IN NUMBER,
    p_estabelecimentoAtivo         IN NUMBER
  )
IS
  v_bufferIdEstoque        VARCHAR2 (32000);
  CURSOR c_estoqueExcluir IS 
    SELECT a.idEstoque
    FROM MOESTOQUES a
    JOIN MOPREDOCUMXESTOQUE b ON b.idEstoque = a.idEstoque
    JOIN MOPREDOCUMXITENS c ON c.idItemPreDocumento = b.idItemPreDocumento
    WHERE c.preDocumento = p_preDocumento
    ORDER BY a.idEstoque;
  CURSOR c_item
  IS 
    SELECT 
      cab.modeloDocumento,
      cab.entradaSaida,
      cab.atualizaCustoMedio,
      cab.atualizaUltimaCompra,
      cab.estabelecimento,
      cab.dataEmissao,
      cab.dataEntradaSaida,
      modDoc.geraTransferencia,
      modDoc.geraOperacaoEmTransito,
      modDoc.transitoLocalEstoque,
      locEstTransito.indicadorPropriedadePosseItem locEstTransito_indicProprPos,
      item.idItemPreDocumento,
      item.gradeProduto,
      item.idFormulaTinta,
      item.personalizacao,
      item.idLoteEstoque,
      item.localEstoque,
      item.pessoaParticipante,
      item.quantidade,
      item.precoCustoOperacao,
      item.valorCustoOperacao,
      item.precoCMV,
      item.valorCMV,
      item.quantidadeExtemporanea,
      item.valorAcrescimoExtempTotal,
      item.observacoes,
      prod.controlaNumeroSerie,
      prod.controleEstoque,
      uniMed.casasDecimaisUnidadeMedida,
      locEst.indicadorPropriedadePosseItem locEst_indicProprPosseItem,
      COALESCE (estXLoc.solicitaEnderecoEstoque,0) estXLoc_solicitaEnderecoEst,
      COALESCE (cabTransf.estabelecimentoEntrada,0) docTransf_estabelecEntrada,
      COALESCE (cabTransf.estabelecimentoSaida,0) docTransf_estabelecSaida
    FROM MOPREDOCUMXITENS item
    JOIN MOPREDOCUMENTOS cab
    ON cab.preDocumento = item.preDocumento
    JOIN CAGRADESPRODUTO gradProd
    ON gradProd.gradeProduto = item.gradeProduto
    JOIN CAPRODUTOS prod
    ON prod.produto = gradProd.produto
    JOIN SIUNIDADESMEDIDA uniMed
    ON uniMed.unidadeMedida = prod.unidadeMedida
    JOIN PAMODELOSDOCUMENTO modDoc
    ON modDoc.modeloDocumento = cab.modeloDocumento
    JOIN PALOCAISESTOQUE locEstTransito
    ON locEstTransito.localEstoque = modDoc.transitoLocalEstoque 
    JOIN PALOCAISESTOQUE locEst
    ON locEst.localEstoque = item.localEstoque
    LEFT JOIN PAESTABELECIMENTOXLOCAISE estXLoc
    ON estXLoc.estabelecimento = cab.estabelecimento
    AND estXLoc.localEstoque = item.localEstoque
    LEFT JOIN MODOCTRANSFXPREDOCUM transfXDoc
    ON transfXDoc.idItemPreDocumento = item.idItemPreDocumento
    AND transfXDoc.entradaSaidaOriginal IN ('E','S')
    LEFT JOIN MODOCUMENTOTRANSFXITENS itemTransf
    ON itemTransf.idItemDocTransferencia = transfXDoc.idItemDocTransferencia
    LEFT JOIN MODOCUMENTOSTRANSFERENCIA cabTransf
    ON cabTransf.documentoTransferencia = itemTransf.documentoTransferencia
    WHERE item.preDocumento = p_preDocumento
    AND item.cancelado = 0
    AND item.quantidade+item.quantidadeExtemporanea > 0
    AND item.movimentaEstoque = 1
    AND cab.statusPreDocumento = 'A';
BEGIN
  v_bufferIdEstoque := '';
  FOR estoqueExcluir IN c_estoqueExcluir
  LOOP
    v_bufferIdEstoque := CASE WHEN (v_bufferIdEstoque IS NULL OR v_bufferIdEstoque = '' OR v_bufferIdEstoque = ' ') THEN '' ELSE RTRIM (v_bufferIdEstoque) || ';' END || TO_CHAR (LPAD(estoqueExcluir.idEstoque,14,'0'));
    ADD_MOESTOQUES_EXCLUI (estoqueExcluir.idEstoque);
  END LOOP;
  FOR item IN c_item
  LOOP
    ADD_PRE_DOC_ITEM_EST_GRAVA(
      p_config_209_filtrarGrupoEcon,
      p_config_362_calcCustoPorGrade,
      v_bufferIdEstoque,
      p_estabelecimentoAtivo,
      item.modeloDocumento,
      item.atualizaCustoMedio,
      item.atualizaUltimaCompra,
      item.entradaSaida,
      item.estabelecimento,
      item.dataEmissao,
      item.dataEntradaSaida,
      item.geraTransferencia,
      item.geraOperacaoEmTransito,
      item.transitoLocalEstoque,
      item.locEstTransito_indicProprPos,
      item.idItemPreDocumento,
      item.gradeProduto,
      item.idFormulaTinta,
      item.personalizacao,
      item.idLoteEstoque,
      item.localEstoque,
      item.pessoaParticipante,
      item.quantidade,
      item.precoCustoOperacao,
      item.valorCustoOperacao,
      item.precoCMV,
      item.valorCMV,
      item.quantidadeExtemporanea,
      item.valorAcrescimoExtempTotal,
      item.observacoes,
      item.controlaNumeroSerie,
      item.controleEstoque,
      item.casasDecimaisUnidadeMedida,
      item.locEst_indicProprPosseItem,
      item.estXLoc_solicitaEnderecoEst,
      item.docTransf_estabelecEntrada,
      item.docTransf_estabelecSaida,
      v_bufferIdEstoque);
  END LOOP;  
END ADD_PRE_DOC_CAB_EST_ATUALIZA;

/

create or replace PROCEDURE ADD_DOC_FISC_ITEM_FIL_INSERE(
    p_bufferIdProdutoFilho   IN VARCHAR2,
    p_estabelecimentoAtivo   IN NUMBER,
    p_idItemDocFiscal        IN NUMBER,
    p_gradeProduto           IN NUMBER,
    p_personalizacao         IN NUMBER,
    p_idLoteEstoque          IN NUMBER,
    p_idEnderecoEstoque      IN NUMBER,
    p_idNumeroSerie          IN NUMBER,
    p_quantidade             IN NUMBER,
    p_precoCustoOperacao     IN NUMBER,
    p_totalCustoOperacao     IN NUMBER,
    p_precoCMV               IN NUMBER,
    p_valorCMV               IN NUMBER,
    p_observacoes            IN VARCHAR2,
    r_bufferIdProdutoFilho   OUT VARCHAR2)
IS
  v_id NUMBER (14,0);
BEGIN
  IF p_bufferIdProdutoFilho IS NOT NULL AND LENGTH(RTRIM(p_bufferIdProdutoFilho)) >= 14 THEN
    v_id                   := TO_NUMBER(SUBSTR(p_bufferIdProdutoFilho, 1, 14));
    r_bufferIdProdutoFilho := RTRIM(SUBSTR(p_bufferIdProdutoFilho,16,32000));
  ELSE
    v_id                   := FUNC_ADD_BUSCA_PROXIMO_ID ('MODOCFISCALXPRODUTOFILHO', 'id', 14, p_estabelecimentoAtivo, NULL);
    r_bufferIdProdutoFilho := '';
  END IF;
  INSERT INTO MODOCFISCALXPRODUTOFILHO (
    id,
    idItemDocFiscal,
    gradeProduto,
    personalizacao,
    idLoteEstoque,
    idEnderecoEstoque,
    idNumeroSerie,
    quantidade,
    precoCustoOperacao,
    totalCustoOperacao,
    precoCMV,
    valorCMV,
    observacoes)
  VALUES(
    v_id,
    p_idItemDocFiscal,
    p_gradeProduto,
    p_personalizacao,
    p_idLoteEstoque,
    p_idEnderecoEstoque,
    p_idNumeroSerie,
    p_quantidade,
    p_precoCustoOperacao,
    p_totalCustoOperacao,
    p_precoCMV,
    p_valorCMV,
    p_observacoes);
END ADD_DOC_FISC_ITEM_FIL_INSERE;

/

create or replace PROCEDURE ADD_DOC_FISC_ITEM_FIL_N_SERIE(
    p_bufferIdProdutoFilho         IN VARCHAR2,
    p_estabelecimentoAtivo         IN NUMBER,
    p_item_idItemDocFiscal         IN NUMBER,
    p_item_gradeProduto            IN NUMBER,
    p_item_personalizacao          IN NUMBER,
    p_item_idLoteEstoque           IN NUMBER,
    p_item_precoCustoOperacao      IN NUMBER,
    p_item_precoCMV                IN NUMBER,
    p_item_observacoes             IN VARCHAR2,
    p_endEst_idEnderecoEstoqueDocF IN NUMBER,
    p_idEnderecoEstoque            IN NUMBER,
    r_bufferIdProdutoFilho         OUT VARCHAR2,
    r_quantidadeNumerosSerie       OUT NUMBER)
IS
  CURSOR c_numSerie IS 
    SELECT idNumeroSerie
    FROM MODOCFISCALXNUMEROSSERIE
    WHERE idItemDocFiscal = p_item_idItemDocFiscal
    AND idEnderecoEstoqueDocFiscal = p_endEst_idEnderecoEstoqueDocF
    AND gradeProduto = p_item_gradeProduto;
BEGIN
  r_bufferIdProdutoFilho   := p_bufferIdProdutoFilho;
  r_quantidadeNumerosSerie := 0;
  FOR numSerie IN c_numSerie
  LOOP
    r_quantidadeNumerosSerie := r_quantidadeNumerosSerie + 1;
    ADD_DOC_FISC_ITEM_FIL_INSERE(
      r_bufferIdProdutoFilho, 
      p_estabelecimentoAtivo,
      p_item_idItemDocFiscal,
      p_item_gradeProduto,
      p_item_personalizacao,
      p_item_idLoteEstoque,
      p_idEnderecoEstoque,
      numSerie.idNumeroSerie,
      1,
      p_item_precoCustoOperacao,
      ROUND (p_item_precoCustoOperacao, 2),
      p_item_precoCMV,
      ROUND (p_item_precoCMV, 2),
      p_item_observacoes,
      r_bufferIdProdutoFilho);    
  END LOOP;
END ADD_DOC_FISC_ITEM_FIL_N_SERIE;

/

create or replace PROCEDURE ADD_DOC_FISC_ITEM_FIL_KIT(
    p_config_209_filtrarGrupoEcon  IN NUMBER,
    p_config_362_calcCustoPorGrade IN NUMBER,
    p_bufferIdProdutoFilho         IN VARCHAR2,
    p_estabelecimentoAtivo         IN NUMBER,
    p_cab_atualizaCustoMedio       IN NUMBER,
    p_cab_estabelecimento          IN NUMBER,
    p_cab_dataEmissao              IN DATE,
    p_cab_dataEntradaSaida         IN DATE,
    p_item_idItemDocFiscal         IN NUMBER,
    p_item_gradeProduto            IN NUMBER,
    p_item_pessoaParticipante      IN NUMBER,
    p_item_quantidade              IN NUMBER,
    p_item_valorCustoOperacao      IN NUMBER,
    p_item_observacoes             IN VARCHAR2,
    p_endEst_idEnderecoEstoqueDocF IN NUMBER,
    p_idEnderecoEstoque            IN NUMBER,
    p_locEst_indicProprPosseItem   IN CHAR,
    r_bufferIdProdutoFilho         OUT VARCHAR2)
IS  
  v_quantidadeNumerosSerie NUMBER;
  v_quantidadeRateioTotal  NUMBER;
  v_quantSaldoRateioTotal  NUMBER;
  v_valorSaldoRateioTotal  NUMBER;
  v_valorCustoManter       NUMBER;
  v_precoCustoKit          NUMBER;
  v_valorCustoKit          NUMBER;
  CURSOR c_kit IS 
    SELECT 
      kit.gradeProdutoFilho,
      kit.manterUltimoCusto,
      gradProdFilho.produto,
      prodFilho.controleEstoque,
      prodFilho.controlaNumeroSerie,
      ROUND(p_item_quantidade * kit.quantidade, uniFilho.casasDecimaisUnidadeMedida) quantidade
    FROM CAGRADEPRODUTOXKITSCOMBOS kit
    JOIN CAGRADESPRODUTO gradProdFilho
    ON gradProdFilho.gradeProduto = kit.gradeProdutoFilho
    JOIN CAPRODUTOS prodFilho
    ON prodFilho.produto = gradProdFilho.produto
    JOIN SIUNIDADESMEDIDA uniFilho
    ON uniFilho.unidadeMedida = prodFilho.unidadeMedida
    WHERE kit.gradeProduto = p_item_gradeProduto
    AND kit.ativo = 1
    AND kit.gradeProduto <> kit.gradeProdutoFilho
    AND ROUND(p_item_quantidade * kit.quantidade, uniFilho.casasDecimaisUnidadeMedida) > 0;
BEGIN
  r_bufferIdProdutoFilho := p_bufferIdProdutoFilho;
  IF p_cab_atualizaCustoMedio = 1 THEN
    SELECT COALESCE(SUM(ROUND(p_item_quantidade * kit.quantidade, uniFilho.casasDecimaisUnidadeMedida)),0)
    INTO v_quantidadeRateioTotal
    FROM CAGRADEPRODUTOXKITSCOMBOS kit
    JOIN CAGRADESPRODUTO gradProdFilho
    ON gradProdFilho.gradeProduto = kit.gradeProdutoFilho
    JOIN CAPRODUTOS prodFilho
    ON prodFilho.produto = gradProdFilho.produto
    JOIN SIUNIDADESMEDIDA uniFilho
    ON uniFilho.unidadeMedida = prodFilho.unidadeMedida
    WHERE kit.gradeProduto = p_item_gradeProduto
    AND kit.ativo = 1
    AND kit.manterUltimoCusto = 0
    AND kit.gradeProduto <> kit.gradeProdutoFilho;
    SELECT ROUND((COALESCE(SUM(ROUND(p_item_quantidade * kit.quantidade, uniFilho.casasDecimaisUnidadeMedida)
      * FUNC_ADD_BUSCA_PRECO_ULT_CUSTO(
          p_config_209_filtrarGrupoEcon,
          p_config_362_calcCustoPorGrade,
          p_cab_estabelecimento,
          TO_DATE ('01/01/1900','DD/MM/YYYY'),
          CASE WHEN p_cab_dataEntradaSaida IS NULL OR p_cab_dataEntradaSaida < p_cab_dataEmissao THEN p_cab_dataEmissao ELSE p_cab_dataEntradaSaida END - 1,
          0,
          gradProdFilho.produto,
          0,
          ' ',
          p_locEst_indicProprPosseItem,
          p_item_pessoaParticipante,
          0)),0)),2)
    INTO v_valorCustoManter
    FROM CAGRADEPRODUTOXKITSCOMBOS kit 
    JOIN CAGRADESPRODUTO gradProdFilho
    ON gradProdFilho.gradeProduto = kit.gradeProdutoFilho
    JOIN CAPRODUTOS prodFilho
    ON prodFilho.produto = gradProdFilho.produto
    JOIN SIUNIDADESMEDIDA uniFilho
    ON uniFilho.unidadeMedida = prodFilho.unidadeMedida
    WHERE kit.gradeProduto = p_item_gradeProduto
    AND kit.ativo = 1
    AND kit.manterUltimoCusto = 1
    AND kit.gradeProduto <> kit.gradeProdutoFilho;
  ELSE
    v_quantidadeRateioTotal := 0;
    v_valorCustoManter      := 0;
  END IF;
  v_quantSaldoRateioTotal := v_quantidadeRateioTotal;
  v_valorSaldoRateioTotal := p_item_valorCustoOperacao - v_valorCustoManter;
  FOR kit IN c_kit
  LOOP  
    IF p_cab_atualizaCustoMedio = 1 AND kit.manterUltimoCusto = 1 THEN
      v_precoCustoKit := FUNC_ADD_BUSCA_PRECO_ULT_CUSTO(
          p_config_209_filtrarGrupoEcon,
          p_config_362_calcCustoPorGrade,
          p_cab_estabelecimento,
          TO_DATE ('01/01/1900','DD/MM/YYYY'),
          CASE WHEN p_cab_dataEntradaSaida IS NULL OR p_cab_dataEntradaSaida < p_cab_dataEmissao THEN p_cab_dataEmissao ELSE p_cab_dataEntradaSaida END - 1,
          0,
          kit.produto,
          0,
          ' ',
          p_locEst_indicProprPosseItem,
          p_item_pessoaParticipante,
          0);
      v_valorCustoKit := ROUND (kit.quantidade * v_precoCustoKit,2);
    ELSIF p_cab_atualizaCustoMedio = 1 AND p_item_valorCustoOperacao > v_valorCustoManter AND v_quantSaldoRateioTotal > kit.quantidade THEN
      v_valorCustoKit := ROUND((p_item_valorCustoOperacao - v_valorCustoManter) * kit.quantidade / v_quantidadeRateioTotal,2);
      v_precoCustoKit := ROUND(v_valorCustoKit / kit.quantidade,7);
      v_quantSaldoRateioTotal := v_quantSaldoRateioTotal - kit.quantidade;
      v_valorSaldoRateioTotal := v_valorSaldoRateioTotal - v_valorCustoKit;
    ELSIF p_cab_atualizaCustoMedio = 1 AND v_valorSaldoRateioTotal > 0 THEN
      v_valorCustoKit := v_valorSaldoRateioTotal;
      v_precoCustoKit := ROUND(v_valorCustoKit / kit.quantidade,7);
      v_quantSaldoRateioTotal := 0;
      v_valorSaldoRateioTotal := 0;
    ELSE
      v_precoCustoKit := 0;
      v_valorCustoKit := 0;
    END IF;
    IF kit.controleEstoque IN (3,4) THEN
      ADD_DOC_FISC_ITEM_FIL_KIT(
        p_config_209_filtrarGrupoEcon,
        p_config_362_calcCustoPorGrade,
        r_bufferIdProdutoFilho,
        p_estabelecimentoAtivo,
        p_cab_atualizaCustoMedio,
        p_cab_estabelecimento,
        p_cab_dataEmissao,
        p_cab_dataEntradaSaida,
        p_item_idItemDocFiscal,
        kit.gradeProdutoFilho,
        p_item_pessoaParticipante,
        kit.quantidade,
        v_valorCustoKit,
        p_item_observacoes,
        p_endEst_idEnderecoEstoqueDocF,
        p_idEnderecoEstoque,
        p_locEst_indicProprPosseItem,
        r_bufferIdProdutoFilho);
    ELSIF kit.controleEstoque IN(1,5,11,12) THEN
      v_quantidadeNumerosSerie := 0;
      IF kit.controlaNumeroSerie > 0 THEN
        ADD_DOC_FISC_ITEM_FIL_N_SERIE(
          r_bufferIdProdutoFilho,
          p_estabelecimentoAtivo,
          p_item_idItemDocFiscal,
          kit.gradeProdutoFilho,
          0, -- p_item_personalizacao
          0, -- p_item_idLoteEstoque
          v_precoCustoKit, -- p_item_precoCustoOperacao,
          0, -- p_item_precoCMV,
          p_item_observacoes,
          p_endEst_idEnderecoEstoqueDocF,
          p_idEnderecoEstoque,
          r_bufferIdProdutoFilho,
          v_quantidadeNumerosSerie);
      END IF;    
      IF kit.quantidade > v_quantidadeNumerosSerie THEN
        ADD_DOC_FISC_ITEM_FIL_INSERE(
          r_bufferIdProdutoFilho,
          p_estabelecimentoAtivo,
          p_item_idItemDocFiscal,
          kit.gradeProdutoFilho,
          0, -- p_personalizacao
          0, -- p_idLoteEstoque
          p_idEnderecoEstoque,
          0, -- p_idNumeroSerie
          kit.quantidade - v_quantidadeNumerosSerie,
          v_precoCustoKit, -- p_precoCustoOperacao
          CASE WHEN v_quantidadeNumerosSerie = 0 THEN v_valorCustoKit WHEN kit.quantidade = 0 THEN 0 ELSE ROUND ((v_valorCustoKit * (kit.quantidade - v_quantidadeNumerosSerie) / kit.quantidade), 2) END, -- p_totalCustoOperacao
          0, -- p_precoCMV
          0, -- p_valorCMV
          p_item_observacoes,
          r_bufferIdProdutoFilho);
      END IF;    
    END IF;
  END LOOP;
END ADD_DOC_FISC_ITEM_FIL_KIT;

/

create or replace PROCEDURE ADD_DOC_FISC_ITEM_FIL_PROD_TIN(
    p_config_209_filtrarGrupoEcon  IN NUMBER,
    p_config_362_calcCustoPorGrade IN NUMBER,
    p_bufferIdProdutoFilho         IN VARCHAR2,
    p_estabelecimentoAtivo         IN NUMBER,
    p_cab_atualizaCustoMedio       IN NUMBER,
    p_cab_estabelecimento          IN NUMBER,
    p_cab_dataEmissao              IN DATE,
    p_cab_dataEntradaSaida         IN DATE,
    p_idItemDocFiscal              IN NUMBER,
    p_item_pessoaParticipante      IN NUMBER,
    p_item_quantidade              IN NUMBER,
    p_item_observacoes             IN VARCHAR2,
    p_endEst_idEnderecoEstoqueDocF IN NUMBER,
    p_idEnderecoEstoque            IN NUMBER,
    p_locEst_indicProprPosseItem   IN CHAR,
    p_tinta_gradeProduto           IN NUMBER,
    p_tinta_quantidade             IN NUMBER,
    r_bufferIdProdutoFilho         OUT VARCHAR2)
IS  
  CURSOR c_grade IS 
    SELECT 
      prod.controleEstoque,
      ROUND(p_item_quantidade * p_tinta_quantidade / 900, uniMed.casasDecimaisUnidadeMedida) quantidade
    FROM CAGRADESPRODUTO gradProd 
    JOIN CAPRODUTOS prod ON prod.produto = gradProd.produto
    JOIN SIUNIDADESMEDIDA uniMed ON uniMed.unidadeMedida = prod.unidadeMedida
    WHERE gradProd.gradeProduto = p_tinta_gradeProduto
    AND ROUND(p_item_quantidade * p_tinta_quantidade / 900, uniMed.casasDecimaisUnidadeMedida) > 0;
BEGIN
  r_bufferIdProdutoFilho := p_bufferIdProdutoFilho;
  FOR grade IN c_grade
  LOOP
    IF grade.controleEstoque IN (3,4) THEN
      ADD_DOC_FISC_ITEM_FIL_KIT(
        p_config_209_filtrarGrupoEcon,
        p_config_362_calcCustoPorGrade,
        r_bufferIdProdutoFilho,
        p_estabelecimentoAtivo,
        p_cab_atualizaCustoMedio,
        p_cab_estabelecimento,
        p_cab_dataEmissao,
        p_cab_dataEntradaSaida,
        p_idItemDocFiscal,
        p_tinta_gradeProduto,
        p_item_pessoaParticipante,
        grade.quantidade,
        0, --p_item_valorCustoOperacao
        p_item_observacoes,
        p_endEst_idEnderecoEstoqueDocF,
        p_idEnderecoEstoque,
        p_locEst_indicProprPosseItem,
        r_bufferIdProdutoFilho);
    ELSIF grade.controleEstoque IN(1,5,11,12) THEN
      ADD_DOC_FISC_ITEM_FIL_INSERE(
        r_bufferIdProdutoFilho,
        p_estabelecimentoAtivo,
        p_idItemDocFiscal,
        p_tinta_gradeProduto,
        0, -- p_personalizacao
        0, -- p_idLoteEstoque
        p_idEnderecoEstoque,
        0, -- p_idNumeroSerie
        grade.quantidade,
        0, -- p_precoCustoOperacao,
        0, -- p_totalCustoOperacao,
        0, -- p_precoCMV,
        0, -- p_valorCMV,
        p_item_observacoes,
        r_bufferIdProdutoFilho);
    END IF;    
  END LOOP;
END ADD_DOC_FISC_ITEM_FIL_PROD_TIN;

/

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

/

create or replace PROCEDURE ADD_DOC_FISC_ITEM_FIL_ENDERECO(
    p_config_209_filtrarGrupoEcon  IN NUMBER,
    p_config_362_calcCustoPorGrade IN NUMBER,
    p_bufferIdProdutoFilho         IN VARCHAR2,
    p_estabelecimentoAtivo         IN NUMBER,
    p_cab_atualizaCustoMedio       IN NUMBER,
    p_cab_estabelecimento          IN NUMBER,
    p_cab_dataEmissao              IN DATE,
    p_cab_dataEntradaSaida         IN DATE,
    p_item_idItemDocFiscal         IN NUMBER,
    p_item_gradeProduto            IN NUMBER,
    p_item_idFormulaTinta          IN NUMBER,
    p_item_personalizacao          IN NUMBER,
    p_item_pessoaParticipante      IN NUMBER,
    p_item_quantidade              IN NUMBER,
    p_item_valorCustoOperacao      IN NUMBER,
    p_item_observacoes             IN VARCHAR2,
    p_prod_controleEstoque         IN NUMBER,
    p_locEst_indicProprPosseItem   IN CHAR,
    r_bufferIdProdutoFilho         OUT VARCHAR2,
    r_quantidadeEnderecoEstoque    OUT NUMBER)
IS
  v_quantidadeNumerosSerie NUMBER (14,0);
  CURSOR c_endEst IS 
    SELECT idEnderecoEstoque,
      idEnderecoEstoqueDocFiscal,
      quantidade
    FROM MODOCFISCALXENDERECOESTOQ
    WHERE idItemDocFiscal = p_item_idItemDocFiscal
    AND quantidade        > 0;
BEGIN
  r_bufferIdProdutoFilho      := p_bufferIdProdutoFilho;
  r_quantidadeEnderecoEstoque := 0;
  FOR endEst IN c_endEst
  LOOP
    r_quantidadeEnderecoEstoque := r_quantidadeEnderecoEstoque + endEst.quantidade;
    IF p_prod_controleEstoque = 12 AND p_item_idFormulaTinta > 0 THEN
      ADD_DOC_FISC_ITEM_FIL_FORM_TIN(
        p_config_209_filtrarGrupoEcon,
        p_config_362_calcCustoPorGrade,
        r_bufferIdProdutoFilho, 
        p_estabelecimentoAtivo, 
        p_cab_atualizaCustoMedio,
        p_cab_estabelecimento,
        p_cab_dataEmissao,
        p_cab_dataEntradaSaida,
        p_item_idItemDocFiscal,
        p_item_idFormulaTinta,
        p_item_pessoaParticipante,
        endEst.quantidade,
        p_item_observacoes,
        endEst.idEnderecoEstoqueDocFiscal,
        endEst.idEnderecoEstoque,
        p_locEst_indicProprPosseItem,
        r_bufferIdProdutoFilho);
    ELSIF p_prod_controleEstoque IN (3,4) THEN
      ADD_DOC_FISC_ITEM_FIL_KIT(
        p_config_209_filtrarGrupoEcon,
        p_config_362_calcCustoPorGrade,
        r_bufferIdProdutoFilho,
        p_estabelecimentoAtivo,
        p_cab_atualizaCustoMedio,
        p_cab_estabelecimento,
        p_cab_dataEmissao,
        p_cab_dataEntradaSaida,
        p_item_idItemDocFiscal,
        p_item_gradeProduto,
        p_item_pessoaParticipante,
        endEst.quantidade,
        CASE WHEN p_item_quantidade = 0 THEN 0 ELSE ROUND ((p_item_valorCustoOperacao * (endEst.quantidade - v_quantidadeNumerosSerie) / p_item_quantidade), 2) END,
        p_item_observacoes,
        endEst.idEnderecoEstoqueDocFiscal,
        endEst.idEnderecoEstoque,
        p_locEst_indicProprPosseItem,
        r_bufferIdProdutoFilho);
    END IF;
  END LOOP;
END ADD_DOC_FISC_ITEM_FIL_ENDERECO;

/

create or replace PROCEDURE ADD_DOC_FISC_ITEM_FIL_GRAVA(
    p_config_209_filtrarGrupoEcon  IN NUMBER,
    p_config_362_calcCustoPorGrade IN NUMBER,
    p_bufferIdProdutoFilho         IN VARCHAR2,
    p_estabelecimentoAtivo         IN NUMBER,
    p_cab_atualizaCustoMedio       IN NUMBER,
    p_cab_estabelecimento          IN NUMBER,
    p_cab_dataEmissao              IN DATE,
    p_cab_dataEntradaSaida         IN DATE,
    p_item_idItemDocFiscal         IN NUMBER,
    p_item_gradeProduto            IN NUMBER,
    p_item_idFormulaTinta          IN NUMBER,
    p_item_personalizacao          IN NUMBER,
    p_item_pessoaParticipante      IN NUMBER,
    p_item_quantidade              IN NUMBER,
    p_item_valorCustoOperacao      IN NUMBER,
    p_item_observacoes             IN VARCHAR2,
    p_prod_controlaNumeroSerie     IN NUMBER,
    p_prod_controleEstoque         IN NUMBER,
    p_locEst_indicProprPosseItem   IN CHAR,
    p_estXLoc_solicitaEnderecoEst  IN NUMBER,
    r_bufferIdProdutoFilho         OUT VARCHAR2)
IS
  v_quantidadeEnderecoEstoque NUMBER (14,0);
  v_quantidadeNumerosSerie    NUMBER (14,0);
BEGIN
  r_bufferIdProdutoFilho      := p_bufferIdProdutoFilho;
  v_quantidadeEnderecoEstoque := 0;
  v_quantidadeNumerosSerie    := 0;
  IF p_estXLoc_solicitaEnderecoEst = 1 AND p_prod_controleEstoque IN (3,4,12) THEN
    ADD_DOC_FISC_ITEM_FIL_ENDERECO(
      p_config_209_filtrarGrupoEcon,
      p_config_362_calcCustoPorGrade,
      r_bufferIdProdutoFilho,
      p_estabelecimentoAtivo,
      p_cab_atualizaCustoMedio,
      p_cab_estabelecimento,
      p_cab_dataEmissao,
      p_cab_dataEntradaSaida,
      p_item_idItemDocFiscal,
      p_item_gradeProduto,
      p_item_idFormulaTinta,
      p_item_personalizacao,
      p_item_pessoaParticipante,
      p_item_quantidade,
      p_item_valorCustoOperacao,
      p_item_observacoes,
      p_prod_controlaNumeroSerie,
      p_prod_controleEstoque,
      r_bufferIdProdutoFilho,
      v_quantidadeEnderecoEstoque);
  END IF;
  IF p_item_quantidade > v_quantidadeEnderecoEstoque THEN
    IF p_prod_controleEstoque = 12 AND p_item_idFormulaTinta > 0 THEN
      ADD_DOC_FISC_ITEM_FIL_FORM_TIN(
        p_config_209_filtrarGrupoEcon,
        p_config_362_calcCustoPorGrade,
        r_bufferIdProdutoFilho, 
        p_estabelecimentoAtivo, 
        p_cab_atualizaCustoMedio,
        p_cab_estabelecimento,
        p_cab_dataEmissao,
        p_cab_dataEntradaSaida,
        p_item_idItemDocFiscal,
        p_item_idFormulaTinta,
        p_item_pessoaParticipante,
        p_item_quantidade - v_quantidadeEnderecoEstoque,
        p_item_observacoes,
        0, -- p_endEst_idEnderecoEstoqueDocF,
        0, -- p_idEnderecoEstoque,
        p_locEst_indicProprPosseItem,
        r_bufferIdProdutoFilho);
    ELSIF p_prod_controleEstoque IN (3,4) THEN
      ADD_DOC_FISC_ITEM_FIL_KIT(
        p_config_209_filtrarGrupoEcon,
        p_config_362_calcCustoPorGrade,
        r_bufferIdProdutoFilho,
        p_estabelecimentoAtivo, 
        p_cab_atualizaCustoMedio,
        p_cab_estabelecimento,
        p_cab_dataEmissao,
        p_cab_dataEntradaSaida,
        p_item_idItemDocFiscal,
        p_item_gradeProduto,
        p_item_pessoaParticipante,
        p_item_quantidade - v_quantidadeEnderecoEstoque,
        CASE WHEN v_quantidadeEnderecoEstoque = 0 THEN p_item_valorCustoOperacao WHEN p_item_quantidade = 0 THEN 0 ELSE ROUND ((p_item_valorCustoOperacao * (p_item_quantidade - v_quantidadeEnderecoEstoque) / p_item_quantidade), 2) END,
        p_item_observacoes,
        0, -- p_endEst_idEnderecoEstoqueDocF
        0, -- p_idEnderecoEstoque,
        p_locEst_indicProprPosseItem,
        r_bufferIdProdutoFilho);
    END IF;
  END IF;
END ADD_DOC_FISC_ITEM_FIL_GRAVA;

/

create or replace PROCEDURE ADD_DOC_FISC_ITEM_FIL_ATUALIZA(
    p_config_209_filtrarGrupoEcon  IN NUMBER,
    p_config_362_calcCustoPorGrade IN NUMBER,
    p_idItemDocFiscal              IN NUMBER,
    p_estabelecimentoAtivo         IN NUMBER
  )
IS
  v_bufferIdProdutoFilho VARCHAR2 (32000);
  CURSOR c_estoqueExcluir IS 
    SELECT a.id
    FROM MODOCFISCALXPRODUTOFILHO a
    JOIN MODOCFISCALXESTOQUE b ON b.id = a.id
    WHERE b.idItemDocFiscal = p_idItemDocFiscal
    ORDER BY a.id;
  CURSOR c_item IS 
    SELECT 
      cab.atualizaCustoMedio,
      cab.estabelecimento,
      cab.dataEmissao,
      cab.dataEntradaSaida,
      item.idItemDocFiscal,
      item.gradeProduto,
      item.idFormulaTinta,
      item.personalizacao,
      item.pessoaParticipante,
      item.quantidade,
      item.valorCustoOperacao,
      item.observacoes,
      prod.controlaNumeroSerie,
      prod.controleEstoque,
      locEst.indicadorPropriedadePosseItem locEst_indicProprPosseItem,
      COALESCE (estXLoc.solicitaEnderecoEstoque,0) estXLoc_solicitaEnderecoEst
    FROM MODOCFISCALXITENS item
    JOIN MODOCUMENTOSFISCAIS cab
    ON cab.idDocumentoFiscal = item.idDocumentoFiscal
    JOIN CAGRADESPRODUTO gradProd
    ON gradProd.gradeProduto = item.gradeProduto
    JOIN CAPRODUTOS prod
    ON prod.produto = gradProd.produto
    JOIN PALOCAISESTOQUE locEst
    ON locEst.localEstoque = item.localEstoque
    LEFT JOIN PAESTABELECIMENTOXLOCAISE estXLoc
    ON estXLoc.estabelecimento = cab.estabelecimento
    AND estXLoc.localEstoque = item.localEstoque
    WHERE item.idItemDocFiscal = p_idItemDocFiscal
    AND item.cancelado = 0
    AND item.quantidade > 0
    AND cab.situacaoDocumentoFiscal BETWEEN 21 AND 23;
BEGIN
  v_bufferIdProdutoFilho := '';
  FOR estoqueExcluir IN c_estoqueExcluir
  LOOP
    v_bufferIdProdutoFilho := CASE WHEN (v_bufferIdProdutoFilho IS NULL OR v_bufferIdProdutoFilho = '' OR v_bufferIdProdutoFilho = ' ') THEN '' ELSE RTRIM (v_bufferIdProdutoFilho) || ';' END || TO_CHAR (LPAD(estoqueExcluir.id,14,'0'));
    DELETE MODOCFISCALXPRODUTOFILHO a WHERE a.id = estoqueExcluir.id;
  END LOOP;
  FOR item IN c_item
  LOOP
    ADD_DOC_FISC_ITEM_FIL_GRAVA(
      p_config_209_filtrarGrupoEcon,
      p_config_362_calcCustoPorGrade,
      v_bufferIdProdutoFilho,
      p_estabelecimentoAtivo,
      item.atualizaCustoMedio,
      item.estabelecimento,
      item.dataEmissao,
      item.dataEntradaSaida,
      item.idItemDocFiscal,
      item.gradeProduto,
      item.idFormulaTinta,
      item.personalizacao,
      item.pessoaParticipante,
      item.quantidade,
      item.valorCustoOperacao,
      item.observacoes,
      item.controlaNumeroSerie,
      item.controleEstoque,
      item.locEst_indicProprPosseItem,
      item.estXLoc_solicitaEnderecoEst,
      v_bufferIdProdutoFilho);
  END LOOP;
END ADD_DOC_FISC_ITEM_FIL_ATUALIZA;

/

create or replace PROCEDURE ADD_DOC_FISC_CAB_FIL_ATUALIZA(
    p_config_209_filtrarGrupoEcon  IN NUMBER,
    p_config_362_calcCustoPorGrade IN NUMBER,
    p_idDocumentoFiscal            IN NUMBER,
    p_estabelecimentoAtivo         IN NUMBER
  )
IS
  v_bufferIdProdutoFilho VARCHAR2 (32000);
  CURSOR c_estoqueExcluir IS
    SELECT a.id
    FROM MODOCFISCALXPRODUTOFILHO a
    JOIN MODOCFISCALXESTOQUE b ON b.id = a.id
    JOIN MODOCFISCALXITENS c ON c.idItemDocFiscal = b.idItemDocFiscal
    WHERE c.idDocumentoFiscal = p_idDocumentoFiscal
    ORDER BY a.id;
  CURSOR c_item
  IS 
    SELECT 
      cab.atualizaCustoMedio,
      cab.estabelecimento,
      cab.dataEmissao,
      cab.dataEntradaSaida,
      item.idItemDocFiscal,
      item.gradeProduto,
      item.idFormulaTinta,
      item.personalizacao,
      item.pessoaParticipante,
      item.quantidade,
      item.valorCustoOperacao,
      item.valorAcrescimoExtempTotal,
      item.observacoes,
      prod.controlaNumeroSerie,
      prod.controleEstoque,
      locEst.indicadorPropriedadePosseItem locEst_indicProprPosseItem,
      COALESCE (estXLoc.solicitaEnderecoEstoque,0) estXLoc_solicitaEnderecoEst
    FROM MODOCFISCALXITENS item
    JOIN MODOCUMENTOSFISCAIS cab
    ON cab.idDocumentoFiscal = item.idDocumentoFiscal
    JOIN CAGRADESPRODUTO gradProd
    ON gradProd.gradeProduto = item.gradeProduto
    JOIN CAPRODUTOS prod
    ON prod.produto = gradProd.produto
    JOIN PALOCAISESTOQUE locEst
    ON locEst.localEstoque = item.localEstoque
    LEFT JOIN PAESTABELECIMENTOXLOCAISE estXLoc
    ON estXLoc.estabelecimento = cab.estabelecimento
    AND estXLoc.localEstoque = item.localEstoque
    WHERE item.idDocumentoFiscal = p_idDocumentoFiscal
    AND item.cancelado = 0
    AND item.quantidade > 0
    AND cab.situacaoDocumentoFiscal BETWEEN 21 AND 23;
BEGIN
  v_bufferIdProdutoFilho := '';
  FOR estoqueExcluir IN c_estoqueExcluir
  LOOP
    v_bufferIdProdutoFilho := CASE WHEN (v_bufferIdProdutoFilho IS NULL OR v_bufferIdProdutoFilho = '' OR v_bufferIdProdutoFilho = ' ') THEN '' ELSE RTRIM (v_bufferIdProdutoFilho) || ';' END || TO_CHAR (LPAD(estoqueExcluir.id,14,'0'));
    DELETE MODOCFISCALXPRODUTOFILHO a WHERE a.id = estoqueExcluir.id;
  END LOOP;
  FOR item IN c_item
  LOOP
    ADD_DOC_FISC_ITEM_FIL_GRAVA(
      p_config_209_filtrarGrupoEcon,
      p_config_362_calcCustoPorGrade,
      v_bufferIdProdutoFilho,
      p_estabelecimentoAtivo,
      item.atualizaCustoMedio,
      item.estabelecimento,
      item.dataEmissao,
      item.dataEntradaSaida,
      item.idItemDocFiscal,
      item.gradeProduto,
      item.idFormulaTinta,
      item.personalizacao,
      item.pessoaParticipante,
      item.quantidade,
      item.valorCustoOperacao,
      item.observacoes,
      item.controlaNumeroSerie,
      item.controleEstoque,
      item.locEst_indicProprPosseItem,
      item.estXLoc_solicitaEnderecoEst,
      v_bufferIdProdutoFilho);
  END LOOP;
END ADD_DOC_FISC_CAB_FIL_ATUALIZA;

/

create or replace PROCEDURE ADD_PRE_DOC_ITEM_FIL_INSERE(
    p_bufferIdProdutoFilho   IN VARCHAR2,
    p_estabelecimentoAtivo   IN NUMBER,
    p_idItemPreDocumento     IN NUMBER,
    p_gradeProduto           IN NUMBER,
    p_personalizacao         IN NUMBER,
    p_idLoteEstoque          IN NUMBER,
    p_idEnderecoEstoque      IN NUMBER,
    p_idNumeroSerie          IN NUMBER,
    p_quantidade             IN NUMBER,
    p_precoCustoOperacao     IN NUMBER,
    p_totalCustoOperacao     IN NUMBER,
    p_precoCMV               IN NUMBER,
    p_valorCMV               IN NUMBER,
    p_observacoes            IN VARCHAR2,
    r_bufferIdProdutoFilho   OUT VARCHAR2)
IS
  v_id NUMBER (14,0);
BEGIN
  IF p_bufferIdProdutoFilho IS NOT NULL AND LENGTH(RTRIM(p_bufferIdProdutoFilho)) >= 14 THEN
    v_id                   := TO_NUMBER(SUBSTR(p_bufferIdProdutoFilho, 1, 14));
    r_bufferIdProdutoFilho := RTRIM(SUBSTR(p_bufferIdProdutoFilho,16,32000));
  ELSE
    v_id                   := FUNC_ADD_BUSCA_PROXIMO_ID ('MOPREDOCUMXPRODUTOFILHO', 'id', 14, p_estabelecimentoAtivo, NULL);
    r_bufferIdProdutoFilho := '';
  END IF;
  INSERT INTO MOPREDOCUMXPRODUTOFILHO (
    id,
    idItemPreDocumento,
    gradeProduto,
    personalizacao,
    idLoteEstoque,
    idEnderecoEstoque,
    idNumeroSerie,
    quantidade,
    precoCustoOperacao,
    totalCustoOperacao,
    precoCMV,
    valorCMV,
    observacoes)
  VALUES(
    v_id,
    p_idItemPreDocumento,
    p_gradeProduto,
    p_personalizacao,
    p_idLoteEstoque,
    p_idEnderecoEstoque,
    p_idNumeroSerie,
    p_quantidade,
    p_precoCustoOperacao,
    p_totalCustoOperacao,
    p_precoCMV,
    p_valorCMV,
    p_observacoes);
END ADD_PRE_DOC_ITEM_FIL_INSERE;

/

create or replace PROCEDURE ADD_PRE_DOC_ITEM_FIL_N_SERIE(
    p_bufferIdProdutoFilho         IN VARCHAR2,
    p_estabelecimentoAtivo         IN NUMBER,
    p_item_idItemPreDocumento      IN NUMBER,
    p_item_gradeProduto            IN NUMBER,
    p_item_personalizacao          IN NUMBER,
    p_item_idLoteEstoque           IN NUMBER,
    p_item_precoCustoOperacao      IN NUMBER,
    p_item_precoCMV                IN NUMBER,
    p_item_observacoes             IN VARCHAR2,
    p_endEst_idEnderecoEstoquePreD IN NUMBER,
    p_idEnderecoEstoque            IN NUMBER,
    r_bufferIdProdutoFilho         OUT VARCHAR2,
    r_quantidadeNumerosSerie       OUT NUMBER)
IS
  CURSOR c_numSerie IS 
    SELECT idNumeroSerie
    FROM MOPREDOCUMXNUMEROSSERIE
    WHERE idItemPreDocumento = p_item_idItemPreDocumento
    AND idEnderecoEstoquePreDocumento = p_endEst_idEnderecoEstoquePreD
    AND gradeProduto = p_item_gradeProduto;
BEGIN
  r_bufferIdProdutoFilho   := p_bufferIdProdutoFilho;
  r_quantidadeNumerosSerie := 0;
  FOR numSerie IN c_numSerie
  LOOP
    r_quantidadeNumerosSerie := r_quantidadeNumerosSerie + 1;
    ADD_PRE_DOC_ITEM_FIL_INSERE(
      r_bufferIdProdutoFilho, 
      p_estabelecimentoAtivo,
      p_item_idItemPreDocumento,
      p_item_gradeProduto,
      p_item_personalizacao,
      p_item_idLoteEstoque,
      p_idEnderecoEstoque,
      numSerie.idNumeroSerie,
      1,
      p_item_precoCustoOperacao,
      ROUND (p_item_precoCustoOperacao, 2),
      p_item_precoCMV,
      ROUND (p_item_precoCMV, 2),
      p_item_observacoes,
      r_bufferIdProdutoFilho);    
  END LOOP;
END ADD_PRE_DOC_ITEM_FIL_N_SERIE;

/

create or replace PROCEDURE ADD_PRE_DOC_ITEM_FIL_KIT(
    p_config_209_filtrarGrupoEcon  IN NUMBER,
    p_config_362_calcCustoPorGrade IN NUMBER,
    p_bufferIdProdutoFilho         IN VARCHAR2,
    p_estabelecimentoAtivo         IN NUMBER,
    p_cab_atualizaCustoMedio       IN NUMBER,
    p_cab_estabelecimento          IN NUMBER,
    p_cab_dataEmissao              IN DATE,
    p_cab_dataEntradaSaida         IN DATE,
    p_item_idItemPreDocumento      IN NUMBER,
    p_item_gradeProduto            IN NUMBER,
    p_item_pessoaParticipante      IN NUMBER,
    p_item_quantidade              IN NUMBER,
    p_item_valorCustoOperacao      IN NUMBER,
    p_item_observacoes             IN VARCHAR2,
    p_endEst_idEnderecoEstoquePreD IN NUMBER,
    p_idEnderecoEstoque            IN NUMBER,
    p_locEst_indicProprPosseItem   IN CHAR,
    r_bufferIdProdutoFilho         OUT VARCHAR2)
IS  
  v_quantidadeNumerosSerie NUMBER;
  v_quantidadeRateioTotal  NUMBER;
  v_quantSaldoRateioTotal  NUMBER;
  v_valorSaldoRateioTotal  NUMBER;
  v_valorCustoManter       NUMBER;
  v_precoCustoKit          NUMBER;
  v_valorCustoKit          NUMBER;
  CURSOR c_kit IS 
    SELECT 
      kit.gradeProdutoFilho,
      kit.manterUltimoCusto,
      gradProdFilho.produto,
      prodFilho.controleEstoque,
      prodFilho.controlaNumeroSerie,
      ROUND(p_item_quantidade * kit.quantidade, uniFilho.casasDecimaisUnidadeMedida) quantidade
    FROM CAGRADEPRODUTOXKITSCOMBOS kit
    JOIN CAGRADESPRODUTO gradProdFilho
    ON gradProdFilho.gradeProduto = kit.gradeProdutoFilho
    JOIN CAPRODUTOS prodFilho
    ON prodFilho.produto = gradProdFilho.produto
    JOIN SIUNIDADESMEDIDA uniFilho
    ON uniFilho.unidadeMedida = prodFilho.unidadeMedida
    WHERE kit.gradeProduto = p_item_gradeProduto
    AND kit.ativo = 1
    AND kit.gradeProduto <> kit.gradeProdutoFilho
    AND ROUND(p_item_quantidade * kit.quantidade, uniFilho.casasDecimaisUnidadeMedida) > 0;
BEGIN
  r_bufferIdProdutoFilho := p_bufferIdProdutoFilho;
  IF p_cab_atualizaCustoMedio = 1 THEN
    SELECT COALESCE(SUM(ROUND(p_item_quantidade * kit.quantidade, uniFilho.casasDecimaisUnidadeMedida)),0)
    INTO v_quantidadeRateioTotal
    FROM CAGRADEPRODUTOXKITSCOMBOS kit
    JOIN CAGRADESPRODUTO gradProdFilho
    ON gradProdFilho.gradeProduto = kit.gradeProdutoFilho
    JOIN CAPRODUTOS prodFilho
    ON prodFilho.produto = gradProdFilho.produto
    JOIN SIUNIDADESMEDIDA uniFilho
    ON uniFilho.unidadeMedida = prodFilho.unidadeMedida
    WHERE kit.gradeProduto = p_item_gradeProduto
    AND kit.ativo = 1
    AND kit.manterUltimoCusto = 0
    AND kit.gradeProduto <> kit.gradeProdutoFilho;
    SELECT ROUND((COALESCE(SUM(ROUND(p_item_quantidade * kit.quantidade, uniFilho.casasDecimaisUnidadeMedida)
      * FUNC_ADD_BUSCA_PRECO_ULT_CUSTO(
          p_config_209_filtrarGrupoEcon,
          p_config_362_calcCustoPorGrade,
          p_cab_estabelecimento,
          TO_DATE ('01/01/1900','DD/MM/YYYY'),
          CASE WHEN p_cab_dataEntradaSaida IS NULL OR p_cab_dataEntradaSaida < p_cab_dataEmissao THEN p_cab_dataEmissao ELSE p_cab_dataEntradaSaida END - 1,
          0,
          gradProdFilho.produto,
          0,
          ' ',
          p_locEst_indicProprPosseItem,
          p_item_pessoaParticipante,
          0)),0)),2)
    INTO v_valorCustoManter
    FROM CAGRADEPRODUTOXKITSCOMBOS kit 
    JOIN CAGRADESPRODUTO gradProdFilho
    ON gradProdFilho.gradeProduto = kit.gradeProdutoFilho
    JOIN CAPRODUTOS prodFilho
    ON prodFilho.produto = gradProdFilho.produto
    JOIN SIUNIDADESMEDIDA uniFilho
    ON uniFilho.unidadeMedida = prodFilho.unidadeMedida
    WHERE kit.gradeProduto = p_item_gradeProduto
    AND kit.ativo = 1
    AND kit.manterUltimoCusto = 1
    AND kit.gradeProduto <> kit.gradeProdutoFilho;
  ELSE
    v_quantidadeRateioTotal := 0;
    v_valorCustoManter      := 0;
  END IF;
  v_quantSaldoRateioTotal := v_quantidadeRateioTotal;
  v_valorSaldoRateioTotal := p_item_valorCustoOperacao - v_valorCustoManter;
  FOR kit IN c_kit
  LOOP  
    IF p_cab_atualizaCustoMedio = 1 AND kit.manterUltimoCusto = 1 THEN
      v_precoCustoKit := FUNC_ADD_BUSCA_PRECO_ULT_CUSTO(
          p_config_209_filtrarGrupoEcon,
          p_config_362_calcCustoPorGrade,
          p_cab_estabelecimento,
          TO_DATE ('01/01/1900','DD/MM/YYYY'),
          CASE WHEN p_cab_dataEntradaSaida IS NULL OR p_cab_dataEntradaSaida < p_cab_dataEmissao THEN p_cab_dataEmissao ELSE p_cab_dataEntradaSaida END - 1,
          0,
          kit.produto,
          0,
          ' ',
          p_locEst_indicProprPosseItem,
          p_item_pessoaParticipante,
          0);
      v_valorCustoKit := ROUND (kit.quantidade * v_precoCustoKit,2);
    ELSIF p_cab_atualizaCustoMedio = 1 AND p_item_valorCustoOperacao > v_valorCustoManter AND v_quantSaldoRateioTotal > kit.quantidade THEN
      v_valorCustoKit := ROUND((p_item_valorCustoOperacao - v_valorCustoManter) * kit.quantidade / v_quantidadeRateioTotal,2);
      v_precoCustoKit := ROUND(v_valorCustoKit / kit.quantidade,7);
      v_quantSaldoRateioTotal := v_quantSaldoRateioTotal - kit.quantidade;
      v_valorSaldoRateioTotal := v_valorSaldoRateioTotal - v_valorCustoKit;
    ELSIF p_cab_atualizaCustoMedio = 1 AND v_valorSaldoRateioTotal > 0 THEN
      v_valorCustoKit := v_valorSaldoRateioTotal;
      v_precoCustoKit := ROUND(v_valorCustoKit / kit.quantidade,7);
      v_quantSaldoRateioTotal := 0;
      v_valorSaldoRateioTotal := 0;
    ELSE
      v_precoCustoKit := 0;
      v_valorCustoKit := 0;
    END IF;
    IF kit.controleEstoque IN (3,4) THEN
      ADD_PRE_DOC_ITEM_FIL_KIT(
        p_config_209_filtrarGrupoEcon,
        p_config_362_calcCustoPorGrade,
        r_bufferIdProdutoFilho,
        p_estabelecimentoAtivo,
        p_cab_atualizaCustoMedio,
        p_cab_estabelecimento,
        p_cab_dataEmissao,
        p_cab_dataEntradaSaida,
        p_item_idItemPreDocumento,
        kit.gradeProdutoFilho,
        p_item_pessoaParticipante,
        kit.quantidade,
        v_valorCustoKit,
        p_item_observacoes,
        p_endEst_idEnderecoEstoquePreD,
        p_idEnderecoEstoque,
        p_locEst_indicProprPosseItem,
        r_bufferIdProdutoFilho);
    ELSIF kit.controleEstoque IN(1,5,11,12) THEN
      v_quantidadeNumerosSerie := 0;
      IF kit.controlaNumeroSerie > 0 THEN
        ADD_PRE_DOC_ITEM_FIL_N_SERIE(
          r_bufferIdProdutoFilho,
          p_estabelecimentoAtivo,
          p_item_idItemPreDocumento,
          kit.gradeProdutoFilho,
          0, -- p_item_personalizacao
          0, -- p_item_idLoteEstoque
          v_precoCustoKit, -- p_item_precoCustoOperacao,
          0, -- p_item_precoCMV,
          p_item_observacoes,
          p_endEst_idEnderecoEstoquePreD,
          p_idEnderecoEstoque,
          r_bufferIdProdutoFilho,
          v_quantidadeNumerosSerie);
      END IF;    
      IF kit.quantidade > v_quantidadeNumerosSerie THEN
        ADD_PRE_DOC_ITEM_FIL_INSERE(
          r_bufferIdProdutoFilho,
          p_estabelecimentoAtivo,
          p_item_idItemPreDocumento,
          kit.gradeProdutoFilho,
          0, -- p_personalizacao
          0, -- p_idLoteEstoque
          p_idEnderecoEstoque,
          0, -- p_idNumeroSerie
          kit.quantidade - v_quantidadeNumerosSerie,
          v_precoCustoKit, -- p_precoCustoOperacao
          CASE WHEN v_quantidadeNumerosSerie = 0 THEN v_valorCustoKit WHEN kit.quantidade = 0 THEN 0 ELSE ROUND ((v_valorCustoKit * (kit.quantidade - v_quantidadeNumerosSerie) / kit.quantidade), 2) END, -- p_totalCustoOperacao
          0, -- p_precoCMV
          0, -- p_valorCMV
          p_item_observacoes,
          r_bufferIdProdutoFilho);
      END IF;    
    END IF;
  END LOOP;
END ADD_PRE_DOC_ITEM_FIL_KIT;

/

create or replace PROCEDURE ADD_PRE_DOC_ITEM_FIL_PROD_TIN(
    p_config_209_filtrarGrupoEcon  IN NUMBER,
    p_config_362_calcCustoPorGrade IN NUMBER,
    p_bufferIdProdutoFilho         IN VARCHAR2,
    p_estabelecimentoAtivo         IN NUMBER,
    p_cab_atualizaCustoMedio       IN NUMBER,
    p_cab_estabelecimento          IN NUMBER,
    p_cab_dataEmissao              IN DATE,
    p_cab_dataEntradaSaida         IN DATE,
    p_idItemPreDocumento           IN NUMBER,
    p_item_pessoaParticipante      IN NUMBER,
    p_item_quantidade              IN NUMBER,
    p_item_observacoes             IN VARCHAR2,
    p_endEst_idEnderecoEstoquePreD IN NUMBER,
    p_idEnderecoEstoque            IN NUMBER,
    p_locEst_indicProprPosseItem   IN CHAR,
    p_tinta_gradeProduto           IN NUMBER,
    p_tinta_quantidade             IN NUMBER,
    r_bufferIdProdutoFilho         OUT VARCHAR2)
IS  
  CURSOR c_grade IS 
    SELECT 
      prod.controleEstoque,
      ROUND(p_item_quantidade * p_tinta_quantidade / 900, uniMed.casasDecimaisUnidadeMedida) quantidade
    FROM CAGRADESPRODUTO gradProd 
    JOIN CAPRODUTOS prod ON prod.produto = gradProd.produto
    JOIN SIUNIDADESMEDIDA uniMed ON uniMed.unidadeMedida = prod.unidadeMedida
    WHERE gradProd.gradeProduto = p_tinta_gradeProduto
    AND ROUND(p_item_quantidade * p_tinta_quantidade / 900, uniMed.casasDecimaisUnidadeMedida) > 0;
BEGIN
  r_bufferIdProdutoFilho := p_bufferIdProdutoFilho;
  FOR grade IN c_grade
  LOOP
    IF grade.controleEstoque IN (3,4) THEN
      ADD_PRE_DOC_ITEM_FIL_KIT(
        p_config_209_filtrarGrupoEcon,
        p_config_362_calcCustoPorGrade,
        r_bufferIdProdutoFilho,
        p_estabelecimentoAtivo,
        p_cab_atualizaCustoMedio,
        p_cab_estabelecimento,
        p_cab_dataEmissao,
        p_cab_dataEntradaSaida,
        p_idItemPreDocumento,
        p_tinta_gradeProduto,
        p_item_pessoaParticipante,
        grade.quantidade,
        0, --p_item_valorCustoOperacao
        p_item_observacoes,
        p_endEst_idEnderecoEstoquePreD,
        p_idEnderecoEstoque,
        p_locEst_indicProprPosseItem,
        r_bufferIdProdutoFilho);
    ELSIF grade.controleEstoque IN(1,5,11,12) THEN
      ADD_PRE_DOC_ITEM_FIL_INSERE(
        r_bufferIdProdutoFilho,
        p_estabelecimentoAtivo,
        p_idItemPreDocumento,
        p_tinta_gradeProduto,
        0, -- p_personalizacao
        0, -- p_idLoteEstoque
        p_idEnderecoEstoque,
        0, -- p_idNumeroSerie
        grade.quantidade,
        0, -- p_precoCustoOperacao,
        0, -- p_totalCustoOperacao,
        0, -- p_precoCMV,
        0, -- p_valorCMV,
        p_item_observacoes,
        r_bufferIdProdutoFilho);
    END IF;    
  END LOOP;
END ADD_PRE_DOC_ITEM_FIL_PROD_TIN;

/

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

/

create or replace PROCEDURE ADD_PRE_DOC_ITEM_FIL_ENDERECO(
    p_config_209_filtrarGrupoEcon  IN NUMBER,
    p_config_362_calcCustoPorGrade IN NUMBER,
    p_bufferIdProdutoFilho         IN VARCHAR2,
    p_estabelecimentoAtivo         IN NUMBER,
    p_cab_atualizaCustoMedio       IN NUMBER,
    p_cab_estabelecimento          IN NUMBER,
    p_cab_dataEmissao              IN DATE,
    p_cab_dataEntradaSaida         IN DATE,
    p_item_idItemPreDocumento      IN NUMBER,
    p_item_gradeProduto            IN NUMBER,
    p_item_idFormulaTinta          IN NUMBER,
    p_item_personalizacao          IN NUMBER,
    p_item_pessoaParticipante      IN NUMBER,
    p_item_quantidade              IN NUMBER,
    p_item_valorCustoOperacao      IN NUMBER,
    p_item_observacoes             IN VARCHAR2,
    p_prod_controleEstoque         IN NUMBER,
    p_locEst_indicProprPosseItem   IN CHAR,
    r_bufferIdProdutoFilho         OUT VARCHAR2,
    r_quantidadeEnderecoEstoque    OUT NUMBER)
IS
  v_quantidadeNumerosSerie NUMBER (14,0);
  CURSOR c_endEst IS 
    SELECT idEnderecoEstoque,
      idEnderecoEstoquePreDocumento,
      quantidade
    FROM MOPREDOCUMXENDERECOESTOQ
    WHERE idItemPreDocumento = p_item_idItemPreDocumento
    AND quantidade        > 0;
BEGIN
  r_bufferIdProdutoFilho      := p_bufferIdProdutoFilho;
  r_quantidadeEnderecoEstoque := 0;
  FOR endEst IN c_endEst
  LOOP
    r_quantidadeEnderecoEstoque := r_quantidadeEnderecoEstoque + endEst.quantidade;
    IF p_prod_controleEstoque = 12 AND p_item_idFormulaTinta > 0 THEN
      ADD_PRE_DOC_ITEM_FIL_FORM_TIN(
        p_config_209_filtrarGrupoEcon,
        p_config_362_calcCustoPorGrade,
        r_bufferIdProdutoFilho, 
        p_estabelecimentoAtivo, 
        p_cab_atualizaCustoMedio,
        p_cab_estabelecimento,
        p_cab_dataEmissao,
        p_cab_dataEntradaSaida,
        p_item_idItemPreDocumento,
        p_item_idFormulaTinta,
        p_item_pessoaParticipante,
        endEst.quantidade,
        p_item_observacoes,
        endEst.idEnderecoEstoquePreDocumento,
        endEst.idEnderecoEstoque,
        p_locEst_indicProprPosseItem,
        r_bufferIdProdutoFilho);
    ELSIF p_prod_controleEstoque IN (3,4) THEN
      ADD_PRE_DOC_ITEM_FIL_KIT(
        p_config_209_filtrarGrupoEcon,
        p_config_362_calcCustoPorGrade,
        r_bufferIdProdutoFilho,
        p_estabelecimentoAtivo,
        p_cab_atualizaCustoMedio,
        p_cab_estabelecimento,
        p_cab_dataEmissao,
        p_cab_dataEntradaSaida,
        p_item_idItemPreDocumento,
        p_item_gradeProduto,
        p_item_pessoaParticipante,
        endEst.quantidade,
        CASE WHEN p_item_quantidade = 0 THEN 0 ELSE ROUND ((p_item_valorCustoOperacao * (endEst.quantidade - v_quantidadeNumerosSerie) / p_item_quantidade), 2) END,
        p_item_observacoes,
        endEst.idEnderecoEstoquePreDocumento,
        endEst.idEnderecoEstoque,
        p_locEst_indicProprPosseItem,
        r_bufferIdProdutoFilho);
    END IF;
  END LOOP;
END ADD_PRE_DOC_ITEM_FIL_ENDERECO;

/

create or replace PROCEDURE ADD_PRE_DOC_ITEM_FIL_GRAVA(
    p_config_209_filtrarGrupoEcon  IN NUMBER,
    p_config_362_calcCustoPorGrade IN NUMBER,
    p_bufferIdProdutoFilho         IN VARCHAR2,
    p_estabelecimentoAtivo         IN NUMBER,
    p_cab_atualizaCustoMedio       IN NUMBER,
    p_cab_estabelecimento          IN NUMBER,
    p_cab_dataEmissao              IN DATE,
    p_cab_dataEntradaSaida         IN DATE,
    p_item_idItemPreDocumento      IN NUMBER,
    p_item_gradeProduto            IN NUMBER,
    p_item_idFormulaTinta          IN NUMBER,
    p_item_personalizacao          IN NUMBER,
    p_item_pessoaParticipante      IN NUMBER,
    p_item_quantidade              IN NUMBER,
    p_item_valorCustoOperacao      IN NUMBER,
    p_item_observacoes             IN VARCHAR2,
    p_prod_controlaNumeroSerie     IN NUMBER,
    p_prod_controleEstoque         IN NUMBER,
    p_locEst_indicProprPosseItem   IN CHAR,
    p_estXLoc_solicitaEnderecoEst  IN NUMBER,
    r_bufferIdProdutoFilho         OUT VARCHAR2)
IS
  v_quantidadeEnderecoEstoque NUMBER (14,0);
  v_quantidadeNumerosSerie    NUMBER (14,0);
BEGIN
  r_bufferIdProdutoFilho      := p_bufferIdProdutoFilho;
  v_quantidadeEnderecoEstoque := 0;
  v_quantidadeNumerosSerie    := 0;
  IF p_estXLoc_solicitaEnderecoEst = 1 AND p_prod_controleEstoque IN (3,4,12) THEN
    ADD_PRE_DOC_ITEM_FIL_ENDERECO(
      p_config_209_filtrarGrupoEcon,
      p_config_362_calcCustoPorGrade,
      r_bufferIdProdutoFilho,
      p_estabelecimentoAtivo,
      p_cab_atualizaCustoMedio,
      p_cab_estabelecimento,
      p_cab_dataEmissao,
      p_cab_dataEntradaSaida,
      p_item_idItemPreDocumento,
      p_item_gradeProduto,
      p_item_idFormulaTinta,
      p_item_personalizacao,
      p_item_pessoaParticipante,
      p_item_quantidade,
      p_item_valorCustoOperacao,
      p_item_observacoes,
      p_prod_controlaNumeroSerie,
      p_prod_controleEstoque,
      r_bufferIdProdutoFilho,
      v_quantidadeEnderecoEstoque);
  END IF;
  IF p_item_quantidade > v_quantidadeEnderecoEstoque THEN
    IF p_prod_controleEstoque = 12 AND p_item_idFormulaTinta > 0 THEN
      ADD_PRE_DOC_ITEM_FIL_FORM_TIN(
        p_config_209_filtrarGrupoEcon,
        p_config_362_calcCustoPorGrade,
        r_bufferIdProdutoFilho, 
        p_estabelecimentoAtivo, 
        p_cab_atualizaCustoMedio,
        p_cab_estabelecimento,
        p_cab_dataEmissao,
        p_cab_dataEntradaSaida,
        p_item_idItemPreDocumento,
        p_item_idFormulaTinta,
        p_item_pessoaParticipante,
        p_item_quantidade - v_quantidadeEnderecoEstoque,
        p_item_observacoes,
        0, -- p_endEst_idEnderecoEstoquePreD,
        0, -- p_idEnderecoEstoque,
        p_locEst_indicProprPosseItem,
        r_bufferIdProdutoFilho);
    ELSIF p_prod_controleEstoque IN (3,4) THEN
      ADD_PRE_DOC_ITEM_FIL_KIT(
        p_config_209_filtrarGrupoEcon,
        p_config_362_calcCustoPorGrade,
        r_bufferIdProdutoFilho,
        p_estabelecimentoAtivo, 
        p_cab_atualizaCustoMedio,
        p_cab_estabelecimento,
        p_cab_dataEmissao,
        p_cab_dataEntradaSaida,
        p_item_idItemPreDocumento,
        p_item_gradeProduto,
        p_item_pessoaParticipante,
        p_item_quantidade - v_quantidadeEnderecoEstoque,
        CASE WHEN v_quantidadeEnderecoEstoque = 0 THEN p_item_valorCustoOperacao WHEN p_item_quantidade = 0 THEN 0 ELSE ROUND ((p_item_valorCustoOperacao * (p_item_quantidade - v_quantidadeEnderecoEstoque) / p_item_quantidade), 2) END,
        p_item_observacoes,
        0, -- p_endEst_idEnderecoEstoquePreD
        0, -- p_idEnderecoEstoque,
        p_locEst_indicProprPosseItem,
        r_bufferIdProdutoFilho);
    END IF;
  END IF;
END ADD_PRE_DOC_ITEM_FIL_GRAVA;

/

create or replace PROCEDURE ADD_PRE_DOC_ITEM_FIL_ATUALIZA(
    p_config_209_filtrarGrupoEcon  IN NUMBER,
    p_config_362_calcCustoPorGrade IN NUMBER,
    p_idItemPreDocumento           IN NUMBER,
    p_estabelecimentoAtivo         IN NUMBER
  )
IS
  v_bufferIdProdutoFilho VARCHAR2 (32000);
  CURSOR c_estoqueExcluir IS 
    SELECT a.id
    FROM MOPREDOCUMXPRODUTOFILHO a
    JOIN MOPREDOCUMXESTOQUE b ON b.id = a.id
    WHERE b.idItemPreDocumento = p_idItemPreDocumento
    ORDER BY a.id;
  CURSOR c_item IS 
    SELECT 
      cab.atualizaCustoMedio,
      cab.estabelecimento,
      cab.dataEmissao,
      cab.dataEntradaSaida,
      item.idItemPreDocumento,
      item.gradeProduto,
      item.idFormulaTinta,
      item.personalizacao,
      item.pessoaParticipante,
      item.quantidade,
      item.valorCustoOperacao,
      item.observacoes,
      prod.controlaNumeroSerie,
      prod.controleEstoque,
      locEst.indicadorPropriedadePosseItem locEst_indicProprPosseItem,
      COALESCE (estXLoc.solicitaEnderecoEstoque,0) estXLoc_solicitaEnderecoEst
    FROM MOPREDOCUMXITENS item
    JOIN MOPREDOCUMENTOS cab
    ON cab.preDocumento = item.preDocumento
    JOIN CAGRADESPRODUTO gradProd
    ON gradProd.gradeProduto = item.gradeProduto
    JOIN CAPRODUTOS prod
    ON prod.produto = gradProd.produto
    JOIN PALOCAISESTOQUE locEst
    ON locEst.localEstoque = item.localEstoque
    LEFT JOIN PAESTABELECIMENTOXLOCAISE estXLoc
    ON estXLoc.estabelecimento = cab.estabelecimento
    AND estXLoc.localEstoque = item.localEstoque
    WHERE item.idItemPreDocumento = p_idItemPreDocumento
    AND item.cancelado = 0
    AND item.quantidade > 0
    AND cab.statusPreDocumento = 'A';
BEGIN
  v_bufferIdProdutoFilho := '';
  FOR estoqueExcluir IN c_estoqueExcluir
  LOOP
    v_bufferIdProdutoFilho := CASE WHEN (v_bufferIdProdutoFilho IS NULL OR v_bufferIdProdutoFilho = '' OR v_bufferIdProdutoFilho = ' ') THEN '' ELSE RTRIM (v_bufferIdProdutoFilho) || ';' END || TO_CHAR (LPAD(estoqueExcluir.id,14,'0'));
    DELETE MOPREDOCUMXPRODUTOFILHO a WHERE a.id = estoqueExcluir.id;
  END LOOP;
  FOR item IN c_item
  LOOP
    ADD_PRE_DOC_ITEM_FIL_GRAVA(
      p_config_209_filtrarGrupoEcon,
      p_config_362_calcCustoPorGrade,
      v_bufferIdProdutoFilho,
      p_estabelecimentoAtivo,
      item.atualizaCustoMedio,
      item.estabelecimento,
      item.dataEmissao,
      item.dataEntradaSaida,
      item.idItemPreDocumento,
      item.gradeProduto,
      item.idFormulaTinta,
      item.personalizacao,
      item.pessoaParticipante,
      item.quantidade,
      item.valorCustoOperacao,
      item.observacoes,
      item.controlaNumeroSerie,
      item.controleEstoque,
      item.locEst_indicProprPosseItem,
      item.estXLoc_solicitaEnderecoEst,
      v_bufferIdProdutoFilho);
  END LOOP;
END ADD_PRE_DOC_ITEM_FIL_ATUALIZA;

/

create or replace PROCEDURE ADD_PRE_DOC_CAB_FIL_ATUALIZA(
    p_config_209_filtrarGrupoEcon  IN NUMBER,
    p_config_362_calcCustoPorGrade IN NUMBER,
    p_preDocumento                 IN NUMBER,
    p_estabelecimentoAtivo         IN NUMBER
  )
IS
  v_bufferIdProdutoFilho VARCHAR2 (32000);
  CURSOR c_estoqueExcluir IS
    SELECT a.id
    FROM MOPREDOCUMXPRODUTOFILHO a
    JOIN MOPREDOCUMXESTOQUE b ON b.id = a.id
    JOIN MOPREDOCUMXITENS c ON c.idItemPreDocumento = b.idItemPreDocumento
    WHERE c.preDocumento = p_preDocumento
    ORDER BY a.id;
  CURSOR c_item
  IS 
    SELECT 
      cab.atualizaCustoMedio,
      cab.estabelecimento,
      cab.dataEmissao,
      cab.dataEntradaSaida,
      item.idItemPreDocumento,
      item.gradeProduto,
      item.idFormulaTinta,
      item.personalizacao,
      item.pessoaParticipante,
      item.quantidade,
      item.valorCustoOperacao,
      item.valorAcrescimoExtempTotal,
      item.observacoes,
      prod.controlaNumeroSerie,
      prod.controleEstoque,
      locEst.indicadorPropriedadePosseItem locEst_indicProprPosseItem,
      COALESCE (estXLoc.solicitaEnderecoEstoque,0) estXLoc_solicitaEnderecoEst
    FROM MOPREDOCUMXITENS item
    JOIN MOPREDOCUMENTOS cab
    ON cab.preDocumento = item.preDocumento
    JOIN CAGRADESPRODUTO gradProd
    ON gradProd.gradeProduto = item.gradeProduto
    JOIN CAPRODUTOS prod
    ON prod.produto = gradProd.produto
    JOIN PALOCAISESTOQUE locEst
    ON locEst.localEstoque = item.localEstoque
    LEFT JOIN PAESTABELECIMENTOXLOCAISE estXLoc
    ON estXLoc.estabelecimento = cab.estabelecimento
    AND estXLoc.localEstoque = item.localEstoque
    WHERE item.preDocumento = p_preDocumento
    AND item.cancelado = 0
    AND item.quantidade > 0
    AND cab.statusPreDocumento = 'A';
BEGIN
  v_bufferIdProdutoFilho := '';
  FOR estoqueExcluir IN c_estoqueExcluir
  LOOP
    v_bufferIdProdutoFilho := CASE WHEN (v_bufferIdProdutoFilho IS NULL OR v_bufferIdProdutoFilho = '' OR v_bufferIdProdutoFilho = ' ') THEN '' ELSE RTRIM (v_bufferIdProdutoFilho) || ';' END || TO_CHAR (LPAD(estoqueExcluir.id,14,'0'));
    DELETE MOPREDOCUMXPRODUTOFILHO a WHERE a.id = estoqueExcluir.id;
  END LOOP;
  FOR item IN c_item
  LOOP
    ADD_PRE_DOC_ITEM_FIL_GRAVA(
      p_config_209_filtrarGrupoEcon,
      p_config_362_calcCustoPorGrade,
      v_bufferIdProdutoFilho,
      p_estabelecimentoAtivo,
      item.atualizaCustoMedio,
      item.estabelecimento,
      item.dataEmissao,
      item.dataEntradaSaida,
      item.idItemPreDocumento,
      item.gradeProduto,
      item.idFormulaTinta,
      item.personalizacao,
      item.pessoaParticipante,
      item.quantidade,
      item.valorCustoOperacao,
      item.observacoes,
      item.controlaNumeroSerie,
      item.controleEstoque,
      item.locEst_indicProprPosseItem,
      item.estXLoc_solicitaEnderecoEst,
      v_bufferIdProdutoFilho);
  END LOOP;
END ADD_PRE_DOC_CAB_FIL_ATUALIZA;

/

create or replace PROCEDURE ADD_PRE_DOC_ROT_EFET_ORCAMENTO(
    p_exclusivo               IN VARCHAR2,
    p_orcamento               IN NUMBER,
    p_usuarioLogado           IN NUMBER,
    p_estabelecimentoAtivo    IN NUMBER,
    p_sessao                  IN NUMBER,
    p_sessaoCaixa             IN NUMBER,
    p_idTerminalSiTef         IN VARCHAR2,
    p_serieFiscal             IN VARCHAR2,
    p_subSerieFiscal          IN NUMBER,
    p_documentoFiscal         IN NUMBER,
    p_dataEmissao             IN DATE,
    p_timezone                IN VARCHAR2,
    p_dataEntradaSaida        IN DATE,
    p_comissionadoB           IN NUMBER,
    p_comissionadoC           IN NUMBER,
    p_novaEtapaOrcamento      IN NUMBER,
    p_versaoAplicativo        IN VARCHAR2,
    r_preDocumento            OUT NUMBER)
IS
  v_tipoDocumento          NUMBER;
  v_fatoContabil           NUMBER;
  v_preDocumento           NUMBER;
  v_estabelecimento        NUMBER;
  v_pessoa                 NUMBER;
  v_colaboradorResponsavel NUMBER;
  CURSOR c_itens
  IS SELECT idItemOrcamento, CASE WHEN cancelado = 0 THEN FUNC_ADD_BUSCA_PROXIMO_ID('MOPREDOCUMXITENS', 'idItemPreDocumento', 0, p_estabelecimentoAtivo, NULL) ELSE 0 END idItemPreDocumento, sequencia, cancelado, modeloDocumento, vendedor, gradeProduto, servico, idFormulaTinta, personalizacao, idLoteEstoque, operacaoFiscal, movimentaEstoque, geraFinanceiro, localEstoque, pessoaParticipante, controleQuantidade, unidadeMedidaConversao, conversorQuantidade, loteMinimo, loteMultiplo, altura, largura, comprimento, pecas, quantidade, quantidadeConvertida, quantidadeConferida, pesoLiquido, pesoBruto, tipoPreco, tabelaPreco, precoSugestaoAPrazo, precoSugestaoAVista, precoDesconto, precoMinimo, usarPrecoAVista, precoPautaTabelado, precoUnitarioBruto, acrescimoUnitarioComposicao, precoUnitario, precoUnitarioConvertido, valorProdutoServicoBruto, valorProdutoServico, percDescontoItem, valorDescontoItem, percAcrescimoItem, valorAcrescimoItem, valorFreteItem, valorSeguroItem, valorAdicFreteMarinhaMerItem, valorDespesasAduaneirasItem, valorFreteGeral, valorSeguroGeral, valorDescontoGeral, valorOutrasDespesasGeral, valorAdicFreteMarinhaMerGeral, valorDespesasAduaneirasGeral, valorBasePagamento, valorDescontoPagamento, valorOutrasDespesasPagamento, valorJurosPagamento, valorFreteTotal, valorSeguroTotal, valorDescontoTotal, valorOutrasDespesasTotal, valorAdicFreteMarinhaMerTotal, valorDespesasAduaneirasTotal, cfop, indicadorISSQN, aliquotaISSQN, baseISSQN, valorISSQN, aliquotaIRRF, baseIRRF, valorIRRF, aliquotaINSS, baseINSS, valorINSS, retencaoPIS, baseRetPIS, valorRetPIS, retencaoCOFINS, baseRetCOFINS, valorRetCOFINS, retencaoCSLL, baseRetCSLL, valorRetCSLL, aliquotaII, baseII, valorII, aliquotaIOF, baseIOF, valorIOF, codigoEnquadramentoIPI, stIPI, aliquotaIPI, valorAliquotaIPI, baseIPI, valorIPI, stPIS, aliquotaPIS, valorAliquotaPIS, basePIS, valorPIS, aliquotaPISST, valorAliquotaPISST, basePISST, valorPISST, stCOFINS, aliquotaCOFINS, valorAliquotaCOFINS, baseCOFINS, valorCOFINS, aliquotaCOFINSST, valorAliquotaCOFINSST, baseCOFINSST, valorCOFINSST, stSimplesNacional, creditoSimplesNacional, baseCreditoSimplesNacional, valorCreditoSimplesNacional, stICMS, modalidadeBaseCalcICMS, reducaoBaseICMS, aliquotaICMS, diferimentoICMS, motivoDesoneracaoICMS, baseICMS, valorICMSOperacao, valorICMSDiferido, valorICMS, valorICMSDesoneracao, modalidadeBaseCalcICMSST, margemValorAdicionadoST, reducaoBaseST, aliquotaICMSST, aliquotaSTSuportConsFinal, baseICMSST, valorICMSST, baseICMSSTAnteriormente, valorICMSSTAnteriormente, valorICMSProprioSubstituto, reducaoBaseICMSEfetivo, aliquotaICMSEfetivo, baseICMSEfetivo, valorICMSEfetivo, aliquotaICMSUFDestinatario, aliquotaICMSInterestadual, partilhaICMSInterestadual, baseICMSUFDestinatario, valorICMSUFDestinatario, baseICMSUFRemetente, valorICMSUFRemetente, aliquotaFCP, baseFCP, valorFCP, aliquotaFCPST, baseFCPST, valorFCPST, aliquotaFCPSTAnteriormente, baseFCPSTAnteriormente, valorFCPSTAnteriormente, aliquotaFCPUFDestinatario, baseFCPUFDestinatario, valorFCPUFDestinatario, aliquotaEstimadaImpFederais, aliquotaEstimadaImpEstaduais, aliquotaEstimadaImpMunicipais, baseEstimadaImpostos, valorEstimadoImpFederais, valorEstimadoImpEstaduais, valorEstimadoImpMunicipais, valorImpostosSomaPagamento, valorImpostosDiminuiPagamento, valorLiquidoItem, observacoesDigitadas, observacoes
     FROM MOORCAMENTOXITENS
     WHERE orcamento = p_orcamento
     ORDER BY sequencia;
  CURSOR c_endEst
  IS SELECT a.idEnderecoEstoqueOrcamento, a.idItemOrcamento, FUNC_ADD_BUSCA_PROXIMO_ID('MOPREDOCUMXENDERECOESTOQ', 'idEnderecoEstoquePreDocumento', 0, p_estabelecimentoAtivo, NULL) idEnderecoEstoquePreDocumento, a.idEnderecoEstoque, a.posicaoCaixaEstoque, a.quantidade, 0 quantidadeDevolvidaRetornada, a.quantidadeConferida, a.observacoes
     FROM MOORCAMENTOXENDERECOESTOQ a
     JOIN MOORCAMENTOXITENS b ON b.idItemOrcamento = a.idItemOrcamento
     WHERE b.orcamento = p_orcamento
     AND b.cancelado = 0;
  CURSOR c_pagtos
  IS SELECT idPagamentoOrcamento, FUNC_ADD_BUSCA_PROXIMO_ID('MOPREDOCUMXPAGAMENTOS', 'idPagamentoPreDocumento', 0, p_estabelecimentoAtivo, NULL) idPagamentoPreDocumento, pagamentoTroco, sequencia, indicadorFormaPagamento, meioPagamento, condicaoPagamento, cobranca, numeroParcelas, somaPrazoParcelas, valorXPrazoParcelas, prazoMedio, prazoMedioPonderado, valorEntradaMinima, valorPagamentoBruto, percDescontoPagamento, valorDescontoPagamento, percOutrasDespesasPagamento, valorOutrasDespesasPagamento, fatorJurosPagamento, valorJurosPagamento, valorPagamentoImpostosSoma, valorPagamentoImpostosDiminui, valorPagamentoLiquido, valorFinanceiro, observacoes
     FROM MOORCAMENTOXPAGAMENTOS
     WHERE orcamento = p_orcamento
     ORDER BY pagamentoTroco, sequencia;
  CURSOR c_mot_cab IS
