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

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);
}
}
}