using Moq; using Microsoft.EntityFrameworkCore; using Xunit; using LCU.Library.Internal.CoreApiWrapperModel.CoreModels.CoreRequests; using LCU.Library.Internal.CoreApiWrapperModel.CoreModels.Transaction; using ReserveManagementSystemApi.Helpers; using ReserveManagementSystemApi.Mappers; using ReserveManagementSystemApi.ServiceClients; using ReserveManagementSystemApi.Services; using ReserveManagementSystemLib.Configuration; using ReserveManagementSystemLib.Models; using ReserveManagementSystemLib.Repositories; using ReserveManagementSystemLib.Persistence; namespace ReserveManagementSystemApi.Test.Service { public class ExportServiceTest { private ExportService _exportService; private Mock _mockCoreApiServiceClient; private Mock _mockMinorAccountRepository; private Mock _mockConfiguration; private AppDbContext _appDbContext; private ILoanRepository _loanRepository; public ExportServiceTest() { _mockCoreApiServiceClient = new Mock(); _mockMinorAccountRepository = new Mock(); _mockConfiguration = new Mock(); var options = new DbContextOptionsBuilder() .UseInMemoryDatabase(Guid.NewGuid().ToString()) .Options; _appDbContext = new AppDbContext(options); _loanRepository = new LoanRepository(_appDbContext); _mockConfiguration.Object.DefaultBatchSize = 100; _mockConfiguration.Object.DefaultImportStartDate = "2021-07-01 00:00:00"; _mockConfiguration.Object.DefaultConvertedLoanPostDate = "2021-10-31"; _exportService = new ExportService(_loanRepository, _mockCoreApiServiceClient.Object, _mockMinorAccountRepository.Object, _mockConfiguration.Object); } [Fact] public async Task SendExportChargebacksAsyncTest_OK() { var loan = new Loan(); loan.ExportedChargebackDate = null; loan.PaidLoanDate = Convert.ToDateTime("2021-11-01"); loan.LoanNumber = "1111100000"; loan.LoanId = 1; loan.DealerOrganizationNumber = "15500"; loan.AccountType = "DL01"; loan.Dealer = new Dealer() { DealerAccountNumber = "7788888", DealerOrganizationNumber = "15500" }; loan.Adjustment = 0; loan.ChargeBack = (decimal)22.00; var account = new MinorAccountType() { MinorAccountTypeId = 1, GeneralLedgerAccountNumber = "11111111", AccountType = "DL01" }; _loanRepository.Add(loan); _mockMinorAccountRepository.Setup(repo => repo.GetMinorAccountType("DL01")).Returns(account); var result = ExportMapper.MapLoanToIndirectLoanForChargeback(loan, account); var groupedList = new List { result }; var response = new MonetaryTransactionResponse() { WasSuccessful = true }; var listResponse = new List { response }; var resultBatch = BatchHelper.CreateBatch(groupedList, _mockConfiguration.Object.DefaultBatchSize); List batchList = new List(resultBatch.FirstOrDefault()); _mockCoreApiServiceClient.Setup(x => x.PostMonetaryTransactions(batchList)).Returns(Task.FromResult(listResponse)).Verifiable(); var numberOfLoansUpdatedSuccessfully = await _exportService.SendBatchListMonetaryTransactionRequests(groupedList); var success = numberOfLoansUpdatedSuccessfully[0].WasSuccessful.ToString(); Assert.True(true, success); } #region "Unit tests for Chargeback rounding" [Fact] public async Task MappedExportRoundedUpChargebackAsyncTest_OK() { var loan = new Loan(); loan.ExportedReserveDate = null; loan.ExportedChargebackDate = null; loan.LoanNumber = "1111100000"; loan.LoanId = 1; loan.DealerOrganizationNumber = "15500"; loan.AccountType = "DL01"; loan.Dealer = new Dealer() { DealerAccountNumber = "7788888", DealerOrganizationNumber = "15500" }; var account = new MinorAccountType() { MinorAccountTypeId = 1, GeneralLedgerAccountNumber = "11111111", AccountType = "DL01" }; loan.Adjustment = 0; loan.ChargeBack = (decimal)502.525; var result = ExportMapper.MapLoanToIndirectLoanForChargeback(loan, account); var groupedList = new List { result }; var resultBatch = BatchHelper.CreateBatch(groupedList, _mockConfiguration.Object.DefaultBatchSize); List batchList = new List(resultBatch.FirstOrDefault()); Assert.Equal(-502.53, batchList[0].MonetaryTransactionRequests[1].TransactionAmount); Assert.Equal("ChrgBk-1111100000", batchList[0].MonetaryTransactionRequests[1].Description); } [Fact] public async Task MappedExportRoundedDownChargebackAsyncTest_OK() { { var loan = new Loan(); loan.ExportedReserveDate = null; loan.ExportedChargebackDate = null; loan.LoanNumber = "2411000009999"; loan.LoanId = 1; loan.DealerOrganizationNumber = "15500"; loan.AccountType = "DL01"; loan.Dealer = new Dealer() { DealerAccountNumber = "7788888", DealerOrganizationNumber = "15500" }; var account = new MinorAccountType() { MinorAccountTypeId = 1, GeneralLedgerAccountNumber = "11111111", AccountType = "DL01" }; loan.Adjustment = 0; loan.ChargeBack = (decimal)38.171850; var result = ExportMapper.MapLoanToIndirectLoanForChargeback(loan, account); var groupedList = new List { result }; var resultBatch = BatchHelper.CreateBatch(groupedList, _mockConfiguration.Object.DefaultBatchSize); List batchList = new List(resultBatch.FirstOrDefault()); Assert.Equal(-38.17, batchList[0].MonetaryTransactionRequests[1].TransactionAmount); Assert.Equal("ChrgBk-2411000009999", batchList[0].MonetaryTransactionRequests[1].Description); } } #endregion #region "Unit tests for Reserve rounding" [Fact] public void MappedExportRoundedUpReserveAsyncTest1_OK() { var loan = new Loan(); loan.ExportedReserveDate = null; loan.ExportedChargebackDate = null; loan.LoanNumber = "1111100000"; loan.LoanId = 1; loan.DealerOrganizationNumber = "15500"; loan.AccountType = "DL01"; loan.Dealer = new Dealer() { DealerAccountNumber = "7788888", DealerOrganizationNumber = "15500" }; loan.Adjustment = 0; loan.ReserveAmount = (decimal)502.525; var result = ExportMapper.MapLoanToIndirectLoanForReserve(loan); var groupedList = new List { result }; var resultBatch = BatchHelper.CreateBatch(groupedList, _mockConfiguration.Object.DefaultBatchSize); List batchList = new List(resultBatch.FirstOrDefault()); //in order to test reserve rounding set the reserves and adjustments accordingly. Assert.Equal(-502.53, batchList[0].MonetaryTransactionRequests[0].TransactionAmount); } [Fact] public void MappedExportRoundedUpReserveAsyncTest2_OK() { var loan = new Loan(); loan.ExportedReserveDate = null; loan.ExportedChargebackDate = null; loan.LoanNumber = "1111100000"; loan.LoanId = 1; loan.DealerOrganizationNumber = "15500"; loan.AccountType = "DL01"; loan.Dealer = new Dealer() { DealerAccountNumber = "7788888", DealerOrganizationNumber = "15500" }; loan.Adjustment = 0; loan.ReserveAmount = (decimal)1237.715; var result = ExportMapper.MapLoanToIndirectLoanForReserve(loan); var groupedList = new List { result }; var resultBatch = BatchHelper.CreateBatch(groupedList, _mockConfiguration.Object.DefaultBatchSize); List batchList = new List(resultBatch.FirstOrDefault()); //in order to test reserve rounding set the reserves and adjustments accordingly. Assert.Equal(-1237.72, batchList[0].MonetaryTransactionRequests[0].TransactionAmount); } [Fact] public async Task MappedExportRoundedUpReserveAsyncTest3_OK() { var loan = new Loan(); loan.ExportedReserveDate = null; loan.ExportedChargebackDate = null; loan.LoanNumber = "1111100000"; loan.LoanId = 1; loan.DealerOrganizationNumber = "15500"; loan.AccountType = "DL01"; loan.Dealer = new Dealer() { DealerAccountNumber = "7788888", DealerOrganizationNumber = "15500" }; loan.Adjustment = 0; loan.ReserveAmount = (decimal)1439.675; var result = ExportMapper.MapLoanToIndirectLoanForReserve(loan); var groupedList = new List { result }; var resultBatch = BatchHelper.CreateBatch(groupedList, _mockConfiguration.Object.DefaultBatchSize); List batchList = new List(resultBatch.FirstOrDefault()); //in order to test reserve rounding set the reserves and adjustments accordingly. Assert.Equal(-1439.68, batchList[0].MonetaryTransactionRequests[0].TransactionAmount); } [Fact] public async Task MappedExportRoundedDownReserveAsyncTest1_OK() { var loan = new Loan(); loan.ExportedReserveDate = null; loan.ExportedChargebackDate = null; loan.LoanNumber = "1111100000"; loan.LoanId = 1; loan.DealerOrganizationNumber = "15500"; loan.AccountType = "DL01"; loan.Dealer = new Dealer() { DealerAccountNumber = "7788888", DealerOrganizationNumber = "15500" }; loan.Adjustment = 0; loan.ReserveAmount = (decimal)1982.1045; var result = ExportMapper.MapLoanToIndirectLoanForReserve(loan); var groupedList = new List { result }; var resultBatch = BatchHelper.CreateBatch(groupedList, _mockConfiguration.Object.DefaultBatchSize); List batchList = new List(resultBatch.FirstOrDefault()); //in order to test reserve rounding set the reserves and adjustments accordingly. Assert.Equal(-1982.10, batchList[0].MonetaryTransactionRequests[0].TransactionAmount); } [Fact] public async Task MappedExportRoundedDownReserveAsyncTest2_OK() { var loan = new Loan(); loan.ExportedReserveDate = null; loan.ExportedChargebackDate = null; loan.LoanNumber = "1111100000"; loan.LoanId = 1; loan.DealerOrganizationNumber = "15500"; loan.AccountType = "DL01"; loan.Dealer = new Dealer() { DealerAccountNumber = "7788888", DealerOrganizationNumber = "15500" }; loan.Adjustment = 0; loan.ReserveAmount = (decimal)1803.52449; var result = ExportMapper.MapLoanToIndirectLoanForReserve(loan); var groupedList = new List { result }; var resultBatch = BatchHelper.CreateBatch(groupedList, _mockConfiguration.Object.DefaultBatchSize); List batchList = new List(resultBatch.FirstOrDefault()); //in order to test reserve rounding set the reserves and adjustments accordingly. Assert.Equal(-1803.52, batchList[0].MonetaryTransactionRequests[0].TransactionAmount); } [Fact] public async Task MappedExportRoundedDownReserveAsyncTest3_OK() { var loan = new Loan(); loan.ExportedReserveDate = null; loan.ExportedChargebackDate = null; loan.LoanNumber = "1111100000"; loan.LoanId = 1; loan.DealerOrganizationNumber = "15500"; loan.AccountType = "DL01"; loan.Dealer = new Dealer() { DealerAccountNumber = "7788888", DealerOrganizationNumber = "15500" }; loan.Adjustment = 0; loan.ReserveAmount = (decimal)38.171850; var result = ExportMapper.MapLoanToIndirectLoanForReserve(loan); var groupedList = new List { result }; var resultBatch = BatchHelper.CreateBatch(groupedList, _mockConfiguration.Object.DefaultBatchSize); List batchList = new List(resultBatch.FirstOrDefault()); //in order to test reserve rounding set the reserves and adjustments accordingly. Assert.Equal(-38.17, batchList[0].MonetaryTransactionRequests[0].TransactionAmount); } [Fact] public async Task MappedExportRoundedDownTenThousandthReserveAsyncTest1_OK() { var loan = new Loan(); loan.ExportedReserveDate = null; loan.ExportedChargebackDate = null; loan.LoanNumber = "1111100000"; loan.LoanId = 1; loan.DealerOrganizationNumber = "15500"; loan.AccountType = "DL01"; loan.Dealer = new Dealer() { DealerAccountNumber = "7788888", DealerOrganizationNumber = "15500" }; loan.Adjustment = 0; loan.ReserveAmount = (decimal)4240.9217; var result = ExportMapper.MapLoanToIndirectLoanForReserve(loan); var groupedList = new List { result }; var resultBatch = BatchHelper.CreateBatch(groupedList, _mockConfiguration.Object.DefaultBatchSize); List batchList = new List(resultBatch.FirstOrDefault()); //in order to test reserve rounding set the reserves and adjustments accordingly. Assert.Equal(-4240.92, batchList[0].MonetaryTransactionRequests[0].TransactionAmount); } [Fact] public async Task MappedExportRoundedDownTenThousandthReserveAsyncTest2_OK() { var loan = new Loan(); loan.ExportedReserveDate = null; loan.ExportedChargebackDate = null; loan.LoanNumber = "1111100000"; loan.LoanId = 1; loan.DealerOrganizationNumber = "15500"; loan.AccountType = "DL01"; loan.Dealer = new Dealer() { DealerAccountNumber = "7788888", DealerOrganizationNumber = "15500" }; loan.Adjustment = 0; loan.ReserveAmount = (decimal)397.2345; var result = ExportMapper.MapLoanToIndirectLoanForReserve(loan); var groupedList = new List { result }; var resultBatch = BatchHelper.CreateBatch(groupedList, _mockConfiguration.Object.DefaultBatchSize); List batchList = new List(resultBatch.FirstOrDefault()); //in order to test reserve rounding set the reserves and adjustments accordingly. Assert.Equal(-397.23, batchList[0].MonetaryTransactionRequests[0].TransactionAmount); } [Fact] public async Task MappedExportRoundedDownTenThousandthReserveAsyncTest3_OK() { var loan = new Loan(); loan.ExportedReserveDate = null; loan.ExportedChargebackDate = null; loan.LoanNumber = "1111100000"; loan.LoanId = 1; loan.DealerOrganizationNumber = "15500"; loan.AccountType = "DL01"; loan.Dealer = new Dealer() { DealerAccountNumber = "7788888", DealerOrganizationNumber = "15500" }; loan.Adjustment = 0; loan.ReserveAmount = (decimal)434.9949; var result = ExportMapper.MapLoanToIndirectLoanForReserve(loan); var groupedList = new List { result }; var resultBatch = BatchHelper.CreateBatch(groupedList, _mockConfiguration.Object.DefaultBatchSize); List batchList = new List(resultBatch.FirstOrDefault()); //in order to test reserve rounding set the reserves and adjustments accordingly. Assert.Equal(-434.99, batchList[0].MonetaryTransactionRequests[0].TransactionAmount); } [Fact] public async Task MappedExportRoundedDownTenThousandthReserveAsyncTest4_OK() { var loan = new Loan(); loan.ExportedReserveDate = null; loan.ExportedChargebackDate = null; loan.LoanNumber = "1111100000"; loan.LoanId = 1; loan.DealerOrganizationNumber = "15500"; loan.AccountType = "DL01"; loan.Dealer = new Dealer() { DealerAccountNumber = "7788888", DealerOrganizationNumber = "15500" }; loan.Adjustment = 0; loan.ReserveAmount = (decimal)1513.1451; var result = ExportMapper.MapLoanToIndirectLoanForReserve(loan); var groupedList = new List { result }; var resultBatch = BatchHelper.CreateBatch(groupedList, _mockConfiguration.Object.DefaultBatchSize); List batchList = new List(resultBatch.FirstOrDefault()); //in order to test reserve rounding set the reserves and adjustments accordingly. Assert.Equal(-1513.15, batchList[0].MonetaryTransactionRequests[0].TransactionAmount); } [Fact] public async Task MappedExportRoundedDownTenThousandthReserveAsyncTest5_OK() { var loan = new Loan(); loan.ExportedReserveDate = null; loan.ExportedChargebackDate = null; loan.LoanNumber = "1111100000"; loan.LoanId = 1; loan.DealerOrganizationNumber = "15500"; loan.AccountType = "DL01"; loan.Dealer = new Dealer() { DealerAccountNumber = "7788888", DealerOrganizationNumber = "15500" }; loan.Adjustment = 0; loan.ReserveAmount = (decimal)4240.9247; var result = ExportMapper.MapLoanToIndirectLoanForReserve(loan); var groupedList = new List { result }; var resultBatch = BatchHelper.CreateBatch(groupedList, _mockConfiguration.Object.DefaultBatchSize); List batchList = new List(resultBatch.FirstOrDefault()); //in order to test reserve rounding set the reserves and adjustments accordingly. Assert.Equal(-4240.92, batchList[0].MonetaryTransactionRequests[0].TransactionAmount); } [Fact] public async Task MappedExportRoundedUpTenThousandthReserveAsyncTest1_OK() { var loan = new Loan(); loan.ExportedReserveDate = null; loan.ExportedChargebackDate = null; loan.LoanNumber = "1111100000"; loan.LoanId = 1; loan.DealerOrganizationNumber = "15500"; loan.AccountType = "DL01"; loan.Dealer = new Dealer() { DealerAccountNumber = "7788888", DealerOrganizationNumber = "15500" }; loan.Adjustment = 0; loan.ReserveAmount = (decimal)1513.154999; //value that would be written to DB is 1513.155 var result = ExportMapper.MapLoanToIndirectLoanForReserve(loan); var groupedList = new List { result }; var resultBatch = BatchHelper.CreateBatch(groupedList, _mockConfiguration.Object.DefaultBatchSize); List batchList = new List(resultBatch.FirstOrDefault()); //in order to test reserve rounding set the reserves and adjustments accordingly. Assert.Equal(-1513.16, batchList[0].MonetaryTransactionRequests[0].TransactionAmount); } #endregion #region "Unit tests for reserve rounding with adjustments" [Fact] public async Task MappedExportRoundedDownReserveAdjustmentAsyncTest_OK() { var loan = new Loan(); loan.ExportedReserveDate = null; loan.ExportedChargebackDate = null; loan.LoanNumber = "1111100000"; loan.LoanId = 1; loan.DealerOrganizationNumber = "15500"; loan.AccountType = "DL01"; loan.Dealer = new Dealer() { DealerAccountNumber = "7788888", DealerOrganizationNumber = "15500" }; var adjustmentCalculation = (decimal)(1513.154999 - 1803.4656); //1513.16 - 1803.47 loan.Adjustment = (decimal)adjustmentCalculation; loan.ReserveAmount = (decimal)1513.155; //as saved in DB var result = ExportMapper.MapLoanToIndirectLoanForReserve(loan); var groupedList = new List { result }; var resultBatch = BatchHelper.CreateBatch(groupedList, _mockConfiguration.Object.DefaultBatchSize); List batchList = new List(resultBatch.FirstOrDefault()); //in order to test adjustment to the reserve rounding set the reserves and adjustments accordingly. Assert.Equal(290.31, batchList[0].MonetaryTransactionRequests[0].TransactionAmount); } [Fact] public async Task MappedExportRoundedDownTenThousandthReserveAdjustmentAsyncTest_OK() { var loan = new Loan(); loan.ExportedReserveDate = null; loan.ExportedChargebackDate = null; loan.LoanNumber = "1111100000"; loan.LoanId = 1; loan.DealerOrganizationNumber = "15500"; loan.AccountType = "DL01"; loan.Dealer = new Dealer() { DealerAccountNumber = "7788888", DealerOrganizationNumber = "15500" }; var adjustmentCalculation = (decimal)(1513.1489 - 1803.4734); //-290.3245 loan.Adjustment = (decimal)adjustmentCalculation; loan.ReserveAmount = (decimal)1513.1489; //as saved in DB var result = ExportMapper.MapLoanToIndirectLoanForReserve(loan); var groupedList = new List { result }; var resultBatch = BatchHelper.CreateBatch(groupedList, _mockConfiguration.Object.DefaultBatchSize); List batchList = new List(resultBatch.FirstOrDefault()); //in order to test adjustment to the reserve rounding set the reserves and adjustments accordingly. Assert.Equal(290.32, batchList[0].MonetaryTransactionRequests[0].TransactionAmount); } [Fact] public async Task MappedExportRoundedUpHundredThousandthReserveAdjustmentAsyncTest_OK() { var loan = new Loan(); loan.ExportedReserveDate = null; loan.ExportedChargebackDate = null; loan.LoanNumber = "1111100000"; loan.LoanId = 1; loan.DealerOrganizationNumber = "15500"; loan.AccountType = "DL01"; loan.Dealer = new Dealer() { DealerAccountNumber = "7788888", DealerOrganizationNumber = "15500" }; var adjustmentCalculation = (decimal)(1513.145 - 1803.52449); //-290.37949 //Reserve written to DB 1803.5245 loan.Adjustment = (decimal)adjustmentCalculation; loan.ReserveAmount = (decimal)1513.145; //as saved in DB var result = ExportMapper.MapLoanToIndirectLoanForReserve(loan); var groupedList = new List { result }; var resultBatch = BatchHelper.CreateBatch(groupedList, _mockConfiguration.Object.DefaultBatchSize); List batchList = new List(resultBatch.FirstOrDefault()); //in order to test adjustment to the reserve rounding set the reserves and adjustments accordingly. Assert.Equal(290.38, batchList[0].MonetaryTransactionRequests[0].TransactionAmount); } [Fact] public async Task MappedExportRoundedUpMillionthReserveNegativeOneAdjustmentAsyncTest_OK() { var loan = new Loan(); loan.ExportedReserveDate = null; loan.ExportedChargebackDate = null; loan.LoanNumber = "1111100000"; loan.LoanId = 1; loan.DealerOrganizationNumber = "15500"; loan.AccountType = "DL01"; loan.Dealer = new Dealer() { DealerAccountNumber = "7788888", DealerOrganizationNumber = "15500" }; var adjustmentCalculation = (decimal)(39.171450 - 38.171550); //0.999899999999997 loan.Adjustment = (decimal)adjustmentCalculation; loan.ReserveAmount = (decimal)38.1715; //as saved in DB var result = ExportMapper.MapLoanToIndirectLoanForReserve(loan); var groupedList = new List { result }; var resultBatch = BatchHelper.CreateBatch(groupedList, _mockConfiguration.Object.DefaultBatchSize); List batchList = new List(resultBatch.FirstOrDefault()); //in order to test adjustment to the reserve rounding set the reserves and adjustments accordingly. Assert.Equal(-1, batchList[0].MonetaryTransactionRequests[0].TransactionAmount); } [Fact] public async Task MappedExportRoundedUpMillionthReservePositiveOneAdjustmentAsyncTest_OK() { var loan = new Loan(); loan.ExportedReserveDate = null; loan.ExportedChargebackDate = null; loan.LoanNumber = "1111100000"; loan.LoanId = 1; loan.DealerOrganizationNumber = "15500"; loan.AccountType = "DL01"; loan.Dealer = new Dealer() { DealerAccountNumber = "7788888", DealerOrganizationNumber = "15500" }; var adjustmentCalculation = (decimal)(38.171550 - 39.171450); //-0.999899999999997 loan.Adjustment = (decimal)adjustmentCalculation; loan.ReserveAmount = (decimal)38.1715; //as saved in DB var result = ExportMapper.MapLoanToIndirectLoanForReserve(loan); var groupedList = new List { result }; var resultBatch = BatchHelper.CreateBatch(groupedList, _mockConfiguration.Object.DefaultBatchSize); List batchList = new List(resultBatch.FirstOrDefault()); //in order to test adjustment to the reserve rounding set the reserves and adjustments accordingly. Assert.Equal(1, batchList[0].MonetaryTransactionRequests[0].TransactionAmount); } [Fact] public async Task MappedExportRoundedUpMillionthReserveNoAdjustmentAsyncTest_OK() { var loan = new Loan(); loan.ExportedReserveDate = null; loan.ExportedChargebackDate = null; loan.LoanNumber = "1111100000"; loan.LoanId = 1; loan.DealerOrganizationNumber = "15500"; loan.AccountType = "DL01"; loan.Dealer = new Dealer() { DealerAccountNumber = "7788888", DealerOrganizationNumber = "15500" }; var adjustmentCalculation = (decimal)(38.171450 - 38.171850); //-0.000399999999999068 loan.Adjustment = (decimal)adjustmentCalculation; loan.ReserveAmount = (decimal)38.1719; //as saved in DB var result = ExportMapper.MapLoanToIndirectLoanForReserve(loan); var groupedList = new List { result }; var resultBatch = BatchHelper.CreateBatch(groupedList, _mockConfiguration.Object.DefaultBatchSize); List batchList = new List(resultBatch.FirstOrDefault()); //in order to test adjustment to the reserve rounding set the reserves and adjustments accordingly. Assert.Equal(0, batchList[0].MonetaryTransactionRequests[0].TransactionAmount); } #endregion } }