Files
monorepo/LCU.API.Internal.DocumentIngestor/LCU.API.Internal.DocumentIngestor/Services/DocumentProcessorServices/FosDnaDocumentProcessingService.cs
T
2026-03-25 14:50:13 -05:00

258 lines
14 KiB
C#

using System.Globalization;
using LCU.API.Internal.DocumentIngestor.Services.AttributeDeterminingServices;
using LCU.API.Internal.DocumentIngestor.Services.MicroApiServices;
using LCU.Library.DocumentType.Enums;
using LCU.Library.DocumentType.Extensions;
using LCU.Library.DocumentType.Models.Requests.Account;
using LCU.Library.DocumentType.Models.Requests.Attributes;
using LCU.Library.DocumentType.Models.Requests.PrimaryOwner;
using LCU.Library.Internal.DocumentIngestorModels.Entities;
using LCU.Library.Internal.DocumentIngestorModels.Enums;
using LCU.Library.Internal.DocumentIngestorModels.Models;
using LCU.Library.Internal.DocumentIngestorModels.Models.IndexFileDocuments;
using LCU.Library.Internal.DocumentIngestorModels.Validations;
using LCU.Library.Internal.LCUServiceFactory.Configurations;
using Newtonsoft.Json;
using Serilog;
namespace LCU.API.Internal.DocumentIngestor.Services.DocumentProcessorServices
{
public class FosDnaDocumentProcessingService : DocumentProcessingService, IDocumentProcessingService
{
private const DataSourceTypes DataSource = DataSourceTypes.DNA;
private const SourceTypes Source = SourceTypes.FOS;
private readonly IPrimaryOwnerDeterminingService _primaryOwnerDeterminingService;
private readonly IAccountOwnerDeterminingService _accountOwnerDeterminingService;
private readonly IFileOperationsApiService _fileOperationsApiService;
private readonly IDocumentTypeUploaderApiService _documentTypeUploaderApiService;
public FosDnaDocumentProcessingService(IPrimaryOwnerDeterminingService primaryOwnerDeterminingService,
IAccountOwnerDeterminingService accountDeterminingService,
IFileOperationsApiService fileOperationsApiService,
IDocumentTypeUploaderApiService documentTypeUploaderApiService,
ServicesFactoryConfiguration servicesFactoryConfiguration)
: base(servicesFactoryConfiguration)
{
_documentTypeUploaderApiService = documentTypeUploaderApiService;
_fileOperationsApiService = fileOperationsApiService;
_primaryOwnerDeterminingService = primaryOwnerDeterminingService;
_accountOwnerDeterminingService = accountDeterminingService;
}
public async Task<ProcessResult> ProcessRequest(ProcessingRequest request)
{
var processResult = new ProcessResult();
try
{
Log.Debug("Starting FosDnaDocument ProcessRequest.");
ArgumentNullException.ThrowIfNull(request);
var documentValues = JsonConvert.DeserializeObject<FosDnaDocument>(request.DocumentValuePayload);
ArgumentNullException.ThrowIfNull(documentValues);
processResult = ValidateRecord(processResult, documentValues, request.OwnerOverrideInfo);
if (!processResult.Success)
{
return processResult;
}
if (!DateTime.TryParseExact(documentValues.CreationDate, "MMddyyyy", CultureInfo.InvariantCulture, DateTimeStyles.AssumeLocal, out var creationDate))
{
var message = $"A Creation Date of '{documentValues.CreationDate}' could not be properly formatted " +
$"for an Account Owner of AccountNumber: {documentValues?.AccountNumber} and EntityName: {documentValues?.EntityName}";
processResult = ProcessResult.ProcessDataMappingFailure(processResult, message);
return processResult;
}
if (EnumExtensions.IsDocumentTypeOf<PrimaryOwnerDocumentTypes>(documentValues.DocType))
{
processResult = await HandlePrimaryOwner(request, processResult, documentValues, creationDate);
}
else if (EnumExtensions.IsDocumentTypeOf<AccountDocumentTypes>(documentValues.DocType))
{
processResult = await HandleAccountOwner(request, processResult, documentValues, creationDate);
}
else
{
var message = $"Document Type of {documentValues.DocType} could not be found." +
$"for an Account Owner of AccountNumber: {documentValues?.AccountNumber} and EntityName: {documentValues?.EntityName}";
Log.Error(message);
processResult = ProcessResult.ProcessCriticalFailure(processResult, message);
return processResult;
}
Log.Debug("Ending FosDna ProcessRequest.");
}
catch (Exception exception)
{
var message = "An Exception occured while FosDnaDocument ProcessRequest. " +
$"Exception Message: {exception.Message} ";
Log.Error(exception, message);
processResult = ProcessResult.ProcessCriticalFailure(processResult, message);
}
return processResult;
}
public ProcessResult ValidateRecord(ProcessResult processResult,
FosDnaDocument documentValues,
OwnerOverrideInfo? ownerOverrideInfo)
{
// Keep at top to set EntityUnknown for PsInfoChangeNotice documents with invalid Account Numbers
// Business would like override to skip AccountNumber validation for PsInfoChangeNotice
if (!SkipAccountNumberValidationForPsInfoChangeNotice(documentValues.DocType, ownerOverrideInfo))
{
processResult = MetaDataValidation.ValidateAccountNumber(processResult, documentValues.AccountNumber);
processResult = SetToEntityUnknown(processResult, documentValues.DocType, ownerOverrideInfo);
}
processResult = MetaDataValidation.ValidateFileName(processResult, documentValues.DocName);
processResult = MetaDataValidation.ValidateFullName(processResult, documentValues.EntityName);
return processResult;
}
public async Task<ProcessResult> HandlePrimaryOwner(ProcessingRequest request,
ProcessResult processResult,
FosDnaDocument documentValues,
DateTime creationDate)
{
var primaryOwnerAttribute = await _primaryOwnerDeterminingService.DeterminePrimaryOwnerAttribute(documentValues.EntityName,
documentValues.AccountNumber,
creationDate,
request.OwnerOverrideInfo);
if (!primaryOwnerAttribute.Success)
{
processResult = ProcessResult.ProcessDataMappingFailure(processResult,
primaryOwnerAttribute.Message);
return processResult;
}
var primaryOwnerRequest = await BuildPrimaryOwnerUploadRequest(request, documentValues, creationDate, primaryOwnerAttribute.Payload);
await _documentTypeUploaderApiService.UploadPrimaryOwnerDocument(primaryOwnerRequest, request, processResult);
return processResult;
}
public async Task<ProcessResult> HandleAccountOwner(ProcessingRequest request,
ProcessResult processResult,
FosDnaDocument documentValues,
DateTime creationDate)
{
var accountOwnerAttribute = await _accountOwnerDeterminingService.DetermineAccountOwnerAttribute(documentValues.EntityName,
documentValues.AccountNumber,
creationDate,
request.OwnerOverrideInfo);
if (!accountOwnerAttribute.Success)
{
processResult = ProcessResult.ProcessDataMappingFailure(processResult,
accountOwnerAttribute.Message);
return processResult;
}
var accountOwnerRequest = await BuildAccountUploadRequest(request, documentValues, creationDate, accountOwnerAttribute.Payload);
await _documentTypeUploaderApiService.UploadAccountDocument(accountOwnerRequest, request, processResult);
return processResult;
}
public async Task<PrimaryOwnerDocumentRequest> BuildPrimaryOwnerUploadRequest(ProcessingRequest request,
FosDnaDocument documentValues,
DateTime creationDate,
PrimaryOwnerAttribute primaryOwnerAttribute)
{
var contentBytes = await _fileOperationsApiService.GetContentBytes(request.IngestorRequest.RootPath,
request.DocumentFileName);
var type = documentValues.DocType.GetValueFromName<PrimaryOwnerDocumentTypes>();
ArgumentNullException.ThrowIfNull(type);
var primaryOwnerDocumentRequest = new PrimaryOwnerDocumentRequest
{
Content = contentBytes,
PrimaryOwnerAttribute = primaryOwnerAttribute,
PrimaryOwnerDocumentMetadata = new PrimaryOwnerDocumentMetadata
{
Source = Source,
DataSource = DataSource,
Name = documentValues.DocName,
Type = type,
CreatedDate = creationDate,
TraceId = request.IngestorRunInfoId
}
};
return primaryOwnerDocumentRequest;
}
public async Task<AccountDocumentRequest> BuildAccountUploadRequest(ProcessingRequest request,
FosDnaDocument documentValues,
DateTime creationDate,
AccountAttribute accountAttribute)
{
var contentBytes = await _fileOperationsApiService.GetContentBytes(request.IngestorRequest.RootPath,
request.DocumentFileName);
var type = documentValues.DocType.GetValueFromName<AccountDocumentTypes>();
ArgumentNullException.ThrowIfNull(type);
var accountOwnerDocumentRequest = new AccountDocumentRequest
{
Content = contentBytes,
AccountAttribute = accountAttribute,
AccountDocumentMetadata = new AccountDocumentMetadata
{
Source = Source,
DataSource = DataSource,
Name = documentValues.DocName,
Type = type,
CreatedDate = creationDate,
TraceId = request.IngestorRunInfoId
}
};
return accountOwnerDocumentRequest;
}
private ProcessResult SetToEntityUnknown(ProcessResult processResult,
string documentType,
OwnerOverrideInfo? ownerOverrideInfo)
{
if (string.IsNullOrWhiteSpace(documentType)
|| processResult.Success
|| processResult.ProcessStatusType != ProcessStatusTypes.DataMappingFailure
|| ownerOverrideInfo is not null)
{
return processResult;
}
if (EnumExtensions.IsDocumentTypeOf<PrimaryOwnerDocumentTypes>(documentType))
{
switch (documentType.GetValueFromName<PrimaryOwnerDocumentTypes>())
{
case PrimaryOwnerDocumentTypes.PsInfoChangeNotice:
processResult.EntityIsUnknown = true;
break;
}
}
return processResult;
}
private bool SkipAccountNumberValidationForPsInfoChangeNotice(string docType, OwnerOverrideInfo? ownerOverrideInfo)
{
if (!EnumExtensions.IsDocumentTypeOf<PrimaryOwnerDocumentTypes>(docType))
{
return false;
}
if (ownerOverrideInfo is null
|| docType.GetValueFromName<PrimaryOwnerDocumentTypes>() != PrimaryOwnerDocumentTypes.PsInfoChangeNotice)
{
return false;
}
return true;
}
}
}