Files
2026-04-20 14:47:24 -05:00

144 lines
4.6 KiB
C#

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<Decimal> nadaValues = new List<decimal>();
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<Decimal> 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.
}
}
}