Esempio n. 1
0
        public void GiftVoucherProduct_NotIncludedDiscountableTotal()
        {
            //Arrange
            var basket = new Model.Basket();

            var hat = new BasketItem(1, "Hat", ProductCategoryHat, 25.00m);

            basket.AddBasketItem(hat);

            var jumper = new BasketItem(4, "� Gift Voucher", ProductCategoryGiftCard, 30.00m);

            basket.AddBasketItem(jumper);

            var offerVoucher = new OfferVoucher("111-333", "�00 off baskets over �.00 Offer Voucher", 5.00m, 50.00m);

            //Act
            var addOfferVoucherResult = basket.AddVoucher(offerVoucher);

            //Assert
            Assert.AreEqual(addOfferVoucherResult, false);
            Assert.AreEqual(basket.BasketItems.Count, 2);
            Assert.AreEqual(basket.Vouchers.Count, 0);
            Assert.That(basket.VoucherNotAppliedMessage, Is.Not.Null);
            Assert.AreEqual(basket.VoucherNotAppliedMessage, "You have not reached the spend threshold for voucher 111-333. Spend another �.01 to receive �00 discount from your basket total.");
            Assert.AreEqual(basket.GetSubTotal(), 55.00m);
        }
Esempio n. 2
0
        bool IsVoucherValid(GiftVoucher voucher)
        {
            bool isVoucherValid = false;

            if (voucher.GetType() == typeof(GiftVoucher))
            {
                isVoucherValid = true;
                _discountTotal = _discountTotal + voucher.Discount;
            }
            else if (!IsOfferVoucherAlreadyApplied)
            {
                if (voucher.GetType() == typeof(OfferVoucher))
                {
                    OfferVoucher offerVoucher = (OfferVoucher)voucher;
                    isVoucherValid = IsOfferVoucherValid(offerVoucher);
                }
                else if (voucher.GetType() == typeof(CategoryOfferVoucher))
                {
                    CategoryOfferVoucher offerVoucher = (CategoryOfferVoucher)voucher;
                    isVoucherValid = IsCategoryOfferVoucherValid(offerVoucher);
                }
            }
            else
            {
                _errorMessage = "You can only use one offer voucher at a time.";
            }

            return(isVoucherValid);
        }
Esempio n. 3
0
        bool IsOfferVoucherValid(OfferVoucher voucher)
        {
            bool isValid = IsVoucherThresholdMet(voucher);

            _discountTotal = (isValid) ? _discountTotal + voucher.Discount : _discountTotal;
            return(isValid);
        }
Esempio n. 4
0
        public void Basket4()
        {
            var product1 = new Product {
                Name = "Hat", Price = 25.00M, Category = ProductCategory.Clothing
            };
            var product2 = new Product {
                Name = "Jumper", Price = 26M, Category = ProductCategory.Clothing
            };
            var offerVoucher = new OfferVoucher {
                Name = "YYY-YYY", Discount = 5M, Threshold = 50
            };
            var giftVoucher = new GiftVoucher {
                Name = "XXX-XXX", Value = 5M
            };

            var basket = new Basket(new GiftVoucherService(), new ProductService(new Data.ProductRepository()));

            basket.AddProduct(1);
            basket.AddProduct(4);
            basket.Voucher = offerVoucher;
            basket.AddGiftVoucher(giftVoucher);

            Assert.AreEqual(41M, basket.Total);
            Assert.IsNull(basket.Message);
        }
Esempio n. 5
0
        public void Basket3()
        {
            var product1 = new Product {
                Name = "Hat", Price = 25.00M, Category = ProductCategory.Clothing
            };
            var product2 = new Product {
                Name = "Jumper", Price = 26M, Category = ProductCategory.Clothing
            };
            var product3 = new Product {
                Name = "Head Light", Price = 3.5M, Category = ProductCategory.HeadGear
            };
            var voucher = new OfferVoucher {
                Name = "YYY-YYY", Discount = 5M, Category = ProductCategory.HeadGear, Threshold = 50
            };

            var basket = new Basket(new GiftVoucherService(), new ProductService(new Data.ProductRepository()));

            basket.AddProduct(1);
            basket.AddProduct(4);
            basket.AddProduct(9);
            basket.Voucher = voucher;

            Assert.AreEqual(51M, basket.Total);
            Assert.IsNull(basket.Message);
        }
