166 lines
6.6 KiB
C#
166 lines
6.6 KiB
C#
using System.Xml.Linq;
|
|
using CRIF.ACTion.Common;
|
|
using CRIF.ACTion.Common.Parsers;
|
|
using Serilog;
|
|
using Landmark.OLA.Models.Decisioning;
|
|
using Landmark.OLA.Models.Decisioning.Enums;
|
|
|
|
namespace CRIF.ACTion.Decisioning
|
|
{
|
|
public class GetApplicationProductsResponseParser : IResponseParser<DecisioningDetails>
|
|
{
|
|
private string LoanApplicationId;
|
|
|
|
private const string ApplicationsPath = "/actionAPI/getApplicationProducts/msg:appExportResponse/msg:applications/app:application";
|
|
private const string AppDetailsPath = "/app:application/app:appDetails";
|
|
private readonly XName AppDetailStatusesName = CrifNamespaces.App + "appDetailStatuses";
|
|
private readonly XName AppDetailStatusName = CrifNamespaces.App + "appDetailStatus";
|
|
private readonly XName StatusAttribute = CrifNamespaces.App + "statusType";
|
|
private const string DecisionTypeValue = "DecisionStatus";
|
|
private readonly XName DecisionResultName = CrifNamespaces.App + "status";
|
|
private readonly XName AppDetailStipulationsName = CrifNamespaces.App + "appDetailStipulations";
|
|
private readonly XName StipulationName = CrifNamespaces.App + "stipulation";
|
|
private readonly XName StipulationIdName = CrifNamespaces.Common + "stipulationID";
|
|
|
|
public GetApplicationProductsResponseParser()
|
|
{
|
|
}
|
|
|
|
public void SetLoanId(string loanApplicationId)
|
|
{
|
|
LoanApplicationId = loanApplicationId;
|
|
}
|
|
|
|
public DecisioningDetails Parse(XElement xElement)
|
|
{
|
|
if (string.IsNullOrWhiteSpace(LoanApplicationId))
|
|
{
|
|
throw new ArgumentException("Must set valid LoanApplicationId with SetLoanId(loanApplicationId)");
|
|
}
|
|
|
|
var namespaceManager = CrifNamespaces.GetNamespaceManager(xElement);
|
|
|
|
var applicationElement = xElement.XElementXPathSelectElement(ApplicationsPath, namespaceManager);
|
|
|
|
if (applicationElement == null)
|
|
{
|
|
//CRIF didn't recognize this application ID
|
|
throw new ArgumentException("The Application Id was not recognized by the decisioning system.");
|
|
}
|
|
|
|
if (!applicationElement.Attribute(CrifNamespaces.App + "applicationID").Value.Equals(LoanApplicationId))
|
|
{
|
|
Log.Fatal("CRIF XML does not match expected loan ID {loanId}", LoanApplicationId);
|
|
throw new InvalidOperationException("Unexpected vendor response.");
|
|
}
|
|
|
|
var appDetailElements = applicationElement.XElementXPathSelectElement(AppDetailsPath, namespaceManager).Elements().ToList();
|
|
|
|
for (int detailIndex = appDetailElements.Count - 1; detailIndex >= 0; detailIndex--)
|
|
{
|
|
var detail = appDetailElements[detailIndex];
|
|
|
|
var statuses = GetElementFromElement(detail, AppDetailStatusesName);
|
|
|
|
var decision = GetElementFromElementWithAttributeIdentifier(statuses, AppDetailStatusName, StatusAttribute, DecisionTypeValue);
|
|
|
|
if (decision == null)
|
|
{
|
|
appDetailElements.Remove(detail);
|
|
continue;
|
|
}
|
|
|
|
var decisionResult = GetAttributeFromElement(decision, DecisionResultName);
|
|
|
|
var status = (DecisioningResult)Enum.Parse(typeof(DecisioningResult), decisionResult.Value);
|
|
|
|
if (status == DecisioningResult.DecisionStatus_Cancelled)
|
|
{
|
|
appDetailElements.Remove(detail);
|
|
}
|
|
}
|
|
|
|
if (appDetailElements.Count != 1)
|
|
{
|
|
if (appDetailElements.Count == 0)
|
|
{
|
|
return new DecisioningDetails()
|
|
{
|
|
DecisioningState = DecisioningState.Unknown
|
|
};
|
|
}
|
|
|
|
throw new ArgumentException($"Application contains {appDetailElements.Count} appDetail elements. An appDetailID is required.");
|
|
}
|
|
|
|
var appDetailStatuses = GetElementFromElement(appDetailElements.SingleOrDefault(), AppDetailStatusesName);
|
|
|
|
var decisionStatus = GetElementFromElementWithAttributeIdentifier(appDetailStatuses, AppDetailStatusName, StatusAttribute, DecisionTypeValue);
|
|
|
|
var stipulations = GetStipulations(appDetailElements.Single().Element(AppDetailStipulationsName));
|
|
|
|
if (decisionStatus == null)
|
|
{
|
|
return new DecisioningDetails(stipulations)
|
|
{
|
|
DecisioningState = DecisioningState.Unknown,
|
|
};
|
|
}
|
|
else
|
|
{
|
|
var decisioningResult = GetAttributeFromElement(decisionStatus, DecisionResultName);
|
|
|
|
var statusResult = (DecisioningResult)Enum.Parse(typeof(DecisioningResult), decisioningResult.Value);
|
|
|
|
return new DecisioningDetails(stipulations)
|
|
{
|
|
DecisioningState = DecisioningState.Ready,
|
|
DecisioningResult = statusResult,
|
|
};
|
|
}
|
|
}
|
|
|
|
private ICollection<int> GetStipulations(XElement appDetailStipulations)
|
|
{
|
|
var stipulations = new List<int>();
|
|
|
|
if (appDetailStipulations is null)
|
|
{
|
|
return stipulations;
|
|
}
|
|
|
|
foreach (var stipulationElement in appDetailStipulations.Elements())
|
|
{
|
|
var appDetailStipulation = stipulationElement.Element(StipulationName);
|
|
|
|
var stipulationIdString = appDetailStipulation.Attribute(StipulationIdName).Value;
|
|
|
|
if (int.TryParse(stipulationIdString, out int stipulationId))
|
|
{
|
|
if (CrifConstants.StipulationsToShow.ContainsKey(stipulationId))
|
|
{
|
|
stipulations.Add(stipulationId);
|
|
}
|
|
}
|
|
}
|
|
|
|
return stipulations;
|
|
}
|
|
|
|
private static XElement GetElementFromElement(XElement element, XName elementToFind)
|
|
{
|
|
return element.Element(elementToFind);
|
|
}
|
|
|
|
private static XElement GetElementFromElementWithAttributeIdentifier(XElement element, XName elementToSearch, XName attribute, string identifier)
|
|
{
|
|
return element.Elements(elementToSearch).SingleOrDefault(x => x.Attribute(attribute).Value.Equals(identifier));
|
|
}
|
|
|
|
private static XAttribute GetAttributeFromElement(XElement element, XName attribute)
|
|
{
|
|
return element.Attribute(attribute);
|
|
}
|
|
}
|
|
}
|