Adding
This commit is contained in:
+160
@@ -0,0 +1,160 @@
|
||||
using System.Globalization;
|
||||
using System.IO;
|
||||
using CsvHelper;
|
||||
using CsvHelper.Configuration;
|
||||
using LCU.API.Internal.Operations.IncentiveApi.Models.Action;
|
||||
using LCU.API.Internal.Operations.IncentiveApiLib.Repositories;
|
||||
using LCU.Library.Internal.IncentiveApiModels.Entities;
|
||||
using LCU.Library.Internal.IncentiveApiModels.Enums;
|
||||
using LCU.API.Internal.Operations.IncentiveApi.Services.MicroApiServices;
|
||||
using LCU.Library.Internal.IncentiveApiModels.Requests;
|
||||
using LCU.API.Internal.Operations.IncentiveApi.Services.Transformations;
|
||||
using LCU.Library.Internal.ApiResponse.Services;
|
||||
using LCU.Library.Internal.Exceptions;
|
||||
using LCU.Library.Internal.IncentiveApiModels.Results;
|
||||
|
||||
namespace LCU.API.Internal.Operations.IncentiveApi.Services.Action;
|
||||
|
||||
public class ActionCreditCardImportService : IActionCreditCardImportService
|
||||
{
|
||||
private readonly IUserRepository _userRepository;
|
||||
private readonly IActivityService _activityService;
|
||||
private readonly IDeadActivityService _deadActivityService;
|
||||
private readonly IFileOperationsApiService _fileOperationsApiService;
|
||||
private readonly ProcessResult _actionCreditCardResult;
|
||||
|
||||
public ActionCreditCardImportService(IUserRepository userRepository, IFileOperationsApiService fileOperationsApiService,
|
||||
IActivityService activityService, IDeadActivityService deadActivityService)
|
||||
{
|
||||
_userRepository = userRepository;
|
||||
_fileOperationsApiService = fileOperationsApiService;
|
||||
_activityService = activityService;
|
||||
_deadActivityService = deadActivityService;
|
||||
_actionCreditCardResult = new ProcessResult();
|
||||
}
|
||||
|
||||
public async Task RunActionCreditCardProcess(ActionCreditCardRequest request)
|
||||
{
|
||||
try
|
||||
{
|
||||
var importedPersonal = await ImportTransactions<ActionCreditCardPersonalRow>("personal", request);
|
||||
Log.Information($"Imported {importedPersonal.Count} credit cards - personal.");
|
||||
|
||||
var importedBusiness = await ImportTransactions<ActionCreditCardBusinessRow>("business", request);
|
||||
Log.Information($"Imported {importedBusiness.Count} credit cards - business.");
|
||||
|
||||
_actionCreditCardResult.MessageStack.Add($"Imported {importedPersonal.Count()} personal and {importedBusiness.Count()} business credit cards.");
|
||||
await QueueReturnResponse.QueueResponse(request, _actionCreditCardResult.Success, _actionCreditCardResult.MessageStack);
|
||||
}
|
||||
catch (Exception exception)
|
||||
{
|
||||
var message = $"There was an issue with handling Import Action Credit Card Sales Exception Message: {exception.Message}.";
|
||||
_actionCreditCardResult.MessageStack.Add(message);
|
||||
_actionCreditCardResult.Success = false;
|
||||
await QueueReturnResponse.QueueResponse(request, _actionCreditCardResult.Success, _actionCreditCardResult.MessageStack);
|
||||
throw new ServiceException(message);
|
||||
}
|
||||
}
|
||||
|
||||
public async Task<IReadOnlyCollection<Activity>> ImportTransactions<T>(string fileIdentifier, ActionCreditCardRequest request) where T : IActionFileObject
|
||||
{
|
||||
var dynamicFileListRequest = request.ToDynamicActionCreditCardFileListRequest();
|
||||
var files = await _fileOperationsApiService.BuildDynamicFileList(dynamicFileListRequest);
|
||||
|
||||
var activity = new List<Activity>();
|
||||
foreach (var fileName in files)
|
||||
{
|
||||
var stringContent = _fileOperationsApiService.GetFileContent($"{request.FinalBasePath}{fileName}");
|
||||
using var stringReader = new StringReader(stringContent.Result);
|
||||
var config = new CsvConfiguration(CultureInfo.InvariantCulture)
|
||||
{
|
||||
Delimiter = ",",
|
||||
HasHeaderRecord = true,
|
||||
HeaderValidated = null,
|
||||
MissingFieldFound = null,
|
||||
IgnoreBlankLines = true
|
||||
};
|
||||
|
||||
using var csv = new CsvReader(stringReader, config);
|
||||
var records = csv.GetRecords<T>().ToList();
|
||||
var allActivity = await CreateActivity(records);
|
||||
await _activityService.SaveActivityRangeAsync(allActivity);
|
||||
|
||||
activity.AddRange(allActivity);
|
||||
}
|
||||
|
||||
return activity;
|
||||
}
|
||||
|
||||
public async Task<IReadOnlyCollection<Activity>> CreateActivity<T>(IEnumerable<T> transactions) where T : IActionFileObject
|
||||
{
|
||||
var activities = new List<Activity>();
|
||||
var deadActivities = new List<DeadActivity>();
|
||||
foreach (var actionSaleRow in transactions)
|
||||
{
|
||||
var email = actionSaleRow.GetEmployeeEmail();
|
||||
var employee = string.IsNullOrEmpty(email) ? null : await FindEmployee(email);
|
||||
|
||||
if (employee == null)
|
||||
{
|
||||
email = actionSaleRow.GetLoanOfficerEmail();
|
||||
employee = string.IsNullOrEmpty(email) ? null : await FindEmployee(email);
|
||||
}
|
||||
|
||||
if (employee == null)
|
||||
{
|
||||
email = actionSaleRow.GetLoanOfficerEmailByName();
|
||||
employee = string.IsNullOrEmpty(email) ? null : await FindEmployee(email);
|
||||
}
|
||||
|
||||
if(employee == null){
|
||||
|
||||
Log.Warning($"Action Import, No user for {email}. Saving as Dead Activity.");
|
||||
deadActivities.Add(actionSaleRow.CreateDeadActivity(DeadActivityReason.MissingRequiredField, $"Action Import, No user for {email}", email));
|
||||
continue;
|
||||
}
|
||||
|
||||
var homeDept = employee.FindHomeDepartment();
|
||||
if (homeDept == null)
|
||||
{
|
||||
Log.Warning($"User has no reliably determinable home department, {employee.EmployeeId}. Saving as Dead Activity.");
|
||||
deadActivities.Add(
|
||||
actionSaleRow.CreateDeadActivity(DeadActivityReason.MissingRequiredField,
|
||||
$"User has no reliably determinable home department, {employee.EmployeeId}", email, employee.EmployeeId));
|
||||
continue;
|
||||
}
|
||||
|
||||
var activity = actionSaleRow.CreateActivity(employee);
|
||||
if (activities.Any(x => x.SourceId == activity.SourceId))
|
||||
{
|
||||
Log.Fatal(
|
||||
$"Duplicate activity in credit card file for Incentive Manager, sourceId is {activity.SourceId}");
|
||||
continue;
|
||||
}
|
||||
activities.Add(activity);
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
await _deadActivityService.SaveDeadActivityRange(deadActivities);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Log.Error(ex, "Failed to save dead activities from ActionCreditCardImportService. Dead Activities will be lost.");
|
||||
}
|
||||
return activities;
|
||||
}
|
||||
|
||||
private async Task<AppUser> FindEmployee(string employeeEmail)
|
||||
{
|
||||
try
|
||||
{
|
||||
return await _userRepository.FindUserByAdEmailAsync(employeeEmail);
|
||||
}
|
||||
catch(Exception ex)
|
||||
{
|
||||
Log.Warning(ex, "Error when finding user by email in ActionCreditCardImportService.");
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
+172
@@ -0,0 +1,172 @@
|
||||
using System.Globalization;
|
||||
using System.IO;
|
||||
using CsvHelper;
|
||||
using CsvHelper.Configuration;
|
||||
using LCU.API.Internal.Operations.IncentiveApi.Models.Action;
|
||||
using LCU.API.Internal.Operations.IncentiveApiLib.Repositories;
|
||||
using LCU.Library.Internal.IncentiveApiModels.Entities;
|
||||
using LCU.Library.Internal.IncentiveApiModels.Enums;
|
||||
using LCU.API.Internal.Operations.IncentiveApi.Services.MicroApiServices;
|
||||
using LCU.Library.Internal.IncentiveApiModels.Requests;
|
||||
using LCU.API.Internal.Operations.IncentiveApi.Services.Transformations;
|
||||
using LCU.Library.Internal.IncentiveApiModels.Results;
|
||||
using LCU.Library.Internal.ApiResponse.Services;
|
||||
using LCU.Library.Internal.Exceptions;
|
||||
|
||||
namespace LCU.API.Internal.Operations.IncentiveApi.Services.Action;
|
||||
|
||||
public class ActionVehicleImportService : IActionVehicleImportService
|
||||
{
|
||||
private readonly IUserRepository _userRepository;
|
||||
private readonly IActivityService _activityService;
|
||||
private readonly IDeadActivityService _deadActivityService;
|
||||
private readonly IFileOperationsApiService _fileOperationsApiService;
|
||||
private readonly ProcessResult _actionVehicleProcessResult;
|
||||
static readonly CultureInfo USEnglish = new CultureInfo("en-US");
|
||||
|
||||
public ActionVehicleImportService(IUserRepository userRepository, IFileOperationsApiService fileOperationsApiService, IActivityService activityService, IDeadActivityService deadActivityService)
|
||||
{
|
||||
_userRepository = userRepository;
|
||||
_fileOperationsApiService = fileOperationsApiService;
|
||||
_activityService = activityService;
|
||||
_deadActivityService = deadActivityService;
|
||||
_actionVehicleProcessResult = new ProcessResult();
|
||||
}
|
||||
|
||||
public async Task RunActionVehicleProcess(ActionVehicleRequest request)
|
||||
{
|
||||
try
|
||||
{
|
||||
var importedVehicleSales = await ImportTransactions<ActionSaleRow>(request);
|
||||
Log.Information($"Imported {importedVehicleSales.Count} Action Vehicle Sales.");
|
||||
|
||||
_actionVehicleProcessResult.MessageStack.Add($"Imported {importedVehicleSales.Count()} Action Vehicle Sales.");
|
||||
await QueueReturnResponse.QueueResponse(request, _actionVehicleProcessResult.Success, _actionVehicleProcessResult.MessageStack);
|
||||
}
|
||||
catch (Exception exception)
|
||||
{
|
||||
var message = $"There was an issue with handling Import Action Vehicle Sales Exception Message: {exception.Message}.";
|
||||
_actionVehicleProcessResult.MessageStack.Add(message);
|
||||
_actionVehicleProcessResult.Success = false;
|
||||
await QueueReturnResponse.QueueResponse(request, _actionVehicleProcessResult.Success, _actionVehicleProcessResult.MessageStack);
|
||||
throw new ServiceException(message);
|
||||
}
|
||||
}
|
||||
|
||||
public async Task<IReadOnlyCollection<Activity>> ImportTransactions<T>(ActionVehicleRequest request) where T : ActionSaleRow
|
||||
{
|
||||
var dynamicFileListRequest = request.ToDynamicActionVehicleFileListRequest();
|
||||
var files = await _fileOperationsApiService.BuildDynamicFileList(dynamicFileListRequest);
|
||||
|
||||
var activity = new List<Activity>();
|
||||
foreach (var fileName in files)
|
||||
{
|
||||
var stringContent = await _fileOperationsApiService.GetFileContent($"{request.FinalBasePath}{fileName}");
|
||||
using var stringReader = new StringReader(stringContent);
|
||||
var config = new CsvConfiguration(CultureInfo.InvariantCulture)
|
||||
{
|
||||
Delimiter = ",",
|
||||
HasHeaderRecord = true,
|
||||
HeaderValidated = null,
|
||||
MissingFieldFound = null,
|
||||
IgnoreBlankLines = true
|
||||
};
|
||||
|
||||
using var csv = new CsvReader(stringReader, config);
|
||||
var records = csv.GetRecords<T>().ToList();
|
||||
var allActivity = await CreateActivity(records);
|
||||
await _activityService.SaveActivityRangeAsync(allActivity);
|
||||
|
||||
activity.AddRange(allActivity);
|
||||
}
|
||||
|
||||
return activity;
|
||||
}
|
||||
|
||||
public async Task<IReadOnlyCollection<Activity>> CreateActivity(IEnumerable<ActionSaleRow> transactions)
|
||||
{
|
||||
var activities = new List<Activity>();
|
||||
var deadActivities = new List<DeadActivity>();
|
||||
foreach (var actionSaleRow in transactions)
|
||||
{
|
||||
var activity = new Activity()
|
||||
{
|
||||
Product = Product.Vehicle,
|
||||
Type = ActivityType.Sale,
|
||||
State = ActivityState.Accepted,
|
||||
SourceSystem = SystemType.Action,
|
||||
SourceCreated = DateTime.Parse(actionSaleRow.OPEN_DATE),
|
||||
Accepted = DateTime.Parse(actionSaleRow.OPEN_DATE).Date.AddHours(12),
|
||||
SourceId = actionSaleRow.IndAppID,
|
||||
Detail = new ActivityDetail()
|
||||
{
|
||||
AccountNumber = actionSaleRow.Account_Number,
|
||||
MemberName = actionSaleRow.Borrower_Name,
|
||||
AccountBalance = ParseMoneyDouble(actionSaleRow.IndAmtFinanced)
|
||||
},
|
||||
EmployeeEmail = null,
|
||||
EmployeeId = null,
|
||||
DepartmentId = -1
|
||||
};
|
||||
|
||||
var employee = await FindEmployee(actionSaleRow.EmailAddress);
|
||||
if (employee == null)
|
||||
{
|
||||
Log.Warning($"Action Import, No user for {actionSaleRow.EmailAddress}. Saving as Dead Activity.");
|
||||
activity.EmployeeEmail = actionSaleRow.EmailAddress;
|
||||
deadActivities.Add(new DeadActivity(activity,
|
||||
DeadActivityReason.MissingRequiredField,
|
||||
$"Action Import, No user for {actionSaleRow.EmailAddress}")
|
||||
);
|
||||
continue;
|
||||
}
|
||||
|
||||
activity.AppUserId = employee.Id;
|
||||
activity.EmployeeEmail = employee.AdEmail;
|
||||
activity.EmployeeId = employee.EmployeeId;
|
||||
|
||||
var homeDept = employee.FindHomeDepartment();
|
||||
if (homeDept == null)
|
||||
{
|
||||
Log.Warning($"User has no reliably determinable home department, {employee.EmployeeId}. Saving as Dead Activity.");
|
||||
deadActivities.Add(new DeadActivity(activity,
|
||||
DeadActivityReason.MissingRequiredField,
|
||||
$"User has no reliably determinable home department, {employee.EmployeeId}. Saving as Dead Activity."));
|
||||
continue;
|
||||
}
|
||||
|
||||
activity.DepartmentId = homeDept.DepartmentId;
|
||||
activities.Add(activity);
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
await _deadActivityService.SaveDeadActivityRange(deadActivities);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Log.Error(ex, "Failed to save dead activities from ActionVehicleImportService. Dead Activities will be lost.");
|
||||
}
|
||||
|
||||
return activities;
|
||||
}
|
||||
|
||||
public double? ParseMoneyDouble(string indAmtFinanced)
|
||||
{
|
||||
var parsed = decimal.Parse(indAmtFinanced, System.Globalization.NumberStyles.Currency, USEnglish);
|
||||
return (double)parsed;
|
||||
}
|
||||
|
||||
private async Task<AppUser> FindEmployee(string employeeEmail)
|
||||
{
|
||||
try
|
||||
{
|
||||
return await _userRepository.FindUserByAdEmailAsync(employeeEmail);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Log.Error(ex, "Error when finding user by email in ActionVehicleImportService.");
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
+12
@@ -0,0 +1,12 @@
|
||||
using LCU.Library.Internal.IncentiveApiModels.Entities;
|
||||
using LCU.API.Internal.Operations.IncentiveApi.Models.Action;
|
||||
using LCU.Library.Internal.IncentiveApiModels.Requests;
|
||||
|
||||
namespace LCU.API.Internal.Operations.IncentiveApi.Services.Action;
|
||||
|
||||
public interface IActionCreditCardImportService
|
||||
{
|
||||
Task RunActionCreditCardProcess(ActionCreditCardRequest request);
|
||||
Task<IReadOnlyCollection<Activity>> ImportTransactions<T>(string fileIdentifier, ActionCreditCardRequest request) where T : IActionFileObject;
|
||||
Task<IReadOnlyCollection<Activity>> CreateActivity<T>(IEnumerable<T> transactions) where T : IActionFileObject;
|
||||
}
|
||||
+12
@@ -0,0 +1,12 @@
|
||||
using LCU.Library.Internal.IncentiveApiModels.Entities;
|
||||
using LCU.API.Internal.Operations.IncentiveApi.Models.Action;
|
||||
using LCU.Library.Internal.IncentiveApiModels.Requests;
|
||||
|
||||
namespace LCU.API.Internal.Operations.IncentiveApi.Services.Action;
|
||||
|
||||
public interface IActionVehicleImportService
|
||||
{
|
||||
Task RunActionVehicleProcess(ActionVehicleRequest request);
|
||||
Task<IReadOnlyCollection<Activity>> ImportTransactions<T>(ActionVehicleRequest request) where T : ActionSaleRow;
|
||||
Task<IReadOnlyCollection<Activity>> CreateActivity(IEnumerable<ActionSaleRow> transactions);
|
||||
}
|
||||
Reference in New Issue
Block a user