public IEnumerable <IRemuneracao> AbaterValorExcedenteDasRemuneracoes(ILimiteDeRemuneracao limiteOriginario, IEnumerable <IRemuneracao> remuneracoes, Dinheiro valorExcedente) { //TODO funciona apenas para real Dinheiro valorTotal = remuneracoes.Select(rem => rem.ValorAjustado).SomaDinheiro(); ConcurrentStack <IRemuneracao> remuneracoesAbatidas = new ConcurrentStack <IRemuneracao>(); Dinheiro totalAbatido = Dinheiro.Zero; Parallel.ForEach(remuneracoes, (rem) => { decimal percentualDeAbatimento = decimal.Round(rem.ValorAjustado / valorTotal, 7); Dinheiro valorDoAbatimento = percentualDeAbatimento * valorExcedente; Dinheiro valorDoAbatimentoArrendondado = Dinheiro.Arredondar(valorDoAbatimento, 7); IRemuneracao remuneracaoDivididaEmPartesAbatidas = AbaterRemuneracao(rem, valorDoAbatimentoArrendondado, limiteOriginario); if (limiteOriginario.Tipo.Id.Equals("LIMITE_MINIMO") && remuneracaoDivididaEmPartesAbatidas.ValorAjustado > Dinheiro.Zero || limiteOriginario.Tipo.Id.Equals("LIMITE_MAXIMO")) { remuneracoesAbatidas.Push(remuneracaoDivididaEmPartesAbatidas); totalAbatido += valorDoAbatimentoArrendondado; } }); Dinheiro diferencaDeExcedente = Dinheiro.Arredondar(valorExcedente - totalAbatido, 6); if (diferencaDeExcedente != Dinheiro.Zero && remuneracoesAbatidas.Count() > 0) { CorrecaoDeArredondamentoDeExcedente(remuneracoesAbatidas.First(), diferencaDeExcedente); } return(remuneracoesAbatidas); }