using System.Xml.Linq; using CRIF.ACTion.Common; using Landmark.OLA.Models.Assets; using Landmark.OLA.Models.Assets.Enums; using static CRIF.ACTion.Common.ContactMechanisms; namespace CRIF.ACTion.Loan.Assets { public class RealEstateProperty : IProperty { private protected readonly RealEstateBase _realEstateBase; private protected readonly string _elementName; private protected readonly string _propertyType; public RealEstateProperty(RealEstateBase realEstateBase, string elementName = "propertyRealEstate", string propertyType = "RealEstate") { _realEstateBase = realEstateBase; _elementName = elementName; _propertyType = propertyType; } public XElement Build(params XElement[] content) { var classType = _realEstateBase.GetType(); if (classType.Equals(typeof(ManufacturedHome)) || classType.IsSubclassOf(typeof(ManufacturedHome))) { var realEstateElement = GetRealEstateElement((ManufacturedHome)_realEstateBase); realEstateElement.Add( new XAttribute(CrifNamespaces.Common + "lienPositionID", LienPositionType.First) ); return realEstateElement; } else if (classType.Equals(typeof(RealEstate)) || classType.IsSubclassOf(typeof(RealEstate))) { var realEstateElement = GetRealEstateElement((RealEstate)_realEstateBase); realEstateElement.Add( new XAttribute(CrifNamespaces.Common + "lienPositionID", GetLienPosition(_realEstateBase.LienPosition)) ); return realEstateElement; } else { throw new ArgumentException("Unexpected object given to constructor for RealEstateProperty"); } } private XElement GetRealEstateElement(RealEstate realEstate) { return GetRealEstateElement(realEstate, realEstate.Type.Value.ToString()); } private XElement GetRealEstateElement(ManufacturedHome manufacturedHome) { var element = GetRealEstateElement(manufacturedHome, manufacturedHome.Type.Value.ToString(), manufacturedHome.EstimatedLandValuation, manufacturedHome.EstimatedHomeValuation); //The valuation fields above are suppose to go in totalValue and finalEstimatedValue as written. //It's a little strange but that's how CRIF stores that data. // This has to be before propertyLot, otherwise CRIF will complain! if (manufacturedHome.Lot.AnnualPropertyTax.HasValue) { var propertyTaxesElement = new XElement(CrifNamespaces.Common + "propertyTaxes"); var propertyTaxElement = new XElement( CrifNamespaces.Common + "propertyTax", new XAttribute(CrifNamespaces.Common + "taxEntity", "IRS"), new XAttribute(CrifNamespaces.Common + "amount", manufacturedHome.Lot.AnnualPropertyTax.Value.ToString()), new XAttribute(CrifNamespaces.Common + "paymentFrequency", "Annually") ); propertyTaxesElement.Add(propertyTaxElement); element.Add(propertyTaxesElement); } var propertyLotElement = new XElement(CrifNamespaces.Common + "propertyLot"); if (manufacturedHome.Lot.RentalAmt.HasValue) { propertyLotElement.Add(new XAttribute(CrifNamespaces.Common + "rentalAmt", manufacturedHome.Lot.RentalAmt.Value)); } element.Add(propertyLotElement); return element; } private XElement GetRealEstateElement(RealEstateBase realEstateBase, string subtype, decimal? finalEstimatedValue = null, decimal? totalValue = null) { var propertyRealEstateElement = new XElement(CrifNamespaces.Common + _elementName, new XAttribute(CrifNamespaces.Common + "id", realEstateBase.Id), new XAttribute(CrifNamespaces.Common + "propertySubType", subtype), // new XAttribute(CrifNamespaces.Common + "hasClearTitleFL", realEstate.HasClearTitle), new XAttribute(CrifNamespaces.Common + "initialEstimatedValue", realEstateBase.InitialEstimatedValue), new XAttribute(CrifNamespaces.Common + "propertyType", _propertyType), new XAttribute(CrifNamespaces.Common + "ownerOccupiedTypeID", realEstateBase.Use.Value)); if(finalEstimatedValue.HasValue) { propertyRealEstateElement.Add(new XAttribute(CrifNamespaces.Common + "finalEstimatedValue", finalEstimatedValue)); } if (totalValue.HasValue) { propertyRealEstateElement.Add(new XAttribute(CrifNamespaces.Common + "totalValue", totalValue)); } var contactMechanismsElement = GetContactMechanisms(realEstateBase); propertyRealEstateElement.Add(GetPropertyDetails(realEstateBase)); propertyRealEstateElement.Add(contactMechanismsElement); return propertyRealEstateElement; } private static XElement GetContactMechanisms(RealEstateBase realEstateBase) { var contactMechanismType = CrifContactMechanism.RealEstateAddress; var idRef = ""; var classType = realEstateBase.GetType(); if (classType.Equals(typeof(ManufacturedHome)) || classType.IsSubclassOf(typeof(ManufacturedHome))) { contactMechanismType = CrifContactMechanism.ParkContactAddress; idRef = ((ManufacturedHome)realEstateBase).Lot.Id.ToString(); } else if (classType.Equals(typeof(RealEstate)) || classType.IsSubclassOf(typeof(RealEstate))) { idRef = ((RealEstate)realEstateBase).RealEstateAddress.Id.ToString(); } var contactMechanismsElement = new XElement(CrifNamespaces.Common + "contactMechanisms", new XElement(CrifNamespaces.Common + "contactMechanism", new XAttribute(CrifNamespaces.Common + "contactMechanismType", contactMechanismType.ToString()), new XElement(CrifNamespaces.Common + "addressRef", new XAttribute(CrifNamespaces.Common + "idRef", idRef)), new XElement(CrifNamespaces.Common + "contactMechanismCategory", new XAttribute(CrifNamespaces.Common + "CD", (int)GetContactMechanismCategory(contactMechanismType))) )); return contactMechanismsElement; } private static XAttribute[] GetPropertyDetails(RealEstateBase realEstateBase) { var attributeList = new List(); if (realEstateBase.HasSpa.HasValue) { attributeList.Add(new XAttribute(CrifNamespaces.Common + "hasSpaFL", realEstateBase.HasSpa.Value)); } if (realEstateBase.HasPool.HasValue) { attributeList.Add(new XAttribute(CrifNamespaces.Common + "hasPoolFL", realEstateBase.HasPool.Value)); } if (realEstateBase.HasBasement.HasValue) { attributeList.Add(new XAttribute(CrifNamespaces.Common + "hasBasementFL", realEstateBase.HasBasement.Value)); } if (realEstateBase.HasCentralAir.HasValue) { attributeList.Add(new XAttribute(CrifNamespaces.Common + "hasCentralAirFL", realEstateBase.HasCentralAir.Value)); } if (realEstateBase.HasGarage.HasValue) { attributeList.Add(new XAttribute(CrifNamespaces.Common + "hasGarageFL", realEstateBase.HasGarage.Value)); } if (realEstateBase.InFloodZone.HasValue) { attributeList.Add(new XAttribute(CrifNamespaces.Common + "inFloodZoneFL", realEstateBase.InFloodZone.Value)); } if (realEstateBase.InEquity.HasValue) { attributeList.Add(new XAttribute(CrifNamespaces.Common + "inEquityFL", realEstateBase.InEquity.Value)); } if (realEstateBase.IsPropertyHeldInTrust.HasValue) { attributeList.Add(new XAttribute(CrifNamespaces.Common + "isPropertyHeldInTrust", realEstateBase.IsPropertyHeldInTrust.Value)); } return [.. attributeList]; } public static LienPositionType GetLienPosition(LienPosition lienPositionData) { if (lienPositionData.HasFirstMortgage && lienPositionData.HasSecondMortgage) { if (lienPositionData.PayoffFirstMortgage && lienPositionData.PayoffSecondMortgage) { return LienPositionType.First; } else if (!lienPositionData.PayoffFirstMortgage && !lienPositionData.PayoffSecondMortgage) { return LienPositionType.Third; } else if (lienPositionData.PayoffFirstMortgage || lienPositionData.PayoffSecondMortgage) { return LienPositionType.Second; } } else if (lienPositionData.HasFirstMortgage || lienPositionData.HasSecondMortgage) { if (lienPositionData.PayoffFirstMortgage || lienPositionData.PayoffSecondMortgage) { return LienPositionType.First; } else { return LienPositionType.Second; } } return LienPositionType.First; } } }