419 lines
20 KiB
C#
419 lines
20 KiB
C#
using LCU.API.Internal.DocumentIngestor.Services.MicroApiServices;
|
|
using LCU.API.Internal.DocumentIngestor.Utilities;
|
|
using LCU.Library.DocumentType.Enums;
|
|
using LCU.Library.DocumentType.Extensions;
|
|
using LCU.Library.DocumentType.Models.Requests.Attributes;
|
|
using LCU.Library.Internal.CoreApiWrapperModel.CoreModels.Agreements;
|
|
using LCU.Library.Internal.CoreApiWrapperModel.CoreModels.Mixed;
|
|
using LCU.Library.Internal.CoreApiWrapperModel.CoreModels.Tax;
|
|
using LCU.Library.Internal.DocumentIngestorModels.Entities;
|
|
using LCU.Library.Internal.DocumentIngestorModels.Enums;
|
|
using LCU.Library.Internal.DocumentIngestorModels.Models;
|
|
using LCU.Library.Internal.Exceptions;
|
|
|
|
namespace LCU.API.Internal.DocumentIngestor.Services.AttributeDeterminingServices;
|
|
|
|
public class PrimaryOwnerDeterminingService : BaseOwnerDeterminingService, IPrimaryOwnerDeterminingService
|
|
{
|
|
private readonly ICoreApiWrapperService _coreApiWrapperService;
|
|
|
|
public PrimaryOwnerDeterminingService(ICoreApiWrapperService coreApiWrapperService)
|
|
{
|
|
_coreApiWrapperService = coreApiWrapperService;
|
|
}
|
|
|
|
public async Task<ErrorCaptureResult<PrimaryOwnerAttribute>> DeterminePrimaryOwnerAttribute(string entityName,
|
|
string accountNumber,
|
|
DateTime creationDate,
|
|
OwnerOverrideInfo overrideRequest)
|
|
{
|
|
|
|
if (overrideRequest != null)
|
|
{
|
|
return await OverridePrimaryOwnerAttribute(accountNumber, overrideRequest);
|
|
}
|
|
|
|
var primaryOwnerAttribute = new PrimaryOwnerAttribute
|
|
{
|
|
AccountNumber = accountNumber
|
|
};
|
|
|
|
var accountOwnerships = await _coreApiWrapperService.GetOwnersByAccountNumber(accountNumber, creationDate.ToShortDateString());
|
|
|
|
if (!accountOwnerships.Any())
|
|
{
|
|
var message = $"A PersonNumber or OrganizationNumber could not be determined for a Primary Owner of AccountNumber: {accountNumber} and EntityName: {entityName}. " +
|
|
"The DNA call provided no results back.";
|
|
return ErrorCaptureResult<PrimaryOwnerAttribute>.CreateErrorPayload(message, primaryOwnerAttribute);
|
|
}
|
|
|
|
var primaryOwners = accountOwnerships.Where(account => account.IsPrimaryOwner).ToList();
|
|
|
|
if (primaryOwners.Count != 1)
|
|
{
|
|
var message = $"A PersonNumber or OrganizationNumber could not be determined for an Account Owner of AccountNumber: {accountNumber} and EntityName: {entityName}. " +
|
|
$"The DNA call provided no single primary owner back, but responded with {accountOwnerships.ToDetailString()}";
|
|
return ErrorCaptureResult<PrimaryOwnerAttribute>.CreateErrorPayload(message, primaryOwnerAttribute);
|
|
}
|
|
|
|
var primaryOwner = primaryOwners.First();
|
|
|
|
var doesReturnNameMatch = primaryOwner.PersonNumber > 0
|
|
? DoesPersonNameMatchExpectedEntityName(primaryOwner, entityName)
|
|
: DoesNameMatchExpectedEntityName(primaryOwner.OrganizationName, entityName);
|
|
|
|
if (!doesReturnNameMatch)
|
|
{
|
|
var message = $"A PersonNumber or OrganizationNumber could not be determined for an Account Owner of AccountNumber: {accountNumber} and EntityName: {entityName}. " +
|
|
$"The DNA call provided a primary owner of: {primaryOwner.ToDetailString()}, which did not match the EntityName";
|
|
return ErrorCaptureResult<PrimaryOwnerAttribute>.CreateErrorPayload(message, primaryOwnerAttribute);
|
|
}
|
|
|
|
if (primaryOwner.PersonNumber > 0)
|
|
{
|
|
primaryOwnerAttribute.PersonNumber = primaryOwner.PersonNumber.ToString();
|
|
}
|
|
else
|
|
{
|
|
primaryOwnerAttribute.OrganizationNumber = primaryOwner.ByOrgNbr.ToString();
|
|
}
|
|
|
|
return ErrorCaptureResult<PrimaryOwnerAttribute>.CreateSuccessPayload(primaryOwnerAttribute);
|
|
}
|
|
|
|
public async Task<ErrorCaptureResult<PrimaryOwnerAttribute>> DeterminePrimaryOwnerAttribute(string entityName,
|
|
string accountNumber,
|
|
string taxId,
|
|
OwnerOverrideInfo overrideRequest)
|
|
{
|
|
if (overrideRequest != null)
|
|
{
|
|
return await OverridePrimaryOwnerAttribute(accountNumber, overrideRequest);
|
|
}
|
|
|
|
var primaryOwnerAttribute = new PrimaryOwnerAttribute
|
|
{
|
|
AccountNumber = accountNumber
|
|
};
|
|
|
|
var personsTaxIdData = await _coreApiWrapperService.GetPersonsTaxIdData(taxId);
|
|
var personTaxIdDataResponses = personsTaxIdData.ToList();
|
|
|
|
if (DetermineIfPrimaryOwnerIsPerson(entityName, personTaxIdDataResponses, primaryOwnerAttribute, out var errorCaptureResult))
|
|
{
|
|
return errorCaptureResult;
|
|
}
|
|
|
|
var organizationTaxIdData = await _coreApiWrapperService.GetOrganizationsTaxIdData(taxId);
|
|
var organizationTaxIdDataResponses = organizationTaxIdData.ToList();
|
|
|
|
if (DetermineIfPrimaryOwnerIsOrganization(entityName, organizationTaxIdDataResponses, primaryOwnerAttribute, out var successPayload))
|
|
{
|
|
return successPayload;
|
|
}
|
|
|
|
if (!organizationTaxIdDataResponses.Any() && !personTaxIdDataResponses.Any())
|
|
{
|
|
var message = $"A PersonNumber or OrganizationNumber could not be determined for an Account Owner of AccountNumber: {accountNumber}, Tin: {taxId} and EntityName: {entityName}. " +
|
|
"The DNA call provided no results back.";
|
|
return ErrorCaptureResult<PrimaryOwnerAttribute>.CreateErrorPayload(message, primaryOwnerAttribute);
|
|
}
|
|
|
|
var errorMessage = $"A PersonNumber or OrganizationNumber could not be determined for an Account Owner of AccountNumber: {accountNumber}, Tin: {taxId} and EntityName: {entityName}. " +
|
|
"The DNA call provided no primary owner back, but responded with " +
|
|
string.Join
|
|
(
|
|
"; ",
|
|
personTaxIdDataResponses.ToDetailString(),
|
|
organizationTaxIdDataResponses.ToDetailString()
|
|
);
|
|
|
|
return ErrorCaptureResult<PrimaryOwnerAttribute>.CreateErrorPayload(errorMessage, primaryOwnerAttribute);
|
|
}
|
|
|
|
public async Task<ErrorCaptureResult<PrimaryOwnerAttribute>> DeterminePrimaryOwnerAttributeByMemberNumberOrUserId(string memberNumberOrUserId,
|
|
string accountNumber,
|
|
string docType,
|
|
DateTime creationDate,
|
|
OwnerOverrideInfo overrideRequest)
|
|
{
|
|
if (overrideRequest != null)
|
|
{
|
|
return await OverridePrimaryOwnerAttribute(accountNumber, overrideRequest);
|
|
}
|
|
|
|
var primaryOwnerAttribute = new PrimaryOwnerAttribute()
|
|
{
|
|
AccountNumber = accountNumber
|
|
};
|
|
|
|
Agreement? agreementByMemberNumberOrUserId;
|
|
long personNumber = 0;
|
|
long orgNumber = 0;
|
|
|
|
if (
|
|
memberNumberOrUserId.ToUpper().StartsWith("M") ||
|
|
EnumExtensions.GetValueFromName<PrimaryOwnerDocumentTypes>(docType) == PrimaryOwnerDocumentTypes.MmStmxt
|
|
)
|
|
{
|
|
try
|
|
{
|
|
PersonOrganization personOrganization = await _coreApiWrapperService.GetPersonOrOrganizationNumberByMemberId(memberNumberOrUserId.ToUpper().TrimStart('M'));
|
|
|
|
if (personOrganization.PersonNumber != null)
|
|
{
|
|
personNumber = long.Parse(personOrganization.PersonNumber);
|
|
}
|
|
else if (personOrganization.OrganizationNumber != null)
|
|
{
|
|
orgNumber = long.Parse(personOrganization.OrganizationNumber);
|
|
}
|
|
else
|
|
{
|
|
return ErrorCaptureResult<PrimaryOwnerAttribute>.CreateErrorPayload($"Error finding PersonOrganization by MemberId: {memberNumberOrUserId}", primaryOwnerAttribute);
|
|
}
|
|
}
|
|
catch (ServiceException ex)
|
|
{
|
|
return ErrorCaptureResult<PrimaryOwnerAttribute>.CreateErrorPayload(ex.Message, primaryOwnerAttribute);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
try
|
|
{
|
|
agreementByMemberNumberOrUserId = await _coreApiWrapperService.GetAgreementByUserId(memberNumberOrUserId);
|
|
|
|
if (agreementByMemberNumberOrUserId == null)
|
|
{
|
|
var message =
|
|
$"An agreement could not be found from GetAgreementByUserId for User ID: {memberNumberOrUserId}";
|
|
return ErrorCaptureResult<PrimaryOwnerAttribute>.CreateErrorPayload(message, primaryOwnerAttribute);
|
|
}
|
|
|
|
personNumber = agreementByMemberNumberOrUserId.PersonNumber;
|
|
orgNumber = agreementByMemberNumberOrUserId.ByOrgNbr;
|
|
} catch (ServiceException ex)
|
|
{
|
|
return ErrorCaptureResult<PrimaryOwnerAttribute>.CreateErrorPayload(ex.Message, primaryOwnerAttribute);
|
|
}
|
|
}
|
|
|
|
if (EnumExtensions.GetValueFromName<PrimaryOwnerDocumentTypes>(docType) == PrimaryOwnerDocumentTypes.MmStmxt)
|
|
{
|
|
try
|
|
{
|
|
var agreementAccount = await _coreApiWrapperService.GetAgreementAccountByAccountId(accountNumber);
|
|
|
|
if (agreementAccount == null)
|
|
{
|
|
var message =
|
|
$"An agreement account could not be found from GetAgreementAccountByAccountId for Account Number: {accountNumber}";
|
|
return ErrorCaptureResult<PrimaryOwnerAttribute>.CreateErrorPayload(message, primaryOwnerAttribute);
|
|
}
|
|
|
|
if (personNumber != agreementAccount.TaxReportForPersonNumber && orgNumber != agreementAccount.TaxReportForOrgNumber)
|
|
{
|
|
var message =
|
|
$"Person numbers ({personNumber}/{agreementAccount.TaxReportForPersonNumber}) and Organization numbers ({orgNumber}/{agreementAccount.TaxReportForOrgNumber}) did not match from GetAgreementAccountByAccountId for Account Number: {accountNumber}";
|
|
return ErrorCaptureResult<PrimaryOwnerAttribute>.CreateErrorPayload(message, primaryOwnerAttribute);
|
|
}
|
|
|
|
}
|
|
catch (ServiceException ex)
|
|
{
|
|
return ErrorCaptureResult<PrimaryOwnerAttribute>.CreateErrorPayload(ex.Message, primaryOwnerAttribute);
|
|
}
|
|
}
|
|
|
|
if (orgNumber == 0)
|
|
{
|
|
primaryOwnerAttribute.PersonNumber = personNumber.ToString();
|
|
}
|
|
else
|
|
{
|
|
primaryOwnerAttribute.OrganizationNumber = orgNumber.ToString();
|
|
}
|
|
|
|
return ErrorCaptureResult<PrimaryOwnerAttribute>.CreateSuccessPayload(primaryOwnerAttribute);
|
|
}
|
|
|
|
public async Task<ErrorCaptureResult<PrimaryOwnerAttribute>> DeterminePrimaryOwnerAttributeByMemberNumberOrUserId(string memberNumberOrUserId,
|
|
string entityName,
|
|
OwnerOverrideInfo overrideRequest)
|
|
{
|
|
var primaryOwnerAttribute = new PrimaryOwnerAttribute();
|
|
|
|
if (overrideRequest != null)
|
|
{
|
|
return await OverridePrimaryOwnerAttribute(null, overrideRequest);
|
|
}
|
|
|
|
Agreement? agreementByMemberNumberOrUserId;
|
|
var returnedName = string.Empty;
|
|
long personNumber = 0;
|
|
long orgNumber = 0;
|
|
|
|
if (memberNumberOrUserId.ToUpper().StartsWith("M") || memberNumberOrUserId.ToUpper().StartsWith("C"))
|
|
{
|
|
try
|
|
{
|
|
PersonOrganization personOrganization = await _coreApiWrapperService.GetPersonOrOrganizationNumberByMemberId(memberNumberOrUserId.ToUpper().TrimStart('M').TrimStart('C'));
|
|
|
|
if (personOrganization.PersonNumber != null)
|
|
{
|
|
personNumber = long.Parse(personOrganization.PersonNumber);
|
|
returnedName = personOrganization.EntityName;
|
|
}
|
|
else if (personOrganization.OrganizationNumber != null)
|
|
{
|
|
orgNumber = long.Parse(personOrganization.OrganizationNumber);
|
|
returnedName = personOrganization.EntityName;
|
|
}
|
|
else
|
|
{
|
|
return ErrorCaptureResult<PrimaryOwnerAttribute>.CreateErrorPayload($"Error finding PersonOrganization by MemberId: {memberNumberOrUserId}", primaryOwnerAttribute);
|
|
}
|
|
}
|
|
catch (ServiceException ex)
|
|
{
|
|
return ErrorCaptureResult<PrimaryOwnerAttribute>.CreateErrorPayload(ex.Message, primaryOwnerAttribute);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
try
|
|
{
|
|
agreementByMemberNumberOrUserId = await _coreApiWrapperService.GetAgreementByUserId(memberNumberOrUserId);
|
|
|
|
if (agreementByMemberNumberOrUserId == null)
|
|
{
|
|
// Checking to make sure UserId is not improperly mapped memberNumber
|
|
PersonOrganization personOrganization = await _coreApiWrapperService.GetPersonOrOrganizationNumberByMemberId(memberNumberOrUserId.ToUpper().TrimStart('M').TrimStart('C'));
|
|
|
|
if (personOrganization.PersonNumber != null)
|
|
{
|
|
personNumber = long.Parse(personOrganization.PersonNumber);
|
|
returnedName = personOrganization.EntityName;
|
|
}
|
|
else if (personOrganization.OrganizationNumber != null)
|
|
{
|
|
orgNumber = long.Parse(personOrganization.OrganizationNumber);
|
|
returnedName = personOrganization.EntityName;
|
|
}
|
|
else
|
|
{
|
|
var message =
|
|
$"An agreement could not be found from GetAgreementByUserId for User ID: {memberNumberOrUserId}";
|
|
return ErrorCaptureResult<PrimaryOwnerAttribute>.CreateErrorPayload(message, primaryOwnerAttribute);
|
|
}
|
|
|
|
}
|
|
else
|
|
{
|
|
personNumber = agreementByMemberNumberOrUserId.PersonNumber;
|
|
orgNumber = agreementByMemberNumberOrUserId.ByOrgNbr;
|
|
|
|
if (orgNumber == 0)
|
|
{
|
|
returnedName = $"{agreementByMemberNumberOrUserId.FirstName} {agreementByMemberNumberOrUserId.MiddleInitial} {agreementByMemberNumberOrUserId.LastName} {agreementByMemberNumberOrUserId.Suffix}";
|
|
}
|
|
else
|
|
{
|
|
returnedName = agreementByMemberNumberOrUserId.OrganizationName;
|
|
}
|
|
}
|
|
|
|
} catch (ServiceException ex)
|
|
{
|
|
return ErrorCaptureResult<PrimaryOwnerAttribute>.CreateErrorPayload(ex.Message, primaryOwnerAttribute);
|
|
}
|
|
}
|
|
|
|
if (!DoesNameMatchExpectedEntityName(returnedName, entityName))
|
|
{
|
|
var message =
|
|
$"The entityName ({entityName}) did not match from GetAgreementAccountByAccountId for returnedName: {returnedName}";
|
|
return ErrorCaptureResult<PrimaryOwnerAttribute>.CreateErrorPayload(message, primaryOwnerAttribute);
|
|
}
|
|
|
|
if (orgNumber == 0)
|
|
{
|
|
primaryOwnerAttribute.PersonNumber = personNumber.ToString();
|
|
}
|
|
else
|
|
{
|
|
primaryOwnerAttribute.OrganizationNumber = orgNumber.ToString();
|
|
}
|
|
|
|
return ErrorCaptureResult<PrimaryOwnerAttribute>.CreateSuccessPayload(primaryOwnerAttribute);
|
|
}
|
|
|
|
private async Task<ErrorCaptureResult<PrimaryOwnerAttribute>> OverridePrimaryOwnerAttribute(string accountNumber, OwnerOverrideInfo request)
|
|
{
|
|
var primaryOwnerAttribute = new PrimaryOwnerAttribute()
|
|
{
|
|
AccountNumber = accountNumber,
|
|
PersonNumber = request.EntityType == EntityTypes.Person ? request.EntityId : null,
|
|
OrganizationNumber = request.EntityType == EntityTypes.Organization ? request.EntityId : null,
|
|
};
|
|
|
|
return ErrorCaptureResult<PrimaryOwnerAttribute>.CreateSuccessPayload(primaryOwnerAttribute);
|
|
}
|
|
|
|
private static bool DetermineIfPrimaryOwnerIsPerson(string entityName,
|
|
IReadOnlyCollection<PersonTaxIdDataResponse> personTaxIdDataResponses,
|
|
PrimaryOwnerAttribute primaryOwnerAttribute,
|
|
out ErrorCaptureResult<PrimaryOwnerAttribute>? errorCaptureResult)
|
|
{
|
|
errorCaptureResult = null;
|
|
|
|
if (!personTaxIdDataResponses.Any())
|
|
{
|
|
return false;
|
|
}
|
|
var personNumber = personTaxIdDataResponses
|
|
.Where(person => DoesNameMatchExpectedEntityName(person.NameLastFirstMiddleSuffix, entityName))
|
|
.Select(p => p.PersonNumber).FirstOrDefault();
|
|
|
|
var personNumberString = personNumber <= 0 ? null : personNumber.ToString();
|
|
|
|
if (string.IsNullOrEmpty(personNumberString))
|
|
{
|
|
return false;
|
|
}
|
|
|
|
primaryOwnerAttribute.PersonNumber = personNumberString;
|
|
errorCaptureResult = ErrorCaptureResult<PrimaryOwnerAttribute>.CreateSuccessPayload(primaryOwnerAttribute);
|
|
return true;
|
|
}
|
|
|
|
private static bool DetermineIfPrimaryOwnerIsOrganization(string entityName,
|
|
IReadOnlyCollection<OrganizationTaxIdDataResponse> organizationTaxIdDataResponses,
|
|
PrimaryOwnerAttribute primaryOwnerAttribute,
|
|
out ErrorCaptureResult<PrimaryOwnerAttribute>? successPayload)
|
|
{
|
|
successPayload = null;
|
|
|
|
if (!organizationTaxIdDataResponses.Any())
|
|
{
|
|
return false;
|
|
}
|
|
|
|
var organizationNumber = organizationTaxIdDataResponses
|
|
.Where(org => DoesNameMatchExpectedEntityName(org.Name, entityName))
|
|
.Select(p => p.OrganizationNumber).FirstOrDefault();
|
|
|
|
var organizationNumberString = organizationNumber != 0 ? organizationNumber.ToString() : null;
|
|
|
|
if (string.IsNullOrEmpty(organizationNumberString))
|
|
{
|
|
return false;
|
|
}
|
|
|
|
primaryOwnerAttribute.OrganizationNumber = organizationNumberString;
|
|
successPayload = ErrorCaptureResult<PrimaryOwnerAttribute>.CreateSuccessPayload(primaryOwnerAttribute);
|
|
return true;
|
|
}
|
|
}
|