예제 #1
0
        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);
        }
예제 #2
0
        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);
        }
예제 #3
0
        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);
        }
예제 #4
0
        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);
        }