Esempio n. 6
0
        public void Voucher_with_category__basket_value_equals_threshold()
        {
            var product1 = new Product {
                Id = 1, Name = "Shirt", Price = 20.00M, Category = ProductCategory.Clothing
            };
            var product2 = new Product {
                Id = 2, Name = "Shirt", Price = 30.00M, Category = ProductCategory.Clothing
            };
            var offerVoucher = new OfferVoucher {
                Name = "YYY-YYY", Discount = 5M, Threshold = 50, Category = ProductCategory.Clothing
            };

            var mock = new Mock <IProductService>();

            mock.Setup(s => s.Get(1)).Returns(product1);
            mock.Setup(s => s.Get(2)).Returns(product2);

            var basket = new Basket(new GiftVoucherService(), mock.Object);

            basket.AddProduct(1);
            basket.AddProduct(2);
            basket.Voucher = offerVoucher;

            Assert.AreEqual(50M, basket.Total);
            Assert.AreEqual("You have not reached the spend threshold for voucher YYY-YYY. Spend another �01 to receive �00 discount from your basket total.", basket.Message);
        }
Esempio n. 7
0
        public void Voucher_no_category__basket_value_insufficient_because_of_gift_voucher()
        {
            var product1 = new Product {
                Id = 1, Name = "Hat", Price = 25.00M, Category = ProductCategory.Clothing
            };
            var product2 = new Product {
                Id = 2, Name = "aaa-aaa", Price = 50.00M, Category = ProductCategory.GiftVoucher
            };
            var offerVoucher = new OfferVoucher {
                Name = "YYY-YYY", Discount = 5M, Threshold = 50
            };

            var mock = new Mock <IProductService>();

            mock.Setup(s => s.Get(1)).Returns(product1);
            mock.Setup(s => s.Get(2)).Returns(product2);

            var basket = new Basket(new GiftVoucherService(), mock.Object);

            basket.AddProduct(1);
            basket.AddProduct(2);
            basket.Voucher = offerVoucher;

            Assert.AreEqual(75M, basket.Total);
            Assert.AreEqual("You have not reached the spend threshold for voucher YYY-YYY. Spend another �.01 to receive �00 discount from your basket total.", basket.Message);
        }
        private bool OfferIsApplicable(List <Product> products, OfferVoucher offer)
        {
            if (offer.ApplicableProductTypes != null)
            {
                var allBasketProductTypes     = products.Select(type => type.ProductType);
                var productTypesMatchingOffer = allBasketProductTypes.Intersect(offer.ApplicableProductTypes);

                if (productTypesMatchingOffer.Count() > 0)
                {
                    decimal sum = 0.00m;

                    foreach (var product in products)
                    {
                        if (productTypesMatchingOffer.Contains(product.ProductType))
                        {
                            sum += product.Price;
                        }
                    }

                    if (sum < offer.Value)
                    {
                        offer.Value = sum;
                    }

                    return(true);
                }
            }

            return(false);
        }
Esempio n. 9
0
        public void Voucher_with_category__basket_value_sufficient__category_total_less_than_voucher()
        {
            var product1 = new Product {
                Id = 1, Name = "Jumper", Price = 55.00M, Category = ProductCategory.Clothing
            };
            var product2 = new Product {
                Id = 2, Name = "Head Light", Price = 3.50M, Category = ProductCategory.HeadGear
            };
            var offerVoucher = new OfferVoucher {
                Name = "YYY-YYY", Discount = 5M, Threshold = 50, Category = ProductCategory.HeadGear
            };

            var mock = new Mock <IProductService>();

            mock.Setup(s => s.Get(1)).Returns(product1);
            mock.Setup(s => s.Get(2)).Returns(product2);

            var basket = new Basket(new GiftVoucherService(), mock.Object);

            basket.AddProduct(1);
            basket.AddProduct(2);
            basket.Voucher = offerVoucher;

            Assert.AreEqual(55M, basket.Total);
            Assert.IsNull(basket.Message);
        }
Esempio n. 10
0
        private async Task <(IEnumerable <VoucherApplicationResponse>, string)> FormatVouchers(IEnumerable <Voucher> vouchers, IEnumerable <Item> items)
        {
            var          giftVouchers = new List <GiftVoucher>();
            OfferVoucher offerVoucher = null;

            foreach (var voucher in vouchers)
            {
                switch (voucher.VoucherType)
                {
                case VoucherType.Offer:
                    if (offerVoucher != null)
                    {
                        return(null, "Can only apply one offer voucher");
                    }
                    offerVoucher = await _voucherRepository.GetOfferVoucherByVoucherId(voucher.VoucherId).ConfigureAwait(false);

                    break;

                case VoucherType.Gift:
                    giftVouchers.Add(await _voucherRepository.GetGiftVoucherByVoucherId(voucher.VoucherId).ConfigureAwait(false));
                    break;
                }
            }

            return(ApplyVouchersItems(offerVoucher, giftVouchers, items));
        }
