using ShippingCosts.Contracts; namespace ShippingCosts.Implementations; /// /// Calculates the shipping costs for the Leonding Parcel Service carrier /// /// public sealed class LPSShippingCostCalculator(ICountryDistanceProvider countryDistanceProvider) : ShippingCostCalculatorBase(countryDistanceProvider) { public override string CarrierName => "Leonding Parcel Service"; public override decimal? CalculateShippingCosts(string targetCountry, IMeasuredBox box) { if (!CountryDistanceProvider.IsPossibleCountry(targetCountry)) { return null; } decimal? weightCost = CalculateWeightCost(box.Weight); if (weightCost == null) { return null; } decimal? sizeCost = CalculateSizeCost(box); if (sizeCost == null) { return null; } decimal distanceCost = CalcDistanceCost(targetCountry); return weightCost + sizeCost + distanceCost; } private decimal? CalculateWeightCost(double weight) { if (weight <= 0) { return null; } if (weight < 1.5) { return 0; } if (weight < 2) { return 0.5M; } if (weight < 3) { return 1.5M; } return Math.Min(20M, (decimal)(weight * 0.55)); } private decimal? CalculateSizeCost(IMeasuredBox box) { int sizeSum = SumOfLongestAndShortestSides(box); if (sizeSum <= 0) { return null; } if (sizeSum < 250) { return 0; } if (sizeSum < 400) { return 0.75M; } if (sizeSum < 650) { return 1.25M; } if (sizeSum < 900) { return 2.6M; } return 3.5M; } private decimal CalcDistanceCost(string targetCountry) { decimal baseCost = 2.99M; var distanceInfo = CountryDistanceProvider.GetDistanceTo(targetCountry); if (distanceInfo == null) { return baseCost; } if (!distanceInfo.Value.IsEuMember) { baseCost += 2.49M; } if (distanceInfo.Value.ApproxDistance == 0) { return baseCost; } int distanceUnits = Math.Max(1, (int)Math.Ceiling(distanceInfo.Value.ApproxDistance / 500.0)); decimal perUnitCost = 1.1M; if (distanceInfo.Value.IsDirectNeighbor) { perUnitCost *= 0.75M; } return baseCost + (distanceUnits * perUnitCost); } }