789 lines
37 KiB
C#
789 lines
37 KiB
C#
using System.Xml.Linq;
|
|
using CRIF.ACTion.Common;
|
|
using CRIF.ACTion.Common.Builders;
|
|
using CRIF.ACTion.Configuration;
|
|
using CRIF.ACTion.Services.Landmark.DistributionChannel;
|
|
using CRIF.ACTion.Services.Landmark.SourceChannel;
|
|
using Landmark.OLA.Models;
|
|
using Landmark.OLA.Models.Addresses;
|
|
using Landmark.OLA.Models.Individuals;
|
|
using Landmark.OLA.Models.Individuals.Enums;
|
|
using Landmark.OLA.Models.Loan.Enums;
|
|
using static CRIF.ACTion.Common.ContactMechanisms;
|
|
|
|
namespace CRIF.ACTion.Loan.Individuals
|
|
{
|
|
public class PartiesSection : CrifRequestSection
|
|
{
|
|
|
|
private enum CrifGender
|
|
{
|
|
NoneSelected,
|
|
Female,
|
|
NotProvided,
|
|
Male,
|
|
NotApplicable,
|
|
MaleFemale,
|
|
}
|
|
|
|
private readonly IDistributionChannelLookupService _distributionChannelLookupService;
|
|
|
|
|
|
public PartiesSection(XNamespace sectionNamespace,
|
|
CrifSettings settings,
|
|
IDistributionChannelLookupService distributionChannelLookupService = null)
|
|
: base(sectionNamespace, "parties", settings)
|
|
{
|
|
_distributionChannelLookupService = distributionChannelLookupService ??
|
|
new LandmarkDistributionChannelLookupService(settings);
|
|
}
|
|
|
|
public void AddNonApplicant(INonApplicant individual, bool isMarried = false)
|
|
{
|
|
var individualElement = GetNonApplicantElement(individual, isMarried);
|
|
|
|
AddContent(individualElement);
|
|
}
|
|
|
|
public void AddApplicant(IApplicant individual,
|
|
Guid? externalSpouseId = null,
|
|
PropertyLot mfgHomeLot = null)
|
|
{
|
|
XElement partyRelationships = null;
|
|
|
|
if (externalSpouseId.HasValue ||
|
|
individual.HasAnyNonApplicantSpouse() ||
|
|
individual.Employers?.Count > 0)
|
|
{
|
|
partyRelationships = GetApplicantPartyRelationshipsSectionElement(individual, externalSpouseId);
|
|
}
|
|
|
|
var individualElement = GetInitialIndividualElement(individual, partyRelationships, mfgHomeLot);
|
|
|
|
SetHmdaData(individual, individualElement);
|
|
|
|
//this must occur last within the individual element
|
|
var maritalStatusElement = GetMaritalStatusElement(individual.IsMarried ?? false);
|
|
individualElement.Add(maritalStatusElement);
|
|
|
|
AddContent(individualElement);
|
|
}
|
|
|
|
public void AddHistory(IIndividualHistory individual, bool isMarried = false, bool requiresHMDA = false)
|
|
{
|
|
XElement partyRelationships = null;
|
|
|
|
if (individual.Employers?.Count > 0)
|
|
{
|
|
partyRelationships = GetHistoryPartyRelationshipsSectionElement(individual);
|
|
}
|
|
|
|
var individualElement = GetInitialIndividualElement(individual, partyRelationships);
|
|
if (requiresHMDA)
|
|
{
|
|
AddNonApplicantHmdaDetermination(individualElement);
|
|
}
|
|
//this must occur last within the individual element
|
|
var maritalStatusElement = GetMaritalStatusElement(isMarried);
|
|
individualElement.Add(maritalStatusElement);
|
|
|
|
AddContent(individualElement);
|
|
}
|
|
|
|
public static void AddNonApplicantHmdaDetermination(XElement individualElement)
|
|
{
|
|
var ethnicityDeterminationElement = new XElement(CrifNamespaces.Common + "ethnicityDetermination",
|
|
new XAttribute(CrifNamespaces.Common + "lookupType", "GMIDetermination"),
|
|
new XAttribute(CrifNamespaces.Common + "CD", "T"),
|
|
new XAttribute(CrifNamespaces.Common + "name", "No Co-Applicant"),
|
|
new XAttribute(CrifNamespaces.Common + "isActive", true),
|
|
new XAttribute(CrifNamespaces.Common + "externalSystemCode", "3"));
|
|
individualElement.Add(ethnicityDeterminationElement);
|
|
var raceDeterminationElement = new XElement(CrifNamespaces.Common + "raceDetermination",
|
|
new XAttribute(CrifNamespaces.Common + "lookupType", "GMIDetermination"),
|
|
new XAttribute(CrifNamespaces.Common + "CD", "T"),
|
|
new XAttribute(CrifNamespaces.Common + "name", "No Co-Applicant"),
|
|
new XAttribute(CrifNamespaces.Common + "isActive", true),
|
|
new XAttribute(CrifNamespaces.Common + "externalSystemCode", "3"));
|
|
individualElement.Add(raceDeterminationElement);
|
|
var sexDeterminationElement = new XElement(CrifNamespaces.Common + "sexDetermination",
|
|
new XAttribute(CrifNamespaces.Common + "lookupType", "GMIDetermination"),
|
|
new XAttribute(CrifNamespaces.Common + "CD", "T"),
|
|
new XAttribute(CrifNamespaces.Common + "name", "No Co-Applicant"),
|
|
new XAttribute(CrifNamespaces.Common + "isActive", true),
|
|
new XAttribute(CrifNamespaces.Common + "externalSystemCode", "3"));
|
|
individualElement.Add(sexDeterminationElement);
|
|
var applicationTakenMethodElement = new XElement(CrifNamespaces.Common + "applicationTakenMethod",
|
|
new XAttribute(CrifNamespaces.Common + "lookupType", "ApplicationTakenMethod"),
|
|
new XAttribute(CrifNamespaces.Common + "CD", "2"),
|
|
new XAttribute(CrifNamespaces.Common + "name", "Internet"),
|
|
new XAttribute(CrifNamespaces.Common + "isActive", true),
|
|
new XAttribute(CrifNamespaces.Common + "description", "Internet"));
|
|
individualElement.Add(applicationTakenMethodElement);
|
|
}
|
|
|
|
private XElement GetNonApplicantElement(INonApplicant individual, bool isMarried = false)
|
|
{
|
|
var individualElement = new XElement(CrifNamespaces.Common + "individual",
|
|
new XAttribute(CrifNamespaces.Common + "id", individual.Id),
|
|
new XAttribute(CrifNamespaces.Common + "languageID", individual.Language.Value),
|
|
new XAttribute(CrifNamespaces.Common + "firstName", BuilderUtils.FormatCrifData(individual.FirstName)),
|
|
new XAttribute(CrifNamespaces.Common + "lastName", BuilderUtils.FormatCrifData(individual.LastName)),
|
|
new XAttribute(CrifNamespaces.Common + "ssn", individual.SSN ?? "")
|
|
);
|
|
|
|
if (!string.IsNullOrWhiteSpace(individual.MiddleInitial))
|
|
{
|
|
individualElement.Add(new XAttribute(CrifNamespaces.Common + "middleName", BuilderUtils.FormatCrifData(individual.MiddleInitial)));
|
|
}
|
|
|
|
var contact = new XElement(CrifNamespaces.Common + "contactMechanisms");
|
|
var currentAddress = GetAddressContactMechanismElement(individual.MailingAddress.Id, CrifContactMechanism.CurrentAddress);
|
|
|
|
contact.Add(currentAddress);
|
|
individualElement.Add(contact);
|
|
|
|
//this must occur last within the individual element
|
|
var maritalStatusElement = GetMaritalStatusElement(isMarried);
|
|
individualElement.Add(maritalStatusElement);
|
|
|
|
return individualElement;
|
|
}
|
|
|
|
private XElement GetInitialIndividualElement(IIndividualHistory individual,
|
|
XElement partyRelationshipElement = null,
|
|
PropertyLot mfgHomeLot = null)
|
|
{
|
|
ModelValidator.Validate(individual);
|
|
|
|
var individualElement = new XElement(CrifNamespaces.Common + "individual",
|
|
new XAttribute(CrifNamespaces.Common + "id", individual.Id),
|
|
new XAttribute(CrifNamespaces.Common + "languageID", individual.Language.Value),
|
|
new XAttribute(CrifNamespaces.Common + "firstName", BuilderUtils.FormatCrifData(individual.FirstName)),
|
|
new XAttribute(CrifNamespaces.Common + "lastName", BuilderUtils.FormatCrifData(individual.LastName)),
|
|
new XAttribute(CrifNamespaces.Common + "dob", Dates.GetFormattedDOB(individual.DOB.Value)),
|
|
new XAttribute(CrifNamespaces.Common + "ssn", individual.SSN),
|
|
new XAttribute(CrifNamespaces.Common + "customerNum", individual.CustomerNumber)
|
|
);
|
|
|
|
if (individual.IsLandmarkEmployee.HasValue)
|
|
{
|
|
individualElement.Add(new XAttribute(CrifNamespaces.Common + "isEmployeeFL", individual.IsLandmarkEmployee.Value));
|
|
}
|
|
|
|
var contact = GetContactMechanismsSectionElement(individual);
|
|
individualElement.Add(contact);
|
|
|
|
individualElement.Add(partyRelationshipElement); //order matters for this element
|
|
|
|
if (individual.Employers?.Count > 0 || individual.OtherIncomes?.Count > 0)
|
|
{
|
|
var incomes = GetIncomesSectionElement(individual);
|
|
individualElement.Add(incomes);;
|
|
}
|
|
|
|
var tradesElement = GetTradesElement(individual, mfgHomeLot);
|
|
individualElement.Add(tradesElement);
|
|
|
|
if (individual.Suffix != null)
|
|
{
|
|
var suffixElement = GetSuffixElement(individual);
|
|
individualElement.Add(suffixElement);
|
|
}
|
|
|
|
if (!string.IsNullOrWhiteSpace(individual.MiddleInitial))
|
|
{
|
|
individualElement.Add(new XAttribute(CrifNamespaces.Common + "middleName", BuilderUtils.FormatCrifData(individual.MiddleInitial)));
|
|
}
|
|
|
|
return individualElement;
|
|
}
|
|
|
|
private void SetHmdaData(IApplicant individual, XElement individualElement)
|
|
{
|
|
var racesDetermination = false;
|
|
if (individual.HmdaValues.Races != null && individual.HmdaValues.Races.Count > 0)
|
|
{
|
|
var racesElement = GetRacesElement(individual);
|
|
individualElement.Add(racesElement);
|
|
|
|
racesDetermination = true;
|
|
}
|
|
|
|
var ethnicitiesDetermination = false;
|
|
if (individual.HmdaValues.Ethnicities != null && individual.HmdaValues.Ethnicities.Count > 0)
|
|
{
|
|
var ethnicitiesElement = GetEthnicitiesElement(individual);
|
|
individualElement.Add(ethnicitiesElement);
|
|
|
|
ethnicitiesDetermination = true;
|
|
}
|
|
|
|
if (ethnicitiesDetermination)
|
|
{
|
|
if (!(individual.HmdaValues.Ethnicities.Count == 1 && individual.HmdaValues.Ethnicities.Contains(Ethnicity.NotProvided)))
|
|
{
|
|
var ethnicityDeterminationElement = new XElement(CrifNamespaces.Common + "ethnicityDetermination",
|
|
new XAttribute(CrifNamespaces.Common + "lookupType", "GMIDetermination"),
|
|
new XAttribute(CrifNamespaces.Common + "CD", "N"),
|
|
new XAttribute(CrifNamespaces.Common + "name", "Not Collected on the Basis of Visual Observation or Surname"),
|
|
new XAttribute(CrifNamespaces.Common + "isActive", true),
|
|
new XAttribute(CrifNamespaces.Common + "externalSystemCode", "3"));
|
|
individualElement.Add(ethnicityDeterminationElement);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (racesDetermination)
|
|
{
|
|
if (!(individual.HmdaValues.Races.Count == 1 && individual.HmdaValues.Races.Contains(Race.NotProvided)))
|
|
{
|
|
var raceDeterminationElement = new XElement(CrifNamespaces.Common + "raceDetermination",
|
|
new XAttribute(CrifNamespaces.Common + "lookupType", "GMIDetermination"),
|
|
new XAttribute(CrifNamespaces.Common + "CD", "N"),
|
|
new XAttribute(CrifNamespaces.Common + "name", "Not Collected on the Basis of Visual Observation or Surname"),
|
|
new XAttribute(CrifNamespaces.Common + "isActive", true),
|
|
new XAttribute(CrifNamespaces.Common + "externalSystemCode", "3"));
|
|
individualElement.Add(raceDeterminationElement);
|
|
}
|
|
|
|
}
|
|
|
|
if (individual.HmdaValues.Sexes != null && individual.HmdaValues.Sexes.Count > 0)
|
|
{
|
|
var sexElements = GetSexAttributes(individual);
|
|
individualElement.Add(sexElements);
|
|
|
|
if (!(individual.HmdaValues.Sexes.Count == 1 && individual.HmdaValues.Sexes.Contains(Sex.NotProvided)))
|
|
{
|
|
var sexDeterminationElement = new XElement(CrifNamespaces.Common + "sexDetermination",
|
|
new XAttribute(CrifNamespaces.Common + "lookupType", "GMIDetermination"),
|
|
new XAttribute(CrifNamespaces.Common + "CD", "N"),
|
|
new XAttribute(CrifNamespaces.Common + "name", "Not Collected on the Basis of Visual Observation or Surname"),
|
|
new XAttribute(CrifNamespaces.Common + "isActive", true),
|
|
new XAttribute(CrifNamespaces.Common + "externalSystemCode", "3"));
|
|
individualElement.Add(sexDeterminationElement);
|
|
}
|
|
|
|
|
|
}
|
|
|
|
var applicationTakenMethodElement = GetApplicationTakenMethodElement(individual);
|
|
individualElement.Add(applicationTakenMethodElement);
|
|
}
|
|
|
|
public XElement GetApplicationTakenMethodElement(IApplicant individual)
|
|
{
|
|
if (!GetApplicationTakenMethodElementRequired(individual))
|
|
{
|
|
return null;
|
|
}
|
|
|
|
var applicationTakenMethodElement = new XElement(CrifNamespaces.Common + "applicationTakenMethod",
|
|
new XAttribute(CrifNamespaces.Common + "lookupType", "ApplicationTakenMethod"),
|
|
new XAttribute(CrifNamespaces.Common + "CD", "2"),
|
|
new XAttribute(CrifNamespaces.Common + "name", "Internet"),
|
|
new XAttribute(CrifNamespaces.Common + "isActive", true),
|
|
new XAttribute(CrifNamespaces.Common + "description", "Internet"));
|
|
|
|
return applicationTakenMethodElement;
|
|
}
|
|
|
|
public static XElement GetSuffixElement(IIndividualHistory individual)
|
|
{
|
|
var suffixType = SuffixMap.GetSuffixType(individual.Suffix);
|
|
|
|
var suffixElement = new XElement(CrifNamespaces.Common + "suffix",
|
|
new XAttribute(CrifNamespaces.Common + "lookupType", "Suffix"),
|
|
new XAttribute(CrifNamespaces.Common + "CD", suffixType.CD),
|
|
new XAttribute(CrifNamespaces.Common + "name", suffixType.Name),
|
|
new XAttribute(CrifNamespaces.Common + "isActive", true));
|
|
|
|
return suffixElement;
|
|
|
|
}
|
|
|
|
public static XElement GetTradesElement(IIndividualHistory individual, PropertyLot mfgHomeLot)
|
|
{
|
|
var tradesElement = new XElement(CrifNamespaces.Common + "trades");
|
|
|
|
var mortgageOrRentTradeElement = new XElement(CrifNamespaces.Common + "trade",
|
|
new XAttribute(CrifNamespaces.Common + "accountTypeCD", "RealEstateMortgage"),
|
|
new XAttribute(CrifNamespaces.Common + "tradeTypeID", "Mortgage"),
|
|
new XAttribute(CrifNamespaces.Common + "creditorName", "Rent - Mortgage"),
|
|
new XAttribute(CrifNamespaces.Common + "debtStatusCD", "Include"),
|
|
new XAttribute(CrifNamespaces.Common + "ecoaCD", "Individual"),
|
|
new XAttribute(CrifNamespaces.Common + "isCurrResidenceRentMortgage", true),
|
|
new XAttribute(CrifNamespaces.Common + "monthlyPayment", individual.Address.MonthlyPayment),
|
|
|
|
new XElement(CrifNamespaces.Common + "kindOfBusiness",
|
|
new XAttribute(CrifNamespaces.Common + "lookupType", "KOB"),
|
|
new XAttribute(CrifNamespaces.Common + "CD", "FM")));
|
|
|
|
tradesElement.Add(mortgageOrRentTradeElement);
|
|
|
|
if ((!(mfgHomeLot is null)) && mfgHomeLot.RentalAmt.HasValue)
|
|
{
|
|
var mfgHomeLotRentalElement = new XElement(CrifNamespaces.Common + "trade",
|
|
new XAttribute(CrifNamespaces.Common + "tradeTypeID", "Mortgage"),
|
|
new XAttribute(CrifNamespaces.Common + "creditorName", "Lot Rent"),
|
|
new XAttribute(CrifNamespaces.Common + "debtStatusCD", "Include"),
|
|
new XAttribute(CrifNamespaces.Common + "ecoaCD", "Individual"),
|
|
new XAttribute(CrifNamespaces.Common + "monthlyPayment", mfgHomeLot.RentalAmt.Value),
|
|
|
|
new XElement(CrifNamespaces.Common + "kindOfBusiness",
|
|
new XAttribute(CrifNamespaces.Common + "lookupType", "KOB"),
|
|
new XAttribute(CrifNamespaces.Common + "CD", "FM")));
|
|
|
|
tradesElement.Add(mfgHomeLotRentalElement);
|
|
}
|
|
|
|
if (individual.OtherIncomes?.Count > 0)
|
|
{
|
|
foreach (var income in individual.OtherIncomes)
|
|
{
|
|
if (income.IncomeTypeCD == IncomeType.Alimony)
|
|
{
|
|
double monthlyAlimony = (double)income.AmountPerPeriod / 12;
|
|
var alimonyElement = new XElement(CrifNamespaces.Common + "trade",
|
|
new XAttribute(CrifNamespaces.Common + "tradeTypeID", "Open"),
|
|
new XAttribute(CrifNamespaces.Common + "creditorName", "Alimony/Child Support - Payment"),
|
|
new XAttribute(CrifNamespaces.Common + "debtStatusCD", "Include"),
|
|
new XAttribute(CrifNamespaces.Common + "ecoaCD", "Individual"),
|
|
new XAttribute(CrifNamespaces.Common + "monthlyPayment", monthlyAlimony),
|
|
new XElement(CrifNamespaces.Common + "kindOfBusiness",
|
|
new XAttribute(CrifNamespaces.Common + "lookupType", "KOB"),
|
|
new XAttribute(CrifNamespaces.Common + "CD", "VK")));
|
|
tradesElement.Add(alimonyElement);
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
return tradesElement;
|
|
}
|
|
|
|
private static bool GetApplicationTakenMethodElementRequired(IApplicant individual)
|
|
{
|
|
var hasRaces = individual.HmdaValues.Races != null && individual.HmdaValues.Races.Count > 0;
|
|
var hasEthnicities = individual.HmdaValues.Ethnicities != null && individual.HmdaValues.Ethnicities.Count > 0;
|
|
var hasSexes = individual.HmdaValues.Sexes != null && individual.HmdaValues.Sexes.Count > 0;
|
|
|
|
return hasRaces || hasEthnicities || hasSexes;
|
|
}
|
|
|
|
public static XAttribute[] GetSexAttributes(IApplicant individual)
|
|
{
|
|
var attributeList = new List<XAttribute>();
|
|
|
|
var hasMale = individual.HmdaValues.Sexes.Contains(Sex.Male);
|
|
var hasFemale = individual.HmdaValues.Sexes.Contains(Sex.Female);
|
|
var isNotProvided = individual.HmdaValues.Sexes.Contains(Sex.NotProvided);
|
|
|
|
var genderCDValue = CrifGender.NoneSelected;
|
|
|
|
if (isNotProvided && !hasMale && !hasFemale)
|
|
{
|
|
attributeList.Add(new XAttribute(CrifNamespaces.Common + "genderCD", Sex.NotProvided));
|
|
return [.. attributeList];
|
|
}
|
|
|
|
if (hasMale)
|
|
{
|
|
if (hasFemale)
|
|
{
|
|
genderCDValue = CrifGender.MaleFemale;
|
|
}
|
|
else
|
|
{
|
|
genderCDValue = CrifGender.Male;
|
|
}
|
|
}
|
|
else if (hasFemale)
|
|
{
|
|
genderCDValue = CrifGender.Female;
|
|
}
|
|
|
|
if (genderCDValue != CrifGender.NoneSelected)
|
|
{
|
|
attributeList.Add(new XAttribute(CrifNamespaces.Common + "genderCD", genderCDValue.ToString()));
|
|
}
|
|
|
|
//Yes, you both could provide an answer and say that you don't wish to provide an answer
|
|
//Validation will likely restrict that
|
|
//Ignore Not Provided if Other Values are Selected
|
|
attributeList.Add(new XAttribute(CrifNamespaces.Common + "refusedToFurnishGenderFL", false));
|
|
return [.. attributeList];
|
|
}
|
|
|
|
public static XElement GetRacesElement(IApplicant individual)
|
|
{
|
|
var racesElement = new XElement(CrifNamespaces.Common + "races");
|
|
|
|
if (individual.HmdaValues.Races.Count == 1 && individual.HmdaValues.Races.Contains(Race.NotProvided)){
|
|
var raceElement = new XElement(CrifNamespaces.Common + "race",
|
|
new XAttribute(CrifNamespaces.Common + "isCheckedFL", true),
|
|
new XAttribute(CrifNamespaces.Common + "race", Race.NotProvided.ToString()));
|
|
|
|
racesElement.RemoveNodes();
|
|
racesElement.Add(raceElement);
|
|
return racesElement;
|
|
}
|
|
|
|
foreach (Race raceOption in (Race[])Enum.GetValues(typeof(Race)))
|
|
{
|
|
var isChecked = individual.HmdaValues.Races.Contains(raceOption);
|
|
|
|
bool isNotProvided = (raceOption == Race.NotProvided);
|
|
|
|
string otherRaceInfoValue = null;
|
|
switch (raceOption)
|
|
{
|
|
case Race.AmericanIndianAlaskaNative:
|
|
otherRaceInfoValue = individual.HmdaValues.AmericanIndianAlaskaNativeTribe;
|
|
break;
|
|
case Race.OtherAsian:
|
|
otherRaceInfoValue = individual.HmdaValues.OtherAsianRace;
|
|
break;
|
|
case Race.OtherPacificIslander:
|
|
otherRaceInfoValue = individual.HmdaValues.OtherPacificIslanderRace;
|
|
break;
|
|
}
|
|
var hasOtherValue = !string.IsNullOrWhiteSpace(otherRaceInfoValue);
|
|
|
|
//Ignore not provided if it is not the only ethnicity selected
|
|
if ( (isChecked || hasOtherValue) && !isNotProvided)
|
|
{
|
|
|
|
var raceElement = new XElement(CrifNamespaces.Common + "race",
|
|
new XAttribute(CrifNamespaces.Common + "isCheckedFL", isChecked),
|
|
new XAttribute(CrifNamespaces.Common + "race", raceOption.ToString()));
|
|
|
|
if (hasOtherValue)
|
|
{
|
|
raceElement.Add(new XAttribute(CrifNamespaces.Common + "otherRaceInfo", BuilderUtils.FormatCrifData(otherRaceInfoValue)));
|
|
}
|
|
|
|
racesElement.Add(raceElement);
|
|
}
|
|
}
|
|
|
|
return racesElement;
|
|
}
|
|
|
|
public static XElement GetEthnicitiesElement(IApplicant individual)
|
|
{
|
|
var ethnicitiesElement = new XElement(CrifNamespaces.Common + "ethnicities");
|
|
|
|
if (individual.HmdaValues.Ethnicities.Count == 1 && individual.HmdaValues.Ethnicities.Contains(Ethnicity.NotProvided)){
|
|
var ethnicityElement = new XElement(CrifNamespaces.Common + "ethnicity",
|
|
new XAttribute(CrifNamespaces.Common + "isCheckedFL", true),
|
|
new XAttribute(CrifNamespaces.Common + "ethnicity", Ethnicity.NotProvided.ToString()));
|
|
|
|
ethnicitiesElement.RemoveNodes();
|
|
ethnicitiesElement.Add(ethnicityElement);
|
|
return ethnicitiesElement;
|
|
}
|
|
|
|
foreach (Ethnicity ethnicityOption in (Ethnicity[])Enum.GetValues(typeof(Ethnicity)))
|
|
{
|
|
var isChecked = individual.HmdaValues.Ethnicities.Contains(ethnicityOption);
|
|
|
|
bool isNotProvided = (ethnicityOption == Ethnicity.NotProvided);
|
|
|
|
string otherEthnicityInfo = null;
|
|
switch (ethnicityOption)
|
|
{
|
|
case Ethnicity.OtherHispanicLatino:
|
|
otherEthnicityInfo = individual.HmdaValues.OtherHispanicLatinoEthnicity;
|
|
break;
|
|
}
|
|
var hasOtherValue = !string.IsNullOrWhiteSpace(otherEthnicityInfo);
|
|
|
|
//Ignore not provided if it is not the only ethnicity selected
|
|
if ( (isChecked || hasOtherValue) && !isNotProvided)
|
|
{
|
|
var ethnicityElement = new XElement(CrifNamespaces.Common + "ethnicity",
|
|
new XAttribute(CrifNamespaces.Common + "isCheckedFL", isChecked),
|
|
new XAttribute(CrifNamespaces.Common + "ethnicity", ethnicityOption.ToString()));
|
|
|
|
if (hasOtherValue)
|
|
{
|
|
ethnicityElement.Add(new XAttribute(CrifNamespaces.Common + "otherEthnicityInfo", BuilderUtils.FormatCrifData(otherEthnicityInfo)));
|
|
}
|
|
|
|
ethnicitiesElement.Add(ethnicityElement);
|
|
}
|
|
}
|
|
|
|
return ethnicitiesElement;
|
|
}
|
|
|
|
public static XElement GetIncomesSectionElement(IIndividualHistory individual)
|
|
{
|
|
var incomesElement = new XElement(CrifNamespaces.Common + "incomes");
|
|
if (individual.Employers?.Count > 0)
|
|
{
|
|
foreach (var employer in individual.Employers)
|
|
{
|
|
var income = employer.Income;
|
|
|
|
ModelValidator.Validate(income);
|
|
|
|
var incomeElement = new IncomeSectionBuilder(income).Build();
|
|
|
|
var employerRefElement = new XElement(CrifNamespaces.Common + "employerRef",
|
|
new XAttribute(CrifNamespaces.Common + "idRef", employer.GetOrCreateGuid()));
|
|
incomeElement.Add(employerRefElement);
|
|
incomesElement.Add(incomeElement);
|
|
}
|
|
}
|
|
if (individual.OtherIncomes?.Count > 0)
|
|
{
|
|
foreach (var income in individual.OtherIncomes)
|
|
{
|
|
if (income.IncomeTypeCD != IncomeType.Alimony)
|
|
{
|
|
var incomeElement = new IncomeSectionBuilder(income).Build();
|
|
incomesElement.Add(incomeElement);
|
|
}
|
|
}
|
|
}
|
|
return incomesElement;
|
|
}
|
|
|
|
public static XElement GetHistoryPartyRelationshipsSectionElement(IIndividualHistory individual)
|
|
{
|
|
var prElement = new XElement(CrifNamespaces.Common + "partyRelationships");
|
|
if (individual.Employers?.Count > 0)
|
|
{
|
|
foreach (var employer in individual.Employers)
|
|
{
|
|
ModelValidator.Validate(employer);
|
|
|
|
var employmentType = employer.EmploymentType;
|
|
|
|
var employmentElement = new XElement(CrifNamespaces.Common + "employment",
|
|
new XAttribute(CrifNamespaces.Common + "relationshipType", "Employment"));
|
|
var partyRefElement = new XElement(CrifNamespaces.Common + "partyRef",
|
|
new XAttribute(CrifNamespaces.XSI + "type", $"{CrifNamespaces.Common.Prefix}:EmployerRef"),
|
|
new XAttribute(CrifNamespaces.Common + "idRef", employer.GetOrCreateGuid()),
|
|
new XAttribute(CrifNamespaces.Common + "partyType", "Employer"));
|
|
var employmentSubRelElement = new XElement(CrifNamespaces.Common + "employmentSubRel",
|
|
new XAttribute(CrifNamespaces.Common + "isCurrentFL", employer.CurrentEmployer),
|
|
new XAttribute(CrifNamespaces.Common + "title", BuilderUtils.FormatCrifData(employer.Title)),
|
|
new XAttribute(CrifNamespaces.Common + "monthsEmployed", employer.MonthsEmployed),
|
|
new XAttribute(CrifNamespaces.Common + "isSelfEmployed", false), //TODO #239: is this always false?
|
|
new XAttribute(CrifNamespaces.Common + "employmentType", employmentType));
|
|
var userEmploymentTypeElement = new XElement(CrifNamespaces.Common + "userEmploymentType",
|
|
new XAttribute(CrifNamespaces.Common + "lookupType", "UserEmploymentType"), //TODO #240: Does this have other values?
|
|
new XAttribute(CrifNamespaces.Common + "CD", UserEmploymentType.GetCrifUserEmploymentTypeIndex(employmentType)), //TODO #240
|
|
new XAttribute(CrifNamespaces.Common + "name", UserEmploymentType.GetCrifUserEmploymentTypeName(employmentType)));
|
|
|
|
employmentSubRelElement.Add(userEmploymentTypeElement);
|
|
employmentElement.Add(partyRefElement);
|
|
employmentElement.Add(employmentSubRelElement);
|
|
prElement.Add(employmentElement);
|
|
}
|
|
}
|
|
|
|
return prElement;
|
|
}
|
|
|
|
public static XElement GetApplicantPartyRelationshipsSectionElement(IApplicant individual,
|
|
Guid? externalSpouseId = null)
|
|
{
|
|
var prElement = GetHistoryPartyRelationshipsSectionElement(individual);
|
|
|
|
prElement.Add(GetMarriageElement(individual, externalSpouseId));
|
|
|
|
return prElement;
|
|
}
|
|
|
|
private static XElement GetMarriageElement(IApplicant individual, Guid? externalSpouseId = null)
|
|
{
|
|
if (!(individual.HasAnyNonApplicantSpouse() || externalSpouseId.HasValue))
|
|
{
|
|
return null;
|
|
}
|
|
|
|
Guid spouseId;
|
|
|
|
if (externalSpouseId.HasValue)
|
|
{
|
|
spouseId = externalSpouseId.Value;
|
|
}
|
|
else
|
|
{
|
|
if (individual.NonApplicantSpouse is not null)
|
|
{
|
|
spouseId = individual.NonApplicantSpouse.Id;
|
|
}
|
|
else
|
|
{
|
|
spouseId = individual.DetailedNonApplicantSpouse.Id;
|
|
}
|
|
}
|
|
|
|
var partyRef = new XElement(CrifNamespaces.Common + "partyRef",
|
|
new XAttribute(CrifNamespaces.XSI + "type", $"{CrifNamespaces.Common.Prefix}:IndividualRef"),
|
|
new XAttribute(CrifNamespaces.Common + "idRef", spouseId),
|
|
new XAttribute(CrifNamespaces.Common + "partyType", "Individual"));
|
|
|
|
var marriageRelationshipElement = new XElement(CrifNamespaces.Common + "partyRelationship",
|
|
new XAttribute(CrifNamespaces.Common + "relationshipType", "Marriage"),
|
|
partyRef);
|
|
|
|
return marriageRelationshipElement;
|
|
}
|
|
|
|
public static XElement GetMaritalStatusElement(bool isMarried)
|
|
{
|
|
var maritalStatusElement = new XElement(CrifNamespaces.Common + "maritalStatus",
|
|
new XAttribute(CrifNamespaces.Common + "lookupType", "MaritalStatus"),
|
|
new XAttribute(CrifNamespaces.Common + "CD", MaritalStatus.GetMaritalStatusCode(isMarried)),
|
|
new XAttribute(CrifNamespaces.Common + "name", MaritalStatus.GetMaritalStatusName(isMarried)));
|
|
|
|
return maritalStatusElement;
|
|
}
|
|
|
|
public static XElement GetContactMechanismsSectionElement(IIndividualHistory individual)
|
|
{
|
|
var contact = new XElement(CrifNamespaces.Common + "contactMechanisms");
|
|
|
|
var mechanismType = ContactMechanisms.GetPhoneType(individual.PhoneType.Value);
|
|
var primaryPhone = GetContactMechanismElement(individual.Phone, mechanismType);
|
|
|
|
var email = GetContactMechanismElement(individual.Email, ContactMechanisms.CrifContactMechanism.EMail);
|
|
|
|
var currentAddress = GetAddressContactMechanismElement(individual.Address.Id, ContactMechanisms.CrifContactMechanism.CurrentAddress);
|
|
|
|
contact.Add(primaryPhone);
|
|
contact.Add(email);
|
|
contact.Add(currentAddress);
|
|
|
|
if (individual.SecondaryPhone?.Length > 0)
|
|
{
|
|
mechanismType = ContactMechanisms.GetPhoneType(individual.SecondaryPhoneType.Value);
|
|
var secondaryPhone = GetContactMechanismElement(individual.SecondaryPhone, mechanismType);
|
|
|
|
contact.Add(secondaryPhone);
|
|
}
|
|
|
|
if (individual.MailingAddress is not null)
|
|
{
|
|
var mailingAddressElement = GetAddressContactMechanismElement(individual.MailingAddress.Id, ContactMechanisms.CrifContactMechanism.MailingAddress);
|
|
contact.Add(mailingAddressElement);
|
|
}
|
|
else
|
|
{
|
|
var mailingAddressElement = GetAddressContactMechanismElement(individual.Address.Id,ContactMechanisms.CrifContactMechanism.MailingAddress);
|
|
contact.Add(mailingAddressElement);
|
|
}
|
|
|
|
if (individual.PreviousAddresses?.Count > 0)
|
|
{
|
|
foreach (var previousAddress in individual.PreviousAddresses)
|
|
{
|
|
var previousAddressElement = GetAddressContactMechanismElement(previousAddress.Id, ContactMechanisms.CrifContactMechanism.PreviousAddress);
|
|
contact.Add(previousAddressElement);
|
|
}
|
|
}
|
|
|
|
return contact;
|
|
}
|
|
|
|
public static XElement GetAddressContactMechanismElement(Guid addressRef, ContactMechanisms.CrifContactMechanism contactMechanismType)
|
|
{
|
|
var contactMechanismCategory = ContactMechanisms.GetContactMechanismCategory(contactMechanismType);
|
|
|
|
var contactMechanism = new XElement(CrifNamespaces.Common + "contactMechanism",
|
|
new XAttribute(CrifNamespaces.Common + "contactMechanismType", contactMechanismType),
|
|
new XElement(CrifNamespaces.Common + "addressRef",
|
|
new XAttribute(CrifNamespaces.Common + "idRef", addressRef)
|
|
),
|
|
new XElement(CrifNamespaces.Common + "contactMechanismCategory",
|
|
new XAttribute(CrifNamespaces.Common + "CD", (int)contactMechanismCategory)
|
|
)
|
|
);
|
|
|
|
return contactMechanism;
|
|
}
|
|
|
|
public static XElement GetEmployerContactMechanismsSectionElement(Employer employer)
|
|
{
|
|
var contact = new XElement(CrifNamespaces.Common + "contactMechanisms");
|
|
if (!string.IsNullOrWhiteSpace(employer.WorkPhone))
|
|
{
|
|
contact.Add(GetContactMechanismElement(employer.WorkPhone, CrifContactMechanism.WorkPhone));
|
|
}
|
|
return contact;
|
|
}
|
|
|
|
public static XElement GetContactMechanismElement(string contactString, CrifContactMechanism contactMechanismType)
|
|
{
|
|
var contactMechanismCategory = GetContactMechanismCategory(contactMechanismType);
|
|
|
|
var contactMechanism = new XElement(CrifNamespaces.Common + "contactMechanism",
|
|
new XAttribute(CrifNamespaces.Common + "contactMechanismType", contactMechanismType),
|
|
new XAttribute(CrifNamespaces.Common + "contactString", BuilderUtils.FormatCrifData(contactString)),
|
|
new XElement(CrifNamespaces.Common + "contactMechanismCategory",
|
|
new XAttribute(CrifNamespaces.Common + "CD", (int)contactMechanismCategory)
|
|
)
|
|
);
|
|
|
|
return contactMechanism;
|
|
}
|
|
|
|
public void AddOrganizationParty(Guid orgId)
|
|
{
|
|
var organization = new XElement(CrifNamespaces.Common + "organization",
|
|
new XAttribute(CrifNamespaces.Common + "id", orgId),
|
|
new XAttribute(CrifNamespaces.Common + "partyID", 4)); //Per CRIF Documentation
|
|
|
|
AddContent(organization);
|
|
}
|
|
|
|
public void AddSourceChannelParty(Guid channelId, LoanType loanType)
|
|
{
|
|
var channelLookup = new LandmarkSourceChannelLookupService(_settings);
|
|
|
|
int partyId = channelLookup.GetSourceChannelByLoanType(loanType);
|
|
|
|
AddChannelParty(channelId, partyId);
|
|
}
|
|
|
|
public void AddServicingChannelParty(Guid channelId, string zipCode)
|
|
{
|
|
var partyId = _distributionChannelLookupService.GetDistributionChannelByZipCode(zipCode);
|
|
|
|
AddChannelParty(channelId, partyId);
|
|
}
|
|
|
|
private void AddChannelParty(Guid channelId, int partyId)
|
|
{
|
|
var channel = new XElement(CrifNamespaces.Common + "channel",
|
|
new XAttribute(CrifNamespaces.Common + "id", channelId),
|
|
new XAttribute(CrifNamespaces.Common + "partyID", partyId));
|
|
|
|
AddContent(channel);
|
|
}
|
|
|
|
public void AddEmployer(Employer employer)
|
|
{
|
|
ModelValidator.Validate(employer);
|
|
|
|
var employerElement = new XElement(CrifNamespaces.Common + "employer",
|
|
new XAttribute(CrifNamespaces.Common + "id", employer.GetOrCreateGuid()),
|
|
new XAttribute(CrifNamespaces.Common + "name", BuilderUtils.FormatCrifData(employer.Name)),
|
|
new XAttribute(CrifNamespaces.Common + "languageID", employer.Language));
|
|
|
|
var contact = GetEmployerContactMechanismsSectionElement(employer);
|
|
|
|
employerElement.Add(contact);
|
|
AddContent(employerElement);
|
|
}
|
|
}
|
|
}
|