Files
2026-03-11 11:18:25 -05:00

238 lines
13 KiB
C#

using System.Xml.Linq;
using CRIF.ACTion.Common.Builders;
using CRIF.ACTion.Common;
using CRIF.ACTion.Configuration;
using CRIF.ACTion.Services.Landmark;
using Landmark.OLA.Models.Loan;
using Landmark.OLA.Models.Loan.Enums;
namespace CRIF.ACTion.Loan
{
public class AppDetailsSection : CrifRequestSection
{
private readonly string _elementName;
private readonly string _interestRateType;
private readonly string _calculationType;
private readonly ProductIdService _productIdTranslator;
protected AppDetailsSection(XNamespace sectionNamespace, string elementName, CrifSettings settings,
string interestRateType = null, string calculationType = null)
: base(sectionNamespace, "appDetails", settings)
{
_elementName = elementName;
_interestRateType = string.IsNullOrWhiteSpace(interestRateType) ? "Variable" : interestRateType;
_calculationType = string.IsNullOrWhiteSpace(calculationType) ? "OpenEnd" : calculationType;
_productIdTranslator = new ProductIdService(settings);
}
public static bool IsHMDA(LoanType? loanType)
{
HMDALoanType hmdaType;
try
{
hmdaType = (HMDALoanType)Enum.Parse(typeof(HMDALoanType), loanType.ToString());
}
catch
{
return false;
}
return true;
}
public virtual void SetDetails(LoanApplication loanApplication, Guid channelRef, object[] additionalContent = null, XElement fieldsElement = null, XElement vehicleValuationsElement = null)
{
var appDetailElement = new XElement(CrifNamespaces.App + _elementName,
new XAttribute(CrifNamespaces.App + "contractRate", 0m), //Per Ben V. at Landmark, we should send in 0 so that CRIF can set the correct rate
new XAttribute(CrifNamespaces.App + "financedAmt", loanApplication.RequestedAmount),
new XAttribute(CrifNamespaces.App + "termFrequencyCD", "Monthly"),
new XAttribute(CrifNamespaces.App + "calculationType", _calculationType),
new XAttribute(CrifNamespaces.App + "loanType", "Consumer"),
new XAttribute(CrifNamespaces.App + "interestRateType", _interestRateType),
new XAttribute(CrifNamespaces.App + "rankNum", 1),
new XAttribute(CrifNamespaces.App + "isApplicantRequestedInterestRate", false),
new XAttribute(CrifNamespaces.App + "isApplicantRequestedAmountRequested", true),
new XAttribute(CrifNamespaces.App + "principal", loanApplication.RequestedAmount), //TODO #234: Why is the loan amount listed twice?
new XAttribute(CrifNamespaces.App + "isApplicantRequestedTerm", true),
new XAttribute(CrifNamespaces.App + "isHMDAFL", IsHMDA(loanApplication.LoanType))
);
if (loanApplication.TermLengthInMonths.HasValue)
{
appDetailElement.Add(new XAttribute(CrifNamespaces.App + "termInMonths", loanApplication.TermLengthInMonths.Value));
}
var appDetailParties = new XElement(CrifNamespaces.App + "appDetailParties",
new XElement(CrifNamespaces.App + "appDetailParty",
new XAttribute(CrifNamespaces.Common + "idRef", channelRef),
new XAttribute(CrifNamespaces.Common + "partyType", "Channel"),
new XAttribute(CrifNamespaces.App + "appPartyType", "ServicingChannel")));
var appDetailRequestedAmts = new XElement(CrifNamespaces.App + "appDetailRequestedAmts",
new XElement(CrifNamespaces.App + "appDetailRequestedAmt",
new XAttribute(CrifNamespaces.App + "requestedAmount", loanApplication.RequestedAmount), //TODO #234: Financed amount is listed 3 times? Are the other 2 from the calculator?
new XAttribute(CrifNamespaces.App + "requestedAmountType", "Generic")));
var product = new XElement(CrifNamespaces.App + "product",
new XAttribute(CrifNamespaces.Common + "productID",
_productIdTranslator.GetProductId(loanApplication.LoanType.Value)));
var loanPurposes = new XElement(CrifNamespaces.App + "loanPurposes",
new XElement(CrifNamespaces.App + "appDetailLoanPurpose",
new XAttribute(CrifNamespaces.App + "rank", 1),
new XElement(CrifNamespaces.App + "loanPurpose",
new XAttribute(CrifNamespaces.Common + "CD", (int)loanApplication.Purpose.Value)
)));
appDetailElement.Add(appDetailParties);
appDetailElement.Add(additionalContent);
appDetailElement.Add(appDetailRequestedAmts);
appDetailElement.Add(product);
string productId = _productIdTranslator.GetProductId(loanApplication.LoanType.Value).ToString();
XElement appFieldsElement = null;
if (_settings.CustomFields != null && _settings.CustomFields.ProductIdToCategoryId.TryGetValue(productId, out string productCategoryId))
{
CustomPropertyStatusData customPropertyRenovationData = _settings.CustomFields.CustomPropertyRenovationFieldData.Find(x => x.ProductCategoryId == productCategoryId);
if (customPropertyRenovationData != null)
{
bool realEstateNotNullValue = loanApplication.RealEstate?.CurrentlyBeingRemodeledOrImproved ?? false;
string propertyRenovationValueCode = realEstateNotNullValue ? customPropertyRenovationData.YesId : customPropertyRenovationData.NoId;
appFieldsElement = GetLookupFieldLinkElement(customPropertyRenovationData.CustomFieldId, propertyRenovationValueCode, "AppDetail", appFieldsElement);
}
CustomPropertyStatusData customPropertySaleData = _settings.CustomFields.CustomPropertySaleFieldData.Find(x => x.ProductCategoryId == productCategoryId);
if (customPropertySaleData != null)
{
bool realEstateNotNullValue = loanApplication.RealEstate?.CurrentlyListedForSale ?? false;
string propertySaleValueCode = realEstateNotNullValue ? customPropertySaleData.YesId : customPropertySaleData.NoId;
appFieldsElement = GetLookupFieldLinkElement(customPropertySaleData.CustomFieldId, propertySaleValueCode, "AppDetail", appFieldsElement);
}
CustomJointCreditData customJointCreditData = _settings.CustomFields.CustomJointCreditFieldData.Find(x => x.ProductCategoryId == productCategoryId);
if (customJointCreditData != null)
{
string jointCreditValueCode = loanApplication.CoApplicant != null ? customJointCreditData.JointlyId : customJointCreditData.IndividuallyId;
appFieldsElement = GetLookupFieldLinkElement(customJointCreditData.CustomFieldId, jointCreditValueCode, "ProductCategory", appFieldsElement);
}
}
if (!string.IsNullOrWhiteSpace(loanApplication.PromoCode))
{
if (_settings.CustomFieldMappings.LoanTypeToPromoId.TryGetValue(productId, out string promoFieldId))
{
appFieldsElement = GetStringFieldLinkElement(promoFieldId, loanApplication.PromoCode, "ProductCategory", appFieldsElement);
}
}
if (loanApplication.Vehicle != null)
{
if (!string.IsNullOrWhiteSpace(loanApplication.Vehicle.LicensePlateNumber))
{
if (_settings.CustomFieldMappings.CustomFieldID.TryGetValue("LicensePlateNumber", out string customFieldId))
{
appFieldsElement = GetStringFieldLinkElement(customFieldId, loanApplication.Vehicle.LicensePlateNumber, "ProductCategory", appFieldsElement);
}
}
if (!string.IsNullOrWhiteSpace(loanApplication.Vehicle.CountyTitled))
{
if (_settings.CustomFieldMappings.CustomFieldID.TryGetValue("CountyTitled", out string customFieldId))
{
appFieldsElement = GetStringFieldLinkElement(customFieldId, loanApplication.Vehicle.CountyTitled, "ProductCategory", appFieldsElement);
}
}
if (!string.IsNullOrWhiteSpace(loanApplication.Vehicle.MunicipalityWhereKept))
{
if (_settings.CustomFieldMappings.CustomFieldID.TryGetValue("MunicipalityWhereKept", out string customFieldId))
{
appFieldsElement = GetStringFieldLinkElement(customFieldId, loanApplication.Vehicle.MunicipalityWhereKept, "ProductCategory", appFieldsElement);
}
}
var municipalityTypeCode = GetMunicipalityTypeCode(loanApplication.Vehicle.MunicipalityType);
if (!string.IsNullOrWhiteSpace(municipalityTypeCode))
{
if (_settings.CustomFieldMappings.CustomFieldID.TryGetValue("MunicipalityType", out string customFieldId))
{
appFieldsElement = GetLookupFieldLinkElement(customFieldId, municipalityTypeCode, "ProductCategory", appFieldsElement);
}
}
}
if (appFieldsElement != null)
{
appDetailElement.Add(appFieldsElement); //Order matters for this element.
}
appDetailElement.Add(loanPurposes);
appDetailElement.Add(vehicleValuationsElement); //Order matters for this element.
AddContent(appDetailElement);
}
private static XElement GetStringFieldLinkElement(string customFieldId, string value, string fieldLevel, XElement fieldsElement)
{
fieldsElement = CreateFieldsElementIfNull(fieldsElement);
var stringFieldLinkElement = new XElement(CrifNamespaces.Common + "stringFieldLink",
new XAttribute(CrifNamespaces.Common + "value", value));
var customFieldElement = new XElement(CrifNamespaces.Common + "customField",
new XAttribute(CrifNamespaces.Common + "ID", customFieldId),
new XAttribute(CrifNamespaces.Common + "fieldLevel", fieldLevel));
fieldsElement.Add(stringFieldLinkElement);
stringFieldLinkElement.Add(customFieldElement);
return fieldsElement;
}
private static XElement GetLookupFieldLinkElement(string Id, string value, string fieldLevel, XElement fieldsElement)
{
fieldsElement = CreateFieldsElementIfNull(fieldsElement);
var lookupFieldLinkElement = new XElement(CrifNamespaces.Common + "lookupFieldLink",
new XAttribute(CrifNamespaces.Common + "value", value),
new XElement(CrifNamespaces.Common + "customLookupField",
new XAttribute(CrifNamespaces.Common + "ID", Id),
new XAttribute(CrifNamespaces.Common + "fieldLevel", fieldLevel)));
fieldsElement.Add(lookupFieldLinkElement);
return fieldsElement;
}
private static XElement CreateFieldsElementIfNull(XElement fieldsElement)
{
if (fieldsElement == null)
{
fieldsElement = new XElement(CrifNamespaces.App + "fields");
}
return fieldsElement;
}
private string GetMunicipalityTypeCode(string municipalityType)
{
if (string.IsNullOrWhiteSpace(municipalityType))
{
return null;
}
if (_settings?.CustomFieldMappings?.MunicipalityTypeCode == null)
{
return null;
}
var key = municipalityType.Trim().ToUpperInvariant();
return _settings.CustomFieldMappings.MunicipalityTypeCode.TryGetValue(key, out string code)
? code
: null;
}
}
}