first commit
This commit is contained in:
+24
@@ -0,0 +1,24 @@
|
||||
using System.Xml.Linq;
|
||||
using CRIF.ACTion.Common;
|
||||
using CRIF.ACTion.Common.Builders;
|
||||
|
||||
namespace CRIF.ACTion.Configuration
|
||||
{
|
||||
public class ConfigurationRequestBuilder : BuilderBase
|
||||
{
|
||||
private readonly string SettingName;
|
||||
|
||||
public ConfigurationRequestBuilder(string settingName, CrifSettings settings)
|
||||
: base(CrifNamespaces.Empty, settings)
|
||||
{
|
||||
SettingName = settingName;
|
||||
}
|
||||
|
||||
public override XElement Build(params XElement[] content)
|
||||
{
|
||||
var retrieveCriffConfigurationElement = new XElement(CrifNamespaces.Empty + SettingName);
|
||||
return base.Build(retrieveCriffConfigurationElement);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
+78
@@ -0,0 +1,78 @@
|
||||
using System.Xml.Linq;
|
||||
using Serilog;
|
||||
using CRIF.ACTion.Common;
|
||||
using CRIF.ACTion.Common.Parsers;
|
||||
|
||||
namespace CRIF.ACTion.Configuration
|
||||
{
|
||||
public class ConfigurationRequestResponseParser : IResponseParser<SortedList<int, string>>
|
||||
{
|
||||
private const string _channelsPath = "/actionAPI/getChannels/msg:maintExportResponse/msg:maintenanceEntities/maint:parties/common:channel/common:channelClassifications/common:channelClassification/common:channelClassificationItem";
|
||||
|
||||
public ConfigurationRequestResponseParser()
|
||||
{
|
||||
}
|
||||
|
||||
public SortedList<int, string> Parse(XElement xElement)
|
||||
{
|
||||
SortedList<int, string> mappingList = [];
|
||||
|
||||
try
|
||||
{
|
||||
var namespaceManager = CrifNamespaces.GetNamespaceManager(xElement);
|
||||
IEnumerable<XElement> channelNodeList = xElement.XElementXPathSelectElements(_channelsPath, namespaceManager);
|
||||
|
||||
foreach (XElement channelNode in channelNodeList)
|
||||
{
|
||||
try
|
||||
{
|
||||
string nodeAttributeValue = StandardizedStringValue(channelNode.Attribute(CrifNamespaces.Common + "name").Value);
|
||||
if (ChannelIsActive(nodeAttributeValue))
|
||||
{
|
||||
|
||||
string partyIdString = channelNode.Parent.Parent.Parent.Attribute(CrifNamespaces.Common + "partyID").Value;
|
||||
string name = channelNode.Parent.Parent.Parent.Attribute(CrifNamespaces.Common + "name").Value;
|
||||
_ = int.TryParse(partyIdString, out int partyId);
|
||||
mappingList.Add(partyId, name);
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Log.Error("Error trying to parse CRIF BranchName Configuration Response", ex.Message, ex.StackTrace);
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Log.Error("Error trying to parse CRIF BranchName Configuration Response", ex.Message, ex.StackTrace);
|
||||
}
|
||||
return mappingList;
|
||||
}
|
||||
|
||||
private static bool ChannelIsActive(string nodeAttributeValue)
|
||||
{
|
||||
bool channelIsActive = false;
|
||||
if (!string.IsNullOrWhiteSpace(nodeAttributeValue))
|
||||
{
|
||||
channelIsActive =
|
||||
(
|
||||
nodeAttributeValue.Equals("BRANCH") ||
|
||||
nodeAttributeValue.Equals("INTERNET") ||
|
||||
nodeAttributeValue.Equals("ON-LINE")
|
||||
);
|
||||
}
|
||||
return channelIsActive;
|
||||
}
|
||||
|
||||
private static string StandardizedStringValue(string InputString)
|
||||
{
|
||||
string standardizedString = "";
|
||||
if (!string.IsNullOrWhiteSpace(InputString))
|
||||
{
|
||||
standardizedString = InputString.Trim().ToUpper();
|
||||
}
|
||||
return standardizedString;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,86 @@
|
||||
|
||||
namespace CRIF.ACTion
|
||||
{
|
||||
|
||||
/************
|
||||
This file should be migrated to appsettings.json and the CrifSettings class
|
||||
*************/
|
||||
public class CrifConstants
|
||||
{
|
||||
public static TimeSpan SubmissionTimeoutInMinutes => new(0, 2, 0);
|
||||
|
||||
public static int EQ_ListedForSale_Field_Id = -110;
|
||||
public static int EQ_ListedForSale_Field_True = 272;
|
||||
public static int EQ_ListedForSale_Field_False = 271;
|
||||
|
||||
public static int EQ_CurrentlyBeingRemodeledOrImproved_Field_Id = -109;
|
||||
public static int EQ_CurrentlyBeingRemodeledOrImproved_Field_True = 270;
|
||||
public static int EQ_CurrentlyBeingRemodeledOrImproved_Field_False = 269;
|
||||
|
||||
public static int Borrower_IsApplicantNonSigningSpouse_Field_Id = -73;
|
||||
public static int Borrower_IsApplicantNonSigningSpouse_Field_Borrower = 85;
|
||||
public static int Borrower_IsApplicantNonSigningSpouse_Field_NonSigningMarriedToPrimary = 84;
|
||||
public static int Borrower_IsApplicantNonSigningSpouse_Field_NonSigningMarriedToCo = 83;
|
||||
|
||||
public static int TCPA_Opt_Out_Field_Id = -112;
|
||||
|
||||
public static Dictionary<Collateral, int> CollateralIds = new Dictionary<Collateral, int>
|
||||
{
|
||||
//Take from CRIF database: select * from v_RptLuCollateralType_v001
|
||||
{Collateral.Vehicle, 1},
|
||||
{Collateral.ResidentialRealEstate, 2},
|
||||
{Collateral.Marine, 3},
|
||||
{Collateral.ManufacturedHome, 4},
|
||||
{Collateral.RecreationalVehicle, 5},
|
||||
{Collateral.Stocks, 6},
|
||||
{Collateral.Bonds, 7},
|
||||
{Collateral.Insurance, 8},
|
||||
{Collateral.CDs, 9},
|
||||
{Collateral.CDsOrSavings, 18},
|
||||
{Collateral.Collateral401k, 10},
|
||||
{Collateral.CommercialRealEstate, 11},
|
||||
{Collateral.AccountsReceivable, 12},
|
||||
{Collateral.SecuredOther, 13},
|
||||
{Collateral.ManufacturedHomeAndLand, 14},
|
||||
{Collateral.Motorcycle, 15},
|
||||
{Collateral.ATV, 16},
|
||||
{Collateral.Snowmobile, 17},
|
||||
};
|
||||
|
||||
public static int SpecialHandlingCode_OneBorrower_with_NonapplicantSpouse = 8;
|
||||
|
||||
public static Dictionary<int, string> StipulationsToShow = new Dictionary<int, string>
|
||||
{
|
||||
//matches occur by int ID. Text is only used to easily identify stipulations.
|
||||
{20, "A Personal Guaranty form is required for all business loans" },
|
||||
{92, "Cards can only be issued to business owner and owner's spouse"},
|
||||
{58, "Final Approval is dependent on Appraisal, Title, and Flood"},
|
||||
{82, "Landmark Business savings account must be established."},
|
||||
{85, "Must show proof borrower is a current student."},
|
||||
{59, "Two years of income verification is required"},
|
||||
};
|
||||
|
||||
public enum Collateral
|
||||
{
|
||||
//These enum int values have no relation to CRIF's int values. Use the dictionary above instead.
|
||||
Vehicle,
|
||||
ResidentialRealEstate,
|
||||
Marine,
|
||||
ManufacturedHome,
|
||||
RecreationalVehicle,
|
||||
Stocks,
|
||||
Bonds,
|
||||
Insurance,
|
||||
CDs,
|
||||
CDsOrSavings,
|
||||
Collateral401k, //enums must start with a letter
|
||||
CommercialRealEstate,
|
||||
AccountsReceivable,
|
||||
SecuredOther,
|
||||
ManufacturedHomeAndLand,
|
||||
Motorcycle,
|
||||
ATV,
|
||||
Snowmobile,
|
||||
};
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,106 @@
|
||||
|
||||
namespace CRIF.ACTion.Configuration
|
||||
{
|
||||
public class CrifSettings
|
||||
{
|
||||
public ApiConnectionSettings ApiSettings { get; set; }
|
||||
public SourceChannelSettings SourceChannels { get; set; }
|
||||
public ProductIdSettings ProductIds { get; set; }
|
||||
public ServicingChannelSettings ServicingChannels { get; set; }
|
||||
public CustomFieldMappings CustomFieldMappings { get; set; }
|
||||
public CustomFieldConfigs CustomFields { get; set; }
|
||||
public FormatCategorySettings FormatCategoryMappings { get; set; }
|
||||
}
|
||||
|
||||
public class CustomJointCreditData
|
||||
{
|
||||
public string CustomFieldId { get; set; }
|
||||
|
||||
public string ProductCategoryId { get; set; }
|
||||
|
||||
public string SortOrder { get; set; }
|
||||
|
||||
public string IndividuallyId { get; set; }
|
||||
|
||||
public string JointlyId { get; set; }
|
||||
}
|
||||
|
||||
public class CustomPropertyStatusData
|
||||
{
|
||||
public string CustomFieldId { get; set; }
|
||||
|
||||
public string ProductCategoryId { get; set; }
|
||||
|
||||
public string SortOrder { get; set; }
|
||||
|
||||
public string YesId { get; set; }
|
||||
|
||||
public string NoId { get; set; }
|
||||
|
||||
public string NaId { get; set; }
|
||||
}
|
||||
|
||||
public class CustomFieldConfigs
|
||||
{
|
||||
public List<CustomPropertyStatusData> CustomPropertyRenovationFieldData { get; set; }
|
||||
public List<CustomPropertyStatusData> CustomPropertySaleFieldData { get; set; }
|
||||
public List<CustomJointCreditData> CustomJointCreditFieldData { get; set; }
|
||||
public Dictionary<string, string> ProductIdToCategoryId { get; set; }
|
||||
}
|
||||
|
||||
public class CustomFieldMappings
|
||||
{
|
||||
public Dictionary<string, string> LoanTypeToPromoId { get; set; }
|
||||
public Dictionary<string, string> CustomFieldID { get; set; }
|
||||
public Dictionary<string, string> MunicipalityTypeCode { get; set; }
|
||||
}
|
||||
|
||||
public class CustomFieldIDMappings
|
||||
{
|
||||
public Dictionary<string, string> CustomFieldID { get; set; }
|
||||
}
|
||||
|
||||
public class ApiConnectionSettings
|
||||
{
|
||||
public string EndpointUrl { get; set; }
|
||||
public string Username { get; set; }
|
||||
public int InterfaceId { get; set; }
|
||||
public string OrgCode { get; set; }
|
||||
public int OrgId { get; set; }
|
||||
}
|
||||
|
||||
public class SourceChannelSettings
|
||||
{
|
||||
public int DefaultSourceChannelId { get; set; }
|
||||
public int CreditCardSourceChannelId { get; set; }
|
||||
}
|
||||
|
||||
public class ProductIdSettings
|
||||
{
|
||||
public int CC_CashBack { get; set; }
|
||||
public int CC_Rewards { get; set; }
|
||||
public int CC_Student { get; set; }
|
||||
public int CC_Secure { get; set; }
|
||||
public int EQ_HELOC_Flex { get; set; }
|
||||
public int EQ_Home_Equity_Fixed { get; set; }
|
||||
public int EQ_Mtg_Refi_Express { get; set; }
|
||||
public int EQ_Mfg_Home_And_Land { get; set; }
|
||||
public int V_Vehicle { get; set; }
|
||||
public int V_VehiclePreapproval { get; set; }
|
||||
public int M_Boat { get; set; }
|
||||
public int P_Powersport { get; set; }
|
||||
public int T_TrailerMotorhome { get; set; }
|
||||
public int S_Signature { get; set; }
|
||||
}
|
||||
|
||||
public class FormatCategorySettings
|
||||
{
|
||||
public Dictionary<string, int> Categories { get; set; }
|
||||
public Dictionary<string, string> DocumentToCategory { get; set; }
|
||||
}
|
||||
|
||||
public class ServicingChannelSettings
|
||||
{
|
||||
public int DefaultServicingChannel { get; set; }
|
||||
}
|
||||
}
|
||||
+222
@@ -0,0 +1,222 @@
|
||||
using System.Xml.Linq;
|
||||
using Serilog;
|
||||
using CRIF.ACTion.Common;
|
||||
using CRIF.ACTion.Common.Parsers;
|
||||
|
||||
namespace CRIF.ACTion.Configuration
|
||||
{
|
||||
public class CustomFieldRequestResponseParser : IResponseParser<CustomFieldConfigs>
|
||||
{
|
||||
private const string _customFieldsPath = "/actionAPI/getCustomFields/msg:maintExportResponse/msg:maintenanceEntities/maint:maintenanceEntity/maint:fields/common:customLookupField";
|
||||
|
||||
public CustomFieldRequestResponseParser()
|
||||
{
|
||||
}
|
||||
|
||||
public CustomFieldConfigs Parse(XElement xElement)
|
||||
{
|
||||
CustomFieldConfigs customFieldConfig = new();
|
||||
|
||||
try
|
||||
{
|
||||
var namespaceManager = CrifNamespaces.GetNamespaceManager(xElement);
|
||||
IEnumerable<XElement> customFieldNodeList = xElement.XElementXPathSelectElements(_customFieldsPath, namespaceManager);
|
||||
List<string> RenovationMatchCriteria = ["IS THE PROPERTY CURRENTLY BEING REMODELED OR IMPROVED?"];
|
||||
List<string> SaleMatchCriteria = ["IS THE PROPERTY CURRENTLY LISTED FOR SALE?"];
|
||||
List<string> JointMatchCriteria = ["INTENT FOR JOINT CREDIT"];
|
||||
|
||||
customFieldConfig.CustomPropertyRenovationFieldData = ParseCustomPropertyStatusData(customFieldNodeList, RenovationMatchCriteria);
|
||||
customFieldConfig.CustomPropertySaleFieldData = ParseCustomPropertyStatusData(customFieldNodeList, SaleMatchCriteria);
|
||||
customFieldConfig.CustomJointCreditFieldData = ParseCustomJointCreditData(customFieldNodeList, JointMatchCriteria);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Log.Error("Error trying to parse CRIF Custom Field Configuration Response", ex.Message, ex.StackTrace);
|
||||
}
|
||||
return customFieldConfig;
|
||||
}
|
||||
|
||||
private List<CustomJointCreditData> ParseCustomJointCreditData(IEnumerable<XElement> customFieldNodeList, List<string> MatchCriteria)
|
||||
{
|
||||
List<CustomJointCreditData> customDataSet = [];
|
||||
|
||||
foreach (XElement node in customFieldNodeList)
|
||||
{
|
||||
try
|
||||
{
|
||||
string nodeAttributeValue = node.Attribute(CrifNamespaces.Common + "name").Value;
|
||||
if (CustomFieldIsActive(nodeAttributeValue, MatchCriteria))
|
||||
{
|
||||
string individuallyId = "";
|
||||
string jointlyId = "";
|
||||
string productCategoryId = "";
|
||||
|
||||
IEnumerable<XElement> childNodes = node.Descendants().Elements();
|
||||
|
||||
foreach (XElement option in childNodes)
|
||||
{
|
||||
if (option.Name.LocalName.Equals("FIELDSELECTION", StringComparison.CurrentCultureIgnoreCase))
|
||||
{
|
||||
var attributes = option.Attributes();
|
||||
|
||||
foreach (var attribute in attributes)
|
||||
{
|
||||
string idValue = "";
|
||||
string nameValue = "";
|
||||
|
||||
if (attribute.Name.LocalName.Equals("FIELDSELECTIONID", StringComparison.CurrentCultureIgnoreCase))
|
||||
{
|
||||
idValue = attribute.Value;
|
||||
nameValue = attribute.NextAttribute.Value.ToUpper();
|
||||
|
||||
switch (nameValue)
|
||||
{
|
||||
case "INDIVIDUALLY":
|
||||
individuallyId = idValue;
|
||||
break;
|
||||
case "JOINTLY":
|
||||
jointlyId = idValue;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (option.Name.LocalName.ToUpper() == "PRODUCTCATEGORY")
|
||||
{
|
||||
productCategoryId = option.LastAttribute.Value;
|
||||
}
|
||||
}
|
||||
|
||||
CustomJointCreditData data = new()
|
||||
{
|
||||
CustomFieldId = node.Attribute(CrifNamespaces.Common + "ID").Value,
|
||||
ProductCategoryId = productCategoryId,
|
||||
SortOrder = node.Attribute(CrifNamespaces.Common + "sortOrder").Value,
|
||||
JointlyId = jointlyId,
|
||||
IndividuallyId = individuallyId
|
||||
};
|
||||
|
||||
customDataSet.Add(data);
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Log.Error("Error trying to parse CRIF Custom Field Configuration Response", ex.Message, ex.StackTrace);
|
||||
}
|
||||
}
|
||||
|
||||
return customDataSet;
|
||||
}
|
||||
|
||||
private List<CustomPropertyStatusData> ParseCustomPropertyStatusData(IEnumerable<XElement> customFieldNodeList, List<string> MatchCriteria)
|
||||
{
|
||||
List<CustomPropertyStatusData> customDataSet = [];
|
||||
|
||||
foreach (XElement node in customFieldNodeList)
|
||||
{
|
||||
try
|
||||
{
|
||||
string nodeAttributeValue = node.Attribute(CrifNamespaces.Common + "name").Value;
|
||||
if (CustomFieldIsActive(nodeAttributeValue, MatchCriteria))
|
||||
{
|
||||
string yesId = "";
|
||||
string noId = "";
|
||||
string naId = "";
|
||||
string productCategoryId = "";
|
||||
|
||||
IEnumerable<XElement> childNodes = node.Descendants().Elements();
|
||||
|
||||
foreach (XElement option in childNodes)
|
||||
{
|
||||
if (option.Name.LocalName.Equals("FIELDSELECTION", StringComparison.CurrentCultureIgnoreCase))
|
||||
{
|
||||
var attributes = option.Attributes();
|
||||
|
||||
foreach (var attribute in attributes)
|
||||
{
|
||||
string idValue = "";
|
||||
string nameValue = "";
|
||||
|
||||
if (attribute.Name.LocalName.ToUpper() == "FIELDSELECTIONID")
|
||||
{
|
||||
idValue = attribute.Value;
|
||||
nameValue = attribute.NextAttribute.Value.ToUpper();
|
||||
|
||||
switch (nameValue)
|
||||
{
|
||||
case "YES":
|
||||
yesId = idValue;
|
||||
break;
|
||||
case "NO":
|
||||
noId = idValue;
|
||||
break;
|
||||
case "N/A (FLEX FIXED DRAWS ONLY)":
|
||||
naId = idValue;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (option.Name.LocalName.ToUpper() == "PRODUCTCATEGORY")
|
||||
{
|
||||
productCategoryId = option.LastAttribute.Value;
|
||||
}
|
||||
}
|
||||
|
||||
CustomPropertyStatusData data = new CustomPropertyStatusData
|
||||
{
|
||||
CustomFieldId = node.Attribute(CrifNamespaces.Common + "ID").Value,
|
||||
ProductCategoryId = productCategoryId,
|
||||
SortOrder = node.Attribute(CrifNamespaces.Common + "sortOrder").Value,
|
||||
NoId = noId,
|
||||
YesId = yesId,
|
||||
NaId = naId
|
||||
};
|
||||
|
||||
customDataSet.Add(data);
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Log.Error("Error trying to parse CRIF Custom Field Configuration Response", ex.Message, ex.StackTrace);
|
||||
}
|
||||
}
|
||||
|
||||
return customDataSet;
|
||||
}
|
||||
|
||||
private bool CustomFieldIsActive(string NodeAttributeValue, List<string> ActiveMatchCriteria)
|
||||
{
|
||||
bool isActive = false;
|
||||
foreach (string compare in ActiveMatchCriteria)
|
||||
{
|
||||
string standardizedNodeString = StandardizedStringValue(NodeAttributeValue);
|
||||
string standardizedCompareString = StandardizedStringValue(compare);
|
||||
|
||||
bool validCompareInput = !string.IsNullOrWhiteSpace(standardizedNodeString) && !string.IsNullOrWhiteSpace(compare);
|
||||
if (validCompareInput && !isActive)
|
||||
{
|
||||
isActive =
|
||||
(
|
||||
standardizedNodeString.Equals(standardizedCompareString)
|
||||
);
|
||||
}
|
||||
}
|
||||
return isActive;
|
||||
}
|
||||
|
||||
private string StandardizedStringValue(string InputString)
|
||||
{
|
||||
string standardizedString = "";
|
||||
if (!string.IsNullOrWhiteSpace(InputString))
|
||||
{
|
||||
standardizedString = InputString.Trim().ToUpper();
|
||||
}
|
||||
return standardizedString;
|
||||
}
|
||||
}
|
||||
}
|
||||
+47
@@ -0,0 +1,47 @@
|
||||
using System.Xml.Linq;
|
||||
using Serilog;
|
||||
using CRIF.ACTion.Common;
|
||||
using CRIF.ACTion.Common.Parsers;
|
||||
|
||||
namespace CRIF.ACTion.Configuration
|
||||
{
|
||||
public class ProductDetailsResponseParser : IResponseParser<Dictionary<string, string>>
|
||||
{
|
||||
private const string _productDetailsPath = "/actionAPI/getProducts/msg:maintExportResponse/msg:maintenanceEntities/maint:maintenanceEntity/maint:products/common:product/common:productCategory";
|
||||
|
||||
public ProductDetailsResponseParser()
|
||||
{
|
||||
}
|
||||
|
||||
public Dictionary<string, string> Parse(XElement xElement)
|
||||
{
|
||||
Dictionary<string, string> mappingList = [];
|
||||
|
||||
try
|
||||
{
|
||||
var namespaceManager = CrifNamespaces.GetNamespaceManager(xElement);
|
||||
IEnumerable<XElement> channelNodeList = xElement.XElementXPathSelectElements(_productDetailsPath, namespaceManager);
|
||||
|
||||
foreach (XElement channelNode in channelNodeList)
|
||||
{
|
||||
try
|
||||
{
|
||||
string productId = channelNode.Parent.Attribute(CrifNamespaces.Common + "productID").Value;
|
||||
string categoryId = channelNode.Attribute(CrifNamespaces.Common + "productCategoryID").Value;
|
||||
mappingList.Add(productId, categoryId);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Log.Error("Error trying to parse CRIF Product information from node in Configuration Response", ex.Message, ex.StackTrace);
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Log.Error("Error trying to parse CRIF Products Configuration Response", ex.Message, ex.StackTrace);
|
||||
}
|
||||
return mappingList;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user