public ParcelCalculationsResult Calculate(IEnumerable <Parcel> parcels,
                                                  Action <DeliveryOptions> configureOptions = null)
        {
            if (parcels == null)
            {
                throw new ArgumentNullException(nameof(parcels));
            }

            var deliveryOptions = new DeliveryOptions(false);

            configureOptions?.Invoke(deliveryOptions);

            var parcelCosts = parcels
                              .Select((p, i) =>
            {
                var(metadata, cost) = CalculateParcelCost(p);

                return(new ParcelDeliveryCost($"Parcel #{i}, {metadata.ParcelType.ToString()} Parcel",
                                              metadata.ParcelType, cost));
            })
                              .ToArray();

            var deliveryDiscounts = _discountCalculator.CalculateDiscount(parcelCosts).ToArray();

            var costAfterDiscount = parcelCosts.Sum(pc => pc.Cost) - deliveryDiscounts.Sum(d => d.Discount);

            var fastDeliveryCost = CalculateFastDeliveryCost(deliveryOptions, costAfterDiscount);

            return(new ParcelCalculationsResult(parcelCosts, deliveryDiscounts, fastDeliveryCost));
        }
        public decimal Calculate(Order order)
        {
            #region

            if (order == null)
            {
                throw new ArgumentNullException(nameof(order));
            }

            if (order.Quantity <= 0)
            {
                throw new ArgumentOutOfRangeException(nameof(order.Quantity));
            }


            #endregion

            if (discountValidatorStrategy.CanDiscount(order))
            {
                return(order.Amount - discountCalculatorStrategy.CalculateDiscount(order));
            }
            else
            {
                return(order.Amount);
            }
        }
예제 #3
0
        public ParcelOrderOutput BuildOrder(ParcelOrder parcelOrder)
        {
            if (!parcelOrder.ParcelOrderItems.HaveValidParcelItems())
            {
                throw new Exception("Invalid Process.");
            }

            var parcelOrderOutput = new ParcelOrderOutput
            {
                IsSpeedy = parcelOrder.Speedy
            };

            var parcelBySize   = parcelOrder.ParcelOrderItems.Where(p => p.CalculationType.Equals(CalculationType.BySize));
            var parcelByWeight = parcelOrder.ParcelOrderItems.Where(p => p.CalculationType.Equals(CalculationType.ByWeight));


            if (parcelBySize.Any())
            {
                var(lineItems, totalCost) = ComposeLineItems(parcelBySize, ParcelBySizeSelector());

                parcelOrderOutput.LineItems.AddRange(lineItems);
                parcelOrderOutput.TotalCost += totalCost;
            }

            if (parcelByWeight.Any())
            {
                var(lineItems, totalCost) = ComposeLineItems(parcelByWeight, ParcelByWeightSelector());

                parcelOrderOutput.LineItems.AddRange(lineItems);
                parcelOrderOutput.TotalCost += totalCost;
            }

            // apply discounts
            if (parcelOrder.DiscountToApply.Any())
            {
                AppliedDiscount discount;

                if (parcelOrder.DiscountToApply.Contains(DiscountTypes.Mixed))
                {
                    discount = _discountCalculator.CalculateMixedDiscount(parcelOrderOutput.LineItems);
                }
                else
                {
                    discount = _discountCalculator.CalculateDiscount(parcelOrderOutput.LineItems);
                }

                parcelOrderOutput.TotalCost  = discount.TotalCost;
                parcelOrderOutput.TotalSaved = discount.SavedCost;
            }

            if (parcelOrder.Speedy)
            {
                parcelOrderOutput.TotalCost *= 2;
            }

            return(parcelOrderOutput);
        }
        public void CalculatorExceptionTest()
        {
            // Arrange
            IDiscountCalculator discountCalculator = CreateDiscountCalculator();

            // Act
            Action act = () => discountCalculator.CalculateDiscount(null);

            // Asserts

            act.Should().Throw <ArgumentNullException>();
        }
 public decimal CalculateDiscount(Sale sale)
 {
     var stopWatch = new Stopwatch();
     stopWatch.Start();
     try
     {
         return _discountCalculator.CalculateDiscount(sale);
     }
     finally
     {
         stopWatch.Stop();
         Console.WriteLine($"Performance: {stopWatch.ElapsedMilliseconds} ms");
     }
 }
예제 #6
0
        public decimal CalculateBasketTotal(IBasket basket)
        {
            if (basket == null)
            {
                throw new ArgumentNullException("Basket is null");
            }

            if (_calc == null)
            {
                throw new ArgumentNullException("Calculator is null");
            }

            // Get baskets total
            var total = basket.GetTotal();

            // Apply discounts
            var discount = _calc.CalculateDiscount(basket.Items);

            return(total - discount);
        }
예제 #7
0
        public async Task Given_ValidCarsToPurchase_Should_GiveSumOfDiscountsFromAllConditions()
        {
            var cars = _fixture.CreateMany <Repository.Cars.Car>(3).ToList();

            cars[0].Id = 1;
            cars[1].Id = 2;
            cars[2].Id = 3;

            _carRepositoryCache.GetAllCars().Returns(cars);

            _discountCalculator1.CalculateDiscount(Arg.Any <IReadOnlyList <Repository.Cars.Car> >()).Returns(100M);
            _discountCalculator2.CalculateDiscount(Arg.Any <IReadOnlyList <Repository.Cars.Car> >()).Returns(300M);

            // Act.
            var response = await _sut.CalculateDiscount(new List <int> {
                1, 2, 3
            });

            // Assert.
            response.Discount.Should().Be(400M);
        }
예제 #8
0
 public decimal GetGrandTotal()
 {
     return(GetRunningTotal() - _discountCalculator.CalculateDiscount(BasketItems));
 }
예제 #9
0
 public override void Act()
 {
     _result = _discountCalculator.CalculateDiscount(_customer);
 }
예제 #10
0
        public Money SubtotalCost(IDiscountCalculator visitor)
        {
            var calculatedCost = visitor.CalculateDiscount(this);

            return(calculatedCost);
        }
 public int TotalProductsSum(IEnumerable <Product> products)
 {
     return(products.Sum(p => p.Price)
            - _iscountCalculator.CalculateDiscount(products));
 }
예제 #12
0
 public decimal GetTotal() => _discountCalculator.CalculateDiscount(this);