示例#1
0
        [InlineData(1001, "Ham", 30, 5, 1002, "Fish", 100, 10)] //If we add 1 item with quantity of 2, and another with quantity of 4, then the unit price of each will remain constant while the subtotal (unit price * quantity) will change, it wont match?
        public void After_Adding_Two_Items_With_Different_Quantities_Both_With_A_NoTax_Rule_To_An_Empty_Basket_Both_The_Tax_Of_The_Item_And_The_Basket_Should_Equal_0_And_Both_The_Subtotal_And_The_Total_Of_The_Item_And_Basket_Should_Equal_The_Items_Unit_Price(
            int hamItemId, string hamItemName, decimal hamItemPrice, int hamItemQuantity,
            int fishItemId, string fishItemName, decimal fishItem2Price, int fishItemQuantity)
        {
            //Arrange
            IShoppingItem hamItem = new ShoppingItem(hamItemId, hamItemName, hamItemPrice, new List <ITaxRule>()
            {
                TaxRules.NoTax
            });
            IShoppingItem fishItem = new ShoppingItem(fishItemId, fishItemName, fishItem2Price, new List <ITaxRule>()
            {
                TaxRules.NoTax
            });

            //Act
            _basket.AddItem(hamItem, hamItemQuantity);
            _basket.AddItem(fishItem, fishItemQuantity);

            //Assert
            List <IShoppingBasketItem> basketItems = _basket.Items as List <IShoppingBasketItem>;

            IShoppingBasketItem hamBasketItem  = basketItems.FirstOrDefault(x => x.Id == hamItem.Id);
            IShoppingBasketItem fishBasketItem = basketItems.FirstOrDefault(x => x.Id == fishItem.Id);

            hamBasketItem.Tax.Should().Be(0);
            _basket.Tax.Should().Be(0);
            //hamBasketItem.SubTotal.Should().Be(hamBasketItem.UnitPrice);
            //_basket.SubTotal.Should().Be(hamBasketItem.UnitPrice);

            fishBasketItem.Tax.Should().Be(0);
            _basket.Tax.Should().Be(0);
            //fishBasketItem.SubTotal.Should().Be(fishBasketItem.UnitPrice);
            //_basket.SubTotal.Should().Be(fishBasketItem.UnitPrice);
        }
 private void CalculateTax(IShoppingBasket basket, IShoppingBasketItem basketItem)
 {
     foreach (var taxRule in basketItem.TaxRules)
     {
         taxRule.CalculateTax(basket, basketItem);
     }
 }
示例#3
0
 // I probably would have avoided this side effect, but since basket did not have a TaxRules property of its own, I couldn't think of another reason for why the basket was used as a parameter in CalculateTax()
 protected virtual void UpdateTotals(IShoppingBasket basket, IShoppingBasketItem item, decimal tax)
 {
     item.Tax     += tax;
     item.Total   += tax;
     basket.Tax   += tax;
     basket.Total += tax;
 }
示例#4
0
        public decimal CalculateTax(IShoppingBasket basket, IShoppingBasketItem item)
        {
            var tax = _unitItemTax * item.Quantity;

            UpdateTotals(basket, item, tax);

            return(_unitItemTax);
        }
 private static decimal GetBogofDiscount(IShoppingBasketItem basketItem)
 {
     //Get the discount for odd quantity by getting the even number of items by removing the odd item and dividing by 2
     //then adding the price of 1 item back on to get the total
     return(basketItem.Quantity % 2 == 1
         ? ((basketItem.SubTotal - (basketItem.SubTotal / basketItem.Quantity)) / 2) + (basketItem.SubTotal / basketItem.Quantity)
         : basketItem.SubTotal / 2);
 }
示例#6
0
        public decimal CalculateTax(IShoppingBasket basket, IShoppingBasketItem item)
        {
            var tax = _percentage * item.SubTotal;

            UpdateTotals(basket, item, tax);

            return(tax);
        }
        //Discounts DO NOT use Total and DO NOT take Tax into consideration
        public decimal CalculateDiscount(IShoppingBasketItem basketItem)
        {
            if (basketItem.Quantity <= 1)
            {
                return(0);
            }

            return(GetBogofDiscount(basketItem));
        }
        [InlineData(1001, "Ham", 10)] //Should this say "Updating_An_Item_To_A_Quantity_Of_Less_Than_0" as should be able to remove all "Ham" from _basket to 0, and add "Fish" for example
        public void Updating_An_Item_To_A_Quantity_Of_0_Or_Less_Will_Result_In_An_ArgumentOutOfRangeException_Being_Thrown(int itemId, string itemName, decimal itemPrice)
        {
            //Arrange
            IShoppingItem item = new ShoppingItem(itemId, itemName, itemPrice);

            //Act And Assert
            IShoppingBasketItem basketItem = _basket.AddItem(item);

            _basket.RemoveItem(basketItem);

            Assert.Throws <ArgumentOutOfRangeException>(() => _basket.RemoveItem(basketItem));
        }
        public void Removing_An_Item_That_Doesnt_Exist_In_The_Basket_Will_Result_In_An_KeyNotFoundException_Being_Thrown(int itemId, string itemName, decimal itemPrice)
        {
            //Arrange
            IShoppingItem item = new ShoppingItem(itemId, itemName, itemPrice);

            //Act And Assert
            IShoppingBasketItem basketItem = _basket.AddItem(item);

            IShoppingBasketItem itemThatDoesntExistInBasket = new ShoppingBasketItem(itemId + 1, itemName + "1", itemPrice + 1, null, null);

            //Assert
            Assert.Throws <KeyNotFoundException>(() => _basket.RemoveItem(itemThatDoesntExistInBasket));
        }
        public void After_Updating_The_Quantity_On_An_Item_Already_In_A_Basket_Both_The_Basket_And_Item_Quantities_Are_Correct(int itemId, string itemName, decimal itemPrice)
        {
            //Arrange
            IShoppingItem item = new ShoppingItem(itemId, itemName, itemPrice);

            //Act
            IShoppingBasketItem basketItem = _basket.AddItem(item);

            _basket.AddItem(item, 3);       //As there is no "Edit" method defined on the interface updating the quantity is done by adding another item

            _basket.RemoveItem(basketItem); //As we added 4 Items and removed 1, 3 Items should now remain in the Basket

            //Assert
            List <IShoppingBasketItem> basketItems = _basket.Items as List <IShoppingBasketItem>;

            basketItems.FirstOrDefault(x => x.Id == itemId).Quantity.Should().Be(3);
            basketItems.Sum(x => x.Quantity).Should().Be(3);
        }
