Files
2026-04-20 14:47:24 -05:00

592 lines
23 KiB
C#

using System;
using System.Collections.Generic;
using System.Threading.Tasks;
using LCU.Shared.Collections.RepoApiLib.Models.Settings;
using LCU.Shared.Collections.RepoApiLib.Repositories.Settings;
using LCU.Shared.Collections.RepoApiLib.Repositories;
using Serilog;
using LCU.API.Collections.RepoApi.Exceptions;
using System.Data.SqlClient;
using System.Linq;
using LCU.API.Collections.CollectionsApiLib.Models;
using Microsoft.Extensions.Caching.Memory;
using LCU.API.Collections.RepoApi.Configuration;
using LCU.API.Collections.RepoApi.DataAccess;
using LCU.Shared.Collections.RepoApiLib.Models;
namespace LCU.API.Collections.RepoApi.Services
{
public class SettingsService : ISettingsService
{
private readonly IAccountTypeRepository _accountTypeRepository;
private readonly IAllowedStatusChangeRepository _allowedStatusChangeRepository;
private readonly IBodyStyleRepository _bodyStyleRepository;
private readonly ICleaningLevelRepository _cleaningLevelRepository;
private readonly ICollateralTypeRepository _collateralTypeRepository;
private readonly ICollateralTypeToVehicleTypeRepository _collateralTypeToVehicleTypeRepository;
private readonly IHoldStatusRepository _holdStatusRepository;
private readonly ILoanCategoryRepository _loanCategoryRepository;
private readonly ILocationTypeRepository _locationTypeRepository;
private readonly IVehicleTypeRepository _vehicleTypeRepository;
private readonly IExternalUserRepository _externalUserRepository;
private readonly IRepoCompanyRepository _repoCompanyRepository;
private readonly IUnitOfWork _unitOfWork;
private readonly IMemoryCache _memoryCache;
private readonly ICollectionsDao _collectionsDao;
private readonly RepoApiConfiguration _config;
public SettingsService(
IAccountTypeRepository accountTypeCodesRepository,
IAllowedStatusChangeRepository allowedStatusChangesRepository,
IBodyStyleRepository bodyStyleCodesRepository,
ICleaningLevelRepository cleaningLevelCodesRepository,
ICollateralTypeRepository collateralTypesRepository,
ICollateralTypeToVehicleTypeRepository collateralTypesToVehicleTypesRepository,
IHoldStatusRepository holdStatusCodesRepository,
ILoanCategoryRepository loanCategoriesRepository,
ILocationTypeRepository locationTypeCodesRepository,
IVehicleTypeRepository vehicleTypeCodesRepository,
IExternalUserRepository externalUserRepository,
IRepoCompanyRepository repoCompanyRepository,
IUnitOfWork unitOfWork, IMemoryCache memoryCache,
ICollectionsDao collectionsDao,
RepoApiConfiguration configuration)
{
_accountTypeRepository = accountTypeCodesRepository;
_allowedStatusChangeRepository = allowedStatusChangesRepository;
_bodyStyleRepository = bodyStyleCodesRepository;
_cleaningLevelRepository = cleaningLevelCodesRepository;
_collateralTypeRepository = collateralTypesRepository;
_collateralTypeToVehicleTypeRepository = collateralTypesToVehicleTypesRepository;
_holdStatusRepository = holdStatusCodesRepository;
_loanCategoryRepository = loanCategoriesRepository;
_locationTypeRepository = locationTypeCodesRepository;
_vehicleTypeRepository = vehicleTypeCodesRepository;
_externalUserRepository = externalUserRepository;
_repoCompanyRepository = repoCompanyRepository;
_unitOfWork = unitOfWork;
_memoryCache = memoryCache;
_collectionsDao = collectionsDao;
_config = configuration;
}
public async Task<Settings> GetCachedRepoSettingsAsync()
{
return await _memoryCache.GetOrCreateAsync<Settings>("repoSettings", factory: (ICacheEntry entry) =>
{
entry.AbsoluteExpiration = DateTime.Now.AddSeconds(_config.SettingsCacheExpirationSeconds);
return ListAllSettingsAsync();
});
}
public async Task<Settings> ListAllSettingsAsync()
{
try
{
var result = new Settings
{
AccountTypes = await _accountTypeRepository.ListAllAsync(),
AllowedStatusChanges = await _allowedStatusChangeRepository.ListAllAsync(),
BodyStyles = await _bodyStyleRepository.ListAllAsync(),
CleaningLevels = await _cleaningLevelRepository.ListAllAsync(),
CollateralTypes = await _collateralTypeRepository.ListAllAsync(),
CollateralTypesToVehicleTypes = await _collateralTypeToVehicleTypeRepository.ListAllAsync(),
HoldStatuses = await _holdStatusRepository.ListAllAsync(),
LoanCategories = await _loanCategoryRepository.ListAllAsync(),
LocationTypes = await _locationTypeRepository.ListAllAsync(),
VehicleTypes = await _vehicleTypeRepository.ListAllAsync(),
BranchSet = await _collectionsDao.RetrieveBranchSetAsync(),
ExternalUsers = await _externalUserRepository.ListAsync(),
RepoCompanies = await _repoCompanyRepository.ListAsync() as IReadOnlyCollection<RepoCompany>,
TransactionTypeCodes = _config.TransactionTypeCodes,
TransactionTypeCodeQueryPrefix = _config.TransactionTypeCodeQueryPrefix,
// Convert DateTime format to uppercase for React/Moment JS ToString use
TransactionHistoryParameterDateFormat = _config.TransactionHistoryParameterDateFormat.ToUpper(),
TransactionHistoryStartDateOffset = _config.TransactionHistoryStartDateOffset,
RepoTypeMap = GetRepoTypes()
};
return result;
}
catch (Exception ex)
{
Log.Error(ex, "Failure retrieving Settings.");
throw new ServerErrorException();
}
}
public async Task<AccountType> SaveAsync(AccountType accountType)
{
try
{
await _accountTypeRepository.AddAsync(accountType);
await _unitOfWork.CompleteAsync();
return accountType;
}
catch (Exception ex)
{
Log.Error(ex, $"Failure saving Account Type: {accountType}", accountType);
throw new ServerErrorException();
}
}
public async Task<AllowedStatusChange> SaveAsync(AllowedStatusChange statusChange)
{
try
{
await _allowedStatusChangeRepository.AddAsync(statusChange);
await _unitOfWork.CompleteAsync();
return statusChange;
}
catch (Exception ex)
{
Log.Error(ex, $"Failure saving Allowed Status Change: {statusChange}", statusChange);
throw new ServerErrorException();
}
}
public async Task<BodyStyle> SaveAsync(BodyStyle bodyStyle)
{
try
{
await _bodyStyleRepository.AddAsync(bodyStyle);
await _unitOfWork.CompleteAsync();
return bodyStyle;
}
catch (Exception ex)
{
Log.Error(ex, $"Failure saving Body Style: {bodyStyle}", bodyStyle);
throw new ServerErrorException();
}
}
public async Task<CleaningLevel> SaveAsync(CleaningLevel cleaningLevel)
{
try
{
await _cleaningLevelRepository.AddAsync(cleaningLevel);
await _unitOfWork.CompleteAsync();
return cleaningLevel;
}
catch (Exception ex)
{
Log.Error(ex, $"Failure saving Cleaning Level: {cleaningLevel}", cleaningLevel);
throw new ServerErrorException();
}
}
public async Task<CollateralType> SaveAsync(CollateralType collateralType)
{
try
{
await _collateralTypeRepository.AddAsync(collateralType);
await _unitOfWork.CompleteAsync();
return collateralType;
}
catch (Exception ex)
{
Log.Error(ex, $"Failure saving Collateral: {collateralType}", collateralType);
throw new ServerErrorException();
}
}
public async Task<CollateralTypeToVehicleType> SaveAsync(CollateralTypeToVehicleType collateralToVehicle)
{
try
{
await _collateralTypeToVehicleTypeRepository.AddAsync(collateralToVehicle);
await _unitOfWork.CompleteAsync();
return collateralToVehicle;
}
catch (Exception ex)
{
Log.Error(ex, $"Failure saving Collateral Type to Vehicle Type: {collateralToVehicle}",
collateralToVehicle);
throw new ServerErrorException();
}
}
public async Task<HoldStatus> SaveAsync(HoldStatus holdStatus)
{
try
{
await _holdStatusRepository.AddAsync(holdStatus);
await _unitOfWork.CompleteAsync();
return holdStatus;
}
catch (Exception ex)
{
Log.Error(ex, $"Failure saving Hold Status: {holdStatus}", holdStatus);
throw new ServerErrorException();
}
}
public async Task<LoanCategory> SaveAsync(LoanCategory loanCategory)
{
try
{
await _loanCategoryRepository.AddAsync(loanCategory);
await _unitOfWork.CompleteAsync();
return loanCategory;
}
catch (Exception ex)
{
Log.Error(ex, $"Failure saving Loan Category: {loanCategory}", loanCategory);
throw new ServerErrorException();
}
}
public async Task<LocationType> SaveAsync(LocationType locationType)
{
try
{
await _locationTypeRepository.AddAsync(locationType);
await _unitOfWork.CompleteAsync();
return locationType;
}
catch (Exception ex)
{
Log.Error(ex, $"Failure saving Location Type: {locationType}", locationType);
throw new ServerErrorException();
}
}
public async Task<VehicleType> SaveAsync(VehicleType vehicleType)
{
try
{
await _vehicleTypeRepository.AddAsync(vehicleType);
await _unitOfWork.CompleteAsync();
return vehicleType;
}
catch (Exception ex)
{
Log.Error(ex, $"Failure saving Vehicle Type: {vehicleType}", vehicleType);
throw new ServerErrorException();
}
}
public async Task<AccountType> UpdateAsync(AccountType accountType)
{
var existingAccountType = await _accountTypeRepository.FindByIdAsync(accountType.ID);
if (existingAccountType == null)
{
throw new NotFoundException($" Account Type with id {accountType.ID} not found.");
}
existingAccountType.AccountTypeCode = accountType.AccountTypeCode;
existingAccountType.Description = accountType.Description;
existingAccountType.IsVisible = accountType.IsVisible;
try
{
_accountTypeRepository.Update(existingAccountType);
await _unitOfWork.CompleteAsync();
return (existingAccountType);
}
catch (SqlException ex)
{
Log.Error(ex, $"SQL Failure updating Account Type: {accountType}", accountType);
throw new ServerErrorException();
}
catch (Exception ex)
{
Log.Error(ex, $"Failure updating Account Type: {accountType}", accountType);
throw new ServerErrorException();
}
}
public async Task<AllowedStatusChange> UpdateAsync(AllowedStatusChange allowedStatusChange)
{
var existingStatusChange = await _allowedStatusChangeRepository.FindByIdAsync(allowedStatusChange.ID);
if (existingStatusChange == null)
{
throw new NotFoundException($" Allowed Status Change with id {allowedStatusChange.ID} not found.");
}
existingStatusChange.CurrentStatus = allowedStatusChange.CurrentStatus;
existingStatusChange.AllowedChangeStatus = allowedStatusChange.AllowedChangeStatus;
try
{
_allowedStatusChangeRepository.Update(existingStatusChange);
await _unitOfWork.CompleteAsync();
return (existingStatusChange);
}
catch (SqlException ex)
{
Log.Error(ex, $"SQL Failure updating Allowed Status Change: {allowedStatusChange}",
allowedStatusChange);
throw new ServerErrorException();
}
catch (Exception ex)
{
Log.Error(ex, $"Failure updating Allowed Status Change {allowedStatusChange}", allowedStatusChange);
throw new ServerErrorException();
}
}
public async Task<BodyStyle> UpdateAsync(BodyStyle bodyStyle)
{
var existingBodyStyle = await _bodyStyleRepository.FindByIdAsync(bodyStyle.Code);
if (existingBodyStyle == null)
{
throw new NotFoundException($" Body Style with code {bodyStyle.Code} not found.");
}
existingBodyStyle.Description = bodyStyle.Description;
try
{
_bodyStyleRepository.Update(existingBodyStyle);
await _unitOfWork.CompleteAsync();
return (existingBodyStyle);
}
catch (SqlException ex)
{
Log.Error(ex, $"SQL Failure updating Body Style: {bodyStyle}", bodyStyle);
throw new ServerErrorException();
}
catch (Exception ex)
{
Log.Error(ex, $"Failure updating Body Style: {bodyStyle}", bodyStyle);
throw new ServerErrorException();
}
}
public async Task<CleaningLevel> UpdateAsync(CleaningLevel cleaningLevel)
{
var existingCleaningLevel = await _cleaningLevelRepository.FindByIdAsync(cleaningLevel.Code);
if (existingCleaningLevel == null)
{
throw new NotFoundException($" Cleaning Level with code {cleaningLevel.Code} not found.");
}
existingCleaningLevel.Description = cleaningLevel.Description;
try
{
_cleaningLevelRepository.Update(existingCleaningLevel);
await _unitOfWork.CompleteAsync();
return (existingCleaningLevel);
}
catch (SqlException ex)
{
Log.Error(ex, $"SQL Failure updating Cleaning Level: {cleaningLevel}", cleaningLevel);
throw new ServerErrorException();
}
catch (Exception ex)
{
Log.Error(ex, $"Failure updating Cleaning Level: {cleaningLevel}", cleaningLevel);
throw new ServerErrorException();
}
}
public async Task<CollateralType> UpdateAsync(CollateralType collateralType)
{
var existingCollateralType = await _collateralTypeRepository.FindByIdAsync(collateralType.ID);
if (existingCollateralType == null)
{
throw new NotFoundException($" Collateral Type with code {collateralType.ID} not found.");
}
existingCollateralType.Description = collateralType.Description;
existingCollateralType.LookupHandler = collateralType.LookupHandler;
try
{
_collateralTypeRepository.Update(existingCollateralType);
await _unitOfWork.CompleteAsync();
return (existingCollateralType);
}
catch (SqlException ex)
{
Log.Error(ex, $"SQL Failure updating Collateral Type: {collateralType}", collateralType);
throw new ServerErrorException();
}
catch (Exception ex)
{
Log.Error(ex, $"Failure updating Collateral Type: {collateralType}", collateralType);
throw new ServerErrorException();
}
}
public async Task<CollateralTypeToVehicleType> UpdateAsync(CollateralTypeToVehicleType collateralToVehicle)
{
var existingCollateralToVehicle =
await _collateralTypeToVehicleTypeRepository.FindByIdAsync(collateralToVehicle.ID);
if (existingCollateralToVehicle == null)
{
throw new NotFoundException(
$" Collateral Type To Vehicle Type with id {collateralToVehicle.ID} not found.");
}
existingCollateralToVehicle.CollateralTypeId = collateralToVehicle.CollateralTypeId;
existingCollateralToVehicle.VehicleTypeId = collateralToVehicle.VehicleTypeId;
try
{
_collateralTypeToVehicleTypeRepository.Update(existingCollateralToVehicle);
await _unitOfWork.CompleteAsync();
return (existingCollateralToVehicle);
}
catch (SqlException ex)
{
Log.Error(ex, $"SQL Failure updating Collateral Type To Vehicle Type: {collateralToVehicle}",
collateralToVehicle);
throw new ServerErrorException();
}
catch (Exception ex)
{
Log.Error(ex, $"Failure updating Collateral Type To Vehicle Type: {collateralToVehicle}",
collateralToVehicle);
throw new ServerErrorException();
}
}
public async Task<HoldStatus> UpdateAsync(HoldStatus holdStatus)
{
var existingHoldStatus = await _holdStatusRepository.FindByIdAsync(holdStatus.Code);
if (existingHoldStatus == null)
{
throw new NotFoundException($" Hold Status with code {holdStatus.Code} not found.");
}
existingHoldStatus.Description = holdStatus.Description;
try
{
_holdStatusRepository.Update(existingHoldStatus);
await _unitOfWork.CompleteAsync();
return (existingHoldStatus);
}
catch (SqlException ex)
{
Log.Error(ex, $"SQL Failure updating Hold Status: {holdStatus}", holdStatus);
throw new ServerErrorException();
}
catch (Exception ex)
{
Log.Error(ex, $"Failure updating Hold Status: {holdStatus}", holdStatus);
throw new ServerErrorException();
}
}
public async Task<LoanCategory> UpdateAsync(LoanCategory loanCategory)
{
var existingLoanCategory = await _loanCategoryRepository.FindByIdAsync(loanCategory.ID);
if (existingLoanCategory == null)
{
throw new NotFoundException($" Loan Category with code {loanCategory.ID} not found.");
}
existingLoanCategory.CategoryName = loanCategory.CategoryName;
try
{
_loanCategoryRepository.Update(existingLoanCategory);
await _unitOfWork.CompleteAsync();
return (existingLoanCategory);
}
catch (SqlException ex)
{
Log.Error(ex, $"SQL Failure updating Loan Category: {loanCategory}", loanCategory);
throw new ServerErrorException();
}
catch (Exception ex)
{
Log.Error(ex, $"Failure updating Loan Category: {loanCategory}", loanCategory);
throw new ServerErrorException();
}
}
public async Task<LocationType> UpdateAsync(LocationType locationType)
{
var existingLocationType = await _locationTypeRepository.FindByIdAsync(locationType.Code);
if (existingLocationType == null)
{
throw new NotFoundException($" Location Type with code {locationType.Code} not found.");
}
existingLocationType.Description = locationType.Description;
try
{
_locationTypeRepository.Update(existingLocationType);
await _unitOfWork.CompleteAsync();
return (existingLocationType);
}
catch (SqlException ex)
{
Log.Error(ex, $"SQL Failure updating Location Type: {locationType}", locationType);
throw new ServerErrorException();
}
catch (Exception ex)
{
Log.Error(ex, $"Failure updating Location Type: {locationType}", locationType);
throw new ServerErrorException();
}
}
public async Task<VehicleType> UpdateAsync(VehicleType vehicleType)
{
var existingVehicleType = await _vehicleTypeRepository.FindByIdAsync(vehicleType.Code);
if (existingVehicleType == null)
{
throw new NotFoundException($" Vehicle Type with code {vehicleType.Code} not found.");
}
existingVehicleType.Description = vehicleType.Description;
try
{
_vehicleTypeRepository.Update(existingVehicleType);
await _unitOfWork.CompleteAsync();
return (existingVehicleType);
}
catch (SqlException ex)
{
Log.Error(ex, $"SQL Failure updating Vehicle Type: {vehicleType}", vehicleType);
throw new ServerErrorException();
}
catch (Exception ex)
{
Log.Error(ex, $"Failure updating Vehicle Type: {vehicleType}", vehicleType);
throw new ServerErrorException();
}
}
public async Task SyncExternalUsersAsync(IReadOnlyCollection<ExternalUser> users)
{
await _externalUserRepository.SynchronizeSet(users);
await _unitOfWork.CompleteAsync();
}
private static Dictionary<int, string> GetRepoTypes()
{
return Enum.GetValues(typeof(RepoType))
.Cast<RepoType>()
.ToDictionary(type => (int)type, type => type.ToString() );
}
}
}