Esempio n. 11
0
        public async Task <IActionResult> CreateOffer([FromBody] OfferVoucher voucher)
        {
            if (await _voucherRepository.GetByCode(voucher.Code).ConfigureAwait(false) != null)
            {
                return(BadRequest($"Voucher with code '{voucher.Code}' already exists"));
            }

            if (voucher.SubsetGroup != null && !string.IsNullOrEmpty(voucher.SubsetGroup.Name))
            {
                var subsetGroup = await _subsetRepository.GetByName(voucher.SubsetGroup.Name).ConfigureAwait(false);

                if (subsetGroup == null)
                {
                    return(BadRequest($"Subset with name '{voucher.SubsetGroup.Name}' does not exist"));
                }

                voucher.SubsetGroup.SubsetId = subsetGroup.SubsetId;
            }

            var offerVoucher = await _voucherRepository.Create(voucher).ConfigureAwait(false);

            var locatedAtUri = HttpContext.Request.CreateCreatedUri($"api/vouchers/{offerVoucher.VoucherId}");

            return(Created(locatedAtUri, offerVoucher));
        }
Esempio n. 12
0
        public void OfferVoucher_NotRedeemed_InvalidBasketItems()
        {
            //Arrange
            var basket = new Model.Basket();

            var hat = new BasketItem(1, "Hat", ProductCategoryHat, 25.00m);

            basket.AddBasketItem(hat);

            var jumper = new BasketItem(2, "Jumper", ProductCategoryTops, 26.00m);

            basket.AddBasketItem(jumper);

            var headGearVoucher = new OfferVoucher("111-333", "�00 off Head Gear in baskets over �.00 Offer Voucher", 5.00m, 50.00m, new List <int> {
                ProductCategoryHeadGear
            });

            //Act
            var addVoucherResult = basket.AddVoucher(headGearVoucher);

            //Assert
            Assert.AreEqual(addVoucherResult, false);
            Assert.AreEqual(basket.BasketItems.Count, 2);
            Assert.AreEqual(basket.Vouchers.Count, 0);
            Assert.That(basket.VoucherNotAppliedMessage, Is.Not.Null);
            Assert.AreEqual(basket.VoucherNotAppliedMessage, "There are no products in your basket applicable to voucher Voucher 111-333.");
            Assert.AreEqual(basket.GetSubTotal(), 51.00m);
        }
Esempio n. 13
0
        public void OfferVoucher_PartRedeemed_OK()
        {
            //Arrange
            var basket = new Model.Basket();

            var hat = new BasketItem(1, "Hat", ProductCategoryHat, 25.00m);

            basket.AddBasketItem(hat);

            var jumper = new BasketItem(2, "Jumper", ProductCategoryTops, 26.00m);

            basket.AddBasketItem(jumper);

            var headLight = new BasketItem(3, "Head Light", ProductCategoryHeadGear, 3.50m);

            basket.AddBasketItem(headLight);

            var headGearVoucher = new OfferVoucher("111-333", "�00 off Head Gear in baskets over �.00 Offer Voucher", 5.00m, 50.00m, new List <int> {
                ProductCategoryHeadGear
            });

            //Act
            var addVoucherResult = basket.AddVoucher(headGearVoucher);

            //Assert
            Assert.AreEqual(addVoucherResult, true);
            Assert.AreEqual(basket.BasketItems.Count, 3);
            Assert.AreEqual(basket.Vouchers.Count, 1);
            Assert.That(basket.VoucherNotAppliedMessage, Is.Null);
            Assert.AreEqual(basket.GetSubTotal(), 51.00m);
        }
Esempio n. 14
0
        public void Voucher_WhenOfferVoucherInitialised_return_NotGiftVoucher()
        {
            GiftVoucher  giftVoucher = new GiftVoucher("YYY-YYY", 5);
            OfferVoucher expected    = new OfferVoucher("YYY-YYY", 5);

            expected.Should().NotBe(giftVoucher, "Gift vouchers have different rules to offer vouchers");
        }
