Adding
This commit is contained in:
+21
@@ -0,0 +1,21 @@
|
||||
using System.Collections.Generic;
|
||||
using LCU.API.Collections.RepoApi.Domain.FloorPricing.Strategies;
|
||||
|
||||
namespace LCU.API.Collections.RepoApi.Domain.FloorPricing
|
||||
{
|
||||
public class FloorPricingStrategyFactory : IFloorPricingStrategyFactory
|
||||
{
|
||||
public FloorPricingStrategyFactory()
|
||||
{
|
||||
}
|
||||
|
||||
public IReadOnlyCollection<IFloorPricingStrategy> GetFloorPricingStrategies()
|
||||
{
|
||||
return new List<IFloorPricingStrategy>()
|
||||
{
|
||||
new AutoImsSuggestedValue(),
|
||||
new NadaMmrConditionValue()
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
+13
@@ -0,0 +1,13 @@
|
||||
using LCU.Shared.Collections.RepoApiLib.Models;
|
||||
|
||||
namespace LCU.API.Collections.RepoApi.Domain.FloorPricing
|
||||
{
|
||||
public interface IFloorPricingStrategy
|
||||
{
|
||||
|
||||
FloorPriceCalculationResult CalculateFloorPrice(FloorPriceCalculationParams fpcParams);
|
||||
int GetStrategyWeight();
|
||||
// Requirements and Qualifications
|
||||
|
||||
}
|
||||
}
|
||||
+9
@@ -0,0 +1,9 @@
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace LCU.API.Collections.RepoApi.Domain.FloorPricing
|
||||
{
|
||||
public interface IFloorPricingStrategyFactory
|
||||
{
|
||||
IReadOnlyCollection<IFloorPricingStrategy> GetFloorPricingStrategies();
|
||||
}
|
||||
}
|
||||
+43
@@ -0,0 +1,43 @@
|
||||
using System;
|
||||
using LCU.Shared.Collections.RepoApiLib.Models;
|
||||
|
||||
namespace LCU.API.Collections.RepoApi.Domain.FloorPricing.Strategies
|
||||
{
|
||||
/**
|
||||
* This strategy uses the suggested price from the ImsAutoFileData entry for the auction.
|
||||
*/
|
||||
public class AutoImsSuggestedValue : IFloorPricingStrategy
|
||||
{
|
||||
public AutoImsSuggestedValue() { }
|
||||
|
||||
public FloorPriceCalculationResult CalculateFloorPrice(FloorPriceCalculationParams fpcParams)
|
||||
{
|
||||
var result = new FloorPriceCalculationResult()
|
||||
{
|
||||
StrategyName = this.GetType().FullName,
|
||||
Success = false
|
||||
};
|
||||
|
||||
if (fpcParams?.ImsAutoFileData?.AuctionGuideBookPrice != null)
|
||||
{
|
||||
// Price must be rounded to nearest $5 per business.
|
||||
var inputPrice = (double)(fpcParams.ImsAutoFileData.AuctionGuideBookPrice ?? 0);
|
||||
result.FloorPrice = (decimal) (Math.Round( inputPrice / 5.0) * 5);
|
||||
result.Success = result.FloorPrice > 0;
|
||||
result.FailureReason = result.Success ? "" : "Failed attempt to use auction guide book price.";
|
||||
}
|
||||
else
|
||||
{
|
||||
result.Success = false;
|
||||
result.FailureReason = "Auction Guide Book Price missing.";
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
public int GetStrategyWeight()
|
||||
{
|
||||
return 0; // This is NOT the preferred strategy.
|
||||
}
|
||||
}
|
||||
}
|
||||
+144
@@ -0,0 +1,144 @@
|
||||
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.
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user