using BuddyFinance.Common.Concepts; using BuddyFinance.Common.Encryption; using BuddyFinance.Common.Helpers; using BuddyFinance.Integration.Mappers; using BuddyFinance.Integration.Models; using BuddyFinance.Integration.Models.Enums; using BuddyFinance.Integration.Models.LoanOffers; using BuddyFinance.Integration.Models.LoanRequests; using BuddyFinance.Integration.Models.Loans; using BuddyFinance.Model; using System; using System.Collections.Generic; using System.Configuration; using System.Data.Entity; using System.Linq; namespace BuddyFinance.Integration { public class LoansIntegrator : BaseIntegrator { public double AvailableFunds { get; set; } public GetLoanResult GetLoan(int id) { var result = new GetLoanResult(); try { using (var db = new BuddyFinanceDBEntities()) { var loan = db.Loans.FirstOrDefault(m => m.Id == id); if (loan == null) { result.ErrorCode = (int)ResponseCodes.NotFound; result.ErrorMessage = $"Could not find a loan with id {id}"; } else { result.ErrorCode = (int)ResponseCodes.Success; result.ErrorMessage = "Success"; result.Result = new LoanModel { Id = loan.Id, LoanAmount = loan.LoanAmount, InterestRate = loan.LoanOffer.InterestRate, FirstRepaymentDate = loan.FirstRepaymentDate, LoanDuration = loan.LoanDuration, MonthlyInstallment = loan.MonthlyInstallmentAmount, InitialPayment = loan.InitialPaymentAmount, TotalaPayment = loan.TotalPayment, CreatedDate = loan.CreatedDate, ReferenceNumber = loan.LoanRequest.ReferenceNumber, RepayCompletedDate = loan.RepayCompletedDate, LoanOffer = new LoanOfferModel { Id = loan.LoanOffer.Id, Amount = loan.LoanOffer.Amount, InterestRate = loan.LoanOffer.InterestRate, Lender = new Models.Profiles.Profile { Name = loan.LoanOffer.Profile.Name, Surname = loan.LoanOffer.Profile.Surname, ProfileNumber = loan.LoanOffer.Profile.ProfileNumber }, DateCreated = loan.LoanOffer.DateCreated, ExpiryDate = loan.LoanOffer.ExpiryDate, LenderId = loan.LoanOffer.ProfileId }, LoanRequest = new LoanRequestModel { Id = loan.LoanRequest.Id, RequestedDate = loan.LoanRequest.RequestedDate, FirstPaymentDate = loan.LoanRequest.FirstPaymentDate, Borrower = new Models.Profiles.Profile { Name = loan.LoanRequest.Profile.Name, Surname = loan.LoanRequest.Profile.Surname, ProfileNumber = loan.LoanRequest.Profile.ProfileNumber }, Amount = loan.LoanRequest.Amount, BorrowerId = loan.LoanRequest.BorrowerId }, LoanPayout = loan.LoanPayout == null ? null : new LoanPayoutModel { LoanId = loan.Id, Amount = loan.LoanPayout.PayoutAmount, PayoutDate = loan.LoanPayout.PayoutDate }, TermTypeId = loan.TermTypeId, TermType = new Models.TermType { Id = loan.TermType.Id, Description = loan.TermType.Description }, LoanStatusId = loan.LoanStatusId, Status = new Status { Description = loan.LoanStatus.Description, Id = loan.LoanStatus.Id }, Comment = loan.Comment, LoanRepayments = loan.LoanRepayments.ToList().ConvertAll(m => m.ToRepaymentModel()), LoanSchedules = loan.LoanSchedules.ToList().ConvertAll(m => m.ToScheduleModel(m.LoanRepayments.ToList())) }; if (loan.LoanPayout != null) { result.Result.LoanPayout = new LoanPayoutModel { LoanId = loan.Id, Amount = loan.LoanPayout.PayoutAmount, PayoutDate = loan.LoanPayout.PayoutDate }; } result.TotalRepayment = loan.LoanRepayments.Where(m => m.LoanRepaymentStatusId == (int)LoanRepaymentStatusEnum.Paid).Sum(m => m.PaymentAmount); result.Balance = loan.TotalPayment - result.TotalRepayment; } } } catch (Exception ex) { result.ErrorCode = (int)ResponseCodes.Exception; result.ErrorMessage = ex.Message; } return result; } public GetLoanResult GetRequestLoan(int loanRequestId) { var result = new GetLoanResult(); try { using (var db = new BuddyFinanceDBEntities()) { var loanRequest = db.LoanRequests.Find(loanRequestId); if (loanRequest != null) { //var loanRequest = loanRequestOffer.LoanRequest; var loan = db.Loans.FirstOrDefault(m => m.LoanRequestId == loanRequest.Id); if (loan != null) { result.ErrorCode = (int)ResponseCodes.Success; result.ErrorMessage = ""; result.Result = loan.MapToViewModel(); } else { result.ErrorCode = (int)ResponseCodes.NotFound; result.ErrorMessage = "Could not find loan from loan request offer"; } } } } catch (Exception ex) { result.ErrorCode = (int)ResponseCodes.Exception; result.ExceptionString = GetExeptionString(ex); result.ErrorMessage = ex.Message; } return result; } public GetLoansResult GetAllLoans() { var result = new GetLoansResult(); try { using (var db = new BuddyFinanceDBEntities()) { var loans = db.Loans.Include(m => m.LoanOffer) .Include(m => m.LoanRequest) .Include(m => m.LoanStatus) .Include(m => m.LoanRepayments.Select(n => n.LoanRepaymentStatus)) .ToList(); result.ErrorCode = (int)ResponseCodes.Success; result.ErrorMessage = "Success"; result.Result = !loans.Any() ? new List() : loans.Select(m => new LoanModel { Id = m.Id, LoanAmount = m.LoanAmount, FirstRepaymentDate = m.FirstRepaymentDate, LoanDuration = m.LoanDuration, MonthlyInstallment = m.MonthlyInstallmentAmount, InitialPayment = m.InitialPaymentAmount, TotalaPayment = m.TotalPayment, Comment = m.Comment, LoanOffer = new LoanOfferModel { Id = m.LoanOffer.Id, Amount = m.LoanOffer.Amount, InterestRate = m.LoanOffer.InterestRate, Lender = new Models.Profiles.Profile { Name = m.LoanOffer.Profile.Name, Surname = m.LoanOffer.Profile.Surname, ProfileNumber = m.LoanOffer.Profile.ProfileNumber } }, LoanRequest = new LoanRequestModel { Id = m.LoanRequest.Id, RequestedDate = m.LoanRequest.RequestedDate, FirstPaymentDate = m.LoanRequest.FirstPaymentDate, Borrower = new Models.Profiles.Profile { Name = m.LoanRequest.Profile.Name, Surname = m.LoanRequest.Profile.Surname, ProfileNumber = m.LoanRequest.Profile.ProfileNumber }, }, TermTypeId = m.TermTypeId, TermType = new Models.TermType { Id = m.TermType.Id, Description = m.TermType.Description }, LoanStatusId = m.LoanStatusId, Status = new Status { Description = m.LoanStatus.Description, Id = m.LoanStatus.Id }, LoanRepayments = m.LoanRepayments.ToList().ConvertAll(n => new LoanRepaymentModel { Id = n.Id, LoanId = n.LoanId, PaymentAmount = n.PaymentAmount, PaymentDate = n.PaymentDate, PaymentMethod = n.PaymentMethod, LoanrepaymentStatusId = n.LoanRepaymentStatusId, Status = new Status { Description = n.LoanRepaymentStatus.Description, Id = n.LoanRepaymentStatus.Id }, }) }).ToList(); } } catch (Exception ex) { result.ErrorCode = (int)ResponseCodes.Exception; result.ErrorMessage = ex.Message; } return result; } public UpdateLoanStatusResult UpdateLoanStatus(int loanId, int statusId) { try { using (var db = new BuddyFinanceDBEntities()) { var loan = db.Loans.Find(loanId); if (loan == null) { return new UpdateLoanStatusResult { ErrorCode = (int)ResponseCodes.NotFound, ErrorMessage = "Loan offer does not exists", Result = false }; } else { loan.LoanStatusId = statusId; db.Entry(loan).State = System.Data.Entity.EntityState.Modified; db.SaveChanges(); return new UpdateLoanStatusResult { ErrorCode = (int)ResponseCodes.Success, ErrorMessage = "Successful", Result = true }; } } } catch (Exception ex) { return new UpdateLoanStatusResult { ErrorCode = (int)ResponseCodes.Exception, ErrorMessage = "An error has occurred. Exception: " + ex.ToString() }; } } public GetProfileEarningBracketResult GetProfileEarningBracket(double amount, int? profileId = null) { try { using (var db = new BuddyFinanceDBEntities()) { var profile = db.Profiles.Find(profileId); if (profile != null) amount = profile.EmploymentDetail.GrossMonthlyIncome ?? 0; var bracket = db.LoanEarningBrackets.FirstOrDefault(i => amount >= i.MinAmount && amount <= i.MaxAmount); return new GetProfileEarningBracketResult { ErrorCode = (int)ResponseCodes.Success, ErrorMessage = "Successful", Result = new ProfileEarningBracket { MinAmount = bracket.MinAmount, MaxAmount = bracket.MaxAmount, QualifyingAmount = bracket.QualifyingAmount } }; } } catch (Exception ex) { return new GetProfileEarningBracketResult { ErrorCode = (int)ResponseCodes.Exception, ErrorMessage = ex.Message }; } } public GetLoansResult GetLoans(string profileNumber) { var result = new GetLoansResult((int)ResponseCodes.Success, "Success"); try { using (var db = new BuddyFinanceDBEntities()) { var loans = db.Loans.Where(p => p.Profile.ProfileNumber.Equals(profileNumber)); if (loans.Any()) { result.Result = loans.ToList().ConvertAll(m => new LoanModel { Id = m.Id, Id_ = m.Id.ToEncryptedString(), //UserId = m.UserId, LoanOfferId = m.LoanOfferId, //ProfileId = m.ProfileId, LoanAmount = m.LoanAmount, FirstRepaymentDate = m.FirstRepaymentDate, RepayCompletedDate = m.RepayCompletedDate, LoanDuration = m.LoanDuration, TermTypeId = m.TermTypeId, LoanStatusId = m.LoanStatusId, DateAccepted = m.DateAccepted, CreatedDate = m.CreatedDate, Status = new Models.Status { Description = m.LoanStatus.Description, Id = m.LoanStatus.Id }, TermType = new Models.TermType { Id = m.LoanStatus.Id, Description = m.TermType.Description }, LoanOffer = new LoanOfferModel { Id = m.LoanOffer.Id, Amount = m.LoanOffer.Amount, InterestRate = m.LoanOffer.InterestRate, Lender = new Models.Profiles.Profile { Name = m.LoanOffer.Profile.Name, Surname = m.LoanOffer.Profile.Surname, ProfileNumber = m.LoanOffer.Profile.ProfileNumber, } }, LoanPayout = m.LoanPayout == null ? null : new LoanPayoutModel { LoanId = m.Id, PayoutDate = m.LoanPayout.PayoutDate }, LoanRequest = new LoanRequestModel { Id = m.LoanRequest.Id, RequestedDate = m.LoanRequest.RequestedDate, FirstPaymentDate = m.LoanRequest.FirstPaymentDate, ReferenceNumber = m.LoanRequest.ReferenceNumber, Borrower = new Models.Profiles.Profile { Name = m.LoanRequest.Profile.Name, Surname = m.LoanRequest.Profile.Surname, }, }, }).ToList(); } else { result.ErrorCode = (int)ResponseCodes.NotFound; result.ErrorMessage = "Not found"; } } } catch (Exception ex) { result.ErrorCode = (int)ResponseCodes.Exception; result.ErrorMessage = ex.Message; } return result; } public GetLoansResult GetLoans(int profileId) { var result = new GetLoansResult((int)ResponseCodes.Success, "Success"); try { using (var db = new BuddyFinanceDBEntities()) { var loans = db.Loans.Where(p => p.BorrowerId == profileId).ToList(); //if (loans.Any()) //{ result.Result = !loans.Any() ? new List() : loans.ConvertAll(m => new LoanModel { Id = m.Id, Id_ = m.Id.ToEncryptedString(), LoanAmount = m.LoanAmount, FirstRepaymentDate = m.FirstRepaymentDate, LoanDuration = m.LoanDuration, MonthlyInstallment = m.MonthlyInstallmentAmount, InitialPayment = m.InitialPaymentAmount, TotalaPayment = m.TotalPayment, DateAccepted = m.DateAccepted, RepayCompletedDate = m.RepayCompletedDate, // LoanRepayments = m.LoanRepayments.ToList().ConvertAll(l => l.ToRepaymentModel()), LoanOffer = new LoanOfferModel { Id = m.LoanOffer.Id, Amount = m.LoanOffer.Amount, InterestRate = m.LoanOffer.InterestRate, Lender = new Models.Profiles.Profile { Name = m.LoanOffer.Profile.Name, Surname = m.LoanOffer.Profile.Surname, ProfileNumber = m.LoanOffer.Profile.ProfileNumber, } }, LoanPayout = m.LoanPayout == null ? null : new LoanPayoutModel { LoanId = m.Id, PayoutDate = m.LoanPayout.PayoutDate }, LoanRequest = new LoanRequestModel { Id = m.LoanRequest.Id, RequestedDate = m.LoanRequest.RequestedDate, FirstPaymentDate = m.LoanRequest.FirstPaymentDate, ReferenceNumber = m.LoanRequest.ReferenceNumber, Borrower = new Models.Profiles.Profile { Name = m.LoanRequest.Profile.Name, Surname = m.LoanRequest.Profile.Surname, }, }, TermTypeId = m.TermTypeId, TermType = new Models.TermType { Id = m.TermType.Id, Description = m.TermType.Description }, LoanStatusId = m.LoanStatusId, Status = new Status { Description = m.LoanStatus.Description, Id = m.LoanStatus.Id }, LoanRepayments = m.LoanRepayments.Select(n => new LoanRepaymentModel { Id = n.Id, LoanId = n.LoanId, PaymentAmount = n.PaymentAmount, PaymentDate = n.PaymentDate, PaymentMethod = n.PaymentMethod, LoanrepaymentStatusId = n.LoanRepaymentStatusId, Installment = n.Loan.MonthlyInstallmentAmount, Status = new Status { Description = n.LoanRepaymentStatus.Description, Id = n.LoanRepaymentStatus.Id }, }).ToList(), // result.Balance = m.LoanRepayments.Where(m => m.LoanRepaymentStatusId == (int)LoanRepaymentStatusEnum.Paid).Sum(m => m.PaymentAmount); }); //} //else //{ // result.ErrorCode = (int)ResponseCodes.NotFound; // result.ErrorMessage = "Not found"; // result.Result = new List(); //} } } catch (Exception ex) { result.ErrorCode = (int)ResponseCodes.Exception; result.ErrorMessage = ex.Message; } return result; } public GetLoansResult GetOfferLoans(int offerId) { var result = new GetLoansResult((int)ResponseCodes.Success, "Success"); try { using (var db = new BuddyFinanceDBEntities()) { // var loans = db.LoanOffers.Where(m => m.ProfileId == offerId).SeletMany(m => m.Loans).ToList(); var offer = db.LoanOffers.Find(offerId); if (offer != null) { result.ErrorCode = (int)ResponseCodes.Success; result.ErrorMessage = "Success"; result.Result = !offer.Loans.Any() ? new List() : offer.Loans.ToList().ConvertAll(m => new LoanModel // db.Loans.Where(m => m.LoanOfferId == offerId) { Id = m.Id, LoanAmount = m.LoanAmount, FirstRepaymentDate = m.FirstRepaymentDate, LoanDuration = m.LoanDuration, MonthlyInstallment = m.MonthlyInstallmentAmount, InitialPayment = m.InitialPaymentAmount, TotalaPayment = m.TotalPayment, LoanOffer = new LoanOfferModel { Id = m.LoanOffer.Id, Amount = m.LoanOffer.Amount, InterestRate = m.LoanOffer.InterestRate, Lender = new Models.Profiles.Profile { Name = m.LoanOffer.Profile.Name, Surname = m.LoanOffer.Profile.Surname, } }, LoanRequest = new LoanRequestModel { Id = m.LoanRequest.Id, RequestedDate = m.LoanRequest.RequestedDate, FirstPaymentDate = m.LoanRequest.FirstPaymentDate, Amount = m.LoanRequest.Amount, Borrower = new Models.Profiles.Profile { Name = m.LoanRequest.Profile.Name, Surname = m.LoanRequest.Profile.Surname, }, }, TermTypeId = m.TermTypeId, TermType = new Models.TermType { Id = m.TermType.Id, Description = m.TermType.Description }, LoanStatusId = m.LoanStatusId, Status = new Status { Description = m.LoanStatus.Description, Id = m.LoanStatus.Id }, LoanRepayments = m.LoanRepayments.ToList().ConvertAll(n => new LoanRepaymentModel { Id = n.Id, LoanId = n.LoanId, PaymentAmount = n.PaymentAmount, PaymentDate = n.PaymentDate, PaymentMethod = n.PaymentMethod, LoanrepaymentStatusId = n.LoanRepaymentStatusId, Status = new Status { Description = n.LoanRepaymentStatus.Description, Id = n.LoanRepaymentStatus.Id }, }) }).ToList(); } else { result.ErrorCode = (int)ResponseCodes.NotFound; result.ErrorMessage = "Could not find loans of the supplied offer"; } } } catch (Exception ex) { result.ErrorCode = (int)ResponseCodes.Exception; result.ErrorMessage = ex.Message; } return result; } public GetLoansOffersResults GetLoansOffersLoan(int profileId) { var result = new GetLoansOffersResults(); try { using (var db = new BuddyFinanceDBEntities()) { var loans = db.LoanOffers.Where(m => m.LenderId == profileId).SelectMany(m => m.Loans).ToList(); //var offer = db.LoanOffers.Find(offerId); result.Result = !loans.Any() ? new List() : loans.ConvertAll(m => new LoanModel // db.Loans.Where(m => m.LoanOfferId == offerId) { Id = m.Id, Id_ = m.Id.ToEncryptedString(), LoanAmount = m.LoanAmount, FirstRepaymentDate = m.FirstRepaymentDate, LoanDuration = m.LoanDuration, TermTypeId = m.TermTypeId, MonthlyInstallment = m.MonthlyInstallmentAmount, InitialPayment = m.InitialPaymentAmount, TotalaPayment = m.TotalPayment, RepayCompletedDate = m.RepayCompletedDate, LoanStatusId = m.LoanStatusId, Status = new Status { Description = m.LoanStatus.Description, Id = m.LoanStatus.Id }, TermType = new Models.TermType { Id = m.TermType.Id, Description = m.TermType.Description }, LoanRequest = new LoanRequestModel { FirstPaymentDate = m.LoanRequest.FirstPaymentDate, ReferenceNumber = m.LoanRequest.ReferenceNumber, Amount = m.LoanRequest.Amount } }); result.ErrorCode = (int)ResponseCodes.Success; result.ErrorMessage = "Success"; //else //{ // result.ErrorCode = (int)ResponseCodes.NotFound; // result.ErrorMessage = "No Loans Found for Profile " + profileId; //} } } catch (Exception ex) { result.ErrorCode = (int)ResponseCodes.Exception; result.ErrorMessage = ex.Message; } return result; } public AcceptLoanResult AcceptLoan(int loanId) { var result = new AcceptLoanResult(); try { using (var db = new BuddyFinanceDBEntities()) { var loan = db.Loans.Find(loanId); if (loan != null) { loan.LoanStatusId = (int)LoanStatusEnum.Active; loan.DateAccepted = DateTime.Now; if (loan.LoanStatusId == (int)LoanStatusEnum.Active) { db.SaveChanges(); result.ErrorCode = (int)ResponseCodes.Success; result.ErrorMessage = "Success"; result.Result = true; } else { result.ErrorCode = (int)ResponseCodes.ValidationError; result.ErrorMessage = "Loan not active."; } } else { result.ErrorCode = (int)ResponseCodes.NotFound; result.ErrorMessage = "No Loan found."; } }; } catch (Exception ex) { result.ErrorCode = (int)ResponseCodes.Exception; result.ErrorMessage = ex.Message; } return result; } public GetLoanRepaymentResult GetLoanRepayment(int repaymentId) { var result = new GetLoanRepaymentResult(); try { using (var db = new BuddyFinanceDBEntities()) { var repayment = db.LoanRepayments.Find(repaymentId); if (repayment != null) { result.ErrorCode = (int)ResponseCodes.Success; result.ErrorMessage = "Success"; result.Result = repayment.ToRepaymentModel(); } else { result.ErrorCode = (int)ResponseCodes.NotFound; result.ErrorMessage = "Loan Repayment could not be found"; } } } catch (Exception ex) { result.ErrorCode = (int)ResponseCodes.Exception; result.ErrorMessage = ex.Message; } return result; } public GetLoanRepaymentsResult GetLoanRepayments(int loanId) { var result = new GetLoanRepaymentsResult(); try { using (var db = new BuddyFinanceDBEntities()) { var repayments = db.LoanRepayments.Where(m => m.LoanId == loanId).ToList(); result.ErrorCode = (int)ResponseCodes.Success; result.ErrorMessage = "Success"; result.Result = !repayments.Any() ? new List() : repayments.ConvertAll(repayment => repayment.ToRepaymentModel()); } } catch (Exception ex) { result.ErrorCode = (int)ResponseCodes.Exception; result.ErrorMessage = ex.Message; } return result; } public BaseResult> Schedule(int loanId) { var result = new BaseResult>(); try { using (var db = new BuddyFinanceDBEntities()) { if (!db.Loans.Any(m => m.Id == loanId)) return new BaseResult>((int)ResponseCodes.NotFound, $"Loan with ID {loanId} could not be found"); var schedules = db.LoanSchedules.Where(m => m.LoanId == loanId).ToList(); result.ErrorCode = (int)ResponseCodes.Success; result.ErrorMessage = "Success"; result.Result = !schedules.Any() ? new List() : schedules.ConvertAll(schedule => schedule.ToScheduleModel(db.LoanRepayments.Where(m => m.LoanScheduleId == schedule.Id).ToList())); } } catch (Exception ex) { result.ErrorCode = (int)ResponseCodes.Exception; result.ErrorMessage = ex.Message; } return result; } public LoanRepaymentResult SaveLoanRepayment(LoanRepaymentModel model) { var result = new LoanRepaymentResult(); try { using (var db = new BuddyFinanceDBEntities()) { var loan = db.Loans.Find(model.LoanId); if (loan == null) return new LoanRepaymentResult((int)ResponseCodes.NotFound, $"Loan with ID {model.LoanId} does not exists"); //var budyFinanceProfie = db.Profiles.ToList().Find(t => t.ProfileTypeId == (int)ProfileTypeEnum.BuddyFinance); var budyFinanceProfie = db.Profiles.ToList().Find(t => t.Lender == null && t.Borrower == null); var repayment = db.LoanRepayments.Find(model.Id) ?? new LoanRepayment(); repayment.LoanId = model.LoanId; repayment.LoanScheduleId = model.LoanScheduleId; repayment.LoanRepaymentStatusId = model.LoanrepaymentStatusId; repayment.PaymentAmount = model.PaymentAmount; repayment.PaymentDate = model.PaymentDate; repayment.PaymentMethod = ""; if (repayment.Id == 0) db.LoanRepayments.Add(repayment); else db.Entry(repayment).State = EntityState.Modified; db.SaveChanges(); var schedule = db.LoanSchedules.Find(model.LoanScheduleId); if (schedule != null) { if (repayment.PaymentAmount >= schedule.Amount) schedule.StatusId = (int)LoanScheduleStatusEnum.Completed; else { if (db.LoanRepayments.Where(m => m.LoanScheduleId == schedule.Id).Sum(m => m.PaymentAmount) >= schedule.Amount) schedule.StatusId = (int)LoanScheduleStatusEnum.Completed; else schedule.StatusId = (int)LoanScheduleStatusEnum.Incomplete; } db.Entry(schedule).State = EntityState.Modified; db.SaveChanges(); } var payments = db.LoanRepayments.Where(m => m.LoanId == loan.Id).Sum(k => k.PaymentAmount); if (repayment.LoanRepaymentStatusId == (int)LoanRepaymentStatusEnum.Paid) { // owed to lender // = Montly Intallment var owedToLender = repayment.PaymentAmount; // less 40% Montly initiation fee var initiationAmount = (loan.InitialPaymentAmount * 0.4) / loan.LoanDuration; owedToLender = owedToLender - initiationAmount; // less Montly Service Fee var serviceFee = _fees[FeeTypesEnum.ServiceFee]; owedToLender = owedToLender - serviceFee.Amount; // Owed to Buddy // = month installment - owed to lender var owedToBuddy = repayment.PaymentAmount - owedToLender; //Transactions //borrower db.Transactions.Add(new Transaction { Amount = model.PaymentAmount, Description = "Account Debit. Loan Repayment - " + loan.LoanRequest.ReferenceNumber, Reference = loan.LoanRequest.ReferenceNumber, TransactionDate = DateTime.Now, ProfileId = loan.Profile.Id, ProfileTypeId = (int)ProfileTypeEnum.Borrower, TransactionStatusId = (int)TransactionStatusEnum.Success, TransactionTypeId = (int)TransactionTypeEnum.Debit, LoanId = loan.Id, LoanRepaymentId = repayment.Id }); //Lender var lender = db.Profiles.Find(loan.LoanOffer.ProfileId); db.Transactions.Add(new Transaction { Amount = owedToLender, Description = "Account Credit. Loan Repayment Capital Amount minus Buddy Finance Fees - " + loan.LoanRequest.ReferenceNumber, Reference = loan.LoanRequest.ReferenceNumber, TransactionDate = DateTime.Now, ProfileId = loan.LoanOffer.ProfileId, ProfileTypeId = (int)ProfileTypeEnum.Lender, TransactionStatusId = (int)TransactionStatusEnum.Success, TransactionTypeId = (int)TransactionTypeEnum.Credit, LoanId = loan.Id, LoanRepaymentId = repayment.Id }); lender.AvailableFunds += owedToLender; db.Entry(lender).State = EntityState.Modified; //buddy finace db.Transactions.Add(new Transaction { Amount = owedToBuddy, Description = $"Credit Buddy. Loan Repayment Fees - {loan.LoanRequest.ReferenceNumber}", Reference = loan.LoanRequest.ReferenceNumber, TransactionDate = DateTime.Now, ProfileId = budyFinanceProfie.Id, ProfileTypeId = (int)ProfileTypeEnum.BuddyFinance, TransactionStatusId = (int)TransactionStatusEnum.Success, TransactionTypeId = (int)TransactionTypeEnum.Credit, LoanId = loan.Id, LoanRepaymentId = repayment.Id }); db.SaveChanges(); var amount = Math.Round(loan.TotalPayment, 2); if (payments >= amount) { loan.LoanStatusId = (int)LoanStatusEnum.PaidUp; loan.RepayCompletedDate = DateTime.Now; db.SaveChanges(); } } var loanBalance = loan.TotalPayment - payments; result.ErrorCode = (int)ResponseCodes.Success; result.ErrorMessage = "Success"; result.Result = true; result.LoanScheduleStausId = schedule.StatusId; result.TotalPaid = Math.Round(payments, 2); result.Balance = Math.Round(loanBalance, 2); } } catch (Exception ex) { result.ErrorCode = (int)ResponseCodes.Exception; result.ErrorMessage = ex.Message; } return result; } public AllocatePayoutResult AllocatePayout(LoanPayoutModel model) { var result = new AllocatePayoutResult(); try { using (var db = new BuddyFinanceDBEntities()) { //var loanId = model.LoanId; var loan = db.Loans.Include(m => m.Borrower).Include(m => m.Lender).FirstOrDefault(m => m.Id == model.LoanId); if (loan != null) { var loanPayout = db.LoanPayouts.Where(m => m.LoanId == loan.Id); if (loanPayout.Any()) { db.LoanPayouts.RemoveRange(loanPayout); db.SaveChanges(); } var payoutTx = db.Transactions.FirstOrDefault(m => m.LoanId == loan.Id && m.Description.Equals("Loan Payout")); if (payoutTx != null) { db.Transactions.Remove(payoutTx); db.SaveChanges(); } var repaymentTx = db.Transactions.Where(m => m.LoanId == loan.Id && m.Description.Contains("Loan Repayment: ")); if (repaymentTx != null && repaymentTx.Any()) { db.Transactions.RemoveRange(repaymentTx); db.SaveChanges(); } if (loan.LoanRepayments != null || !loan.LoanRepayments.Any()) { db.LoanRepayments.RemoveRange(loan.LoanRepayments); db.SaveChanges(); } if (loan.LoanSchedules != null || !loan.LoanSchedules.Any()) { db.LoanSchedules.RemoveRange(loan.LoanSchedules); db.SaveChanges(); } //loan.FirstRepaymentDate = model.PayoutDate.AddMonths(1); loan.LoanStatusId = (int)LoanStatusEnum.Active; loan.DateAccepted = DateTime.Now; loan.LoanPayout = new LoanPayout { LoanId = loan.Id, PayoutAmount = model.Amount, PayoutDate = DateTime.Now // model.PayoutDate }; var borrower = loan.Profile; if (borrower != null) { DateTime payDate; var nextMonth = loan.LoanPayout.PayoutDate.AddMonths(1); var salaryDay = db.EmploymentDetails.Find(borrower.Id)?.SalaryDay; if (salaryDay == null || salaryDay == 0) { salaryDay = loan.LoanPayout.PayoutDate.GetNextPaymentDate().Day; payDate = loan.LoanPayout.PayoutDate.GetNextPaymentDate();//new DateTime(nextMonth.Year, nextMonth.Month, salaryDay.Value); } else { if (salaryDay < loan.LoanPayout.PayoutDate.Day) { payDate = new DateTime(nextMonth.Year, nextMonth.Month, salaryDay.Value); } else { payDate = new DateTime(loan.LoanPayout.PayoutDate.Year, loan.LoanPayout.PayoutDate.Month, salaryDay.Value); } } ////7-day rule //var salaryDate = new DateTime(loan.LoanPayout.PayoutDate.Year, loan.LoanPayout.PayoutDate.Month, salaryDay); //if ((salaryDate - loan.LoanPayout.PayoutDate).Days <= 7) //{ // var nextMonth = loan.LoanPayout.PayoutDate.AddMonths(1); // payDate = new DateTime(nextMonth.Year, nextMonth.Month, salaryDay); //} loan.FirstRepaymentDate = payDate; } loan.LoanSchedules = new List(); var payDateLessMonth = loan.FirstRepaymentDate.AddMonths(-1); for (var month = 1; month <= loan.LoanDuration; month++) { loan.LoanSchedules.Add(new LoanSchedule { Description = $"Month {month} Payment", Amount = loan.MonthlyInstallmentAmount, ExpectedPayDate = payDateLessMonth.AddMonths(month), StatusId = (int)LoanScheduleStatusEnum.Pending }); } db.Entry(loan).State = EntityState.Modified; var now = DateTime.Now; db.Transactions.Add(new Transaction { ProfileId = loan.BorrowerId.GetValueOrDefault(), ProfileTypeId = (int)ProfileTypeEnum.Borrower, Amount = loan.LoanAmount, Description = "Loan Payout", Reference = loan.LoanRequest.ReferenceNumber, TransactionDate = now, TransactionStatusId = (int)TransactionStatusEnum.Success, TransactionTypeId = (int)TransactionTypeEnum.Credit, LoanId = loan.Id }); db.Transactions.Add(new Transaction { ProfileId = Constants.BuddyFinanceProfileId, ProfileTypeId = (int)ProfileTypeEnum.BuddyFinance, Amount = loan.LoanAmount, Description = "Loan Payout", Reference = loan.LoanRequest.ReferenceNumber, TransactionDate = now, TransactionStatusId = (int)TransactionStatusEnum.Success, TransactionTypeId = (int)TransactionTypeEnum.Debit, LoanId = loan.Id }); db.SaveChanges(); var mailDetails = new Dictionary { { "[names]", $"{loan.Profile.Name} {loan.Profile.Surname}" }, { "[firstpayment]", $"{loan.FirstRepaymentDate.ToString("dd-MM-yyyy")}"}, { "[amount]", $"{loan.LoanAmount}"}, { "[interest]", $"{loan.LoanOffer.InterestRate}" }, { "[profileNumber]",loan.LoanOffer.Profile.ProfileNumber } }; var templateText = System.IO.File.ReadAllText(ConfigurationManager.AppSettings["TemplatesPath"] + NotificationTempate.LoanApproved.ToString() + ".txt"); var emailBody = mailDetails.Aggregate(templateText, (item, m) => item.Replace(m.Key, m.Value)); _notifications.SendEmail(loan.Profile.EmailAddress, emailBody, "Loan Approved | Buddy Finance", null); result.ErrorCode = (int)ResponseCodes.Success; result.ErrorMessage = "Success"; result.Result = true; result.RepaymentDate = loan.FirstRepaymentDate.ToShortDateString(); } else { result.ErrorCode = (int)ResponseCodes.NotFound; result.ErrorMessage = "Could not find loan specified."; } } } catch (Exception ex) { result.ErrorCode = (int)ResponseCodes.Exception; result.ErrorMessage = ex.Message; } return result; } public BaseResult Statement(int loanId) { var result = new BaseResult(); try { var getLoanResult = this.GetLoan(loanId); if (getLoanResult.ErrorCode != 0) { result.ErrorCode = getLoanResult.ErrorCode; result.ErrorMessage = getLoanResult.ErrorMessage; } else { using (var db = new BuddyFinanceDBEntities()) { var transactions = db.Transactions.Where(m => m.LoanId == loanId).ToList(); var statement = new LoanStatement { Loan = getLoanResult.Result, Transactions = transactions.ToListModel() }; result.Result = statement; } } } catch (Exception ex) { result.ErrorCode = (int)ResponseCodes.Exception; result.ExceptionString = GetExeptionString(ex); result.ErrorMessage = "A problem occured while generating loan statement"; } return result; } public DeactivateLoanResults DeclineLoan(int loanId, string comment) { var result = new DeactivateLoanResults(); try { using (var db = new BuddyFinanceDBEntities()) { var loan = db.Loans.FirstOrDefault(m => m.Id == loanId); if (loan != null) { loan.LoanStatusId = (int)LoanStatusEnum.Declined; loan.Comment = comment; db.SaveChanges(); var mailDetails = new Dictionary { { "[refnumber]", $"{loan.LoanRequest.ReferenceNumber}"}, { "[reason]",comment} }; var templateText = System.IO.File.ReadAllText(ConfigurationManager.AppSettings["TemplatesPath"] + NotificationTempate.LoanDeclinedBorrower.ToString() + ".txt"); var emailBody = mailDetails.Aggregate(templateText, (item, m) => item.Replace(m.Key, m.Value)); _notifications.SendEmail(loan.Profile.EmailAddress , emailBody, "Loan Declined | Buddy Finance", null); templateText = System.IO.File.ReadAllText(ConfigurationManager.AppSettings["TemplatesPath"] + NotificationTempate.LoanDeclinedLender.ToString() + ".txt"); emailBody = mailDetails.Aggregate(templateText, (item, m) => item.Replace(m.Key, m.Value)); _notifications.SendEmail(loan.LoanOffer.Profile.EmailAddress , emailBody, "Loan Declined | Buddy Finance", null); result.ErrorMessage = "Success"; result.ErrorCode = (int)ResponseCodes.Success; result.Result = true; } else { result.ErrorMessage = "Could not find Loan"; result.ErrorCode = (int)ResponseCodes.NotFound; } } } catch (Exception ex) { result.ErrorMessage = ex.Message; result.ErrorCode = (int)ResponseCodes.Exception; } return result; } public DeactivateLoanResults DeactivateLoan(int loanId, string comment) { var result = new DeactivateLoanResults(); try { using (var db = new BuddyFinanceDBEntities()) { var loan = db.Loans.FirstOrDefault(m => m.Id == loanId); if (loan != null) { if (loan.LoanStatusId == (int)LoanStatusEnum.Active) { loan.LoanStatusId = (int)LoanStatusEnum.Deactive; loan.Comment = comment; db.SaveChanges(); var mailDetails = new Dictionary { { "[names]", $"{loan.Profile.Name} {loan.Profile.Surname}" }, { "[firstpayment]", $"{loan.FirstRepaymentDate.ToString("dd-MM-yyyy")}"}, { "[amount]", $"{loan.LoanAmount}"}, { "[interest]", $"{loan.LoanOffer.InterestRate}" }, { "[profileNumber]",loan.LoanOffer.Profile.ProfileNumber}, { "[reason]",comment}, { "[refnumber]", $"{loan.LoanRequest.ReferenceNumber}"}, }; var templateText = System.IO.File.ReadAllText(ConfigurationManager.AppSettings["TemplatesPath"] + NotificationTempate.LoanDeactivated.ToString() + ".txt"); var emailBody = mailDetails.Aggregate(templateText, (item, m) => item.Replace(m.Key, m.Value)); _notifications.SendEmail(loan.Profile.EmailAddress + ";" + loan.LoanOffer.Profile.EmailAddress , emailBody, "Loan Deactivated | Buddy Finance", null); result.ErrorMessage = "Success"; result.ErrorCode = (int)ResponseCodes.Success; result.Result = true; } else { result.ErrorMessage = "Loan is not active"; result.ErrorCode = (int)ResponseCodes.NotFound; } } else { result.ErrorMessage = "Could not find Loan"; result.ErrorCode = (int)ResponseCodes.NotFound; } } } catch (Exception ex) { result.ErrorMessage = ex.Message; result.ErrorCode = (int)ResponseCodes.Exception; } return result; } } }