Esempio n. 15
0
        public void OfferGiftVoucher_Redeemed_OK()
        {
            //Arrange
            var basket = new Model.Basket();

            var hat = new BasketItem(1, "Hat", ProductCategoryHat, 25.00m);

            basket.AddBasketItem(hat);

            var jumper = new BasketItem(2, "Jumper", ProductCategoryTops, 26.00m);

            basket.AddBasketItem(jumper);

            var offerVoucher = new OfferVoucher("111-333", "�00 off baskets over �.00 Offer Voucher", 5.00m, 50.00m);
            var giftVoucher  = new GiftVoucher("111-222", "�00 Gift Voucher", 5.00m);

            //Act
            var addGiftVoucherResult  = basket.AddVoucher(giftVoucher);
            var addOfferVoucherResult = basket.AddVoucher(offerVoucher);

            //Assert
            Assert.AreEqual(addGiftVoucherResult, true);
            Assert.AreEqual(addOfferVoucherResult, true);
            Assert.AreEqual(basket.BasketItems.Count, 2);
            Assert.AreEqual(basket.Vouchers.Count, 2);
            Assert.That(basket.VoucherNotAppliedMessage, Is.Null);
            Assert.AreEqual(basket.GetSubTotal(), 41.00m);
        }
Esempio n. 16
0
        bool IsVoucherThresholdMet(OfferVoucher voucher)
        {
            bool          isValid           = false;
            const decimal thresholdBoundary = 0.01m;
            decimal       adjustedPrice     = _originalPrice;

            List <Product> invalidThresholdItems = BasketItems.Where(w => w.Category == "Gift Vouchers").ToList();

            if (invalidThresholdItems.Count > 0)
            {
                decimal totalInvalidCost = 0;
                foreach (Product product in invalidThresholdItems)
                {
                    totalInvalidCost = totalInvalidCost + product.Price;
                }
                adjustedPrice = (adjustedPrice - totalInvalidCost);
            }

            decimal remainingCostToReachThreshold = (voucher.Threshold - adjustedPrice) + thresholdBoundary;

            if ((invalidThresholdItems.Count() == 0 && _originalPrice > voucher.Threshold) || remainingCostToReachThreshold <= 0)
            {
                isValid = true;
            }
            else
            {
                _errorMessage = $"You have not reached the spend threshold for the voucher {voucher.VoucherCode}. Spend another £{remainingCostToReachThreshold} to receive the £{voucher.Discount} discount from your basket total.";
            }

            return(isValid);
        }
Esempio n. 17
0
        public void Basket_AcceptsOfferVoucher()
        {
            var testOffer = new OfferVoucher(10m, 15m);

            _sut.AddVoucher(testOffer);

            _sut.Vouchers.Should().Contain(testOffer);
        }
        public void GiftVoucher_AcceptsPositiveValue()
        {
            Action act = () =>
            {
                var sut = new OfferVoucher(10m, 10m);
            };

            act.ShouldNotThrow();
        }
        public void GiftVoucher_RejectsNegativeThreshold()
        {
            Action act = () =>
            {
                var sut = new OfferVoucher(10m, -10m);
            };

            act.ShouldThrow <ArgumentException>()
            .WithMessage("Value cannot be negative.");
        }
Esempio n. 20
0
        public void Basket_whenOfferVoucherAdded_return_BasketHasVoucher()
        {
            Cart cart = new Cart(new List <CartItem>()
            {
                new CartItem(new Product("Hat", 10.5, new Category("")), 1)
            });
            OfferVoucher offerVoucher = new OfferVoucher("XXX-XXX", 5);
            Basket       basket       = new Basket(cart, offerVoucher);

            Assert.IsTrue(basket.HasVouchers);
        }
Esempio n. 21
0
        public void Basket_whenOfferVoucherAttachedToCategoryAdded_return_BasketHasVoucher()
        {
            Cart cart = new Cart(new List <CartItem>()
            {
                new CartItem(new Product("Hat", 10.5, new Category("")), 1)
            });
            OfferVoucher expected = new OfferVoucher("XXX-XXX", 5.00, 50.00, new Category("Head Gear"));
            Basket       basket   = new Basket(cart, expected);

            Assert.IsTrue(basket.HasVouchers);
        }
Esempio n. 22
0
        public void Basket_whenOfferVoucherAddedAndOffCodeAppliedAndCodeIsValid_return_ValidCode()
        {
            Cart cart = new Cart(new List <CartItem>()
            {
                new CartItem(new Product("Hat", 10.5, new Category("")), 1)
            });
            OfferVoucher offerVoucher = new OfferVoucher("XXX-XXX", 5);
            Basket       basket       = new Basket(cart, offerVoucher);

            Assert.IsTrue(basket.ApplyVoucher("XXX-XXX"));
        }
Esempio n. 23
0
        public void Basket_whenOfferVoucherAddedAndOffCodeAppledTiCategoryAppliedAndCartHasItemNotInCategory_return_CondNotValid()
        {
            Cart cart = new Cart(new List <CartItem>()
            {
                new CartItem(new Product("Hat", 10.5), 1)
            });
            OfferVoucher expected = new OfferVoucher("XXX-XXX", 5.00, 50.00, new Category("Head Gear"));
            Basket       basket   = new Basket(cart, expected);

            Assert.IsFalse(basket.ApplyVoucher("XXX-XXX"));
        }
