public void Calculate_WhenBaseChargeIncludesACalculatedCharge_ShouldAddMultipleRatesToReverseRatesCollection() { // Arrange var dutyRate = new Rate(5); var baseCharges = new List <ChargeName> { ChargeNames.Item, ChargeNames.Duty }; var orderItem = _orderItemBuilder .WithVatRate(10) .Build(); orderItem.AddReverseRate(new ReverseRate("DutyOnItem", ChargeNames.Duty, dutyRate)); var order = _orderBuilder .WithOrderItems(new List <OrderItem> { orderItem }) .Build(); var sut = new ReverseRateCalculator(ChargeNames.Vat, oi => oi.VatRate, baseCharges); // Act sut.Calculate(order); // Assert orderItem.ReverseRates.Should() .HaveCount(3).And .ContainSingle(rr => rr.Rate == orderItem.VatRate && rr.ChargeName.Value == "VatOnItem" && rr.BaseChargeName.Value == ChargeNames.Vat).And .ContainSingle(rr => rr.Rate == dutyRate && rr.ChargeName.Value == "DutyOnItem" && rr.BaseChargeName.Value == ChargeNames.Duty).And .ContainSingle(rr => rr.Rate == new Rate(0.5m) && rr.ChargeName.Value == "VatOnDutyOnItem" && rr.BaseChargeName.Value == ChargeNames.Vat); }
public void Calculate_WhenBaseChargeAlreadyCalculated_ShouldCalculateForwardAndAddCorrectCharge() { // Arrange var baseCharges = new List <ChargeName> { ChargeNames.Duty }; var orderItem = _orderItemBuilder .WithVatRate(10) .Build(); orderItem.AddCharge(new OrderCharge("DutyOnItem", new Price(CurrencyFakes.EUR, 100), ChargeNames.Duty)); var order = _orderBuilder .WithOrderItems(new List <OrderItem> { orderItem }) .Build(); var sut = new ReverseRateCalculator(ChargeNames.Vat, oi => oi.VatRate, baseCharges); // Act sut.Calculate(order); // Assert orderItem.ReverseRates.Should().BeEmpty(); orderItem.Charges.Should().ContainSingle(c => c.ChargeName.Value == "VatOnDuty" && c.ChargeAmount.Value == 10); }
public void Calculate_WhenBaseChargeIsNotACalculatedCharge_ShouldAddRateToReverseRatesCollection() { // Arrange var baseCharges = new List <ChargeName> { ChargeNames.Item }; var orderItem = _orderItemBuilder .WithVatRate(10) .Build(); var order = _orderBuilder .WithOrderItems(new List <OrderItem> { orderItem }) .Build(); var sut = new ReverseRateCalculator(ChargeNames.Vat, oi => oi.VatRate, baseCharges); // Act sut.Calculate(order); // Assert orderItem.ReverseRates.Should() .ContainSingle(rr => rr.Rate == orderItem.VatRate && rr.ChargeName.Value == "VatOnItem" && rr.BaseChargeName.Value == ChargeNames.Vat); }
public static Calculator?Create(CalculationRange range, IEnumerable <ChargeName> deminimisBaseCharges) { Calculator?calculatorDelegate = null; foreach (var config in range.ChargeConfigurations) { IChargeCalculator calculator; switch (config) { // FIXED RATE CONFIGURATIONS case FixedRateChargeConfiguration fixedChargeConfig when config is FixedRateChargeConfiguration: { calculator = new FixedChargeCalculator(fixedChargeConfig.ChargeName, fixedChargeConfig.FixedChargeAmount); break; } // WEIGHT BASED CONFIGURATIONS case WeightBasedChargeConfiguration weightBasedChargeConfig when config is WeightBasedChargeConfiguration && weightBasedChargeConfig.Rate != null: { calculator = new WeightBasedChargeCalculator(weightBasedChargeConfig.ChargeName, (oi) => weightBasedChargeConfig.Rate); break; } case WeightBasedChargeConfiguration weightBasedChargeConfig when config is WeightBasedChargeConfiguration && config.ChargeName.Value is ChargeNames.Duty: { calculator = new WeightBasedChargeCalculator(weightBasedChargeConfig.ChargeName, (oi) => oi.DutyRate); break; } case WeightBasedChargeConfiguration weightBasedChargeConfig when config is WeightBasedChargeConfiguration && config.ChargeName.Value is ChargeNames.Vat: { calculator = new WeightBasedChargeCalculator(weightBasedChargeConfig.ChargeName, (oi) => oi.VatRate); break; } // RATE BASED CONFIGURATIONS case RateBasedChargeConfiguration rateBasedChargeConfig when config is RateBasedChargeConfiguration && rateBasedChargeConfig.Rate != null: { calculator = new ReverseRateCalculator(rateBasedChargeConfig.ChargeName, (oi) => rateBasedChargeConfig.Rate, rateBasedChargeConfig.BaseCharges); break; } case RateBasedChargeConfiguration rateBasedChargeConfig when config is RateBasedChargeConfiguration && rateBasedChargeConfig.ChargeName.Value is ChargeNames.Duty: { calculator = new ReverseRateCalculator(rateBasedChargeConfig.ChargeName, (oi) => oi.DutyRate, rateBasedChargeConfig.BaseCharges); break; } case RateBasedChargeConfiguration rateBasedChargeConfig when config is RateBasedChargeConfiguration && rateBasedChargeConfig.ChargeName.Value is ChargeNames.Vat: { calculator = new ReverseRateCalculator(rateBasedChargeConfig.ChargeName, (oi) => oi.VatRate, rateBasedChargeConfig.BaseCharges); break; } default: throw new InvalidChargeConfigurationException("Unknown charge configuration - can't create calculator delegate."); } // Add created calculator to delegate calculatorDelegate += calculator.Calculate; } foreach (var deminimisBaseCharge in deminimisBaseCharges) { // Add the item price calculator last calculatorDelegate += new ReversePriceCalculator(deminimisBaseCharge, $"Input{deminimisBaseCharge}").Calculate; } return(calculatorDelegate); }