Esempio n. 1
0
        //https://trello.com/c/MeFaqtiZ
        public void trello_card_122_totalearlypayment()
        {
            var calculator = new LoanScheduleCalculator()
            {
                Interest = 0.06M
            };

            calculator.Calculate(1110, _loan, Parse("2012-12-14 11:11:38.000"));
            _loan.Status = LoanStatus.Live;

            MakePayment(378.59m, Parse("2012-12-18 14:47:08.000"));
            MakePayment(731.41m, Parse("2012-12-18 15:01:07.000"));

            Console.WriteLine(_loan);

            var calc = new LoanRepaymentScheduleCalculator(_loan, Parse("2012-12-21 11:11:38.000"), 0);

            var payment = calc.TotalEarlyPayment();
            var next    = calc.NextEarlyPayment();

            Console.WriteLine(_loan);

            Assert.That(payment, Is.EqualTo(8.64m));
            Assert.That(next, Is.EqualTo(8.64m));
        }
        public void loan_of_600_payment_first_day_totatl_and_installment()
        {
            var loan = new Loan()
            {
            };
            var date = new DateTime(2012, 12, 18);

            _calculator.Calculate(600, loan, date);

            var c = new LoanRepaymentScheduleCalculator(loan, date, 0);

            Console.WriteLine(loan);

            var next = c.NextEarlyPayment();

            Console.WriteLine(loan);

            var totalEarlyPayment = c.TotalEarlyPayment();

            Console.WriteLine(loan);

            Assert.That(next, Is.EqualTo(200m));
            Assert.That(totalEarlyPayment, Is.EqualTo(600m));

            Assert.That(loan.Schedule.All(i => i.Interest > 0), Is.True);
        }
Esempio n. 3
0
		public void CalculatorState() {
			DateTime calcTime = DateTime.UtcNow;
			const long loanID = 10007;
			const int customerID = 59;
			GetLoanState dbState = new GetLoanState(customerID, loanID, calcTime, 357, false);
			try {
				dbState.Execute();
			} catch (NL_ExceptionInputDataInvalid nlExceptionInputDataInvalid) {
				Console.WriteLine(nlExceptionInputDataInvalid.Message);
				return;
			}
			try {
				ALoanCalculator calc = new LegacyLoanCalculator(dbState.Result, calcTime);
				calc.GetState();
				m_oLog.Debug("----------------------------------{0}", calc.WorkingModel);
			} catch (Exception exception) {
				m_oLog.Error("{0}", exception.Message);
			}

			return;

			// old loan
			LoanRepository loanRep = ObjectFactory.GetInstance<LoanRepository>();
			Loan oldLoan = loanRep.Get(dbState.Result.Loan.OldLoanID);
			// old calc
			LoanRepaymentScheduleCalculator oldCalc = new LoanRepaymentScheduleCalculator(oldLoan, calcTime, 0);
			oldCalc.GetState();

			m_oLog.Debug("++++++++++++++++++++++++++++++old loan: {0}", oldLoan);
			m_oLog.Debug("NextEarlyPayment={0}", oldCalc.NextEarlyPayment());
		}
Esempio n. 4
0
        //https://trello.com/c/NHwkJCpE
        public void trello_card_245_one_pound_mistake()
        {
            var calculator = new LoanScheduleCalculator()
            {
                Interest = 0.06M, Term = 3
            };

            calculator.Calculate(1000, _loan, Parse("2012-12-09 00:00:00.000"));
            _loan.Status = LoanStatus.Live;

            Console.WriteLine(_loan);

            var payEarlyCalc = new LoanRepaymentScheduleCalculator(_loan, Parse("2013-01-09 00:00:00.000"), 0);

            var earlyPayment = payEarlyCalc.NextEarlyPayment();

            Assert.That(earlyPayment, Is.EqualTo(394));
        }
Esempio n. 5
0
        public void next_early_payment_for_halfway_loan()
        {
            var now = new DateTime(2013, 01, 01);

            var type = new HalfWayLoanType();
            var loan = new Loan()
            {
                LoanType = type, LoanAmount = 1000, Date = now
            };
            var schedule = _calculator.Calculate(1000m, loan, now);

            Console.WriteLine(loan);

            var pc = new LoanRepaymentScheduleCalculator(loan, now, 0);

            var ep = pc.NextEarlyPayment();

            Assert.That(ep, Is.EqualTo(500));
        }
