Пример #1
0
        public Loan SimulateRescheduling(Loan loan, ScheduleConfiguration rescheduleConfiguration)
        {
            var copyOfLoan = loan.Copy();
            var scheduleConfiguration = _configurationFactory
                .Init()
                .WithLoan(copyOfLoan)
                .Finish()
                .GetConfiguration();

            var schedule = Mapper.Map<IEnumerable<Installment>, IEnumerable<IInstallment>>(copyOfLoan.InstallmentList);
            var scheduleBuilder = new ScheduleBuilder();
            var rescheduleAssembler = new RescheduleAssembler();
            var copyOfRescheduleConfiguration = (IScheduleConfiguration) rescheduleConfiguration.Clone();
            copyOfRescheduleConfiguration.InterestRate *=
                (decimal) scheduleConfiguration.PeriodPolicy.GetNumberOfPeriodsInYear(
                    copyOfRescheduleConfiguration.StartDate,
                    scheduleConfiguration.YearPolicy);

            schedule = rescheduleAssembler.AssembleRescheduling(
                schedule,
                scheduleConfiguration,
                copyOfRescheduleConfiguration,
                scheduleBuilder,
                loan.CalculateActualOlb().Value);

            var newSchedule = Mapper.Map<IEnumerable<IInstallment>, List<Installment>>(schedule);

            copyOfLoan.InstallmentList = newSchedule;
            copyOfLoan.NbOfInstallments = newSchedule.Count();
            return copyOfLoan;
        }
Пример #2
0
        private List<Installment> AssembleRescheduling(Loan loan, ScheduleConfiguration rescheduleConfiguration, IScheduleConfiguration scheduleConfiguration)
        {
            var copyOfLoan = loan.Copy();;
            var schedule = copyOfLoan.InstallmentList;
            // Build a new combined schedule

            // 1. To close all active installments before date of rescheduling.

            // Get the part of the schedule that comes before the rescheduling date...
            var newSchedule =
                from installment in schedule
                where installment.ExpectedDate <= rescheduleConfiguration.StartDate
                select installment;

            // Get overpaid principal = sum of paid principal after the rescheduling date...
            var overpaidPrincipal = (
                from installment in schedule
                where installment.PaidDate > rescheduleConfiguration.StartDate
                select installment
            ).Sum(installment => installment.PaidCapital.Value);

            //Add overpaid principal to paid principal of the last installment before the rescheduling
            if (newSchedule.Any())
                newSchedule.Last().PaidCapital += overpaidPrincipal;

            // Close all active installments before date of rescheduling
            var olbDifference = 0m;
            foreach (var installment in newSchedule)
            {
                installment.OLB += olbDifference;
                olbDifference += installment.CapitalRepayment.Value - installment.PaidCapital.Value;
                installment.CapitalRepayment = installment.PaidCapital;
                installment.InterestsRepayment = installment.PaidInterests;
            }

            // 2. To store amounts of interest paid, those for installments after date of rescheduling.
            var overpaidInterest = (
                from installment in schedule
                where installment.ExpectedDate > rescheduleConfiguration.StartDate
                select installment
            ).Sum(installment => installment.PaidInterests.Value);

            // 3. To get total of first calculated interest. It will be interest between last closed installment and date of rescheduling
            //    plus interest between date of rescheduling and first repayment date

            //    To calculate extra interest for used days.
            //    For the case when date of rescheduling < date of first installment
            var currentOlb = loan.CalculateActualOlb().Value;
            var usedDays = 0;
            if (newSchedule.Any())
            {
                usedDays = (rescheduleConfiguration.StartDate - newSchedule.Last().ExpectedDate).Days;
            }
            var daysInYear = scheduleConfiguration.YearPolicy.GetNumberOfDays(rescheduleConfiguration.StartDate);
            var extraInterest = currentOlb * scheduleConfiguration.InterestRate / 100 * usedDays / daysInYear;

            // To calculate interest between date of rescheduling and first repayment date.
            var daysTillRepayment =
                (rescheduleConfiguration.PreferredFirstInstallmentDate - rescheduleConfiguration.StartDate).Days;
            decimal firstInterest = 0;
            if (rescheduleConfiguration.GracePeriod == 0 || rescheduleConfiguration.ChargeInterestDuringGracePeriod)
                firstInterest = currentOlb*rescheduleConfiguration.InterestRate/100*daysTillRepayment/
                            scheduleConfiguration.PeriodPolicy.GetNumberOfDays(
                                rescheduleConfiguration.PreferredFirstInstallmentDate);

            copyOfLoan.Amount = currentOlb;
            copyOfLoan.InterestRate = rescheduleConfiguration.InterestRate/100;
            copyOfLoan.NbOfInstallments = rescheduleConfiguration.NumberOfInstallments;
            copyOfLoan.GracePeriod = rescheduleConfiguration.GracePeriod;
            copyOfLoan.StartDate = rescheduleConfiguration.StartDate;
            copyOfLoan.FirstInstallmentDate = rescheduleConfiguration.PreferredFirstInstallmentDate;
            copyOfLoan.Product.ChargeInterestWithinGracePeriod = rescheduleConfiguration.ChargeInterestDuringGracePeriod;
            rescheduleConfiguration.RoundingPolicy = scheduleConfiguration.RoundingPolicy;

            var rescheduled = SimulateScheduleCreation(copyOfLoan);
            // Adjust the new schedule's installment numbers
            var increment = newSchedule.Count();
            foreach (var installment in rescheduled)
            {
                installment.Number += increment;
            }

            // Distribute the extra and overpaid interest
            if (rescheduleConfiguration.GracePeriod > 0 && !rescheduleConfiguration.ChargeInterestDuringGracePeriod)
                rescheduled[rescheduleConfiguration.GracePeriod].InterestsRepayment +=
                    rescheduleConfiguration.RoundingPolicy.Round(extraInterest);
            else
                rescheduled.First().InterestsRepayment =
                    rescheduleConfiguration.RoundingPolicy.Round(firstInterest + extraInterest);
            foreach (var installment in rescheduled)
            {
                if (installment.InterestsRepayment < overpaidInterest)
                {
                    installment.PaidInterests = installment.InterestsRepayment;
                    overpaidInterest -= installment.InterestsRepayment.Value;
                }
                else
                {
                    installment.PaidInterests = overpaidInterest;
                    break;
                }
            }

            var result = new List<Installment>();
            result.AddRange(newSchedule);
            result.AddRange(rescheduled);

            return result;
        }
