using System; using System.Collections.Generic; using System.IO; using System.Linq; using Microsoft.Extensions.Options; using MongoDB.Bson; using MongoDB.Driver; using Serilog; using CRIF.ACTion.Configuration; using CRIF.ACTion.Services.Crif; using Landmark.OLA.Models.Loan; namespace Landmark.OLA.Application.DataAccess { public class BranchDataAccess : IDisposable, IBranchDataAccess { private bool disposed = false; private protected readonly CrifSettings _crifSettings; private readonly IDataClient _client; private readonly ICrifVendorClient _vendorClient; private readonly string _collectionName = "Branches"; private readonly string _branchNameCollectionName = "ServicingChannelToBranchName"; private readonly List _branchNameDataListDefaults = new List { new() { ChannelId = 0, BranchName = "Not Found" }, new() { ChannelId = 1, BranchName = "ALL" } }; public BranchDataAccess( IDataClient dataClient, IOptions crifSettings, ICrifVendorClient vendorClient) { _client = dataClient; _crifSettings = crifSettings.Value; _vendorClient = vendorClient; } private IMongoCollection GetBranchContainersCollection() { return _client.GetDatabase().GetCollection(_collectionName); } private IMongoCollection GetBranchNameContainersCollection() { return _client.GetDatabase().GetCollection(_branchNameCollectionName); } public BranchConfig GetBranchConfig() { try { var collection = GetBranchContainersCollection(); var result = collection.Find(new BsonDocument()).ToList().FirstOrDefault(); return result ?? throw new Exception("Could not find branch mapping"); } catch (MongoConnectionException ex) { Log.Error(ex.Message); throw new InvalidDataException("Could not load branch config"); } } public void CreateBranchConfig(BranchConfig branchConfig) { try { var collection = GetBranchContainersCollection(); if (collection.Find(new BsonDocument()).ToList().Count > 0) { throw new Exception("Can only insert 1 branch config"); } collection.InsertOne(branchConfig); } catch (MongoException ex) { Log.Error(ex.Message); throw new InvalidDataException("Error occured while creating branch config"); } catch (Exception e) { Log.Error(e.Message); throw new InvalidDataException("Error occured while creating branch config"); } } public void UpdateBranchConfig(BranchConfig branchConfig) { try { var collection = GetBranchContainersCollection(); ReplaceOneResult result = collection.ReplaceOne(eachLoan => eachLoan.Id == branchConfig.Id, branchConfig); 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 creating updating branch config"); } catch (Exception e) { Log.Error(e.Message); throw new InvalidDataException("Error occured while creating updating branch config"); } } public BranchNameConfig GetBranchNameConfig() { try { var collection = GetBranchNameContainersCollection(); var result = collection.Find(new BsonDocument()).ToList().FirstOrDefault(); if (result == null) { UpsertBranchNameConfig(); } else if (result != null && result.BranchNamesByChannelId.Count <= _branchNameDataListDefaults.Count) { UpsertBranchNameConfig(true); } collection = GetBranchNameContainersCollection(); result = collection.Find(new BsonDocument()).ToList().FirstOrDefault(); return result; } catch (MongoConnectionException ex) { Log.Error(ex.Message); throw new InvalidDataException("Could not load branch name config"); } } public void UpsertBranchNameConfig(bool IsUpdate = false) { try { var collection = GetBranchNameContainersCollection(); if (collection.Find(new BsonDocument()).ToList().Count > 0 && !IsUpdate) { throw new Exception("Can only insert 1 branch name config"); } SortedList configurationDetails = _vendorClient.GetBranchNameConfiguration("getChannels").GetAwaiter().GetResult(); BranchNameConfig branchNameConfig = new(); List branchNameDataList = CreateBranchNameDataList(configurationDetails); branchNameConfig.Id = (Guid.NewGuid()).ToString(); branchNameConfig.Date = DateTime.Now; branchNameConfig.BranchNamesByChannelId = branchNameDataList; if (IsUpdate) { var oldConfig = collection.Find(new BsonDocument()).ToList().FirstOrDefault(); branchNameConfig.Id = oldConfig.Id; ReplaceOneResult result = collection.ReplaceOne(eachConfig => eachConfig.Id == branchNameConfig.Id, branchNameConfig); if (result.MatchedCount == 0 || result.ModifiedCount == 0) { throw new KeyNotFoundException("Item not found"); } } else { collection.InsertOne(branchNameConfig); } } catch (MongoException ex) { Log.Error(ex.Message); throw new InvalidDataException("Error occured while creating branch names config"); } catch (Exception e) { Log.Error(e.Message); throw new InvalidDataException("Error occured while creating branch names config"); } } public void UpdateBranchNameConfig() { UpsertBranchNameConfig(true); } public List CreateBranchNameDataList(SortedList configurationDetails) { List branchNameDataList = _branchNameDataListDefaults; foreach (var branchNameData in configurationDetails) { try { branchNameDataList.Add(new BranchNameData { ChannelId = branchNameData.Key, BranchName = branchNameData.Value }); } catch (Exception ex) { Log.Error(ex.Message); } } return branchNameDataList; } #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; } public int GetDistributionChannelByZipCode(string zipCode) { var config = GetBranchConfig(); foreach (var eachBranch in config.BranchCodesByZip) { if (eachBranch.Zipcode == zipCode) { return eachBranch.ChannelId; } } return _crifSettings.ServicingChannels.DefaultServicingChannel; } #endregion } }