Esempio n. 6
0
        public void interest_only_payments_can_be_late()
        {
            var now = Parse("2012-10-27 00:00:00.000");

            var type = new HalfWayLoanType();
            var loan = new Loan()
            {
                LoanType = type, LoanAmount = 1000, Date = now
            };

            _calculator.Calculate(1000m, loan, now);

            var pc = new LoanRepaymentScheduleCalculator(loan, Parse("2013-01-16 00:00:00.000"), 0);
            var ep = pc.NextEarlyPayment();

            Console.WriteLine(loan);

            Assert.That(loan.Schedule[0].Status, Is.EqualTo(LoanScheduleStatus.Late));
            Assert.That(loan.Schedule[1].Status, Is.EqualTo(LoanScheduleStatus.Late));
            Assert.That(loan.Schedule[2].Status, Is.EqualTo(LoanScheduleStatus.StillToPay));
        }
Esempio n. 7
0
        //https://trello.com/c/IhYey6dp
        public void trello_card_130()
        {
            var calculator = new LoanScheduleCalculator()
            {
                Interest = 0.06M, Term = 10
            };

            calculator.Calculate(2721650, _loan, Parse("2012-08-25 08:20:35.000"));
            _loan.Status = LoanStatus.Live;

            Console.WriteLine(_loan);

            MakePayment(435464.00m, Parse("2012-09-25 13:27:46.000"));
            MakePayment(419134.00m, Parse("2012-10-25 12:15:23.000"));
            MakePayment(402804.00m, Parse("2012-11-25 06:00:48.000"));
            MakePayment(1409923.59m, Parse("2012-12-19 13:27:01.000"));

            var calc = new LoanRepaymentScheduleCalculator(_loan, Parse("2012-12-21 11:11:38.000"), 0);

            var payment = calc.TotalEarlyPayment();
            var next    = calc.NextEarlyPayment();
        }
