diff --git a/exercise.main/Basket.cs b/exercise.main/Basket.cs new file mode 100644 index 00000000..b965a5f7 --- /dev/null +++ b/exercise.main/Basket.cs @@ -0,0 +1,159 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; + +namespace exercise.main +{ + public class Basket + { + private int capacity; + private List items; + private double totalPrice; + + public Basket(int capacity) + { + this.capacity = capacity; + items = new List(); + } + + public void ClearItems() + { + items.Clear(); + } + + public bool ChangeCapacity(int newCapacity) + { + if (newCapacity >= items.Count) + { + capacity = newCapacity; + return true; + } + return false; + } + + public bool AddItems(Inventory inventory, string sku, int quantity) + { + Item itemToAdd = inventory.GetItemBySKU(sku); + if (itemToAdd == null) + { + Console.WriteLine("Item not found"); + return false; + } + if (items.Count + quantity > capacity) + { + Console.WriteLine($"Basket capacity is reached. Current basket: {items.Count}. Capacity: {capacity}"); + return false; + } + + for (int i = 0; i < quantity; i++) + { + items.Add(itemToAdd); + } + return true; + } + + public bool RemoveItems(Inventory inventory, string skuToRemove, int quantityToRemove) + { + Item itemToRemove = inventory.GetItemBySKU(skuToRemove); + if (itemToRemove != null && items.Contains(itemToRemove)) + { + for (int i = 0; i < quantityToRemove; i++) + { + items.Remove(itemToRemove); + } + return true; + } + Console.WriteLine("Item was not found"); + return false; + } + + public string ShowBasket() + { + StringBuilder result = new StringBuilder(); + result.Append(string.Format("{0,3} {1,-1}", "", "~~~ Bob's Bagels ~~~\n")); + result.Append(string.Format("{0,3} {1,-1}", "", DateTime.Now.ToString("dd-MM-yyyy HH:mm:ss"))); + result.Append("\n--------------------------------\n"); + GetProductPrice(result); + result.Append("--------------------------------\n"); + result.Append(string.Format("{0,-26}", "Total Price ") + GetTotalCost()); + result.Append("\n--------------------------------\n"); + result.Append(string.Format("{0,5} {1,-1}", "", "Have a good day!")); + return result.ToString(); + } + + public string GetTotalCost() + { + return string.Format("£{0:F2}", totalPrice); + } + + private StringBuilder GetProductPrice(StringBuilder result) + { + double discountedPrice; + double discounted; + totalPrice = 0; + var uniqueItems = items.Distinct(); + + foreach (var uniqueItem in uniqueItems) + { + string itemName = $"{uniqueItem.Name} {uniqueItem.Variant}"; + int quantity = items.Count(item => item.Equals(uniqueItem)); + + if (uniqueItem.Name.Equals("Bagel")) + { + discountedPrice = CalculateBagelOffer(uniqueItem, quantity); + discounted = uniqueItem.Price * quantity - discountedPrice; + totalPrice += discountedPrice; + + if (discounted > 0) + { + result.Append(string.Format("{0,-20} {1,-4} £{2:F2}\n", itemName, quantity, discountedPrice)); + string discountedString = string.Format("(£{0:F2})\n", discounted); + result.Append(string.Format("{0,-26}", " ") + discountedString); + } + else + { + result.Append(string.Format("{0,-20} {1,-4} £{2:F2}\n", itemName, quantity, discountedPrice)); + } + } + else if (uniqueItem.Sku.Equals("COFD")) + { + discountedPrice = 1.25 * quantity; + discounted = 0.23 * quantity; + result.Append(string.Format("{0,-20} {1,-4} £{2:F2}\n", itemName, quantity, discountedPrice)); + string discountedString = string.Format("(£{0:F2})\n", discounted); + result.Append(string.Format("{0,-26}", " ") + discountedString); + } + else + { + discountedPrice = CalculateItemPrice(uniqueItem, quantity); + totalPrice += discountedPrice; + result.Append(string.Format("{0,-20} {1,-4} £{2:F2}\n", itemName, quantity, discountedPrice)); + } + } + return result; + } + + private double CalculateBagelOffer(Item item, int quantity) + { + double discountedPrice = 0.0; + int remainingBagels; + + int deal12Quantity = quantity / 12; + discountedPrice += deal12Quantity * 3.99; + remainingBagels = quantity % 12; + + int deal6Quantity = remainingBagels / 6; + discountedPrice += deal6Quantity * 2.49; + remainingBagels %= 6; + + discountedPrice += remainingBagels * item.Price; + return discountedPrice; + } + + private double CalculateItemPrice(Item item, int quantity) + { + return item.Price * quantity; + } + } +} diff --git a/exercise.main/Inventory.cs b/exercise.main/Inventory.cs new file mode 100644 index 00000000..c369072c --- /dev/null +++ b/exercise.main/Inventory.cs @@ -0,0 +1,76 @@ +using System; +using System.Collections.Generic; + +namespace exercise.main +{ + public class Inventory + { + private Dictionary bagelInventory = new Dictionary(); + private Dictionary coffeeInventory = new Dictionary(); + private Dictionary fillingInventory = new Dictionary(); + + public Inventory() + { + bagelInventory["BGLO"] = new Item("BGLO", "Bagel", 0.49, "Onion"); + bagelInventory["BGLP"] = new Item("BGLP", "Bagel", 0.39, "Plain"); + bagelInventory["BGLE"] = new Item("BGLE", "Bagel", 0.49, "Everything"); + bagelInventory["BGLS"] = new Item("BGLS", "Bagel", 0.49, "Sesame"); + + coffeeInventory["COFB"] = new Item("COFB", "Coffee", 0.99, "Black"); + coffeeInventory["COFW"] = new Item("COFW", "Coffee", 1.19, "White"); + coffeeInventory["COFC"] = new Item("COFC", "Coffee", 1.29, "Capuccino"); + coffeeInventory["COFL"] = new Item("COFL", "Coffee", 1.29, "Latte"); + coffeeInventory["COFD"] = new Item("COFD", "Coffee", 1.25, "& Bagel"); + + fillingInventory["FILB"] = new Item("FILB", "Filling", 0.12, "Bacon"); + fillingInventory["FILE"] = new Item("FILE", "Filling", 0.12, "Egg"); + fillingInventory["FILC"] = new Item("FILC", "Filling", 0.12, "Cheese"); + fillingInventory["FILX"] = new Item("FILX", "Filling", 0.12, "Cream Cheese"); + fillingInventory["FILS"] = new Item("FILS", "Filling", 0.12, "Smoked Salmon"); + fillingInventory["FILH"] = new Item("FILH", "Filling", 0.12, "Ham"); + } + + public Dictionary GetBagelInventory() => bagelInventory; + public Dictionary GetFillingInventory() => fillingInventory; + public Dictionary GetCoffeeInventory() => coffeeInventory; + + public void PrintInventories() + { + Console.WriteLine("Bagel Inventory:"); + foreach (var kvp in bagelInventory) + { + Console.WriteLine($"Key: {kvp.Key}, Value: {kvp.Value}"); + } + + Console.WriteLine("\nCoffee Inventory:"); + foreach (var kvp in coffeeInventory) + { + Console.WriteLine($"Key: {kvp.Key}, Value: {kvp.Value}"); + } + + Console.WriteLine("\nFilling Inventory:"); + foreach (var kvp in fillingInventory) + { + Console.WriteLine($"Key: {kvp.Key}, Value: {kvp.Value}"); + } + } + public Item GetItemBySKU(string sku) + { + if (sku.Length >= 3) + { + string inventoryType = sku.Substring(0, 3); + switch (inventoryType) + { + case "BGL": + return bagelInventory.ContainsKey(sku) ? bagelInventory[sku] : null; + case "COF": + return coffeeInventory.ContainsKey(sku) ? coffeeInventory[sku] : null; + case "FIL": + return fillingInventory.ContainsKey(sku) ? fillingInventory[sku] : null; + } + } + return null; + } + + } +} diff --git a/exercise.main/Item.cs b/exercise.main/Item.cs new file mode 100644 index 00000000..86a44512 --- /dev/null +++ b/exercise.main/Item.cs @@ -0,0 +1,31 @@ +using System; + +namespace exercise.main +{ + public class Item + { + public string Sku { get; } + public string Name { get; } + public double Price { get; } + public string Variant { get; } + public int Quantity { get; private set; } + + public Item(string sku, string name, double price, string variant) + { + Sku = sku; + Name = name; + Price = price; + Variant = variant; + Quantity = 1; + } + public void SetQuantity(int quantity) + { + Quantity = quantity; + } + + public override string ToString() + { + return $"SKU: {Sku}, Name: {Name}, Price: {Price}, Variant: {Variant}, Quantity: {Quantity}"; + } + } +} diff --git a/exercise.main/Program.cs b/exercise.main/Program.cs index 3751555c..eb2b164e 100644 --- a/exercise.main/Program.cs +++ b/exercise.main/Program.cs @@ -1,2 +1,19 @@ -// See https://aka.ms/new-console-template for more information -Console.WriteLine("Hello, World!"); +using System; +using exercise.main; + +class Program +{ + static void Main(string[] args) + { + + var inventory = new Inventory(); + + Basket basket = new Basket(30); + + basket.AddItems(inventory, "BGLO", 6); + basket.AddItems(inventory, "BGLP", 12); + basket.AddItems(inventory, "BGLE", 6); + basket.AddItems(inventory, "COFB", 1); + Console.WriteLine($"Basket: {basket.ShowBasket()}"); + } +} diff --git a/exercise.main/domain-model.md b/exercise.main/domain-model.md new file mode 100644 index 00000000..745105ad --- /dev/null +++ b/exercise.main/domain-model.md @@ -0,0 +1,24 @@ +| Class | Method | Member | Scenario | Return | +|----------------------|------------------------------------------|-------------------------------------------------------|------------------------------|----------------| +| Basket | addItem(Inventory, item, quantity) | Class Inventory, String item, Integer quantity | full basket | false | +| | | | add item | true | +| | | | Item not found | false | +| | removeItem(Inventory, sku, quantity) | Class Inventory, String item, Integer quantity | remove item | true | +| | | | Item not found | false | +| | changeCapacity(capacity) | Integer capacity | Changed capacity | true | +| | | | Unable to change capacity | false | +| | getTotalCost() | List | Get total cost | Return cost | +| | ItemcsCount() | List | Get item list length | Return Length | +| | ShowBasket() | List | Show Basket List | String Items | +| Inventory | printInventory() | Dictonary inventory,String inventoryName | Show all added products | String[] | +| | GetBagelInventory() | Dictonary | Get all Bagels | Dictonary | +| | GetFillingInventory() | Dictonary | Get all Fillings | Dictonary | +| | GetCoffeeInventory() | Dictonary | Get all Coffees | Dictonary | +| | GetItemBySKU() | Dictonary | Get Item by SKU | Dictonary | +| Item | Name() | | get name | String type | +| | Variant() | | get variant | String variant | +| | Sku() | | get sku | String sku | +| | Price() | | get price | double price | +| | Quantity() | | get quantity | int quantity | +| | setQuantity() | Integer quantity | set quantity | | +| | ToString() | Item | Items as string | string Item | \ No newline at end of file diff --git a/exercise.main/inventory.csv b/exercise.main/inventory.csv new file mode 100644 index 00000000..663dba3d --- /dev/null +++ b/exercise.main/inventory.csv @@ -0,0 +1,16 @@ +SKU,Price,Name,Variant +BGLO,0.49,Bagel,Onion +BGLP,0.39,Bagel,Plain +BGLE,0.49,Bagel,Everything +BGLS,0.49,Bagel,Sesame +COFB,0.99,Coffee,Black +COFW,1.19,Coffee,White +COFC,1.29,Coffee,Capuccino +COFL,1.29,Coffee,Latte +COFD,1.25,Coffee,& Bagel +FILB,0.12,Filling,Bacon +FILE,0.12,Filling,Egg +FILC,0.12,Filling,Cheese +FILX,0.12,Filling,Cream Cheese +FILS,0.12,Filling,Smoked Salmon +FILH,0.12,Filling,Ham \ No newline at end of file diff --git a/exercise.tests/BasketTest.cs b/exercise.tests/BasketTest.cs new file mode 100644 index 00000000..d9801546 --- /dev/null +++ b/exercise.tests/BasketTest.cs @@ -0,0 +1,93 @@ +using exercise.main; + +namespace exercise.tests +{ + [TestFixture] + internal class BasketTest + { + [Test] + public void TestAddItemsToBasket() + { + var inventory = new Inventory(); + var basket = new Basket(5); + + bool result = basket.AddItems(inventory, "BGLO", 2); + Assert.IsTrue(result); + + Assert.IsTrue(basket.AddItems(inventory, "BGLE", 3)); + + Assert.IsFalse(basket.AddItems(inventory, "BGLE", 3)); + + } + + [Test] + public void TestAddItemsExceedingCapacity() + { + + var inventory = new Inventory(); + var basket = new Basket(2); + + + bool result = basket.AddItems(inventory, "BGLO", 3); + Assert.IsFalse(result); + } + + [Test] + public void TestRemoveItemsFromBasket() + { + + var inventory = new Inventory(); + var basket = new Basket(5); + basket.AddItems(inventory, "BGLO", 2); + + + bool result = basket.RemoveItems(inventory, "BGLO", 1); + + Assert.IsTrue(result); + + Assert.IsFalse(basket.RemoveItems(inventory, "BGLE", 1)); + } + + [Test] + public void TestRemoveItemsNotInBasket() + { + + var inventory = new Inventory(); + var basket = new Basket(5); + + + bool result = basket.RemoveItems(inventory, "BGLO", 1); + + + Assert.IsFalse(result); + } + + [Test] + public void TestChangeCapacity() + { + + var basket = new Basket(2); + basket.AddItems(new Inventory(), "BGLO", 2); + + + bool result = basket.ChangeCapacity(3); + + + Assert.IsTrue(result); + } + + [Test] + public void TestChangeCapacityToLowerThanCurrentItems() + { + + var basket = new Basket(3); + basket.AddItems(new Inventory(), "BGLO", 3); + + + bool result = basket.ChangeCapacity(2); + + + Assert.IsFalse(result); + } + } +} diff --git a/exercise.tests/InventoryTest.cs b/exercise.tests/InventoryTest.cs new file mode 100644 index 00000000..abef01fe --- /dev/null +++ b/exercise.tests/InventoryTest.cs @@ -0,0 +1,33 @@ +using System; +using System.Collections; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using exercise.main; + +namespace exercise.tests +{ + internal class InventoryTest + { + [Test] + public void TestGetAllProducts() + { + var inventory = new Inventory(); + + Dictionary bagelInventory = inventory.GetBagelInventory(); + Dictionary coffeeInventory = inventory.GetCoffeeInventory(); + Dictionary fillingInventory = inventory.GetFillingInventory(); + + Assert.IsNotNull(bagelInventory); + Assert.IsNotNull(coffeeInventory); + Assert.IsNotNull(fillingInventory); + + + Assert.IsTrue(bagelInventory.ContainsKey("BGLO")); + Assert.AreEqual("Bagel", bagelInventory["BGLO"].Name); + Assert.AreEqual(0.49, bagelInventory["BGLO"].Price); + } + + } +} diff --git a/exercise.tests/UnitTest1.cs b/exercise.tests/UnitTest1.cs index 7bdb8968..92201551 100644 --- a/exercise.tests/UnitTest1.cs +++ b/exercise.tests/UnitTest1.cs @@ -1,3 +1,6 @@ +using System; +using exercise.main; + namespace exercise.tests; public class Tests diff --git a/exercise.tests/exercise.tests.csproj b/exercise.tests/exercise.tests.csproj index 9fed8e17..9b7caea7 100644 --- a/exercise.tests/exercise.tests.csproj +++ b/exercise.tests/exercise.tests.csproj @@ -16,5 +16,9 @@ + + + +