Example #1
0
        public BasketPricingResults PriceBasket(Basket basket, IEnumerable <IBasketPricingOffer> offers = null)
        {
            var results = new BasketPricingResults {
                ItemCount = 0
            };

            var isValidationFailed = this.ValidateBasket(basket, results);

            if (isValidationFailed)
            {
                return(results);
            }

            var isPricingFailed = this.TryToPriceBasket(basket, results);

            this.CalculateTotalPrice(results);
            if (isPricingFailed)
            {
                return(results);
            }

            this.TryToApplySpecialOffers(basket, results, offers);
            this.CalculateDiscountedPrices(results);

            if (results.FullPrice == results.DiscountedPrice)
            {
                results.Messages.Add(Errors.NoOffersAvailable);
            }

            return(results);
        }
Example #2
0
        private void CalculateDiscountedPrices(BasketPricingResults results)
        {
            var discount = 0m;

            foreach (var item in results.ItemPrices)
            {
                discount += item.Discount ?? 0;
            }

            results.DiscountedPrice = results.FullPrice - discount;
        }
Example #3
0
        private void TryToApplySpecialOffers(Basket basket, BasketPricingResults results, IEnumerable <IBasketPricingOffer> offers)
        {
            if (offers != null && offers.Any())
            {
                var itemsByName = results.ItemPrices.ToDictionary(x => x.Name, StringComparer.OrdinalIgnoreCase);

                foreach (var item in offers)
                {
                    item.ApplyOffers(itemsByName, results);
                }
            }
        }
Example #4
0
        private bool TryToPriceBasket(Basket basket, BasketPricingResults results)
        {
            var pricesToAsk  = basket.Items.Select(x => x.Name).Distinct(StringComparer.OrdinalIgnoreCase);
            var prices       = this.priceRepository.GetItemPrices(pricesToAsk);
            var pricesByName = prices.ToDictionary(x => x.Name, StringComparer.OrdinalIgnoreCase);

            results.ItemPrices = new List <BasketItemPrice>();
            var isFailed = false;

            var itemCount = 0;

            foreach (var item in basket.Items.GroupBy(x => x.Name))
            {
                var itemName      = item.Key;
                var quantity      = item.Count();
                var itemPrice     = pricesByName.TryGetValue(itemName, out var price) ? price.Price : default(decimal?);
                var baskItemPrice =
                    new BasketItemPrice
                {
                    Name      = item.Key,
                    UnitPrice = itemPrice,
                    Quantity  = quantity
                };

                itemCount += quantity;
                results.ItemPrices.Add(baskItemPrice);

                if (!baskItemPrice.UnitPrice.HasValue)
                {
                    results.Messages.Add(string.Format(Errors.PriceUnavailable, baskItemPrice.Name));
                    isFailed = true;
                }
            }

            results.ItemCount = itemCount;

            return(isFailed);
        }
Example #5
0
        private bool ValidateBasket(Basket basket, BasketPricingResults results)
        {
            var isFailed = false;

            if (results.Messages == null)
            {
                results.Messages = new List <string>();
            }

            if (basket is null)
            {
                results.Messages.Add(Errors.BasketIsNull);
                return(true);
            }

            if (basket.Items == null || !basket.Items.Any())
            {
                results.Messages.Add(Errors.BasketIsEmpty);
                isFailed = true;
            }

            return(isFailed);
        }
Example #6
0
        private void CalculateTotalPrice(BasketPricingResults results)
        {
            var totalPrice = results.ItemPrices.Where(x => x.UnitPrice.HasValue).Select(this.CalculatePrice).Sum();

            results.FullPrice = totalPrice;
        }