public ScheduleController(LoanBuilder loanBuilder, ICashRequestRepository cashRequests, ICustomerRepository customerRepository) { _loanBuilder = loanBuilder; _cashRequests = cashRequests; _aprCalc = new APRCalculator(); _customerRepository = customerRepository; }
public void calculateApr2() { var calc = new APRCalculator(); var loanSchedule = new List <LoanScheduleItem> { new LoanScheduleItem { Date = new DateTime(2012, 9, 1), InterestRate = 0.07M, LoanRepayment = 500, Interest = 210, BalanceBeforeRepayment = 3000, Balance = 2500, Fees = 0, AmountDue = 710 }, new LoanScheduleItem { Date = new DateTime(2012, 10, 1), InterestRate = 0.07M, LoanRepayment = 500, Interest = 175, BalanceBeforeRepayment = 2500, Balance = 2000, Fees = 0, AmountDue = 675 }, new LoanScheduleItem { Date = new DateTime(2012, 11, 1), InterestRate = 0.07M, LoanRepayment = 500, Interest = 140, BalanceBeforeRepayment = 2000, Balance = 1500, Fees = 0, AmountDue = 640 }, new LoanScheduleItem { Date = new DateTime(2012, 12, 1), InterestRate = 0.07M, LoanRepayment = 500, Interest = 105, BalanceBeforeRepayment = 1500, Balance = 1000, Fees = 0, AmountDue = 605 }, new LoanScheduleItem { Date = new DateTime(2013, 1, 1), InterestRate = 0.07M, LoanRepayment = 500, Interest = 70, BalanceBeforeRepayment = 1000, Balance = 500, Fees = 0, AmountDue = 570 }, new LoanScheduleItem { Date = new DateTime(2013, 2, 1), InterestRate = 0.07M, LoanRepayment = 500, Interest = 35, BalanceBeforeRepayment = 500, Balance = 0, Fees = 0, AmountDue = 535 } }; var apr = calc.Calculate(3000, loanSchedule, 30, new DateTime(2012, 8, 1)); Assert.That(apr, Is.EqualTo(132.71)); }
public void CalculateAprMonthly() { var calc = new APRCalculator(); var loanSchedule = new List <LoanScheduleItem> { new LoanScheduleItem { Date = new DateTime(2013, 6, 7), InterestRate = 0.0275M, LoanRepayment = 6667, BalanceBeforeRepayment = 40000, }, new LoanScheduleItem { Date = new DateTime(2013, 7, 7), InterestRate = 0.03M, LoanRepayment = 6667, BalanceBeforeRepayment = 33333, }, new LoanScheduleItem { Date = new DateTime(2013, 8, 7), InterestRate = 0.04M, LoanRepayment = 6667, BalanceBeforeRepayment = 26667, }, new LoanScheduleItem { Date = new DateTime(2013, 9, 7), InterestRate = 0.05M, LoanRepayment = 6667, BalanceBeforeRepayment = 20000, }, new LoanScheduleItem { Date = new DateTime(2013, 10, 7), InterestRate = 0.06M, LoanRepayment = 6667, BalanceBeforeRepayment = 13333, }, new LoanScheduleItem { Date = new DateTime(2013, 11, 7), InterestRate = 0.06M, LoanRepayment = 6667, BalanceBeforeRepayment = 6667, } }; for (int i = 0; i < loanSchedule.Count; i++) { var aprMonthRate = calc.CalculateMonthly(40000, loanSchedule, i, 0, new DateTime(2013, 5, 7)); string f = string.Format("month: {0}, APR: {1}", i + 1, aprMonthRate); Console.WriteLine("month: {0}, APR: {1}", i + 1, aprMonthRate); } //Assert.That(aprMonthRate, Is.InRange(42.1,42.2)); /* * var AprMonthRate = Math.Floor((Math.Pow((double)loanSchedule[0].InterestRate + 1, 12) - 1) * 100); * Assert.That(AprMonthRate, Is.EqualTo(42)); */ }
public void calculateAprYoung() { var calc = new APRCalculator(); var loanSchedule = new List <LoanScheduleItem> { new LoanScheduleItem { Date = new DateTime(2013, 7, 18), AmountDue = 2219 }, new LoanScheduleItem { Date = new DateTime(2013, 8, 18), AmountDue = 2169.96M }, new LoanScheduleItem { Date = new DateTime(2013, 9, 18), AmountDue = 2124.16M }, new LoanScheduleItem { Date = new DateTime(2013, 10, 18), AmountDue = 2037.85M }, new LoanScheduleItem { Date = new DateTime(2013, 11, 18), AmountDue = 1996.53M }, new LoanScheduleItem { Date = new DateTime(2013, 12, 18), AmountDue = 1955.22M }, new LoanScheduleItem { Date = new DateTime(2014, 1, 18), AmountDue = 1913.9M }, new LoanScheduleItem { Date = new DateTime(2014, 2, 18), AmountDue = 1872.58M }, new LoanScheduleItem { Date = new DateTime(2014, 3, 18), AmountDue = 1814.61M }, new LoanScheduleItem { Date = new DateTime(2014, 4, 18), AmountDue = 1777.46M }, new LoanScheduleItem { Date = new DateTime(2014, 5, 18), AmountDue = 1740.3M }, new LoanScheduleItem { Date = new DateTime(2014, 5, 18), AmountDue = 1703.15M }, }; var apr = calc.Calculate(20000, loanSchedule, 0, new DateTime(2013, 6, 18)); // Assert.That(apr, Is.EqualTo(35.55)); }
public void calculateApr3() { var calc = new APRCalculator(); var loanSchedule = new List <LoanScheduleItem> { new LoanScheduleItem { Date = new DateTime(2012, 8, 30), InterestRate = 0.05M, LoanRepayment = 2333, Interest = 700, BalanceBeforeRepayment = 14000, Balance = 11667, Fees = 0, AmountDue = 3033 }, new LoanScheduleItem { Date = new DateTime(2012, 9, 30), InterestRate = 0.05M, LoanRepayment = 2333, Interest = 583, BalanceBeforeRepayment = 11667, Balance = 9333, Fees = 0, AmountDue = 2917 }, new LoanScheduleItem { Date = new DateTime(2012, 10, 30), InterestRate = 0.05M, LoanRepayment = 2333, Interest = 467, BalanceBeforeRepayment = 9333, Balance = 7000, Fees = 0, AmountDue = 2800 }, new LoanScheduleItem { Date = new DateTime(2012, 11, 30), InterestRate = 0.05M, LoanRepayment = 2333, Interest = 350, BalanceBeforeRepayment = 7000, Balance = 4667, Fees = 0, AmountDue = 2683 }, new LoanScheduleItem { Date = new DateTime(2012, 12, 30), InterestRate = 0.05M, LoanRepayment = 2333, Interest = 233, BalanceBeforeRepayment = 4667, Balance = 2333, Fees = 0, AmountDue = 2567 }, new LoanScheduleItem { Date = new DateTime(2013, 1, 30), InterestRate = 0.05M, LoanRepayment = 2333, Interest = 117, BalanceBeforeRepayment = 2333, Balance = 0, Fees = 0, AmountDue = 2450 } }; var apr = calc.Calculate(14000, loanSchedule, 112, new DateTime(2012, 7, 30)); Assert.That(apr, Is.EqualTo(83.87)); }
public void calculateApr1() { var calc = new APRCalculator(); var loanSchedule = new List <LoanScheduleItem> { new LoanScheduleItem { Date = new DateTime(2013, 6, 7), InterestRate = 0.0275M, LoanRepayment = 6667, Interest = 1100, BalanceBeforeRepayment = 40000, Balance = 33333, AmountDue = 7767 }, new LoanScheduleItem { Date = new DateTime(2013, 7, 7), InterestRate = 0.0275M, LoanRepayment = 6667, Interest = 917, BalanceBeforeRepayment = 33333, Balance = 26667, Fees = 0, AmountDue = 7583 }, new LoanScheduleItem { Date = new DateTime(2013, 8, 7), InterestRate = 0.0275M, LoanRepayment = 6667, Interest = 733, BalanceBeforeRepayment = 26667, Balance = 20000, Fees = 0, AmountDue = 7400 }, new LoanScheduleItem { Date = new DateTime(2013, 9, 7), InterestRate = 0.0275M, LoanRepayment = 6667, Interest = 550, BalanceBeforeRepayment = 20000, Balance = 13333, Fees = 0, AmountDue = 7217 }, new LoanScheduleItem { Date = new DateTime(2013, 10, 7), InterestRate = 0.0275M, LoanRepayment = 6667, Interest = 367, BalanceBeforeRepayment = 13333, Balance = 6667, Fees = 0, AmountDue = 7033 }, new LoanScheduleItem { Date = new DateTime(2013, 11, 7), InterestRate = 0.0275M, LoanRepayment = 6667, Interest = 183, BalanceBeforeRepayment = 6667, Balance = 0, Fees = 0, AmountDue = 6850 } }; var apr = calc.Calculate(40000, loanSchedule, 0, new DateTime(2013, 5, 7)); Assert.That(apr, Is.EqualTo(38.11)); }
} // constructor /// <exception cref="Exception">PacnetSafeGuard stopped money transfer</exception> /// <exception cref="OverflowException"><paramref /> is less than <see cref="F:System.TimeSpan.MinValue" /> or greater than <see cref="F:System.TimeSpan.MaxValue" />.-or-<paramref /> is <see cref="F:System.Double.PositiveInfinity" />.-or-<paramref name="value" /> is <see cref="F:System.Double.NegativeInfinity" />. </exception> /// <exception cref="LoanDelayViolationException">Condition. </exception> public Loan CreateLoan(Customer cus, decimal loanAmount, PayPointCard card, DateTime now, Ezbob.Backend.ModelsWithDB.NewLoan.NL_Model nlModel = null) { ValidateCustomer(cus); // continue (customer's data/status, finish wizard, bank account data) ValidateAmount(loanAmount, cus); // continue (loanAmount > customer.CreditSum) ValidateOffer(cus); // check offer validity dates - in AddLoan strategy ValidateLoanDelay(cus, now, TimeSpan.FromMinutes(1)); // checks if last loan was taken a minute before "now" - ?? to prevent multiple clicking on "create loan" button? ValidateRepaymentPeriodAndInterestRate(cus); bool isFakeLoanCreate = (card == null); var cr = cus.LastCashRequest; Loan loan = this.loanBuilder.CreateLoan(cr, loanAmount, now); var transfered = loan.LoanAmount - loan.SetupFee; PacnetReturnData ret; if (PacnetSafeGuard(cus, transfered)) { if (!isFakeLoanCreate && !cus.IsAlibaba) { ret = SendMoney(cus, transfered); VerifyAvailableFunds(transfered); } else { log.Debug( "Not sending money via Pacnet. isFake: {0}, isAlibaba: {1}", isFakeLoanCreate, cus.IsAlibaba ); ret = new PacnetReturnData { Status = "Done", TrackingNumber = "fake" }; } // if } else { log.Error("PacnetSafeGuard stopped money transfer"); // ReSharper disable once ThrowingSystemException throw new Exception("PacnetSafeGuard stopped money transfer"); } // if cr.HasLoans = true; loan.Customer = cus; loan.Status = LoanStatus.Live; loan.CashRequest = cr; loan.LoanType = cr.LoanType; loan.GenerateRefNumber(cus.RefNumber, cus.Loans.Count); if (nlModel == null) { nlModel = new NL_Model(cus.Id); } nlModel.UserID = this.context.UserId; // NL fund transfer nlModel.FundTransfer = new NL_FundTransfers() { Amount = loanAmount, // logic transaction - full amount TransferTime = now, FundTransferStatusID = (int)NLFundTransferStatuses.Pending, // (int)NLPacnetTransactionStatuses.InProgress, LoanTransactionMethodID = (int)NLLoanTransactionMethods.Pacnet, PacnetTransactions = new List <NL_PacnetTransactions>() }; PacnetTransaction loanTransaction; if (!cus.IsAlibaba) { loanTransaction = new PacnetTransaction { Amount = loan.LoanAmount, Description = "Ezbob " + FormattingUtils.FormatDateToString(DateTime.Now), PostDate = now, Status = (isFakeLoanCreate) ? LoanTransactionStatus.Done : LoanTransactionStatus.InProgress, TrackingNumber = ret.TrackingNumber, PacnetStatus = ret.Status, Fees = loan.SetupFee, LoanTransactionMethod = this.tranMethodRepo.FindOrDefault("Pacnet"), }; // NL pacnet transaction nlModel.FundTransfer.PacnetTransactions.Add(new NL_PacnetTransactions() { TransactionTime = now, Amount = loanAmount, Notes = "Ezbob " + FormattingUtils.FormatDateToString(DateTime.Now) + " Status: " + ret.Status + " Err:" + ret.Error, StatusUpdatedTime = DateTime.UtcNow, TrackingNumber = ret.TrackingNumber, PacnetTransactionStatusID = (isFakeLoanCreate) ? (int)NLPacnetTransactionStatuses.Done : (int)NLPacnetTransactionStatuses.InProgress, }); } else { // alibaba loanTransaction = new PacnetTransaction { Amount = loan.LoanAmount, Description = "Ezbob " + FormattingUtils.FormatDateToString(DateTime.Now), PostDate = now, Status = LoanTransactionStatus.Done, TrackingNumber = "alibaba deal. CustomerID: " + cus.Id, // TODO save who got the money PacnetStatus = ret.Status, Fees = loan.SetupFee, LoanTransactionMethod = this.tranMethodRepo.FindOrDefault("Manual") }; log.Debug("Alibaba loan, adding manual pacnet transaction to loan schedule"); // NL: only logic transaction created in "alibaba" case; real money transfer will be done later, not transferred to customer (alibaba buyer) directly, but to seller (3rd party) nlModel.FundTransfer.LoanTransactionMethodID = (int)NLLoanTransactionMethods.Manual; } // if // This is the place where the funds transferred to customer saved to DB log.Info( "Save transferred funds to customer {0} amount {1}, isFake {2} , isAlibaba {3}", cus.Id, transfered, isFakeLoanCreate, cus.IsAlibaba ); loan.AddTransaction(loanTransaction); var aprCalc = new APRCalculator(); loan.APR = (decimal)aprCalc.Calculate(loanAmount, loan.Schedule, loan.SetupFee, now); cus.AddLoan(loan); cus.FirstLoanDate = cus.Loans.Min(x => x.Date); cus.LastLoanDate = cus.Loans.Max(x => x.Date); cus.LastLoanAmount = cus.Loans.First(x => x.Date == cus.LastLoanDate).LoanAmount; cus.AmountTaken = cus.Loans.Sum(x => x.LoanAmount); cus.CreditSum = cus.CreditSum - loanAmount; if (loan.SetupFee > 0) { cus.SetupFee = loan.SetupFee; } /** * 1. Build/ReBuild agreement model - private AgreementModel GenerateAgreementModel(Customer customer, Loan loan, DateTime now, double apr); in \App\PluginWeb\EzBob.Web\Code\AgreementsModelBuilder.cs * 2. RenderAgreements: loan.Agreements.Add * 3. RenderAgreements: SaveAgreement (file?) \backend\Strategies\Misc\Agreement.cs strategy */ // NL model - loan. Create history here for agreements processing nlModel.Loan = new NL_Loans(); nlModel.Loan.Histories.Clear(); nlModel.Loan.Histories.Add(new NL_LoanHistory() { Amount = loanAmount, EventTime = now }); // populate nlModel by agreements data also this.agreementsGenerator.RenderAgreements(loan, true, nlModel); var loanHistoryRepository = new LoanHistoryRepository(this.session); loanHistoryRepository.SaveOrUpdate(new LoanHistory(loan, now)); // This is the place where the loan is created and saved to DB log.Info( "Create loan for customer {0} cash request {1} amount {2}", cus.Id, loan.CashRequest.Id, loan.LoanAmount ); // actually this is the place where the loan saved to DB this.session.Flush(); Loan oldloan = cus.Loans.First(s => s.RefNumber.Equals(loan.RefNumber)); nlModel.Loan.OldLoanID = oldloan.Id; nlModel.Loan.Refnum = loan.RefNumber; // TODO generate another refnum with new algorithm in addloan strategy try { // copy newly created agreementtemplateID (for new templeates) //foreach (NL_LoanAgreements ag in nlModel.Loan.LastHistory().Agreements) { // if (ag.LoanAgreementTemplateID == 0) // ag.LoanAgreementTemplateID = oldloan.Agreements.FirstOrDefault(a => a.FilePath.Equals(ag.FilePath)).TemplateID; //} this.serviceClient.Instance.AddLoan(null, cus.Id, nlModel); // ReSharper disable once CatchAllClause } catch (Exception ex) { log.Debug("Failed to save new loan {0}", ex); } // try if (!isFakeLoanCreate) { this.serviceClient.Instance.CashTransferred(cus.Id, transfered, loan.RefNumber, cus.Loans.Count() == 1); } this.serviceClient.Instance.LinkLoanToInvestor(this.context.UserId, cus.Id, loan.Id); // verify see above line 45-48 // // ++++++++ // \App\PluginWeb\EzBob.Web\Code\LoanBuilder.cs , method public Loan CreateNewLoan(CashRequest cr, decimal amount, DateTime now, int term, int interestOnlyTerm = 0) // // calculate setupFee // calculate CalculateBrokerFee // var loanLegal = cr.LoanLegals.LastOrDefault(); // // --------------------- // file \Integration\PaymentServices\Calculators\LoanScheduleCalculator.cs, method // public IList<LoanScheduleItem> Calculate(decimal total, Loan loan = null, DateTime? startDate = null, int interestOnlyTerm = 0) // // calculate Schedules, but use it only for "fill in loan with total data" // GetDiscounts // loanType => GetBalances => fill in loan with total data: Interest, LoanAmount; Principal, Balance (loan.LoanAmount loan.Interest); InterestRate; startDate.Value // --------------------- // // LoanSource // brokerFee // +++++++++++++++++++++ // // line 85 // prepare pacnet transaction => add to loan => loan.arp => add loan to cutomer // agreement // save loan via new LoanHistory (139) // SF // flush this.serviceClient.Instance.SalesForceUpdateOpportunity( cus.Id, cus.Id, new ServiceClientProxy.EzServiceReference.OpportunityModel { Email = cus.Name, CloseDate = now, TookAmount = (int)loan.LoanAmount, ApprovedAmount = (int)(cus.CreditSum ?? 0) + (int)loanAmount, DealCloseType = OpportunityDealCloseReason.Won.ToString(), Origin = cus.CustomerOrigin.Name } ); this.serviceClient.Instance.SalesForceAddUpdateLeadAccount(cus.Id, cus.Name, cus.Id, false, false); //update account with new number of loans HandleSalesForceTopup(cus, now); //EZ-3908 return(loan); } // CreateLoan