Ejemplo n.º 1
0
        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);
        }