Esempio n. 24
0
        public void GivenGiftVoucherProductAndInapplicableOfferVoucherThenCalculateBasketValue()
        {
            var hat          = new Product(25m);
            var giftVoucher  = new Product(30m, ProductCategory.GiftVoucher);
            var offerVoucher = new OfferVoucher(5m, 50);

            _basket.Add(hat);
            _basket.Add(giftVoucher);
            _basket.Add(offerVoucher);

            _basket.TotalValue.Should().Be(55m);
        }
Esempio n. 25
0
        public void GivenProductsAndInapplicableOfferVoucherThenCalculateBasketValue()
        {
            var hat          = new Product(25m);
            var jumper       = new Product(26m);
            var offerVoucher = new OfferVoucher(5m, 50m, ProductCategory.HeadGear);

            _basket.Add(hat);
            _basket.Add(jumper);
            _basket.Add(offerVoucher);

            _basket.TotalValue.Should().Be(51m);
        }
Esempio n. 26
0
        public void Basket_whenOfferVoucherAddedAndOffCodeAppledTiCategoryAppliedAndCartHasItemInCategory_return_Total()
        {
            Cart         cart        = new Cart();
            Product      product1    = cart.Add(new Product("Hat", 25.00), 1);
            Product      product3    = cart.Add(new Product("Jumper", 26.00), 1);
            OfferVoucher expected    = new OfferVoucher("YYY-YYY", 5.00, 50.00, new Category("Head Gear"));
            Basket       basket      = new Basket(cart, expected);
            bool         IsCodeValid = basket.ApplyVoucher("YYY-YYY");

            Assert.AreEqual(51.00, basket.Total);
            IsCodeValid.Should().BeFalse("There are no products in your basket applicable to voucher Voucher YYY-YYY");
        }
Esempio n. 27
0
        public void Basket_CalulatesWithOfferRestrictionAndValueAboveProductValue()
        {
            var testProductA = new Product("Light", 10m, ProductCategory.HeadGear);
            var testProductB = new Product("Jumper", 20m);
            var testVoucher  = new OfferVoucher(15m, 5m, ProductCategory.HeadGear);

            _sut.AddProduct(testProductA);
            _sut.AddProduct(testProductB);
            _sut.AddVoucher(testVoucher);

            _sut.Total().Should().Be(20m);
        }
Esempio n. 28
0
        public void Basket_whenOfferVoucherAddedAndOffCodeAppledTiCategoryAppliedAndCartHasItemInCategoryAndHasMinSpend_return_Total()
        {
            Cart         cart        = new Cart();
            Product      product1    = cart.Add(new Product("Hat", 25.00), 1);
            Product      product2    = cart.Add(new Product("Jumper", 26.00), 1);
            Product      product3    = cart.Add(new Product("Head Light", 3.50, new Category("Head Gear")), 1);
            OfferVoucher expected    = new OfferVoucher("YYY-YYY", 5.00, 50.00, new Category("Head Gear"));
            Basket       basket      = new Basket(cart, expected);
            bool         IsCodeValid = basket.ApplyVoucher("YYY-YYY");

            Assert.AreEqual(51.00, basket.Total);
            IsCodeValid.Should().BeTrue();
        }
Esempio n. 29
0
        public void GivenProductsInapplicableOfferVoucherAndApplicableGiftVoucherThenCalculateBasketValue()
        {
            var hat          = new Product(25);
            var jumper       = new Product(26);
            var giftVoucher  = new GiftVoucher(5m);
            var offerVoucher = new OfferVoucher(5m, 50m);

            _basket.Add(hat);
            _basket.Add(jumper);
            _basket.Add(giftVoucher);
            _basket.Add(offerVoucher);

            _basket.TotalValue.Should().Be(41m);
        }
Esempio n. 30
0
        static void Basket5()
        {
            Console.WriteLine("Basket 5");
            List <Product> basketProducts = new List <Product>
            {
                new Product(true, "Hat", 25.00m, Category.NONE),
                new Product(false, "Gift Voucher", 30.00m, Category.NONE),
            };
            Basket             basket   = new Basket(basketProducts);
            List <GiftVoucher> vouchers = new List <GiftVoucher>();
            OfferVoucher       offer    = new OfferVoucher(5, 50);

            basket.Checkout(vouchers, offer);
        }