using BuddyFinance.Integration.Mappers; using BuddyFinance.Integration.Mocks; using BuddyFinance.Integration.Models.Enums; using BuddyFinance.Integration.Models.Scoring; using BuddyFinance.Integration.Utils; using BuddyFinance.MEF; using BuddyFinance.MEF.Enums; using BuddyFinance.Model; using Microsoft.VisualBasic; using System; using System.Data.Entity; using System.Linq; namespace BuddyFinance.Integration { public class ScoringIntegrator : BaseIntegrator { private readonly Importer importer; public ScoringIntegrator() { importer = new Importer(); } public GetProfileScoringResult GetProfileScoring(int profileId, int loanRequestOfferId, bool useExisting = false, string token = "") { var result = new GetProfileScoringResult(); try { using (var db = new BuddyFinanceDBEntities()) { var loanRequestOffer = db.LoanRequestOffers.FirstOrDefault(m => m.Id == loanRequestOfferId); var borrower = loanRequestOffer.LoanRequest.Profile; var lender = loanRequestOffer.LoanOffer.Profile; if (useExisting) { if (db.ProfileCreditRatingScores.Any(m => m.BorrowerId == borrower.Id)) { var profileScore = db.ProfileCreditRatingScores.FirstOrDefault(m => m.BorrowerId == borrower.Id); if (profileScore.ProfileId == lender.Id) //This guy requested the score @R40 { //give to him for free } else { //charge @R5 for existing score // var borrower = db.Profiles.FirstOrDefault(m => m.Id == loanRequestOfferId); var feeTypeExisiting = _feeTypes[FeeTypesEnum.ViewExistingCreditScore]; db.Transactions.Add(new Transaction { Amount = feeTypeExisiting.Amount, Description = feeTypeExisiting.Description + " " + borrower.ProfileNumber, ProfileId = lender.Id, //Lender ProfileTypeId = (int)ProfileTypeEnum.Lender, TransactionTypeId = (int)TransactionTypeEnum.Debit, Reference = feeTypeExisiting.Description + " " + borrower.ProfileNumber, TransactionDate = DateTime.Now, TransactionStatusId = (int)TransactionStatusEnum.Success }); var lender_ = db.Profiles.FirstOrDefault(m => m.Id == lender.Id); if (lender_ != null) lender_.AvailableFunds -= feeTypeExisiting.Amount; db.Transactions.Add(new Transaction { Amount = feeTypeExisiting.Amount, Description = feeTypeExisiting.Description + " " + borrower.ProfileNumber, ProfileId = Common.Concepts.Constants.BuddyFinanceProfileId, ProfileTypeId = (int)ProfileTypeEnum.BuddyFinance, TransactionTypeId = (int)TransactionTypeEnum.Credit, Reference = feeTypeExisiting.Description + " " + borrower.ProfileNumber, TransactionDate = DateTime.Now, TransactionStatusId = (int)TransactionStatusEnum.Success }); var buddy = db.Profiles.Find(Common.Concepts.Constants.BuddyFinanceProfileId); if (buddy != null) buddy.AvailableFunds += feeTypeExisiting.Amount; db.SaveChanges(); } result.ErrorCode = (int)ResponseCodes.Success; result.ErrorMessage = "Success"; result.Result = profileScore.MapFromModel(); } } else { var feeType = _feeTypes[FeeTypesEnum.CreditScoringFee]; if (lender == null || borrower == null) return new GetProfileScoringResult { ErrorCode = (int)ResponseCodes.NotFound, ErrorMessage = "Profile or Offer Request not found." }; var bureau = importer._components.FirstOrDefault(i => i.Value.CreditBureau == MEF.Enums.CreditBureauEnum.TransUnion); var response = bureau.Value.GetCustomerCreditProfile(new MEF.Concepts.GetCustomerCreditProfileRequest { IdentityNumber = borrower.IdentificationNumber }); var tu_robot = db.RobotScores.FirstOrDefault(i => response.CreditScore >= i.MinScore && response.CreditScore <= i.MaxScore); //var creditRating = db.RobotScores.Where(i => scoreongCreditScore >= i.MinScore && transunionReport.CreditScore <= i.MaxScore); var offer = db.LoanRequestOffers.FirstOrDefault(m => m.Id == loanRequestOfferId); var derivedScore = GetDerivedScore(response, borrower, offer); RobotScore derivedScoreRobot = null; var dbScores = db.RobotScores.OrderBy(m => m.MaxScore).ToList(); //Highest to lowest if (derivedScore <= 0) derivedScoreRobot = dbScores.First(); else { foreach (var x in dbScores) { if (derivedScore <= x.MaxScore) { derivedScoreRobot = x; break; } } var ProfileScore = db.ProfileCreditRatingScores.FirstOrDefault(m => m.ProfileId == lender.Id && m.BorrowerId == borrower.Id)//* && m.LoanRequestOfferId == offerId*/) ?? new ProfileCreditRatingScore { ProfileId = lender.Id, BorrowerId = borrower.Id }; ProfileScore.CreditBureauScore = response.CreditScore; ProfileScore.CreditBureauRobotScoreId = tu_robot.Id; ProfileScore.DerivedScore = derivedScore; ProfileScore.DerivedRobotScoreId = derivedScoreRobot.Id; ProfileScore.Firstname = response.BasicCustomerInformation?.FirstName; ProfileScore.Lastname = response.BasicCustomerInformation?.LastName; if (ProfileScore.Id == 0) { ProfileScore.ScoreDate = DateTime.Now; db.ProfileCreditRatingScores.Add(ProfileScore); } else db.Entry(ProfileScore).State = EntityState.Modified; var buddy = db.Profiles.Find(Common.Concepts.Constants.BuddyFinanceProfileId); //if (buddy != null) // buddy.AvailableFunds += feeType.Amount; db.SaveChanges(); if (feeType != null) { db.Transactions.Add(new Transaction { Amount = feeType.Amount, Description = feeType.Description + " " + borrower.ProfileNumber, ProfileId = lender.Id, ProfileTypeId = (int)ProfileTypeEnum.Lender, TransactionTypeId = (int)TransactionTypeEnum.Debit, Reference = feeType.Description + " " + borrower.ProfileNumber, TransactionDate = DateTime.Now, TransactionStatusId = (int)TransactionStatusEnum.Success }); lender.AvailableFunds -= feeType.Amount; db.Transactions.Add(new Transaction { Amount = feeType.Amount, Description = feeType.Description + " " + borrower.ProfileNumber, ProfileId = Common.Concepts.Constants.BuddyFinanceProfileId, ProfileTypeId = (int)ProfileTypeEnum.BuddyFinance, TransactionTypeId = (int)TransactionTypeEnum.Credit, Reference = feeType.Description + " " + borrower.ProfileNumber, TransactionDate = DateTime.Now, TransactionStatusId = (int)TransactionStatusEnum.Success }); if (buddy != null) buddy.AvailableFunds += feeType.Amount; db.SaveChanges(); } result.ErrorCode = (int)ResponseCodes.Success; result.ErrorMessage = "Successful"; result.Result = ProfileScore.MapFromModel(); } } } } catch (Exception ex) { result.ErrorCode = (int)ResponseCodes.Exception; result.ErrorMessage = "Process could not be completed"; result.ExceptionString = GetExeptionString(ex); } return result; } public int GetDerivedScore(MEF.Concepts.GetCustomerCreditProfileResult bureauReport, Profile profile, LoanRequestOffer offer) { var accounts = bureauReport.Accounts?.Where(i => i.Status == AccountStatusEnum.Active).Sum(i => i.Amount) ?? 0; //var disposable = (profile.GrossIncome - accounts) / base.GlobalSetup.ExpenseFactor; var gross = profile.EmploymentDetail?.GrossMonthlyIncome ?? 0; var disposable = (decimal)(gross - accounts) * (1 - base.GlobalSetup.ExpenseFactor); var term = offer.LoanRequest.TermTypeId == (int)TermTypeEnum.Days ? 1 : offer.LoanRequest.Term; var serviceFee = _fees[FeeTypesEnum.ServiceFee]; var repayment = Financial.Pmt(offer.LoanOffer.InterestRateInPercent / GlobalSetup.InterestType, term, -offer.LoanRequest.Amount) + serviceFee.Amount; var ratio = disposable / (decimal)repayment; var score = (int)(bureauReport.CreditScore * ratio); return score > 950 ? 950 : score; } } }