示例#11
0
        public void After_Adding_A_Single_Item_To_An_Empty_Basket_Both_The_Subtotal_Of_The_Item_And_Basket_Should_Equal_The_Items_Unit_Price(int itemId, string itemName, decimal itemPrice)
        {
            //Arrange
            IShoppingItem item = new ShoppingItem(itemId, itemName, itemPrice, new List <ITaxRule>()
            {
                TaxRules.NoTax
            });

            //Act
            _basket.AddItem(item);

            //Assert
            List <IShoppingBasketItem> basketItems = _basket.Items as List <IShoppingBasketItem>;

            IShoppingBasketItem basketItem = basketItems.FirstOrDefault(x => x.Id == itemId);

            basketItem.SubTotal.Should().Be(basketItem.UnitPrice);
            _basket.SubTotal.Should().Be(basketItem.UnitPrice);
        }
示例#12
0
        public decimal CalculateTax(IShoppingBasket basket, IShoppingBasketItem item)
        {
            var unitItemTax = 0m;

            foreach (var band in _taxBands)
            {
                var applicableValue = (band.Cap ?? item.UnitPrice) - band.Threshold;

                var temporaryItem = new DefaultShoppingBasketItem {
                    SubTotal = applicableValue, Quantity = 1
                };                                                                                               // remove explicit instantiation from here
                unitItemTax += band.TaxRule.CalculateTax(basket, temporaryItem);
            }

            var itemTax = unitItemTax * item.Quantity;

            UpdateTotals(basket, item, itemTax);

            return(itemTax);
        }
示例#13
0
        public void After_Adding_Two_Items_With_A_BuyOneGetOneFree_Discount_rule_To_An_Empty_Basket_Both_The_Discount_Of_The_Item_And_The_Basket_Should_Equal_0_And_Both_The_Subtotal_Of_The_Item_And_Basket_Should_Equal_The_Items_Unit_Price(int itemId, string itemName, decimal itemPrice)
        {
            //Arrange
            IShoppingItem item = new ShoppingItem(itemId, itemName, itemPrice, discountRules: new List <IDiscountRule>()
            {
                DiscountRules.BuyOneGetOneFreeDisountRule
            });

            //Act
            _basket.AddItem(item, 4);

            //Assert
            List <IShoppingBasketItem> basketItems = _basket.Items as List <IShoppingBasketItem>;

            IShoppingBasketItem basketItem = basketItems.FirstOrDefault(x => x.Id == itemId);

            _basket.Discount.Should().Be(20);

            _basket.Total.Should().Be(20);

            basketItem.SubTotal.Should().Be(40);
            _basket.SubTotal.Should().Be(40);
        }
示例#14
0
        public void After_Adding_A_Single_Item_With_A_VatAs20Percent_Tax_rule_To_An_Empty_Basket_Both_The_Tax_Of_The_Item_And_The_Basket_Should_Equal_TwentyPercent_Increase_To_The_TotalCost_And_Both_The_Subtotal_Of_The_Item_And_Basket_Should_Equal_The_Items_Unit_Price(int itemId, string itemName, decimal itemPrice)
        {
            //Arrange
            IShoppingItem item = new ShoppingItem(itemId, itemName, itemPrice, new List <ITaxRule>()
            {
                TaxRules.VatTax
            });

            //Act
            _basket.AddItem(item);

            //Assert
            List <IShoppingBasketItem> basketItems = _basket.Items as List <IShoppingBasketItem>;

            IShoppingBasketItem basketItem = basketItems.FirstOrDefault(x => x.Id == itemId);

            basketItem.Tax.Should().Be(2);
            _basket.Tax.Should().Be(2);
            _basket.Total.Should().Be(12); //20% increase on total cost of 10

            basketItem.SubTotal.Should().Be(basketItem.UnitPrice);
            _basket.SubTotal.Should().Be(basketItem.UnitPrice);
        }
示例#15
0
 // Not completely happy with this solution
 protected override void UpdateTotals(IShoppingBasket basket, IShoppingBasketItem item, decimal tax)
 {
     item.Tax   += tax;
     item.Total += tax;
 }
 //TODO:Please provide the implementation of this type to calculate the tax as a percentage of the sub total for the item
 //Unsure as to why need reference to basket and item. With just basket can iterate over all items, or with just item can calculate individually when required
 public decimal CalculateTax(IShoppingBasket basket, IShoppingBasketItem item)
 {
     return(item.SubTotal * 0M); //Add 0% - NoTax Rule from Rules.md
 }
 public decimal CalculateTax(IShoppingBasket basket, IShoppingBasketItem item)
 {
     return(item.SubTotal * 0.20M); //Add 20%
 }
示例#18
0
 public ShoppingUpdatedEventArgs(IShoppingBasketItem basketItem)
 {
     BasketItem = basketItem;
 }
 public void AddItemToBasket(IShoppingBasketItem line)
 {
     Id = 2;
 }