Files
2026-03-17 08:54:34 -05:00

276 lines
11 KiB
C#

using LCU.Library.Internal.CoreApiWrapperModel.CoreModels.CoreRequests;
using LCU.Library.Internal.CoreApiWrapperModel.CoreModels.Transaction;
using ReserveManagementSystemApi.Mappers;
using ReserveManagementSystemApi.Helpers;
using ReserveManagementSystemApi.Models;
using ReserveManagementSystemApi.ServiceClients;
using ReserveManagementSystemLib.Models;
using ReserveManagementSystemLib.Repositories;
using ReserveManagementSystemLib.Configuration;
namespace ReserveManagementSystemApi.Services
{
public class ExportService: IExportService
{
private readonly ILoanRepository _loanRepository;
private readonly ICoreApiServiceClient _coreApiServiceClient;
private readonly IMinorAccountTypeRepository _minorAccountTypeRepository;
private readonly RmsApiConfiguration _rmsApiConfig;
public ExportService(ILoanRepository loanRepository, ICoreApiServiceClient coreApiServiceClient, IMinorAccountTypeRepository minorAccountTypeRepository, RmsApiConfiguration rmsApiConfig)
{
_loanRepository = loanRepository;
_coreApiServiceClient = coreApiServiceClient;
_minorAccountTypeRepository = minorAccountTypeRepository;
_rmsApiConfig = rmsApiConfig;
}
public async Task<int> ExportReservesAsync(DateTime currentDate)
{
var numberOfLoansUpdated = 0;
try
{
var loansToUpdate = await _loanRepository.GetAll().Where(l => l.ExportedReserveDate == null).ToListAsync();
var groupedLoanRequests = loansToUpdate.Select(ExportMapper.MapLoanToIndirectLoanForReserve).ToList();
var exportResult = await SendBatchListMonetaryTransactionRequests(groupedLoanRequests);
if (exportResult != null || exportResult.Any())
{
var loansExported = new List<Loan>();
loansToUpdate.ForEach(loan =>
{
var validLoan = exportResult.Where(e => e.AccountNumber.ToString() == loan.LoanNumber).FirstOrDefault();
if (validLoan != null && validLoan.WasSuccessful)
{
loan.ExportedReserveDate = currentDate;
numberOfLoansUpdated += 1;
loan.Adjustment = 0;
loansExported.Add(loan); //update successful loan export with exported date
}
else
{
Log.Error($"Failure to export loan reserve account number: {loan.LoanNumber}");
}
});
await _loanRepository.UpdateAsync(loansExported);
Log.Information($"Exported {numberOfLoansUpdated} reserves");
}
}
catch (Exception ex)
{
Log.Error(ex, "Failure exporting loan reserves.");
throw;
}
return numberOfLoansUpdated;
}
public async Task<int> ExportChargebacksAsync(DateTime currentDate)
{
var numberOfLoansUpdated = 0;
try
{
var loansToUpdate = await _loanRepository.GetAll().Where(l => l.ExportedChargebackDate == null && l.PaidLoanDate != null).ToListAsync();
var groupedLoanRequests = new List<GroupedMonetaryTransactionRequest>();
loansToUpdate.ForEach(loan =>
{
var accountType = GetMinorAccountType(loan.AccountType);
groupedLoanRequests.Add(ExportMapper.MapLoanToIndirectLoanForChargeback(loan, accountType));
}
);
var exportResult = await SendBatchListMonetaryTransactionRequests(groupedLoanRequests);
if (exportResult != null || exportResult.Any())
{
var loansExported = new List<Loan>();
loansToUpdate.ForEach(loan =>
{
var accountType = GetMinorAccountType(loan.AccountType);
var validLoan = exportResult.Where(e => e.AccountNumber.ToString() == accountType.GeneralLedgerAccountNumber).FirstOrDefault();
if (validLoan != null && validLoan.WasSuccessful)
{
loan.ExportedChargebackDate = currentDate;
numberOfLoansUpdated += 1;
loan.Adjustment = 0;
loansExported.Add(loan); //update successful loan export with exported date
}
else
{
Log.Error($"Failure to export loan reserve account number: {loan.LoanNumber}");
}
});
await _loanRepository.UpdateAsync(loansExported);
Log.Information($"Exported {numberOfLoansUpdated} chargebacks");
}
else
{
Log.Error("Failure exporting loan chargebacks.");
}
}
catch (Exception ex)
{
Log.Error(ex, "Failure exporting loan chargebacks.");
throw;
}
return numberOfLoansUpdated;
}
public async Task<List<ImportBoatLoan>> ExportBoatLoansAsync(List<Loan> loans)
{
var loansExported = new List<ImportBoatLoan>();
try
{
var reserveLoans = loans.Where(l => l.ReserveAmount != 0);
if (reserveLoans != null || reserveLoans.Any())
{
var groupedReserveRequests = reserveLoans.Select(ExportMapper.MapLoanToIndirectLoanForReserve).ToList();
var exportReserveResult = await SendBatchListMonetaryTransactionRequests(groupedReserveRequests);
loansExported.AddRange(MapBoatExportResults(exportReserveResult, reserveLoans.ToList()));
}
var chargebackLoans = loans.Where(l => l.ChargeBack != 0).ToList();
if (chargebackLoans != null || chargebackLoans.Any())
{
var groupedLoanRequests = new List<GroupedMonetaryTransactionRequest>();
chargebackLoans.ForEach(loan =>
{
var accountType = GetMinorAccountType(loan.AccountType);
groupedLoanRequests.Add(ExportMapper.MapLoanToIndirectLoanForChargeback(loan, accountType));
}
);
var exportResult = await _coreApiServiceClient.PostMonetaryTransactions(groupedLoanRequests);
loansExported.AddRange(MapBoatExportResults(exportResult, chargebackLoans.ToList()));
}
}
catch (Exception ex)
{
Log.Error(ex, "Failure exporting boat loans.");
throw;
}
return loansExported;
}
public async Task<int> MarkReservesAsExportedAsync(List<Loan> loans, DateTime currentDate)
{
try
{
loans.ForEach(l =>
{
l.ExportedReserveDate = currentDate;
});
await _loanRepository.UpdateAsync(loans);
Log.Information($"Marked {loans.Count} loan reserves as exported (without exporting)");
}
catch (Exception ex)
{
Log.Error(ex, "Failure marking loan reserves as exported.");
throw;
}
return loans.Count;
}
public async Task<int> MarkReservesAndChargebacksAsExportedAsync(List<Loan> loans, DateTime currentDate)
{
try
{
loans.ForEach(l =>
{
l.ExportedReserveDate = currentDate;
l.ExportedChargebackDate = currentDate;
});
await _loanRepository.UpdateAsync(loans);
Log.Information($"Marked {loans.Count} loan reserves and chargebacks as exported (without exporting)");
}
catch (Exception ex)
{
Log.Error(ex, "Failure marking loan reserves and chargebacks as exported.");
throw;
}
return loans.Count;
}
private List<ImportBoatLoan> MapBoatExportResults(List<MonetaryTransactionResponse> exportResult, List<Loan> loansToUpdate)
{
var numberOfLoansUpdated = 0;
var loansExported = new List<ImportBoatLoan>();
if (exportResult != null || exportResult.Any())
{
loansToUpdate.ForEach(loan =>
{
var boatLoan = new ImportBoatLoan();
string acccountNumber;
if (loan.ReserveAmount != 0)
{
acccountNumber = loan.LoanNumber;
}
else
{
var accountType = GetMinorAccountType(loan.AccountType);
acccountNumber = accountType.GeneralLedgerAccountNumber;
}
var validLoan = exportResult.Where(e => e.AccountNumber.ToString() == acccountNumber).Any();
var validDealer = exportResult.Where(e => e.AccountNumber.ToString() == loan.Dealer.DealerAccountNumber).Any();
if (validLoan && validDealer)
{
numberOfLoansUpdated += 1;
boatLoan.LoanNumber = loan.LoanNumber;
boatLoan.WasSuccessful = true;
}
else
{
var error = $"Failure to export boat loan account number: {loan.LoanNumber}";
boatLoan.LoanNumber = loan.LoanNumber;
boatLoan.WasSuccessful = false;
boatLoan.ErrorMessage = error;
Log.Error(error);
}
loansExported.Add(boatLoan);
});
Log.Information($"Exported {numberOfLoansUpdated} boat loans");
}
return loansExported;
}
private MinorAccountType GetMinorAccountType(string loanAccountType)
{
var result = _minorAccountTypeRepository.GetMinorAccountType(loanAccountType);
return result;
}
public async Task<List<MonetaryTransactionResponse>> SendBatchListMonetaryTransactionRequests(List<GroupedMonetaryTransactionRequest> groupedLoanRequests)
{
var result = new List<MonetaryTransactionResponse>();
var batchSize = _rmsApiConfig.DefaultBatchSize;
foreach (var batch in BatchHelper.CreateBatch<GroupedMonetaryTransactionRequest>(groupedLoanRequests, batchSize))
{
var response = await _coreApiServiceClient.PostMonetaryTransactions(batch.ToList());
result.AddRange(response);
};
return result;
}
}
}