/// <summary> /// Iterates the basket and calculates any discount on bread based on the beans cans in the basket /// </summary> /// <param name="basketItems">List of items in the basket</param> /// <returns>The total eligible discount if any</returns> public ValidDiscount Apply(IList <BasketItem> basketItems) { var discountType = _currentOffers.GetCurrentOffers().FirstOrDefault(discount => discount.DiscountCode == DiscountCode); var numberOfBeansCan = basketItems.Where(item => item.ProductName == "Beans") .Sum(x => x.NumberOfItems); var numberOfBreadLoaf = basketItems.Where(item => item.ProductName == "Bread") .Sum(x => x.NumberOfItems); if (numberOfBeansCan >= 2 && numberOfBreadLoaf > 0) { var numbersOfBreadLoafEligibleForHalfPrice = numberOfBeansCan / 2; var breadPrice = basketItems.First(item => item.ProductName == "Bread").PricePerItem; if (numberOfBreadLoaf <= numbersOfBreadLoafEligibleForHalfPrice) { numbersOfBreadLoafEligibleForHalfPrice = numberOfBreadLoaf; } var discountAmount = numbersOfBreadLoafEligibleForHalfPrice * (breadPrice / 2); return(new ValidDiscount { OfferType = discountType, DiscountAmount = discountAmount }); } return(null); }
/// <summary> /// Builds a list of BasketItems and returns the list /// </summary> /// <param name="products">space separated products to be added to the basket </param> /// <returns>List of BasketItems</returns> public List <BasketItem> Build(string[] products) { //Group same products together var groupedProducts = products.GroupBy(p => p) .Select(grp => new { ProductName = grp.Key, ProductCount = grp.Count() }).ToList(); var baskets = new List <BasketItem>(); var invalidProducts = new List <string>(groupedProducts.Count); bool skipFurtherProducts = false; //Create BasketItem with product list and their current offers foreach (var groupedProduct in groupedProducts) { var product = _productService.GetProduct(groupedProduct.ProductName); if (product == null) { invalidProducts.Add(groupedProduct.ProductName); skipFurtherProducts = true; //Don't get offers for any further products, as we will throw an exception once accumulating all invalid products continue; } if (skipFurtherProducts) { continue; } //Get current offers for this product var discountType = _currentOffers.GetCurrentOffers() .FirstOrDefault(c => c.ProductId == product.ProductId); //Fill the Basket baskets.Add(new BasketItem { OfferType = discountType, ProductId = product.ProductId, NumberOfItems = groupedProduct.ProductCount, PricePerItem = product.Price, ProductName = product.ProductName }); } if (invalidProducts.Count > 0) { throw new Exception($"Invalid products found: {string.Join(',',invalidProducts)}"); } return(baskets); }
/// <summary> /// Iterate the basket items and if any apples found, apply 10% discount /// </summary> /// <param name="basketItems">List of items in the basket</param> /// <returns>The total eligible discount if any</returns> public ValidDiscount Apply(IList <BasketItem> basketItems) { var discountType = _currentOffers.GetCurrentOffers().FirstOrDefault(discount => discount.DiscountCode == DiscountCode); var productEligibleForDiscount = basketItems.Where(basket => basket.OfferType?.DiscountCode == DiscountCode) .Select(basket => basket) .FirstOrDefault(); if (productEligibleForDiscount != null) { return new ValidDiscount { OfferType = discountType, DiscountAmount = (0.1m) * (productEligibleForDiscount.NumberOfItems * productEligibleForDiscount.PricePerItem) } } ; return(null); } }