using System; using System.Collections.Generic; using System.Linq; using LCU.Shared.Collections.RepoApiLib.Models; using LCU.Shared.Collections.RepoApiLib.WebServices.NADA; using Microsoft.EntityFrameworkCore.Internal; using Enumerable = System.Linq.Enumerable; namespace LCU.API.Collections.RepoApi.Domain.FloorPricing.Strategies { /** * This strategy uses the AutoIms MMR values, the values from Nada, and the condition from AutoIms along * with a specific formula, to calculate a floor. */ public class NadaMmrConditionValue : IFloorPricingStrategy { public FloorPriceCalculationResult CalculateFloorPrice(FloorPriceCalculationParams fpcParams) { var result = new FloorPriceCalculationResult() { StrategyName = this.GetType().FullName, Success = false, ResultWeight = -1 }; if (fpcParams?.CollateralValuation == null || fpcParams?.ImsAutoFileData == null || fpcParams?.VehicleFloorPricingParameters == null || fpcParams?.VehicleFloorPricingParameters?.Any() == false) { // May want to log here, or set a reason code on the result. result.FailureReason = "Missing ImsAuto File, Pricing Parameters, or Collateral Valuation"; return result; } // 1. use condition to find the correct params. // + VehicleDemicalGradeCode is ignored, ApprovedVehicleGrade is preferred, and Vehicle Grade is the fallback. var condition = fpcParams.ImsAutoFileData.ApprovedVehicleGrade ?? fpcParams.ImsAutoFileData.VehicleGrade; if (condition <= 0 || condition == null) { result.FailureReason = "No Condition In AutoIMS File Data"; return result; } // 2. Get the matching floor pricing calculation row. var floorPricing = Enumerable.First(Enumerable.Where(fpcParams.VehicleFloorPricingParameters, x => condition >= x.LowCondition && condition <= x.HighCondition)); // 3. Get the floor pricing params based on matching condition. var mmrValue = GetMMRValueByParam(floorPricing.MMRAdjustedValue, fpcParams.ImsAutoFileData, fpcParams.ImsAutoFileData.AuctionGuideBookPrice ?? 0); List nadaValues = new List(); nadaValues.Add(GetNadaValueByParam(floorPricing.NADAFirstValue, fpcParams.CollateralValuation)); nadaValues.Add(GetNadaValueByParam(floorPricing.NADASecondValue, fpcParams.CollateralValuation)); bool onlyZeroNadaValues = nadaValues.TrueForAll(x => x == 0); if (fpcParams.CollateralValuation.Year <= (DateTime.Now.AddYears(-7).Year) || onlyZeroNadaValues) { nadaValues.Add(fpcParams.CollateralValuation.TradeIn); onlyZeroNadaValues = nadaValues.TrueForAll(x => x == 0); } // If there are no NADA or MMR prices, fail the strategy if (onlyZeroNadaValues && (mmrValue == 0 || mmrValue == fpcParams.ImsAutoFileData.AuctionGuideBookPrice)) { result.FailureReason = "No NADA or MMR prices returned"; return result; } // 4. Run the formula var nadaValue = GetNadaAvgValue(nadaValues); var divisor = mmrValue == 0 || nadaValue == 0 ? 1 : 2; var baseResult = (mmrValue + nadaValue) / divisor; baseResult = (baseResult * floorPricing.PercentageOf) / 100; baseResult = Math.Round(baseResult / 5.0m) * 5; result.FloorPrice = baseResult; result.Success = true; result.ResultWeight = GetStrategyWeight(); return result; } public decimal GetNadaAvgValue(List nadaValues) { Decimal aggregateValue = 0; int valueCount = 0; Decimal aggregateAvgValue = 0; if (nadaValues.Count() > 0) { foreach (var nadaVal in nadaValues) { if (nadaVal > 0) { aggregateValue += nadaVal; valueCount++; } } aggregateAvgValue = aggregateValue / valueCount; } return aggregateAvgValue; } private decimal GetNadaValueByParam(string floorPricingNadaFirstValue, CollateralValuation fpcParamsCollateralValuation) { if (floorPricingNadaFirstValue.ToLower().StartsWith("low")) { return fpcParamsCollateralValuation.LowAdjustedAuctionValue; } if (floorPricingNadaFirstValue.ToLower().StartsWith("avg")) { return fpcParamsCollateralValuation.AverageAdjustedAuctionValue; } return fpcParamsCollateralValuation.HighAdjustedAuctionValue; } private decimal GetMMRValueByParam(string floorPricingMmrValue, ImsAutoFileData fpcParamsImsAutoFileData, decimal defaultValue) { if (floorPricingMmrValue.ToLower().StartsWith("regional")) { return fpcParamsImsAutoFileData.MMRRegionalAdjustedPrice ?? defaultValue; } return fpcParamsImsAutoFileData.MMRNationalAdjustedPrice ?? defaultValue; } public int GetStrategyWeight() { return 99; // This is the preferred strategy. } } }