using BuddyFinance.Integration.Models; using BuddyFinance.Integration.Models.Enums; using BuddyFinance.Integration.Models.LoanOffers; using BuddyFinance.Integration.Models.LoanRequests; using BuddyFinance.Model; using Microsoft.VisualBasic; using System; using System.Collections.Generic; using System.Configuration; using System.Data.Entity; using System.Linq; using BuddyFinance.Common.Encryption; /*Tumelo * 27 October 2017 * */ namespace BuddyFinance.Integration { public class LoanOffersIntergrator : BaseIntegrator { public GetLoanOffersResult GetLoanOffers() { var result = new GetLoanOffersResult(); try { using (var db = new BuddyFinanceDBEntities()) { var loanoffer = db.LoanOffers.Include(m => m.Profile).Where(t => !t.IsDeleted).ToList(); if (loanoffer.Count > 0) { // erro code result.ErrorCode = (int)ResponseCodes.Success; result.ErrorMessage = "Success"; result.Result = loanoffer.Select(m => new LoanOfferModel { Id = m.Id, Amount = m.Amount, Balance = m.Balance, InterestRate = m.InterestRate, Term = m.Term, TermType = new Models.TermType { Description = m.TermType.Description, Id = m.TermType.Id }, IsActive = m.IsActive, DateCreated = m.DateCreated, ExpiryDate = m.ExpiryDate, IsExpired = DateTime.Now > m.ExpiryDate, LenderId = m.LenderId, Lender = new Models.Profiles.Profile { Title = m.Profile.Title, Name = m.Profile.Name, Surname = m.Profile.Surname, ProfileNumber = m.Profile.ProfileNumber } }).ToList(); // result.Result } else if (loanoffer.Count == 0) { result.ErrorCode = (int)ResponseCodes.NotFound; result.ErrorMessage = "No Data found"; } }; } catch (Exception ex) { result.ErrorCode = (int)ResponseCodes.Exception; result.ErrorMessage = " " + ex; } return result; } public GetLoanOffersResult GetLoanOffers(int profileId) { var result = new GetLoanOffersResult(); try { using (var db = new BuddyFinanceDBEntities()) { var loanOffers = db.LoanOffers.Where(t => t.LenderId == profileId && !t.IsDeleted) .OrderByDescending(t => t.Id).ToList(); result.ErrorCode = (int)ResponseCodes.Success; result.ErrorMessage = "Success"; if (!loanOffers.Any()) { //result.ErrorCode = (int)ResponseCodes.NotFound; //result.ErrorMessage = "No Data Found"; result.Result = new List(); } else { //result.ErrorCode = (int)ResponseCodes.Success; //result.ErrorMessage = "Success"; result.Result = new List(); loanOffers.ForEach(loanOffer => { var offer = new LoanOfferModel { Id = loanOffer.Id, //Id_=loanOffer.Id.ToEncryptedString(), LenderId = loanOffer.LenderId, Lender = new Models.Profiles.Profile { Title = loanOffer.Profile.Title, Name = loanOffer.Profile.Name, Surname = loanOffer.Profile.Surname }, Amount = loanOffer.Amount, Balance = loanOffer.Balance, InterestRate = loanOffer.InterestRate, Term = loanOffer.Term, TermType = new Models.TermType { Description = loanOffer.TermType.Description, Id = loanOffer.TermType.Id }, IsActive = loanOffer.IsActive, DateCreated = loanOffer.DateCreated, ExpiryDate = loanOffer.ExpiryDate, IsExpired = DateTime.Now > loanOffer.ExpiryDate, LoanRequestOffers = loanOffer.LoanRequestOffers.ToList().ConvertAll(m => new LoanRequestOfferModel { Id = m.Id, RequestDate = m.RequestDate, LoanOfferId = m.LoanOfferId, LoanRequestId = m.LoanRequestId, Comments = m.Comments, OfferStausId = m.OfferStausId, Status = new Models.Status { Id = m.OfferStatus.Id, Description = m.OfferStatus.Description }, Amount = m.LoanRequest.Amount, Borrower = m.LoanRequest.Profile.ProfileNumber, IsActive = m.IsActive, BorrowerProfile = new Models.Profiles.Profile { ProfileNumber = m.LoanRequest.Profile.ProfileNumber, FullNames = m.LoanRequest.Profile.FullNames, HasExistingScore = db.ProfileCreditRatingScores.Any(n => n.BorrowerId == m.LoanRequest.BorrowerId) } }) }; result.Result.Add(offer); }); } } } catch (Exception ex) { result.ErrorCode = (int)ResponseCodes.Exception; result.ErrorMessage = ex.Message; } return result; } public GetLoanOfferResult GetLoanOffer(int loanOfferId) { var result = new GetLoanOfferResult(); try { using (var db = new BuddyFinanceDBEntities()) { var loanOffer = db.LoanOffers.Find(loanOfferId); //var score = db.ProfileCreditRatingScores; if (loanOffer == null) { result.ErrorCode = (int)ResponseCodes.NotFound; result.ErrorMessage = "No Data Found"; } else { result.ErrorCode = (int)ResponseCodes.Success; result.ErrorMessage = "Success"; result.Result = new LoanOfferModel { Id = loanOffer.Id, //Id_ = (int)loanOffer.Id.ToEncryptedString(), LenderId = loanOffer.LenderId, Lender = new Models.Profiles.Profile { Title = loanOffer.Profile.Title, Name = loanOffer.Profile.Name, Surname = loanOffer.Profile.Surname }, Amount = loanOffer.Amount, Balance = loanOffer.Balance, InterestRate = loanOffer.InterestRate, Term = loanOffer.Term, TermType = new Models.TermType { Description = loanOffer.TermType.Description, Id = loanOffer.TermType.Id }, IsActive = loanOffer.IsActive, DateCreated = loanOffer.DateCreated, ExpiryDate = loanOffer.ExpiryDate, IsExpired = DateTime.Now > loanOffer.ExpiryDate, LoanRequestOffers = loanOffer.LoanRequestOffers.ToList().ConvertAll(m => new LoanRequestOfferModel { Id = m.Id, RequestDate = m.RequestDate, LoanOfferId = m.LoanOfferId, LoanRequestId = m.LoanRequestId, Comments = m.Comments, OfferStausId = m.OfferStausId, LoanRequest = new Models.LoanRequests.LoanRequestModel { Term = loanOffer.Term, TermType = new Models.TermType { Description = m.LoanRequest.TermType.Description, Id = m.LoanRequest.TermType.Id }, }, Status = new Models.Status { Id = m.OfferStatus.Id, Description = m.OfferStatus.Description }, Amount = m.LoanRequest.Amount, Borrower = m.LoanRequest.Profile.ProfileNumber, IsActive = m.IsActive, BorrowerProfile = new Models.Profiles.Profile { ProfileId = m.LoanRequest.Profile.Id, ProfileNumber = m.LoanRequest.Profile.ProfileNumber, FullNames = m.LoanRequest.Profile.FullNames, //SourceOfIncome = new Models.SourceOfIncome //{ // Id = m.LoanRequest.Profile.SourceOfIncome.Id, // Description = m.LoanRequest.Profile.SourceOfIncome.Description //}, //OtherSourceOfIncome = m.LoanRequest.Profile.OtherSourceOfIncome, EmploymentDetail = new Models.EmploymentDetail { GrossMonthlyIncome = m.LoanRequest.Profile.EmploymentDetail?.GrossMonthlyIncome, EmploymentStatus = new Models.EmploymentStatus { Id = m.LoanRequest.Profile.EmploymentStatus.Id, Description = m.LoanRequest.Profile.EmploymentStatus.Description }, }, HasExistingScore = db.ProfileCreditRatingScores.Any(n => n.BorrowerId == m.LoanRequest.BorrowerId) }, //Score = new Models.Scoring.ProfileScore //{ // ScoringDate = db.ProfileCreditRatingScores.FirstOrDefault(n => n.ProfileId == loanOffer.ProfileId && n.LoanRequestOfferId == m.Id)?.ScoreDate, // DerivedScore = db.ProfileCreditRatingScores.FirstOrDefault(n => n.ProfileId == loanOffer.ProfileId && n.LoanRequestOfferId == m.Id)?.DerivedScore, // //CreditBureauRobotFlag = db.ProfileCreditRatingScores.FirstOrDefault(n => n.ProfileId == loanOffer.ProfileId && n.LoanRequestOfferId == m.Id)?.CreditBureauRobotFlag, // //DerivedRobotFlag = db.ProfileCreditRatingScores.FirstOrDefault(n => n.ProfileId == loanOffer.ProfileId && n.LoanRequestOfferId == m.Id)?.DerivedRobotFlag, // // CreditBureauScore = loanOffer.LoanRequestOffers.Where(t => t.LoanRequestId == loanOffer.LoanRequestOffers.) //} //ProfileScore = new Models.LoanRequestModel. //{ // cre //} }) }; } } } catch (Exception ex) { result.ErrorCode = (int)ResponseCodes.Exception; result.ErrorMessage = ex.Message; } return result; } public OfferLoanRequestsResult GetOfferLoanRequests(int loanOfferId) { var result = new OfferLoanRequestsResult(); try { using (var db = new BuddyFinanceDBEntities()) { var offerLoanRequest = db.LoanRequestOffers.Where(m => m.LoanOfferId == loanOfferId); var loanRequest = db.LoanRequestOffers; if (loanRequest != null) { //success result.Result = loanRequest.Select(t => new LoanRequestOfferModel { Id = t.Id, Comments = t.Comments, LoanOfferId = t.LoanOfferId, Status = new Models.Status { Id = t.OfferStatus.Id, Description = t.OfferStatus.Description }, LoanRequestId = t.LoanRequestId, RequestDate = t.RequestDate, LoanRequest = new LoanRequestModel { Term = t.LoanRequest.Term, TermType = new Models.TermType { Id = t.LoanRequest.TermType.Id, Description = t.LoanRequest.TermType.Description } } }).ToList(); } else { result.ErrorCode = (int)ResponseCodes.NotFound; result.ErrorMessage = "No loan request found."; } } } catch (Exception ex) { result.ErrorCode = (int)ResponseCodes.Exception; result.ErrorMessage = ex.Message; } return result; } public BaseResult> LoanRequestOffers(int loanRequestId) { var response = new BaseResult>(); try { using (var db = new BuddyFinanceDBEntities()) { var requestOffers = db.LoanRequestOffers.Where(m => m.LoanRequestId == loanRequestId).ToList(); response.ErrorCode = (int)ResponseCodes.Success; response.ErrorMessage = "Success"; response.Result = !requestOffers.Any() ? new List() : requestOffers.ConvertAll(m => new LoanRequestOfferModel { Id = m.Id, Comments = m.Comments, LoanOfferId = m.LoanOfferId, Status = new Models.Status { Id = m.OfferStatus.Id, Description = m.OfferStatus.Description }, LoanRequestId = m.LoanRequestId, RequestDate = m.RequestDate, Amount = m.LoanRequest.Amount, Lender = m.LoanOffer.Profile?.ProfileNumber//?.Name + " " + m.LoanOffer.Profile?.Surname, }); } } catch (Exception ex) { response.ErrorCode = (int)ResponseCodes.Failure; response.ErrorMessage = "Could not load request offers"; response.ExceptionString = GetExeptionString(ex); } return response; } public BaseResult LoanRequestOffersCount(int profileId) { var response = new BaseResult(); try { using (var db = new BuddyFinanceDBEntities()) { var requests = db.LoanRequestOffers.Where(m => m.LoanOffer.LenderId == profileId && m.OfferStatus.Id == (int)OfferStatusEnum.RequestSent).Count(); response.Result = requests; response.ErrorCode = (int)ResponseCodes.Success; response.ErrorMessage = "Successful"; }; } catch (Exception ex) { response.ErrorCode = (int)ResponseCodes.Exception; response.ErrorMessage = ex.Message; } return response; } //creates a new or update existing loan offer public SaveLoanOfferResult SaveLoanOffer(LoanOfferModel loanOfferModel) { var result = new SaveLoanOfferResult(); var transactionsInt = new TransactionsIntegrator(); try { using (var db = new BuddyFinanceDBEntities()) { var profile = db.Set().Find(loanOfferModel.LenderId); if (profile != null) { //check how much a profile has if fund available create offer based on availabiltity var loanoffer = db.LoanOffers.Find(loanOfferModel.Id) ?? new LoanOffer(); var available = profile.AvailableFunds; // if (loanOfferModel.Amount >= available) { result.ErrorCode = (int)ResponseCodes.ValidationError; result.ErrorMessage = "You don't have enough funds to create this loan offer"; } else { if (loanOfferModel.Amount <= 8000) { if (loanOfferModel.Amount <= 499) { result.ErrorCode = (int)ResponseCodes.ValidationError; result.ErrorMessage = "You cannot make a loan offer less than R500"; } else { //check if the loan offer has request. if (loanoffer.LoanRequestOffers.Count() >= 1) { result.ErrorCode = (int)ResponseCodes.Failure; result.ErrorMessage = "You can not edit a loan offer that already has a request."; } else { if (loanoffer.Id == 0 && !((available - loanOfferModel.Amount) >= 0)) { result.ErrorCode = (int)ResponseCodes.ValidationError; result.ErrorMessage = "You do not have enough funds to create this loan offer"; } else { var offerAmount = loanOfferModel.Amount; var offerInterest = loanOfferModel.InterestRate; var loanBrackects = db.LoanTermBrackets.ToList(); //var offerDuration = loanOfferModel. var success = false; // var message = ""; foreach (var m in loanBrackects) { if (offerAmount >= m.MinAmount && offerAmount <= m.MaxAmount) { if (offerInterest <= 30) { if (loanOfferModel.Term <= m.Duration) { success = true; // message = ""; if (loanoffer.Id != 0) //updating { profile.AvailableFunds += loanoffer.Amount; //Create transaction var addResult_ = transactionsInt.SaveTransaction(new Models.Transactions.Transaction { TransactionId = 0, Amount = loanoffer.Amount, Description = "Account credited. loan offer with ID:" + loanoffer.Id + " updated.", Reference = "", TransactionDate = DateTime.Now,//loanoffer.DateCreated, ProfileId = loanoffer.LenderId, TransactionStatusId = (int)TransactionStatusEnum.Success, TransactionTypeId = (int)TransactionTypeEnum.Credit, ProfileTypeId = (int)ProfileTypeEnum.Lender }); db.SaveChanges(); } loanoffer.Id = loanOfferModel.Id; loanoffer.LenderId = loanOfferModel.LenderId; loanoffer.Term = loanOfferModel.Term; //Tumelo : We can not have a loan of less than a month 05 JAn 2017 loanoffer.TermTypeId = (int)TermTypeEnum.Months; loanoffer.Amount = loanOfferModel.Amount; loanoffer.Balance = loanOfferModel.Amount; loanoffer.InterestRate = loanOfferModel.InterestRate; loanoffer.DateCreated = DateTime.Now; loanoffer.ExpiryDate = DateTime.Now.AddMonths(int.Parse(ConfigurationManager.AppSettings["LoanOfferExpiryDate"])); if (loanoffer.Id == 0) db.LoanOffers.Add(loanoffer); else { if (!loanoffer.IsActive) { db.Entry(loanoffer).State = EntityState.Modified; } else { result.ErrorCode = (int)ResponseCodes.ValidationError; result.ErrorMessage = "Loan offer can not be updated because offer is active."; return result; } } profile.AvailableFunds -= loanoffer.Amount; db.SaveChanges(); //save offer transaction // var transactionsInt = new TransactionsIntegrator(); var addResult = transactionsInt.SaveTransaction(new Models.Transactions.Transaction { //TransactionId = 0, Amount = loanoffer.Amount, Description = "Available Balance Debit for loan offer ID:" + loanoffer.Id, Reference = "", TransactionDate = DateTime.Now,//loanoffer.DateCreated, ProfileId = loanoffer.LenderId, TransactionStatusId = (int)TransactionStatusEnum.Success, TransactionTypeId = (int)TransactionTypeEnum.Debit, ProfileTypeId = (int)ProfileTypeEnum.Lender }); //addResult.ErrorCode = (int)ResponseCodes.Success; //addResult.ErrorMessage = "Successfully add transaction."; db.SaveChanges(); result.ErrorCode = (int)ResponseCodes.Success; result.ErrorMessage = "Success"; result.Result = loanoffer.Id; var mailDetails = new Dictionary { { "[names]", $"{profile.Name} {profile.Surname}" }, { "[reference]", $"{loanoffer.Id}"}, { "[amount]", $"{loanoffer.Amount}"}, { "[interest]", $"{loanoffer.InterestRate}"}, { "[date]", $"{loanoffer.DateCreated}"} }; var templateText = System.IO.File.ReadAllText(ConfigurationManager.AppSettings["TemplatesPath"] + NotificationTempate.LoanOfferCreated.ToString() + ".txt"); var emailBody = mailDetails.Aggregate(templateText, (item, n) => item.Replace(n.Key, n.Value)); var mailSent = _notifications.SendEmail(profile.EmailAddress, emailBody, "Loan Offer Created | Buddy Finance", null); } else { // message = $"Maximum duration for R can not exceed {m.Duration} months."; var loanDuration = db.LoanTermBrackets.FirstOrDefault(x => offerAmount >= x.MinAmount && offerAmount <= x.MaxAmount); result.ErrorCode = (int)ResponseCodes.Failure; result.ErrorMessage = $"Loan Offer of R{loanOfferModel.Amount} cannot exceed {loanDuration.Duration} months."; } } else { result.ErrorCode = (int)ResponseCodes.Failure; result.ErrorMessage = $"Loan Offer Interst rate cannot exceed 30%."; } } else { //var loanDuration = db.LoanTermBrackets.FirstOrDefault(x => offerAmount >= x.MinAmount && offerAmount <= x.MaxAmount); result.ErrorCode = (int)ResponseCodes.Failure; result.ErrorMessage = $"Loan Offer of R{loanOfferModel.Amount} cannot exceed {m.Duration} months."; //result.ErrorMessage = "Loan offer of R"+ loanOfferModel.Amount +" can not exceed "+ loanOfferModel.Term +" Month(s)"; } if (success == true) break; } } } } } else { result.ErrorCode = (int)ResponseCodes.ValidationError; result.ErrorMessage = "The amount chosen exceeds R 8000.00"; } } } else { result.ErrorCode = (int)ResponseCodes.ValidationError; result.ErrorMessage = "Profile could not be found"; } } } catch (Exception ex) { result.ErrorCode = (int)ResponseCodes.Exception; result.ErrorMessage = ex.Message; } return result; } //delete Loan offer if only is not located and re allocate funds to available (tbl Profile |available) public DeleteLoanOffer DeleteLoanOffer(int offerId) { var result = new DeleteLoanOffer(); try { using (var db = new BuddyFinanceDBEntities()) { var loanoffer = db.LoanOffers.Find(offerId); var profile = db.Set().Find(loanoffer.ProfileId); if (loanoffer != null) { if (loanoffer.IsActive == false) { if (loanoffer.IsDeleted == false) { loanoffer.IsDeleted = true; profile.AvailableFunds += loanoffer.Amount; // db.LoanOffers.Remove(loanoffer); db.Entry(loanoffer).State = EntityState.Modified; db.Entry(profile).State = EntityState.Modified; db.SaveChanges(); var transactionsInt = new TransactionsIntegrator(); var addResult = transactionsInt.SaveTransaction(new Models.Transactions.Transaction { TransactionId = 0, Amount = (int)loanoffer.Amount, Description = "Account Credit :Offer ID: " + loanoffer.Id + " Deleted", Reference = "", TransactionDate = DateTime.Now,//loanoffer.DateCreated, ProfileId = loanoffer.ProfileId, TransactionStatusId = (int)TransactionStatusEnum.Success, TransactionTypeId = (int)TransactionTypeEnum.Credit, ProfileTypeId = (int)ProfileTypeEnum.Lender }); db.SaveChanges(); result.ErrorCode = (int)ResponseCodes.Success; result.ErrorMessage = "Success"; var mailDetails = new Dictionary { { "[names]", $"{profile.Name} {profile.Surname}" }, { "[reference]", $"{loanoffer.Id}"}, { "[amount]", $"{loanoffer.Amount}"} }; var templateText = System.IO.File.ReadAllText(ConfigurationManager.AppSettings["TemplatesPath"] + NotificationTempate.LoanOfferDelete.ToString() + ".txt"); var emailBody = mailDetails.Aggregate(templateText, (item, m) => item.Replace(m.Key, m.Value)); _notifications.SendEmail(profile.EmailAddress, emailBody, "Loan Offer Deleted | Buddy Finance", null); } else { result.ErrorCode = (int)ResponseCodes.ValidationError; result.ErrorMessage = "You cannot delete Loan Offer that is already deleted."; } } else { result.ErrorCode = (int)ResponseCodes.ValidationError; result.ErrorMessage = "You cannot delete Loan Offer that is already allocated."; } } else { result.ErrorCode = (int)ResponseCodes.NotFound; result.ErrorMessage = "Loan offer you trying to delete does not exist."; } } } catch (Exception ex) { result.ErrorCode = (int)ResponseCodes.Exception; result.ErrorMessage = ex.Message; } return result; } // var result = new EditLoanOfferResult(); // Get loan offers by Amount public GetLoanOffersResult GetLoanOffersByAmount(GetOffersModel getOffersModel, int? currentUser = null)//, Duration duration, int profileId) { getOffersModel.ProfileId = getOffersModel.ProfileId_.ToDecryptedInt(); var result = new GetLoanOffersResult(); try { using (var db = new BuddyFinanceDBEntities()) { var profile = db.Profiles.Find(getOffersModel.ProfileId); var offers = db.LoanOffers; if (profile != null) { double.TryParse(profile.EmploymentDetail?.GrossMonthlyIncome?.ToString(), out double profileGross); var earningList = db.LoanEarningBrackets.OrderBy(x => x.MinAmount).ToList(); var termList = db.LoanTermBrackets.OrderBy(m => m.MinAmount).ToList(); Model.LoanEarningBracket earnings; Model.LoanTermBracket loanTerm; if (!earningList.Any() || !termList.Any()) { return new GetLoanOffersResult { ErrorCode = (int)ResponseCodes.NotFound, ErrorMessage = "Could not find profile earning bracket" }; } // var profileGross = 4000.00; //var earnings = db.LoanEarningBrackets.ToList().OrderBy(m => m.MaxAmount).ToList().FirstOrDefault(n => n.MaxAmount >= profileGross && n.MaxAmount <= profileGross); // db.LoanEarningBrackets.ToList().FirstOrDefault(n => n.MinAmount >= profileGross && n.MaxAmount <= profileGross); //&& n.MaxAmount <= profile.EmploymentDetail.GrossMonthlyIncome //var loanTerm = db.LoanTermBrackets.FirstOrDefault(n => n.MaxAmount >= profileGross && n.MaxAmount <= profileGross); //var earnings = db.LoanEarningBrackets.OrderBy(m => m.MaxAmount).ToList() // .FirstOrDefault(n => profileGross >= n.MinAmount && profileGross <= n.MaxAmount); // db.LoanEarningBrackets.ToList().FirstOrDefault(n => n.MinAmount >= profileGross && n.MaxAmount <= profileGross); //&& n.MaxAmount <= profile.EmploymentDetail.GrossMonthlyIncome //var earningList = db.LoanEarningBrackets.OrderBy(x => x.MinAmount).ToList(); //var earnings = earningList.Last(x => x.MinAmount >= profileGross); //var loanTerm = termList.FirstOrDefault(n => earnings.QualifyingAmount <= n.MaxAmount); //switch (profileGross) //{ //} var lowest = earningList.First(); if (profileGross < lowest.MinAmount) //Gross income not provided (EmploymentDetail.GrossMonthlyIncome is nullable) { earnings = lowest; loanTerm = termList.FirstOrDefault(m => lowest.MinAmount >= m.MinAmount); //arnings == null ? null : db.LoanTermBrackets.FirstOrDefault(n => earnings.MinAmount >= n.MinAmount && earnings.MinAmount <= n.MaxAmount); } else { earnings = earningList.Last(m => profileGross >= m.MinAmount); loanTerm = termList.Last(m => earnings.QualifyingAmount >= m.MaxAmount); } if (earnings != null) { //var loanoffers = db.LoanOffers.Where(t => t.Balance >= getOffers.Amount // && (t.Term >= getOffers.Term && t.TermTypeId == getOffers.TermType.Id) && t.IsDeleted == false).ToList(); // Order - // closest to my requested Amount // then by created date descending var loanOffers = db.LoanOffers.Where(t => t.Amount == getOffersModel.Amount && t.Balance > 499) .OrderByDescending(m => m.DateCreated).ToList(); //if (loanOffers.Any(m => m.Balance > 499)) //{ result.Earnings = new Models.LoanOffers.LoanEarningBracket { Id = earnings.Id, MaxAmount = earnings.MaxAmount, QualifyingAmount = earnings.QualifyingAmount, MinAmount = earnings.MinAmount }; result.LoanTerm = new Models.LoanOffers.LoanTermBracket { Id = loanTerm.Id, MinAmount = loanTerm.MinAmount, MaxAmount = loanTerm.MaxAmount, Duration = loanTerm.Duration }; result.Result = new List(); loanOffers.Where(m => m.Balance > 0).ToList().ForEach(t => { var offer = new LoanOfferModel { CreatedByCurrentUser = t.ProfileId == currentUser.GetValueOrDefault(), Id = t.Id, Amount = t.Amount, Balance = t.Balance, InterestRate = t.InterestRate, LenderId = t.ProfileId, Lender = new Models.Profiles.Profile { Title = t.Profile.Title, Name = t.Profile.Name, Surname = t.Profile.Surname, ProfileNumber = t.Profile.ProfileNumber, }, Term = t.Term, TermTypeId = t.TermTypeId, TermType = new Models.TermType { Description = t.TermType.Description, Id = t.TermType.Id }, DateCreated = t.DateCreated, ExpiryDate = t.ExpiryDate, IsExpired = DateTime.Now > t.ExpiryDate }; //var loanCalcResult = base.LoanCulculator(new Models.Profiles.LoanCalculatorModel //{ // Amount = getOffersModel.Amount, // Interest = offer.InterestRate, // Duration = getOffersModel.Term //}).Result; var loanCalcResult = base.LoanCulculator(new Models.Profiles.LoanCalculatorModel { Amount = offer.Amount, Interest = offer.InterestRate, Duration = offer.Term }).Result; offer.TotalPayment = loanCalcResult.TotalPayment; offer.MonthlyPayment = loanCalcResult.MonthlyPayment; offer.InitialPayment = loanCalcResult.InitialPayment; offer.InterestAmount = loanCalcResult.Interest; offer.Fees = loanCalcResult.Fees; result.Result.Add(offer); }); //.ToList(); result.ErrorCode = (int)ResponseCodes.Success; result.ErrorMessage = "Success"; //} //else //{ // result.ErrorCode = (int)ResponseCodes.NotFound; // result.ErrorMessage = "Loans Matching your search not found."; //} } else { result.ErrorCode = (int)ResponseCodes.NotFound; result.ErrorMessage = "Earning not found."; } } else { result.ErrorCode = (int)ResponseCodes.NotFound; result.ErrorMessage = "Profile not found."; } } } catch (Exception ex) { result.ErrorCode = (int)ResponseCodes.Exception; result.ErrorMessage = "" + ex; } return result; } //Accept Loan request Offer :Borrower > Lender 13 Nov 17 public AcceptLoanOfferRequest AcceptLoanOfferRequest(int loanRequestOfferId) { var result = new AcceptLoanOfferRequest(); try { using (var db = new BuddyFinanceDBEntities()) { var loanRequestOffer = db.LoanRequestOffers.Find(loanRequestOfferId); if (loanRequestOffer != null) { loanRequestOffer.OfferStausId = (int)OfferStatusEnum.RequestAccepted; loanRequestOffer.LoanOffer.IsActive = true; loanRequestOffer.IsActive = true; db.SaveChanges(); var request = loanRequestOffer.LoanRequest; var offer = loanRequestOffer.LoanOffer; if (offer.Balance >= request.Amount) { if (request.Amount <= offer.Balance) { loanRequestOffer.LoanOffer.Balance -= request.Amount; db.SaveChanges(); } var loanCalculatorResult = base.LoanCulculator(new Models.Profiles.LoanCalculatorModel { Amount = request.Amount, Duration = request.Term, Interest = offer.InterestRate }).Result; var loan = new BuddyFinance.Model.Loan { LoanAmount = request.Amount, LoanRequestId = loanRequestOffer.LoanRequestId, FirstRepaymentDate = loanCalculatorResult.FirstPaymentDate, LoanDuration = request.Term, TermTypeId = loanRequestOffer.LoanOffer.TermTypeId, BorrowerId = request.BorrowerId, LenderId = offer.LenderId, LoanOfferId = loanRequestOffer.LoanOfferId, LoanStatusId = (int)LoanStatusEnum.Pending, CreatedDate = DateTime.Now, MonthlyInstallmentAmount = loanCalculatorResult.MonthlyPayment, InitialPaymentAmount = loanCalculatorResult.InitialPayment, TotalPayment = loanCalculatorResult.TotalPayment, }; db.Loans.Add(loan); loanRequestOffer.LoanRequest.LoanRequestStatusId = (int)LoanRequestStatusEnum.Approved; loanRequestOffer.OfferStausId = (int)OfferStatusEnum.OfferAccepted; loanRequestOffer.IOU_Accepted = true; var message = "The offer is not accepted"; foreach (var offer__ in request.LoanRequestOffers.Where(m => m.Id != loanRequestOfferId).ToList()) { offer__.OfferStausId = (int)OfferStatusEnum.Reject; db.SaveChanges(); var mailDetail = new Dictionary { { "[names]", $"{offer__.LoanOffer.Profile.Name} {offer__.LoanOffer.Profile.Surname}" }, { "[id]", $"{offer__.LoanOffer.Id}"}, { "[comment]", $"{message}"} }; var templateTexts = System.IO.File.ReadAllText(ConfigurationManager.AppSettings["TemplatesPath"] + NotificationTempate.LoanOfferReject.ToString() + ".txt"); var emailBod = mailDetail.Aggregate(templateTexts, (item, m) => item.Replace(m.Key, m.Value)); _notifications.SendEmail(offer__.LoanOffer.Profile.EmailAddress, emailBod, "Loan Offer Status | Buddy Finance", null); } if (loanRequestOffer.LoanOffer.Balance > 0 && loanRequestOffer.LoanOffer.Balance < 500) { // loanRequestOffer.LoanOffer.Balance -= loanRequestOffer.LoanOffer.Balance; var balance = loanRequestOffer.LoanOffer.Balance; // loanRequestOffer.LoanOffer.Profile.AvailableFunds += balance; loanRequestOffer.LoanOffer.Balance -= loanRequestOffer.LoanOffer.Balance; //save offer transaction var transactionsInt = new TransactionsIntegrator(); var addResult = transactionsInt.SaveTransaction(new Models.Transactions.Transaction { TransactionId = 0, Amount = balance, Description = "Available balance credited for loan offer ID:" + loanRequestOffer.LoanOffer.Id, Reference = "", TransactionDate = DateTime.Now,//loanoffer.DateCreated, ProfileId = loanRequestOffer.LoanOffer.ProfileId, TransactionStatusId = (int)TransactionStatusEnum.Success, TransactionTypeId = (int)TransactionTypeEnum.Credit, ProfileTypeId = (int)ProfileTypeEnum.Lender }); db.SaveChanges(); //db.SaveChanges(); //send email + check if tx was added var mailDetailsLender = new Dictionary { { "[names]", $"{loanRequestOffer.LoanOffer.Profile.Name} {loanRequestOffer.LoanOffer.Profile.Surname}" }, { "[amount]",balance.ToString("N2") }, { "[id]", loanRequestOffer.LoanOffer.Id.ToString()} }; var templateTextlender = System.IO.File.ReadAllText(ConfigurationManager.AppSettings["TemplatesPath"] + NotificationTempate.LoanOfferRefund.ToString() + ".txt"); var emailBodylender = mailDetailsLender.Aggregate(templateTextlender, (item, m) => item.Replace(m.Key, m.Value)); _notifications.SendEmail(loanRequestOffer.LoanOffer.Profile.EmailAddress, emailBodylender, "Loan Offer Refund | Buddy Finance", null); } db.SaveChanges(); var mailDetails = new Dictionary { { "[names]", $"{request.Profile.Name} {request.Profile.Surname}" }, { "[lender]", loanRequestOffer.LoanOffer.Profile.FullNames}, { "[loanofferamount]", loanRequestOffer.LoanOffer.Amount.ToString("N2")}, { "[loanrequestamount]", loanRequestOffer.LoanRequest.Amount.ToString("N2")}, { "[loanofferrequest]", loanRequestOffer.LoanRequest.Id.ToString("N2") }, { "[borrowerprofile]", request.Profile.ProfileNumber} }; var templateName = loanRequestOffer.LoanRequest.Amount == loanRequestOffer.LoanOffer.Amount ? NotificationTempate.AcceptLoanOffer : NotificationTempate.AcceptLoanOfferB; var templateText = System.IO.File.ReadAllText(ConfigurationManager.AppSettings["TemplatesPath"] + templateName.ToString() + ".txt"); var emailBody = mailDetails.Aggregate(templateText, (item, m) => item.Replace(m.Key, m.Value)); _notifications.SendEmail(loanRequestOffer.LoanOffer.Profile.EmailAddress, emailBody, "Loan Offer Status | Buddy Finance", null); //acceptLoanRequest.Result = true; //acceptLoanRequest.ErrorCode = (int)ResponseCodes.Success; //acceptLoanRequest.ErrorMessage = "Success"; } else { loanRequestOffer.OfferStausId = (int)OfferStatusEnum.NoFunds; loanRequestOffer.LoanRequest.LoanRequestStatusId = (int)LoanRequestStatusEnum.Expired; db.SaveChanges(); //acceptLoanRequest.ErrorCode = (int)ResponseCodes.NotFound; //acceptLoanRequest.ErrorMessage = "sorry you accepted late, the offer is taken."; var mailDetails = new Dictionary { { "[names]", $"{request.Profile.Name} {request.Profile.Surname}" }, }; var templateText = System.IO.File.ReadAllText(ConfigurationManager.AppSettings["TemplatesPath"] + NotificationTempate.LateOfferAcceptancy.ToString() + ".txt"); var emailBody = mailDetails.Aggregate(templateText, (item, m) => item.Replace(m.Key, m.Value)); _notifications.SendEmail(request.Profile.EmailAddress, emailBody, "Late offer Acceptancy | Buddy Finance", null); //db.SaveChanges(); //send email + check if tx was added } //var borrower = db.Profiles.Find(requestOffer.LoanRequest.BorrowerId); //var mailDetails = new Dictionary // { // { "[names]", $"{borrower.Name} {borrower.Surname}" }, // { "[reference]", $"{requestOffer.LoanRequest.ReferenceNumber}"}, // { "[amount]", $"{requestOffer.LoanRequest.Amount}"}, // { "[lenderno]", $"{requestOffer.LoanOffer.Profile.ProfileNumber}"} // }; //var templateText = System.IO.File.ReadAllText(ConfigurationManager.AppSettings["TemplatesPath"] + NotificationTempate.LoanRequestApproved.ToString() + ".txt"); //var emailBody = mailDetails.Aggregate(templateText, (item, m) => item.Replace(m.Key, m.Value)); //_notifications.SendEmail(borrower.EmailAddress, emailBody, "Loan Request Approved | Buddy Finance", null); result.ErrorCode = (int)ResponseCodes.Success; result.ErrorMessage = "Success"; } else { result.ErrorCode = (int)ResponseCodes.NotFound; result.ErrorMessage = "Loan offer request not found."; } }; } catch (Exception ex) { result.ErrorCode = (int)ResponseCodes.Exception; result.ErrorMessage = ex.Message; } return result; } public RejectLoanOfferRequest RejectLoanOfferRequest(RejectLoanOfferModel model) { var result = new RejectLoanOfferRequest(); try { using (var db = new BuddyFinanceDBEntities()) { var offerRequest = db.LoanRequestOffers.Find(model.Id); //var profile = db.Profiles.Find(offerRequest.LoanOffer.ProfileId); if (offerRequest != null && offerRequest.OfferStausId == (int)LoanRequestStatusEnum.New) { offerRequest.OfferStausId = (int)OfferStatusEnum.Reject; offerRequest.Comments = "Lender Comment :" + model.Comments; //reason db.SaveChanges(); //NOTIFY Borrower var request = db.LoanRequests.Find(offerRequest.LoanRequestId); var offers = request.LoanRequestOffers.ToList(); //.Where(m => m.LoanRequest.Id == model.LoanRequestId).ToList(); //this is not working well Att:Mpho //if (offers.All(m => m.OfferStatus.Id == (int)OfferStatusEnum.Reject)) //{ offerRequest.LoanRequest.LoanRequestStatusId = (int)LoanRequestStatusEnum.Rejected; //} db.SaveChanges(); result.ErrorCode = (int)ResponseCodes.Success; result.ErrorMessage = "Success"; result.Result = true; var mailDetails = new Dictionary { { "[amount]", $"{offerRequest.LoanRequest.Amount}"}, { "[interest]", $"{offerRequest.LoanOffer.InterestRate}"} }; var templateText = System.IO.File.ReadAllText(ConfigurationManager.AppSettings["TemplatesPath"] + NotificationTempate.LoanOfferReject.ToString() + ".txt"); var emailBody = mailDetails.Aggregate(templateText, (item, m) => item.Replace(m.Key, m.Value)); _notifications.SendEmail(offerRequest.LoanRequest.Profile.EmailAddress, emailBody, "Loan Request Status | Buddy Finance", null); } else { result.ErrorCode = (int)ResponseCodes.NotFound; result.ErrorMessage = "Could not find offer with id " + model.Id; } } } catch (Exception ex) { result.ErrorCode = (int)ResponseCodes.Exception; result.ErrorMessage = ex.Message; } return result; } //get loan offers per month(s) : tumelo 11/12/17 public GetLoanOfferPerMonth GetLoanOfferPerMonth(int profileId) { var result = new GetLoanOfferPerMonth(); try { using (var db = new BuddyFinanceDBEntities()) { var loanoffers = db.LoanOffers.Where(t => t.LenderId == profileId); if (loanoffers != null) { //:) } else { result.ErrorCode = (int)ResponseCodes.NotFound; result.ErrorMessage = "Profile not found"; } } } catch (Exception ex) { result.ErrorCode = (int)ResponseCodes.Exception; result.ErrorMessage = ex.Message; } return result; } //get loan requests per loan offer public GetLoanRequestOffers GetLoanRequestOffers(LoanRequestModel loanRequestModel) { var result = new GetLoanRequestOffers(); try { using (var db = new BuddyFinanceDBEntities()) { // var loanrequestoffers = db.LoanRequestOffers.Where(t => t.loanRequest.Profile.Id = loanRequest.Offers); //var loanrequestoffers = db.LoanRequestOffers.Where(t => t.loanRequest.Profile.Id = loanRequest.Id); var loanRequest = db.LoanRequestOffers; if (loanRequest != null) { //success result.Result = loanRequest.Select(t => new LoanRequestOfferModel { Id = t.Id, Comments = t.Comments, LoanOfferId = t.LoanOfferId, LoanOfferStatus = new Models.LoanOfferStatus { Id = t.OfferStatus.Id, Description = t.OfferStatus.Description }, LoanRequestId = t.LoanRequestId, RequestDate = t.RequestDate //ProfileId = t.ProfileId, //Amount = t.Amount, //InterestRate = t.InterestRate, //Term = t.Term, //TermTypeId = t.TermTypeId, //TermType = new Models.TermType //{ // Description = t.TermType.Description, // Id = t.TermType.Id //}, //DateCreated = t.DateCreated, //ExpiryDate = t.ExpiryDate }).ToList(); } else { result.ErrorCode = (int)ResponseCodes.NotFound; result.ErrorMessage = "No loan request found."; } } } catch (Exception ex) { result.ErrorCode = (int)ResponseCodes.Exception; result.ErrorMessage = ex.Message; } return result; } //render loan request when it has no approved request offer public RenderLoanOffer RenderLoanOffer(int loanOfferId) { var result = new RenderLoanOffer(); try { using (var db = new BuddyFinanceDBEntities()) { var offer = db.LoanOffers.Find(loanOfferId); var offerRequests = offer.LoanRequestOffers.ToList(); var funds = offer.Profile.AvailableFunds; var transactionsInt = new TransactionsIntegrator(); if (offer.IsDeleted == false) { if (offerRequests.All(m => m.OfferStausId == (int)OfferStatusEnum.Reject)) { offer.IsDeleted = true; offer.Profile.AvailableFunds += offer.Balance; offer.Balance -= offer.Balance; var addResult = transactionsInt.SaveTransaction(new Models.Transactions.Transaction { TransactionId = 0, Amount = (int)offer.Amount, Description = "Account Credit :Offer ID: " + offer.Id + " Deleted", Reference = "Offer deleted by User", TransactionDate = DateTime.Now,//loanoffer.DateCreated, ProfileId = offer.ProfileId, TransactionStatusId = (int)TransactionStatusEnum.Success, TransactionTypeId = (int)TransactionTypeEnum.Credit, ProfileTypeId = (int)ProfileTypeEnum.Lender }); db.SaveChanges(); result.ErrorCode = (int)ResponseCodes.Success; result.ErrorMessage = "Loan offer successfully been claimed."; } else { result.ErrorCode = (int)ResponseCodes.Failure; result.ErrorMessage = "You can not delete a loan offer that has accepted loan request."; } } else { result.ErrorMessage = "Sorry you can not claim loan offer that is already claimed or deleted."; } } } catch (Exception ex) { result.ErrorCode = (int)ResponseCodes.Exception; result.ErrorMessage = ex.Message; } return result; } //Tumelo : 10 April 2018 A lender can claim their loan offer balance ,should they be a need. public ClaimLoanOfferBalance ClaimLoanOfferBalance(int loanofferId) { var result = new ClaimLoanOfferBalance(); try { using (var db = new BuddyFinanceDBEntities()) { var loanOffer = db.LoanOffers.Find(loanofferId); // When the loan is already allocated, Lender must receive an error when trying to claim balance on a loan that is activated. // just checked if there is any non-pending loan associated with this offer if (db.Loans.Any(m => m.LoanOfferId == loanofferId && m.LoanStatusId == (int)LoanStatusEnum.Active)) { result.ErrorCode = (int)ResponseCodes.ValidationError; result.ErrorMessage = "You can not claim balance if there is a Loan already allocated."; return result; } var transactionsInt = new TransactionsIntegrator(); var profile = db.Profiles.Find(loanOffer.ProfileId); if (loanofferId != 0) { var balanceAmount = loanOffer.Balance; loanOffer.Balance -= loanOffer.Balance; profile.AvailableFunds += balanceAmount; var addResult = transactionsInt.SaveTransaction(new Models.Transactions.Transaction { TransactionId = 0, Amount = (int)balanceAmount, Description = "Account Credit :Offer ID: " + loanOffer.Id + " balance claimed", Reference = "user claimed loan offer balance", TransactionDate = DateTime.Now,//loanoffer.DateCreated, ProfileId = loanOffer.ProfileId, TransactionStatusId = (int)TransactionStatusEnum.Success, TransactionTypeId = (int)TransactionTypeEnum.Credit, ProfileTypeId = (int)ProfileTypeEnum.Lender }); db.SaveChanges(); result.ErrorCode = (int)ResponseCodes.Success; result.ErrorMessage = "Loan offer balance successfully been claimed."; } else { result.ErrorCode = (int)ResponseCodes.NotFound; result.ErrorMessage = "Loan offer not found."; } }; } catch (Exception ex) { result.ErrorCode = (int)ResponseCodes.Exception; result.ErrorMessage = ex.Message; } return result; } } }