Пример #3
0
        public Loan Reschedule(Loan loan, IClient client, ScheduleConfiguration rescheduleConfiguration)
        {
            using (var connection = _loanManager.GetConnection())
            using (var transaction = connection.BeginTransaction())
            {
                try
                {
                    var copyOfLoan = SimulateRescheduling(loan, rescheduleConfiguration);
                    var rescheduleLoanEvent = new RescheduleLoanEvent
                        {
                            Amount = copyOfLoan.CalculateActualOlb(),
                            Date = rescheduleConfiguration.StartDate,
                            ClientType = client.Type,
                            Interest = rescheduleConfiguration.InterestRate,
                            BadLoan = loan.BadLoan,
                            NbOfMaturity = rescheduleConfiguration.NumberOfInstallments,
                            GracePeriod = rescheduleConfiguration.GracePeriod,
                            ChargeInterestDuringGracePeriod = rescheduleConfiguration.ChargeInterestDuringGracePeriod,
                            InstallmentNumber =
                                copyOfLoan.GetLastFullyRepaidInstallment() == null
                                    ? 1
                                    : copyOfLoan.GetLastFullyRepaidInstallment().Number + 1,
                            PreferredFirstInstallmentDate = rescheduleConfiguration.PreferredFirstInstallmentDate,
                            User = _user,
                            PreviousInterestRate = rescheduleConfiguration.PreviousInterestRate,
                        };

                    //insert into table TrancheEvent
                    _ePs.FireEvent(rescheduleLoanEvent, copyOfLoan, transaction);

                    ArchiveInstallments(loan, rescheduleLoanEvent, transaction);

                    //delete all the old installments of the table Installments
                    _instalmentManager.DeleteInstallments(loan.Id, transaction);

                    //insert all the new installments in the table Installments
                    _instalmentManager.AddInstallments(copyOfLoan.InstallmentList, copyOfLoan.Id, transaction);

                    copyOfLoan.Events.Add(rescheduleLoanEvent);
                    transaction.Commit();

                    SetClientStatus(copyOfLoan, client);
                    return copyOfLoan;
                }
                catch
                {
                    transaction.Rollback();
                    throw;
                }
            }
        }
Пример #4
0
        public Loan SimulateRescheduling(Loan loan, ScheduleConfiguration rescheduleConfiguration)
        {
            var copyOfLoan = loan.Copy();
            var scheduleConfiguration = _configurationFactory
                .Init()
                .WithLoan(copyOfLoan)
                .Finish()
                .GetConfiguration();

            var schedule = copyOfLoan.InstallmentList;
            var scheduleBuilder = new ScheduleBuilder();
            var rescheduleAssembler = new RescheduleAssembler();
            var copyOfRescheduleConfiguration = (IScheduleConfiguration)rescheduleConfiguration.Clone();
            if (loan.Product.ScriptName == null)
                schedule = rescheduleAssembler.AssembleRescheduling(
                    schedule,
                    scheduleConfiguration,
                    copyOfRescheduleConfiguration,
                    scheduleBuilder,
                    loan.CalculateActualOlb().Value).ToList();
            else
                schedule = AssembleRescheduling(loan, rescheduleConfiguration, scheduleConfiguration);

            copyOfLoan.InstallmentList = schedule;
            copyOfLoan.NbOfInstallments = schedule.Count();
            return copyOfLoan;
        }