using System; using System.Collections.Generic; using System.IO; using Microsoft.AspNetCore.Hosting; using Microsoft.Extensions.Options; using MongoDB.Bson; using MongoDB.Driver; using Serilog; using Landmark.OLA.Application.Common.Security; using Landmark.OLA.Application.Configuration; using Landmark.OLA.Application.DataAccess; using Landmark.OLA.Application.Services.MicroApiServices; using Landmark.OLA.Models.Loan; using Landmark.OLA.Models.Loan.Enums; using LCU.Library.Internal.NotificationsModels.Models; namespace Landmark.OLA.Application.DataAccessLayer { public class LoanApplicationDataAccess : IDisposable, ILoanApplicationDataAccess { private bool disposed = false; private readonly IDataClient _client; private readonly INotificationsApiService _notificationsApiService; private readonly string _collectionName = "Applications"; private readonly NotificationsApiConfiguration _notificationsApiConfiguration; private readonly Services.Email.IEmailTemplateService _emailTemplateService; public LoanApplicationDataAccess( IDataClient dataClient, INotificationsApiService notificationsApiService, IOptions notificationsApiConfiguration, IWebHostEnvironment webHostEnvironment, Services.Email.IEmailTemplateService emailTemplateService) { _client = dataClient; _notificationsApiService = notificationsApiService; _notificationsApiConfiguration = notificationsApiConfiguration.Value; _emailTemplateService = emailTemplateService; } public LoanContainer GetContainerById(string guid) { try { var collection = GetLoanContainersCollection(); var foundItems = collection.Find(eachContainer => eachContainer.Id == guid); if (foundItems.CountDocuments() != 1) { throw new KeyNotFoundException("Item not found"); } return foundItems.First(); } catch (MongoConnectionException) { return null; } } public string GetContainerIdByLoanId(string loanId) { try { var collection = GetLoanContainersCollection(); var foundItems = collection.Find(eachContainer => eachContainer.LoanId == loanId); if (foundItems.CountDocuments() != 1) { throw new KeyNotFoundException("Item not found"); } return foundItems.First().Id; } catch (MongoConnectionException) { return null; } } public List GetAllMemberContainers(string memberId, string individualId) { try { var collection = GetLoanContainersCollection(); var foundItems = collection.Find(eachContainer => eachContainer.MemberId == memberId && eachContainer.IndividualId == individualId && eachContainer.LoanApplication != null).ToList(); foreach (var container in foundItems) { MemberIdService.RemoveMemberId(container); } return foundItems; } catch (MongoConnectionException) { return []; } } public List GetAllContainers() { try { var collection = GetLoanContainersCollection(); return collection.Find(new BsonDocument()).ToList(); } catch (MongoConnectionException) { return []; } } public List GetLoanContainers(Filter filter) { try { var collection = GetLoanContainersCollection().Find(BuildFilter(filter)).Sort(BuildSorter(filter)).Limit(filter.Count).ToList(); return collection; } catch (MongoConnectionException) { return []; } } public void CreateContainer(LoanContainer loanContainer) { try { var collection = GetLoanContainersCollection(); collection.InsertOne(loanContainer); } catch (Exception e) { Log.Error(e.Message); throw new InvalidDataException("Error occured while creating container"); } } public void UpdateContainer(LoanContainer loanContainer) { try { var collection = GetLoanContainersCollection(); ReplaceOneResult result = collection.ReplaceOne(eachLoan => eachLoan.Id == loanContainer.Id, loanContainer); if (result.MatchedCount == 0 || result.ModifiedCount == 0) { throw new KeyNotFoundException("Item not found"); } } catch (KeyNotFoundException en) { Log.Error(en.Message); throw new KeyNotFoundException(en.Message); } catch (MongoException ex) { Log.Error(ex.Message); throw new InvalidDataException("Error occured while updating container"); } catch (Exception e) { Log.Error(e.Message); throw new InvalidDataException("Error occured while updating container"); } } public void DeleteApplication(string id) { try { var collection = GetLoanContainersCollection(); var foundItems = collection.Find(eachContainer => eachContainer.Id == id); if (foundItems.CountDocuments() != 1) { throw new KeyNotFoundException("Item not found"); } LoanContainer loanContainer = foundItems.First(); loanContainer.LoanApplication = null; ReplaceOneResult result = collection.ReplaceOne(eachContainer => eachContainer.Id == loanContainer.Id, loanContainer); if (result.MatchedCount == 0 || result.ModifiedCount == 0) { throw new KeyNotFoundException("Item not found"); } } catch (KeyNotFoundException en) { Log.Error(en.Message); throw new KeyNotFoundException(en.Message); } catch (MongoException ex) { Log.Error(ex.Message); throw new InvalidDataException("Error occured while deleting application"); } catch (Exception e) { Log.Error(e.Message); throw new InvalidDataException("Error occured while deleting application"); } } public void UpdateStatus(string id, LoanStatus status) { try { var collection = GetLoanContainersCollection(); var foundItems = collection.Find(eachContainer => eachContainer.Id == id); if (foundItems.CountDocuments() != 1) { throw new KeyNotFoundException("Item not found"); } LoanContainer loanContainer = foundItems.First(); loanContainer.Status = status; ReplaceOneResult result = collection.ReplaceOne(eachContainer => eachContainer.Id == loanContainer.Id, loanContainer); if (result.MatchedCount == 0 || result.ModifiedCount == 0) { throw new KeyNotFoundException("Item not found"); } if (status == LoanStatus.Vendor_Error || status == LoanStatus.Application_Error) { var reportId = id; if ( loanContainer.LoanId != null) { reportId = loanContainer.LoanId; } var contentHtml = "There was a " + status + " in loan application: " + reportId + ".

"; var request = new EmailRequest() { Subject = "Vendor Error In Loan Application", Recipient = _notificationsApiConfiguration.ErrorRecipients, Body = _emailTemplateService.BuildBrandedBody(contentHtml) }; _notificationsApiService.SendEmailAsync(request); } } catch (KeyNotFoundException en) { Log.Error(en.Message); throw new KeyNotFoundException(en.Message); } catch (MongoException ex) { Log.Error(ex.Message); throw new InvalidDataException("Error occured while updating status"); } catch (Exception e) { Log.Error(e.Message); throw new InvalidDataException("Error occured while updating status"); } } public void UpdateError(string id, LoanError error) { try { var collection = GetLoanContainersCollection(); var foundItems = collection.Find(eachContainer => eachContainer.Id == id); if (foundItems.CountDocuments() != 1) { throw new KeyNotFoundException("Item not found"); } LoanContainer loanContainer = foundItems.First(); loanContainer.Error = error; ReplaceOneResult result = collection.ReplaceOne(eachContainer => eachContainer.Id == loanContainer.Id, loanContainer); if (result.MatchedCount == 0 || result.ModifiedCount == 0) { throw new KeyNotFoundException("Item not found"); } } catch (KeyNotFoundException en) { Log.Error(en.Message); throw new KeyNotFoundException(en.Message); } catch (MongoException ex) { Log.Error(ex.Message); throw new InvalidDataException("Error occured while updating error"); } catch (Exception e) { Log.Error(e.Message); throw new InvalidDataException("Error occured while updating error"); } } public void UpdateLoanId(string id, string loanId) { var collection = GetLoanContainersCollection(); try { var foundItems = collection.Find(eachContainer => eachContainer.Id == id); if (foundItems.CountDocuments() != 1) { throw new KeyNotFoundException("Item not found"); } LoanContainer loanContainer = foundItems.First(); loanContainer.LoanId = loanId; ReplaceOneResult result = collection.ReplaceOne(eachContainer => eachContainer.Id == loanContainer.Id, loanContainer); if (result.MatchedCount == 0 || result.ModifiedCount == 0) { throw new KeyNotFoundException("Item not found"); } } catch (KeyNotFoundException en) { Log.Error(en.Message); throw new KeyNotFoundException(en.Message); } catch (MongoException ex) { Log.Error(ex.Message); throw new InvalidDataException("Error occured while updating loan id"); } catch (Exception e) { Log.Error(e.Message); throw new InvalidDataException("Error occured while updating loan id"); } } public void DeleteContainer(string id) { var collection = GetLoanContainersCollection(); try { DeleteResult result = collection.DeleteOne(_ => _.Id == id); if (result.DeletedCount != 1) { throw new KeyNotFoundException("Item not found"); } } catch (KeyNotFoundException en) { Log.Error(en.Message); throw new KeyNotFoundException(en.Message); } catch (MongoException ex) { Log.Error(ex.Message); throw new InvalidDataException("Error occured while deleting container"); } catch (Exception e) { Log.Error(e.Message); throw new InvalidDataException("Error occured while deleting container"); } } private IMongoCollection GetLoanContainersCollection() { return _client.GetDatabase().GetCollection(_collectionName); } private static FilterDefinition BuildFilter(Filter filter) { DateTime sDate = filter.StartDate.ToUniversalTime(); DateTime eDate = filter.EndDate.ToUniversalTime(); var builder = Builders.Filter; var filterValue = builder.Gt("Date", sDate) & builder.Lt("Date", eDate); for (int i = 0; i < filter.FilterField.Length; i++) { var field = filter.FilterField[i]; if (field.NotEqual) { filterValue = filterValue & builder.Ne(field.Field, field.FilterValue); } else if (field.Equal) { filterValue = filterValue & builder.Eq(field.Field, field.FilterValue); } else if (field.GreaterThan) { filterValue = filterValue & builder.Gt(field.Field, field.FilterValue); } else if (field.LessThan) { filterValue = filterValue & builder.Lt(field.Field, field.FilterValue); } } return filterValue; } private static string BuildSorter(Filter filter) { return "{ " + filter.SortField + ": " + (filter.SortDesc ? "-1}" : "1}"); } #region IDisposable public void Dispose() { this.Dispose(true); GC.SuppressFinalize(this); } protected virtual void Dispose(bool disposing) { if (!this.disposed) { if (disposing) { } } this.disposed = true; } #endregion } }