Files
2026-04-27 15:26:58 +00:00

172 lines
7.3 KiB
C#

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;
using LCU.API.Internal.Operations.IncentiveApi.Services.Transformations;
using LCU.Library.Internal.IncentiveApiModels.Results;
using LCU.Library.Internal.ApiResponse.Services;
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 SafeQueueReturnResponse.TryQueueResponse(request, _actionVehicleProcessResult.Success, _actionVehicleProcessResult.MessageStack, nameof(ActionVehicleImportService));
}
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 SafeQueueReturnResponse.TryQueueResponse(request, _actionVehicleProcessResult.Success, _actionVehicleProcessResult.MessageStack, nameof(ActionVehicleImportService));
}
}
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;
}
}
}