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; 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(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); } } public async Task> ImportTransactions(ActionVehicleRequest request) where T : ActionSaleRow { var dynamicFileListRequest = request.ToDynamicActionVehicleFileListRequest(); var files = await _fileOperationsApiService.BuildDynamicFileList(dynamicFileListRequest); var activity = new List(); 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().ToList(); var allActivity = await CreateActivity(records); await _activityService.SaveActivityRangeAsync(allActivity); activity.AddRange(allActivity); } return activity; } public async Task> CreateActivity(IEnumerable transactions) { var activities = new List(); var deadActivities = new List(); 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 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; } } }