public void Calculate(Order order)
        {
            foreach (var item in order.OrderItems)
            {
                // For each base charge that this charge should be calculated on top of (item, duty, vat etc.)
                foreach (var baseChargeName in _baseCharges)
                {
                    // All of the charges that we need to calculate on top of
                    // e.g if applying on top of item and vat, and vat was applied on item, the charges we need to calculate on are:
                    // item, vatOnItem
                    var baseCharges = item.Charges.Where(c => c.BaseChargeName == baseChargeName);

                    foreach (var charge in baseCharges.ToList())
                    {
                        if (charge.ChargeAmount.Value == 0)
                        {
                            continue;
                        }

                        var chargeAmount = charge.ChargeAmount * _getRate(item).AsDecimal;

                        var chargeName = ChargeName.FromBaseChargeName(_chargeName, charge.ChargeName);

                        item.AddCharge(new OrderCharge(chargeName, chargeAmount, _chargeName));
                    }
                }
            }
        }
        public void Calculate(Order order)
        {
            foreach (var item in order.OrderItems)
            {
                var chargeAmount = _amount * order.RelativeOrderItemValue(item);

                var chargeName = ChargeName.FromBaseChargeName(_chargeName, ChargeNames.Item);

                item.AddCharge(new OrderCharge(chargeName, chargeAmount, _chargeName));
            }
        }
        public void Calculate_SingleOrderItem_ShouldAddCorrectCharge()
        {
            // Arrange
            var orderItem = _orderItemBuilder.Build();
            var order     = _orderBuilder.WithOrderItems(new List <OrderItem> {
                orderItem
            }).Build();
            var expectedChargeName = ChargeName.FromBaseChargeName(_chargeName, ChargeNames.Item);

            var sut = new FixedChargeCalculator(_chargeName, new Price(CurrencyFakes.EUR, 10));

            // Act
            sut.Calculate(order);

            // Assert
            orderItem.Charges.Should()
            .HaveCount(3).And
            .ContainSingle(c => c.ChargeName.Value == expectedChargeName && c.ChargeAmount.Value == 10);
        }
Beispiel #4
0
        public void Calculate(Order order)
        {
            foreach (var item in order.OrderItems)
            {
                // Loop through each of the charges that this charge type is to be calculated on top of.
                foreach (var baseChargeName in _baseCharges)
                {
                    var baseChargeAmount = item.GetChargeAmount(baseChargeName, order.Currency);

                    // Check to see if a charge has been calculated for this charge type.
                    // If so, do a forward calculation - the calculated charges can be removed from the
                    // inclusive price before applying the reverse rate as they are known.
                    if (baseChargeAmount.Value != 0)
                    {
                        var chargeAmount = baseChargeAmount * _getRate(item).AsDecimal;

                        var chargeName = ChargeName.FromBaseChargeName(_chargeName, baseChargeName);

                        item.AddCharge(new OrderCharge(chargeName, chargeAmount, _chargeName));
                    }

                    // If the charge that we need to calculate on top of has not already been calculated,
                    // and is therefore unknown - we need to calculate the reverse rate.
                    else
                    {
                        // If the base charge is item or delivery (not a calculated rate), just add the rate
                        // for this item to the calculation rates collection. There might be a better way of
                        // identifying these 'non calculated' rates types of charges that would be more flexible.
                        if (baseChargeName.Value == "Item" || baseChargeName.Value == "Delivery")
                        {
                            item.AddReverseRate(new ReverseRate(
                                                    name: ChargeName.FromBaseChargeName(_chargeName, baseChargeName),
                                                    parentChargeName: _chargeName,
                                                    rate: _getRate(item)));
                        }

                        // If the base charge is a calculated rate, we need to calculate a new rate and add it
                        // to the calculated rates collection. All of these rates combined will be used to reverse
                        // back to the item price.
                        else
                        {
                            // Get the current list of rates
                            var reverseRates = item.ReverseRates.ToList();

                            // Get all of the reverse rates related to the current base charge. For example, if we're
                            // calculating a fee, which was calculated on top of duty and vat, we'll need the base
                            // fee rate, the fee on duty rate and the fee on vat rate. This is done by querying the
                            // rates collection by 'parent' charge. In this example, all rates would have a parent charge
                            // of fee.
                            foreach (var reverseRate in reverseRates.Where(x => x.BaseChargeName == baseChargeName))
                            {
                                var rate = _getRate(item).AsDecimal *reverseRate.Rate.AsDecimal * 100;

                                var calculatedRate = new ReverseRate(
                                    name: ChargeName.FromBaseChargeName(_chargeName, reverseRate.ChargeName),
                                    parentChargeName: _chargeName,
                                    rate: new Rate(rate));

                                item.AddReverseRate(calculatedRate);
                            }
                        }
                    }
                }
            }
        }