Esempio n. 8
0
        public ReschedulingResult Result;                  // output

        public override void Execute()
        {
            NL_AddLog(LogType.Info, "Strategy Start", this.ReschedulingArguments, null, null, null);

            if (!this.ReschedulingArguments.RescheduleIn && this.ReschedulingArguments.PaymentPerInterval == null)
            {
                this.Result.Error = "Weekly/monthly payment amount for OUT rescheduling not provided";
                this.loanRep.Clear();
                return;
            }

            try {
                this.loanRep.BeginTransaction();

                GetCurrentLoanState();

                if (this.tLoan == null)
                {
                    this.Result.Error       = string.Format("Loan ID {0} not found", this.ReschedulingArguments.LoanID);
                    this.Result.BlockAction = true;
                    ExitStrategy("Exit_1");
                    return;
                }

                // check status, don't continue for "PaidOff"
                if (this.tLoan.Status == LoanStatus.PaidOff)
                {
                    this.Result.Error       = string.Format("Loan ID {0} paid off. Loan balance: {1}", this.tLoan.Id, 0m.ToString("C2", this.cultureInfo));
                    this.Result.BlockAction = true;
                    ExitStrategy("Exit_2", this.sendDebugMail);
                    return;
                }

                // input validation for "IN"
                if (this.ReschedulingArguments.RescheduleIn && (this.Result.FirstItemDate > this.Result.LoanCloseDate))
                {
                    this.Result.Error       = "Within loan arrangement is impossible";
                    this.Result.BlockAction = true;
                    ExitStrategy("Exit_3", this.sendDebugMail);
                    return;
                }

                // "IN" - check between interval boundaries
                if (this.ReschedulingArguments.RescheduleIn && (this.Result.FirstItemDate < this.Result.ReschedulingIntervalStart || this.Result.FirstItemDate > this.Result.ReschedulingIntervalEnd))
                {
                    this.Result.Error       = "Wrong re-scheduling date sent (any day on the calendar within next 30 days allowed)";
                    this.Result.BlockAction = true;
                    ExitStrategy("Exit_3a", this.sendDebugMail);
                    return;
                }

                // "OUT" - check past date
                if (this.ReschedulingArguments.RescheduleIn == false && this.Result.FirstItemDate.Date < this.Result.ReschedulingIntervalStart)
                {
                    this.Result.Error       = "Wrong re-scheduling date sent (only future date allowed)";
                    this.Result.BlockAction = true;
                    ExitStrategy("Exit_3b", this.sendDebugMail);
                    return;
                }

                this.Result.OpenPrincipal = this.tLoan.Principal;

                // if sent "default" value (0), replace by default calculated
                if (!this.ReschedulingArguments.RescheduleIn && this.ReschedulingArguments.PaymentPerInterval == 0)
                {
                    this.ReschedulingArguments.PaymentPerInterval = this.Result.DefaultPaymentPerInterval;
                }

                Log.Debug("\n==========RE-SCHEDULING======ARGUMENTS: {0}==========LoanState: {1}\n", this.ReschedulingArguments, this.tLoan);

                // check Marking loan {0} as 'PaidOff' in \ezbob\Integration\DatabaseLib\Model\Loans\Loan.cs(362)
                var calc = new LoanRepaymentScheduleCalculator(this.tLoan, DateTime.UtcNow, CurrentValues.Instance.AmountToChargeFrom);

                try {
                    if (calc.NextEarlyPayment() == 0)
                    {
                        this.Result.Error       = string.Format("Loan {0} marked as 'PaidOff'. Loan balance: {1}", this.tLoan.Id, 0m.ToString("C2", this.cultureInfo));
                        this.Result.BlockAction = true;
                        ExitStrategy("Exit_4", this.sendDebugMail);
                        return;
                    }
                    // ReSharper disable once CatchAllClause
                } catch (Exception calcEx) {
                    Log.Info("LoanRepaymentScheduleCalculator NextEarlyPayment EXCEPTION: {0}", calcEx.Message);
                }

                var lastPaidSchedule = this.tLoan.Schedule.OrderBy(s => s.Date).LastOrDefault(s => (s.Status == LoanScheduleStatus.Paid || s.Status == LoanScheduleStatus.PaidOnTime || s.Status == LoanScheduleStatus.PaidEarly));

                // if StopFutureInterest checked - add active "freeze inteval" from FirstItemDate untill NoLimitDate
                if (this.ReschedulingArguments.RescheduleIn == false && this.ReschedulingArguments.StopFutureInterest)
                {
                    //TODO : also add it to NL_InterestFreeze && deactivating.
                    LoanInterestFreeze freeze = new LoanInterestFreeze {
                        Loan             = this.tLoan,
                        StartDate        = lastPaidSchedule != null ? lastPaidSchedule.Date : this.tLoan.Date.Date, //this.Result.FirstItemDate,
                        EndDate          = this.noLimitDate,                                                        // NoLimitDate from LoanEditorController.cs - move to common area
                        InterestRate     = 0,
                        ActivationDate   = this.Result.FirstItemDate,
                        DeactivationDate = null
                    };
                    if (!this.tLoan.InterestFreeze.Contains(freeze))
                    {
                        this.tLoan.InterestFreeze.Add(freeze);
                    }

                    calc.GetState();                     // reload state with freeze consideration
                }

                decimal totalEarlyPayment = calc.TotalEarlyPayment();
                decimal P = this.Result.OpenPrincipal;
                decimal F = calc.FeesToPay;              // unpaid fees
                //decimal I = lastPaidSchedule != null ? (calc.GetInterestRate(lastPaidSchedule.Date.AddDays(1), this.Result.FirstItemDate) *P) : (calc.GetInterestRate(this.tLoan.Date.Date.AddDays(1), this.Result.FirstItemDate) * P); // unpaid interest till rescheduling start date
                decimal I = (totalEarlyPayment - P - F); // unpaid interest till first rescheduled item
                I = I < 0 ? 0 : I;                       // bugfix EZ-4236
                decimal r = ((this.ReschedulingArguments.RescheduleIn == false && this.ReschedulingArguments.StopFutureInterest)) ? 0 : this.tLoan.InterestRate;

                this.Result.ReschedulingBalance = (P + I + F);                 // not final - add to I period from rescheduling date untill new maturity date

                Log.Debug("--------------P: {0}, I: {1}, F: {2}, LoanCloseDate: {3}, totalEarlyPayment: {4}, r: {5}, ReschedulingBalance: {6}, \n lastPaidSchedule: {7}",
                          P,
                          I,
                          F,
                          this.Result.LoanCloseDate.Date,
                          totalEarlyPayment,
                          r,
                          this.Result.ReschedulingBalance,
                          lastPaidSchedule);

                // 3. intervals number

                // IN
                if (this.ReschedulingArguments.RescheduleIn)
                {
                    // add "grace" period - 14 days to maturity date
                    DateTime closeDateWithGrace = this.Result.LoanCloseDate.Date.AddDays(14);

                    this.Result.IntervalsNum = this.ReschedulingArguments.ReschedulingRepaymentIntervalType == RepaymentIntervalTypes.Month ? MiscUtils.DateDiffInMonths(this.Result.FirstItemDate, closeDateWithGrace) : MiscUtils.DateDiffInWeeks(this.Result.FirstItemDate, closeDateWithGrace);

                    // adjust intervals number +1 if needed
                    DateTime rescheduledCloseDate = this.ReschedulingArguments.ReschedulingRepaymentIntervalType == RepaymentIntervalTypes.Month ?
                                                    this.Result.FirstItemDate.AddMonths(this.Result.IntervalsNum) :
                                                    this.Result.FirstItemDate.AddDays(this.Result.IntervalsNum * 7);

                    Log.Debug("rescheduledCloseDate: {0}, Result.IntervalsNum: {1}, Result.LoanCloseDate: {2}, closeDateWithGrace: {3}", rescheduledCloseDate, this.Result.IntervalsNum, this.Result.LoanCloseDate.Date, closeDateWithGrace);

                    TimeSpan ts = closeDateWithGrace.Date.Subtract(rescheduledCloseDate.Date);

                    if (ts.Days > 0)
                    {
                        this.Result.IntervalsNum += 1;
                    }

                    Log.Debug("Adjusted intervals: rescheduledCloseDate: {0}, Result.IntervalsNum: {1}, Result.LoanCloseDate: {2}, closeDateWithGrace: {3}, dDays: {4}", rescheduledCloseDate, this.Result.IntervalsNum, this.Result.LoanCloseDate.Date, closeDateWithGrace, ts.Days);
                }

                // OUT - real intervals (k) calculation
                if (this.ReschedulingArguments.RescheduleIn == false)
                {
                    // too much payment per interval
                    if (this.ReschedulingArguments.PaymentPerInterval > this.Result.ReschedulingBalance)
                    {
                        // ReSharper disable once PossibleInvalidOperationException
                        this.message = string.Format("The entered amount accedes the outstanding balance of {0} for payment of {1}",
                                                     this.Result.ReschedulingBalance.ToString("C2", this.cultureInfo), this.ReschedulingArguments.PaymentPerInterval.Value.ToString("C2", this.cultureInfo));
                        this.Result.Error = this.message;
                        ExitStrategy("Exit_6", this.sendDebugMail);
                        return;
                    }

                    // ReSharper disable once PossibleInvalidOperationException
                    decimal m = (decimal)this.ReschedulingArguments.PaymentPerInterval;

                    // System.DivideByZeroException: Attempted to divide by zero prevent
                    decimal kDiv = (m - this.Result.ReschedulingBalance * r);
                    if (kDiv == 0)
                    {
                        kDiv = 1;
                    }

                    var k = (int)Math.Ceiling(this.Result.ReschedulingBalance / kDiv);
                    this.Result.IntervalsNum = k;

                    Log.Debug("k: {0}, P: {1}, I: {2}, F: {3}, r: {4}, oustandingBalance: {5}, m: {6}, StopFutureInterest: {7}", k, P, I, F, r, this.Result.ReschedulingBalance, m, this.ReschedulingArguments.StopFutureInterest);

                    // uncovered loan - too small payment per interval
                    if (k < 0)
                    {
                        this.Result.Error = "Chosen amount is not sufficient for covering the loan overtime, i.e. accrued interest will be always greater than the repaid amount per payment";
                        ExitStrategy("Exit_7", this.sendDebugMail);
                        return;
                    }

                    this.Result.LoanCloseDate = this.ReschedulingArguments.ReschedulingRepaymentIntervalType == RepaymentIntervalTypes.Month ? this.Result.FirstItemDate.AddMonths(k) : this.Result.FirstItemDate.AddDays(k * 7);

                    Log.Debug("new close date: {0}", this.Result.LoanCloseDate);

                    // DON'T DELETE - can be used in new calculator
                    //int n = (int)Math.Ceiling(P / (m - P * r));
                    //decimal x = 0m; = this.Result.ReschedulingBalance * r * (int)((k + 1) / 2) - P * r * (int)((n + 1) / 2);
                    //Log.Debug("n: {0}, k: {1}, P: {2}, I: {3}, F: {4}, r: {5}, oustandingBalance: {6}, m: {7}, X: {8}, closeDate: {9}, Result.IntervalsNum: {10}", n, k, P, I, F, r, this.Result.ReschedulingBalance, m, x, this.Result.LoanCloseDate, this.Result.IntervalsNum);
                }

                Log.Debug("close date: {0}, intervals: {1}", this.Result.LoanCloseDate, this.Result.IntervalsNum);

                if (this.Result.IntervalsNum == 0)
                {
                    this.Result.Error       = "Rescheduling impossible (calculated payments number 0)";
                    this.Result.BlockAction = true;
                    ExitStrategy("Exit_8", this.sendDebugMail);
                    return;
                }

                // remove unpaid (lates, stilltopays passed) and future unpaid schedule items
                foreach (var rmv in this.tLoan.Schedule.ToList <LoanScheduleItem>())
                {
                    // if loan has future items that already paid ("paid early"), re-scheduling not allowed
                    if ((rmv.Status == LoanScheduleStatus.Paid || rmv.Status == LoanScheduleStatus.PaidOnTime || rmv.Status == LoanScheduleStatus.PaidEarly) && rmv.Date > this.Result.FirstItemDate)
                    {
                        this.Result.Error = string.Format("Currently it is not possible to apply rescheduling future if payment/s relaying in the future have been already covered with early made payment, partially or entirely. " +
                                                          "You can apply rescheduling option after [last covered payment day].");
                        this.Result.BlockAction = true;
                        ExitStrategy("Exit_5", this.sendDebugMail);
                        return;
                    }
                    if (rmv.Date >= this.Result.FirstItemDate)
                    {
                        this.tLoan.Schedule.Remove(rmv);
                    }
                    if (rmv.Date <= this.Result.FirstItemDate && rmv.Status == LoanScheduleStatus.Late)
                    {
                        this.tLoan.Schedule.Remove(rmv);
                        this.tLoan.TryAddRemovedOnReschedule(new LoanScheduleDeleted().CloneScheduleItem(rmv));
                    }
                    if (rmv.Date <= this.Result.FirstItemDate && rmv.Status == LoanScheduleStatus.StillToPay)
                    {
                        this.tLoan.Schedule.Remove(rmv);
                        this.tLoan.TryAddRemovedOnReschedule(new LoanScheduleDeleted().CloneScheduleItem(rmv));
                    }
                }

                decimal balance        = P;
                decimal iPrincipal     = Decimal.Round(P / this.Result.IntervalsNum);
                decimal firstPrincipal = (P - iPrincipal * (this.Result.IntervalsNum - 1));

                //check "first iPrincipal negative" case: if first iPrincipal <= 0, remove this and reduce this.Result.IntervalsNum
                if (firstPrincipal < 0)
                {
                    Log.Debug("AAA Periods: {0}, newInstalment: {1}, close date: {2}, balance: {3}, firstItemDate: {4}, firstPrincipal: {5}, " +
                              "P: {6}, I: {7}, F: {8}, r: {9}", this.Result.IntervalsNum, iPrincipal, this.Result.LoanCloseDate, this.Result.ReschedulingBalance, this.Result.FirstItemDate, firstPrincipal, P, I, F, r);
                    this.Result.IntervalsNum -= 1;
                    firstPrincipal            = iPrincipal;
                    if ((iPrincipal * (this.Result.IntervalsNum - 1) + firstPrincipal) != balance)
                    {
                        this.Result.Error = "Failed to create new schedule.";
                        ExitStrategy("Exit_9", this.sendDebugMail);
                    }
                }

                Log.Debug("Periods: {0}, newInstalment: {1}, close date: {2}, balance: {3}, firstItemDate: {4}, firstPrincipal: {5}, " +
                          "P: {6}, I: {7}, F: {8}, r: {9}", this.Result.IntervalsNum, iPrincipal, this.Result.LoanCloseDate, this.Result.ReschedulingBalance, this.Result.FirstItemDate, firstPrincipal, P, I, F, r);

                // add new re-scheduled items, both for IN/OUT
                int position = this.tLoan.Schedule.Count;
                for (int j = 0; j < this.Result.IntervalsNum; j++)
                {
                    DateTime iStartDate     = this.ReschedulingArguments.ReschedulingRepaymentIntervalType == RepaymentIntervalTypes.Month ? this.Result.FirstItemDate.AddMonths(j) : this.Result.FirstItemDate.AddDays(7 * j);
                    decimal  iLoanRepayment = (j == 0) ? firstPrincipal : iPrincipal;
                    balance -= iLoanRepayment;

                    LoanScheduleItem item = new LoanScheduleItem()
                    {
                        Date          = iStartDate.Date,
                        InterestRate  = r,
                        Status        = LoanScheduleStatus.StillToPay,
                        Loan          = this.tLoan,
                        LoanRepayment = iLoanRepayment,
                        Balance       = balance,
                        Position      = ++position
                    };
                    this.tLoan.Schedule.Add(item);
                }

                //Log.Debug("--------------Loan modified: \n {0}", this.tLoan);

                //  after modification
                if (CheckValidateLoanState(calc) == false)
                {
                    ExitStrategy("Exit_10", this.sendDebugMail);
                    return;
                }

                Log.Debug("--------------Loan recalculated: \n {0}", this.tLoan);

                // prevent schedules with negative iPrincipal (i.e. LoanRepayment:-4.00)
                var negativeIPrincipal = this.tLoan.Schedule.FirstOrDefault(s => s.LoanRepayment < 0);
                if (negativeIPrincipal != null)
                {
                    this.Result.Error = "Negative principal in loan schedule";
                    ExitStrategy("Exit_11", this.sendDebugMail);
                    return;
                }

                // prevent "paidEarly" for newly created schedule items
                var newPaidEarly = this.tLoan.Schedule.FirstOrDefault(s => s.Date > this.ReschedulingArguments.ReschedulingDate && s.Status == LoanScheduleStatus.PaidEarly);
                if (newPaidEarly != null)
                {
                    this.Result.Error = "Wrong balance for re-scheduling calculated. Please, contact support.";
                    ExitStrategy("Exit_12", this.sendDebugMail);
                    return;
                }

                var firstRescheduledItem = this.tLoan.Schedule.FirstOrDefault(s => s.Date.Date == this.Result.FirstItemDate);
                if (firstRescheduledItem != null)
                {
                    this.Result.FirstPaymentInterest = firstRescheduledItem.Interest;
                }

                if (this.ReschedulingArguments.RescheduleIn == false)                   // OUT

                // NOT POSSIBLE WITH CURRENT CALCULATOR < DON'T DELETE
                //OffsetX(x);
                //if (CheckValidateLoanState(calc) == false)
                //	return;
                //Log.Debug("-------Loan recalculated+adjusted to X \n {0}", this.tLoan);

                // unsufficient payment per period
                {
                    LoanScheduleItem overInstalment = this.tLoan.Schedule.FirstOrDefault(s => s.AmountDue > this.ReschedulingArguments.PaymentPerInterval);
                    if (overInstalment != null)
                    {
                        // ReSharper disable once PossibleInvalidOperationException
                        this.message = string.Format("{0}ly payment of {1} not sufficient to pay the loan outstanding balance. Accrued interest: {2}, accumulated fees: {3}, first new instalment: {4}. " +
                                                     "You can choose to reduce the accumulated fees & interest by clearing them via manual payment, before setting the new payment schedule.",
                                                     this.ReschedulingArguments.ReschedulingRepaymentIntervalType,
                                                     this.ReschedulingArguments.PaymentPerInterval.Value.ToString("C2", this.cultureInfo),
                                                     overInstalment.Interest.ToString("C2", this.cultureInfo),    //I.ToString("C2", this.cultureInfo),
                                                     overInstalment.Fees.ToString("C2", this.cultureInfo),
                                                     overInstalment.AmountDue.ToString("C2", this.cultureInfo)
                                                     );
                        this.Result.Error = this.message;
                        ExitStrategy("Exit_13", this.sendDebugMail);
                        return;
                    }
                }

                if (!this.ReschedulingArguments.SaveToDB)
                {
                    ExitStrategy("Exit_14", this.sendDebugMail);
                    return;
                }

                LoanRescheduleSave();
                NL_AddLog(LogType.Info, "Strategy End", this.ReschedulingArguments, this.Result, null, null);
                // ReSharper disable once CatchAllClause
            } catch (Exception ex) {
                Log.Alert(ex, "Failed to get rescheduling data for loan {0}", this.ReschedulingArguments.LoanID);
                NL_AddLog(LogType.Error, "Strategy Faild", this.ReschedulingArguments, null, ex.ToString(), ex.StackTrace);
            }
        }
Esempio n. 9
0
        private static decimal NextPayment(Loan loan, DateTime date)
        {
            var calc = new LoanRepaymentScheduleCalculator(loan, date, 0);

            return(calc.NextEarlyPayment());
        }