diff --git a/BobsBagel.drawio (1).png b/BobsBagel.drawio (1).png new file mode 100644 index 00000000..a8e320e7 Binary files /dev/null and b/BobsBagel.drawio (1).png differ diff --git a/README.md b/README.md index 4b229491..1395dd74 100644 --- a/README.md +++ b/README.md @@ -93,6 +93,20 @@ So we don't get any weird requests, I want customers to only be able to order things that we stock in our inventory. ``` + +``` +11. +As a customer, +So I don't over-spend, +I'd like to get discount when I buy more than 6 bagels. +``` + +``` +11. +As a customer, +So I can see what each of the items costs, +I'd like to get a receipt. +``` ## Bob's Inventory | SKU | Price | Name | Variant | diff --git a/domain-model.md b/domain-model.md new file mode 100644 index 00000000..cb6dd801 --- /dev/null +++ b/domain-model.md @@ -0,0 +1,86 @@ +| Classes | Methods/Properties | Scenario | Outputs | +|---------------|---------------------------------------------------|-------------------------------------------------------|---------------| +|Basket |Add(Bagel bagel) | add Bagel | bool | +|Basket |Remove(Bagel bagel) | Remove Bagel | bool | +|Basket |IsFull() | See if basket is full | bool | +|Basket |ChangeCapacity(int capacity) | Change capacity | bool | +|Basket |RemoveExist(Bagel bagel) | try to remove an item that doesn't exist in my basket | bool | +|Basket |TotalCost() | Check total cost of items in my basket | double | +|Basket |PriceBagel(Bagel bagel) | Check cost of a bagel | double | +|Bagel |Choosefillings() | choose fillings for my bagel | List| +|Basket |PriceFilling(Filling filling) | Check cost of each filling | double | +|Basket |OrderInventory() | order things that we stock in our inventory. | bool | + + + + + +``` +1. +As a member of the public, +So I can order a bagel before work, +I'd like to add a specific type of bagel to my basket. +``` + +``` +2. +As a member of the public, +So I can change my order, +I'd like to remove a bagel from my basket. +``` + +``` +3. +As a member of the public, +So that I can not overfill my small bagel basket +I'd like to know when my basket is full when I try adding an item beyond my basket capacity. +``` + +``` +4. +As a Bob's Bagels manager, +So that I can expand my business, +I’d like to change the capacity of baskets. +``` + +``` +5. +As a member of the public +So that I can maintain my sanity +I'd like to know if I try to remove an item that doesn't exist in my basket. +``` + +``` +6. +As a customer, +So I know how much money I need, +I'd like to know the total cost of items in my basket. +``` + +``` +7. +As a customer, +So I know what the damage will be, +I'd like to know the cost of a bagel before I add it to my basket. +``` + +``` +8. +As a customer, +So I can shake things up a bit, +I'd like to be able to choose fillings for my bagel. +``` + +``` +9. +As a customer, +So I don't over-spend, +I'd like to know the cost of each filling before I add it to my bagel order. +``` + +``` +10. +As the manager, +So we don't get any weird requests, +I want customers to only be able to order things that we stock in our inventory. +``` \ No newline at end of file diff --git a/exercise.main/Basket.cs b/exercise.main/Basket.cs new file mode 100644 index 00000000..87da03bf --- /dev/null +++ b/exercise.main/Basket.cs @@ -0,0 +1,181 @@ +using exercise.main.Product; +using System; +using System.Collections.Generic; +using System.ComponentModel.DataAnnotations; +using System.Linq; +using System.Reflection.Metadata.Ecma335; +using System.Security.Principal; +using System.Text; +using System.Threading.Tasks; + +namespace exercise.main +{ + public class Basket + { + private int _ID = 0; + private int _capacity = 30; + private List _items = new List(); + + private List Amout_bagels() + { + List bagels = new List(); + foreach (IProduct item in _items) + { + if (item is Bagel bagel) + { + bagels.Add(bagel); + } + } + return bagels; + } + + private List Amout_Coffee() + { + List coffee = new List(); + foreach (IProduct item in _items) + { + if (item is Coffee c) + { + if (c.SKU == "COFB") + { + coffee.Add(c); + } + } + } + return coffee; + } + + public bool Add(IProduct item) + { + if (_capacity > 0) + { + _items.Add(item); + _capacity--; + item.ID = _ID; + _ID++; + return true; + } + return false; + } + + public void Remove(int id) + { + _items.RemoveAll(x => x.ID == id); + _capacity++; + } + + //public bool ValidSixBagels() + //{ + + // if (_items.Where(p => p.SKU == "BGLO")) + // { + // return true; + // } + // if (_items.Any(p => p.SKU == "BGLP")) + // { + // return true; + // } + // return false; + //} + + public double Discount() + { + // All bagels cost the same + double total = 0; + double coffeeDiscount = 0; + List bagels = Amout_bagels(); + List coffees = Amout_Coffee(); + + Console.WriteLine("Amout of Bagel: " + bagels.Count); + int BigPackBagels = 0; + int SmallPackBagels = 0; + + int rest = 0; + + if (bagels.Count >= 6) + { + // For Big pack 12 for 3.99 + BigPackBagels += bagels.Count / 12; + + // For Small pack 6 for 2.49 + SmallPackBagels += (bagels.Count - (BigPackBagels * 12)) / 6; + rest += (bagels.Count - (SmallPackBagels * 6)) % 6; + + } + + // Add coffee and Bagel Discount + int amout_coffeeDiscount = 0; + int max = 0; + int coffee = coffees.Count; + if (coffee > rest) // Maybe get this on one-line + { + max = coffee; + } + else + { + max = rest; + } + + for (int i = 0; i < max; i++) + { + if (coffee > 0 & rest > 0) + { + coffee--; + rest--; + amout_coffeeDiscount++; + } + } + + total += amout_coffeeDiscount * 1.25 + coffeeDiscount + (rest * 0.49) + (coffee * 0.99) + (BigPackBagels * 3.99) + (SmallPackBagels * 2.49); + + return total; + } + + public string printReceipt() + { + + StringBuilder sb = new StringBuilder(); + sb.Append($"~~~Bob's Bagels ~~~"); + sb.Append($"\n{DateTime.Now.ToString()}"); + + sb.Append($"\n----------------------------"); + + + + foreach (IProduct item in _items) + { + sb.Append($"\n{item.Name} - £{item.Price}"); + } + sb.Append($"\n----------------------------"); + sb.Append($"\nTotal : {this.TotalCost()}"); + sb.Append($"\nThank you for your order!"); + + return sb.ToString(); + } + +// ~~~Bob's Bagels ~~~ + +// 2021-03-16 21:38:44 + +//---------------------------- + +//Onion Bagel 2 £0.98 +//Plain Bagel 12 £3.99 +//Everything Bagel 6 £2.49 +//Coffee 3 £2.97 + +//---------------------------- +//Total £10.43 + +// Thank you +// for your order! + + public bool IsFull() { return _capacity <= 0; } + + public double TotalCost() { return _items.Sum(product => product.Price); } + + public List Items { get { return _items; } } + + public int Capacity { get { return _capacity; } set { _capacity = value; } } + } +} diff --git a/exercise.main/Inventory.cs b/exercise.main/Inventory.cs new file mode 100644 index 00000000..38a38f47 --- /dev/null +++ b/exercise.main/Inventory.cs @@ -0,0 +1,77 @@ +using exercise.main.Product; +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace exercise.main +{ + public class Inventory + { + // Bagel + public Bagel getOnionBagel() + { + return new Bagel() { SKU = "BGLO", Name = "Onion", BagelPrice = 0.49}; + } + public Bagel getPlainBagel() + { + return new Bagel() { SKU = "BGLP", Name = "Plain", BagelPrice = 0.39 }; + } + public Bagel getEverythingBagel() + { + return new Bagel() { SKU = "BGLE", Name = "Everything", BagelPrice = 0.49 }; + } + public Bagel getSesameBagel() + { + return new Bagel() { SKU = "BGLS", Name = "Sesame", BagelPrice = 0.49 }; + } + + //Coffee + public Coffee getBlackCoffee() + { + return new Coffee() { SKU = "COFB", Name = "Black", Price = 0.99 }; + } + public Coffee getWhiteCoffee() + { + return new Coffee() { SKU = "COFW", Name = "White", Price = 1.19 }; + } + public Coffee getCapuccinoCoffee() + { + return new Coffee() { SKU = "COFC", Name = "Capuccino", Price = 1.19 }; + } + public Coffee getLatteCoffee() + { + return new Coffee() { SKU = "COFL", Name = "Latte", Price = 0.99 }; + } + + //Filling + public Filling GetBaconFilling() + { + return new Filling() { SKU = "FILB", Name = "Bacon", Price = 0.12 }; + } + public Filling GetEggFilling() + { + return new Filling() { SKU = "FILE", Name = "Egg", Price = 0.12 }; + } + public Filling GetCheeseFilling() + { + return new Filling() { SKU = "FILC", Name = "Cheese", Price = 0.12 }; + } + public Filling GetCCFilling() + { + return new Filling() { SKU = "FILX", Name = "Cream Cheese", Price = 0.12 }; + } + public Filling GetSSFilling() + { + return new Filling() { SKU = "FILS", Name = "Smoked Salmon", Price = 0.12 }; + } + public Filling GetHamFilling() + { + return new Filling() { SKU = "FILH", Name = "Ham", Price = 0.12 }; + } + + + } +} diff --git a/exercise.main/Product/Bagel.cs b/exercise.main/Product/Bagel.cs new file mode 100644 index 00000000..6885c707 --- /dev/null +++ b/exercise.main/Product/Bagel.cs @@ -0,0 +1,41 @@ +using System; +using System.Collections.Generic; +using System.Diagnostics.CodeAnalysis; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace exercise.main.Product +{ + public class Bagel : IProduct + { + + private double _price; + private List _filling = new List(); + + public void AddFilling(Filling filling) + { + _filling.Add(filling); + } + + + public void SeeFillingCost() + { + foreach (Filling filling in _filling) + { + Console.WriteLine($"Filling, {filling.Name}: {filling.Price}"); + } + + } + + public string SKU { get; set; } + public string Name { get; set; } + public int ID { get; set; } + + public double BagelPrice { get { return _price; } set { _price = value; } } + + public double Price { get { return _price + _filling.Sum(filling => filling.Price); } set; } + + public List Filling { get { return _filling; } } + } +} diff --git a/exercise.main/Product/Coffee.cs b/exercise.main/Product/Coffee.cs new file mode 100644 index 00000000..bc8648e1 --- /dev/null +++ b/exercise.main/Product/Coffee.cs @@ -0,0 +1,16 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace exercise.main.Product +{ + public class Coffee : IProduct + { + public string SKU { get; set; } + public string Name { get; set; } + public int ID { get; set; } + public double Price { get; set; } + } +} diff --git a/exercise.main/Product/Filling.cs b/exercise.main/Product/Filling.cs new file mode 100644 index 00000000..2a23cbda --- /dev/null +++ b/exercise.main/Product/Filling.cs @@ -0,0 +1,18 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace exercise.main.Product +{ + public class Filling : IProduct + { + private double _price = 0.12; + + public string SKU { get; set; } + public string Name { get; set; } + public int ID { get; set; } + public double Price { get { return _price; } set { _price = value; } } + } +} diff --git a/exercise.main/Product/IProduct.cs b/exercise.main/Product/IProduct.cs new file mode 100644 index 00000000..a031bf97 --- /dev/null +++ b/exercise.main/Product/IProduct.cs @@ -0,0 +1,16 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace exercise.main.Product +{ + public interface IProduct + { + string SKU { get; set; } + string Name { get; set; } + int ID { get; set; } + double Price { get; set; } + } +} diff --git a/exercise.main/Program.cs b/exercise.main/Program.cs index 3751555c..4f3a94f3 100644 --- a/exercise.main/Program.cs +++ b/exercise.main/Program.cs @@ -1,2 +1,15 @@ // See https://aka.ms/new-console-template for more information +using exercise.main; +using exercise.main.Product; + Console.WriteLine("Hello, World!"); + +Basket basket = new Basket(); +Inventory inventory = new Inventory(); +Bagel bagel = inventory.getPlainBagel(); +for (int i = 0; i < 4; i++) +{ + basket.Add(bagel); +} + +Console.WriteLine(basket.printReceipt()); diff --git a/exercise.main/exercise.main.csproj b/exercise.main/exercise.main.csproj index fd4bd08d..4f46db15 100644 --- a/exercise.main/exercise.main.csproj +++ b/exercise.main/exercise.main.csproj @@ -5,6 +5,7 @@ net9.0 enable enable + preview diff --git a/exercise.sln b/exercise.sln index 0efb5453..41e156b2 100644 --- a/exercise.sln +++ b/exercise.sln @@ -9,6 +9,8 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "exercise.tests", "exercise. EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{825CCFE7-4F2E-4770-8393-FEB732F66EE4}" ProjectSection(SolutionItems) = preProject + .gitignore = .gitignore + domain-model.md = domain-model.md extension1.md = extension1.md extension2.md = extension2.md extension3.md = extension3.md @@ -34,4 +36,7 @@ Global GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {CA5904D1-7CBB-41BD-A1A3-6A5FE0525D44} + EndGlobalSection EndGlobal diff --git a/exercise.tests/Extension1Tests.cs b/exercise.tests/Extension1Tests.cs new file mode 100644 index 00000000..2a907437 --- /dev/null +++ b/exercise.tests/Extension1Tests.cs @@ -0,0 +1,115 @@ +using exercise.main; +using exercise.main.Product; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Reflection.Emit; +using System.Text; +using System.Threading.Tasks; + +namespace exercise.tests +{ + public class Extension1Tests + { + Basket _basket = new Basket(); + + private void AddSixBagels() + { + Inventory inventory = new Inventory(); + Bagel bagel = inventory.getPlainBagel(); + for (int i=0; i<6; i++) + { + _basket.Add(bagel); + } + } + + private void AddTwelveBagels() + { + Inventory inventory = new Inventory(); + Bagel bagel = inventory.getPlainBagel(); + for (int i = 0; i < 12; i++) + { + _basket.Add(bagel); + } + } + + [Test] + public void DiscountTest() + { + AddSixBagels(); + + Console.WriteLine("Basket Capacity: " + _basket.Capacity); + Console.WriteLine("Basket Discount: " + _basket.Discount()); + + double result = _basket.Discount(); + + + Assert.That(result, Is.EqualTo(2.49)); + } + + [Test] + public void DiscountTestExampleOne() + { + AddSixBagels(); + AddTwelveBagels(); + + // Adding 3 coffee and 2 Onion + Inventory inventory = new Inventory(); + Bagel bagel = inventory.getOnionBagel(); + Bagel bagel1 = inventory.getOnionBagel(); + Coffee c = inventory.getBlackCoffee(); + Coffee c1 = inventory.getBlackCoffee(); + Coffee c2 = inventory.getBlackCoffee(); + + _basket.Add(bagel); + _basket.Add(bagel1); + _basket.Add(c); + _basket.Add(c1); + _basket.Add(c2); + + Console.WriteLine("Basket Capacity: " + _basket.Capacity); + Console.WriteLine("Basket Discount: " + _basket.Discount()); + + double result = _basket.Discount(); + + + Assert.That(result, Is.EqualTo(9.97)); + + // 2x BGLO = 0.98 + // 12x BGLP = 3.99 + // 6x BGLE = 2.49 + // 3x COF = 2.97 + // ---- + // 9.97 + } + + [Test] + public void DiscountTestExampleTwo() + { + AddTwelveBagels(); // Onion ... + + // Adding 3 coffee and 2 Onion + Inventory inventory = new Inventory(); + Bagel bagel = inventory.getPlainBagel(); + for (int i = 0; i < 4; i++) + { + _basket.Add(bagel); + } + + + Console.WriteLine("Basket Capacity: " + _basket.Capacity); + Console.WriteLine("Basket Discount: " + _basket.Discount()); + + double result = _basket.Discount(); + + + Assert.That(result, Is.EqualTo(5.95)); + } + + //16x BGLP = 5.95 -- Plain cost 0.49 instead for 0.39 + // ---- + // 5.95 + + + } +} diff --git a/exercise.tests/Extension2Tests.cs b/exercise.tests/Extension2Tests.cs new file mode 100644 index 00000000..322852f7 --- /dev/null +++ b/exercise.tests/Extension2Tests.cs @@ -0,0 +1,14 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace exercise.tests +{ + public class Extension2Tests + { + + + } +} diff --git a/exercise.tests/Tests.cs b/exercise.tests/Tests.cs new file mode 100644 index 00000000..6dfeae60 --- /dev/null +++ b/exercise.tests/Tests.cs @@ -0,0 +1,167 @@ +using exercise.main; +using exercise.main.Product; + +namespace exercise.tests; + +public class Tests +{ + [Test] + public void AddTest() + { + Basket basket = new Basket(); + Bagel bagel = new Bagel(); + bagel.Name = "Plain"; + basket.Add(bagel); + + Assert.That(basket.Items[0].Name, Is.EqualTo("Plain")); + Assert.That(basket.Capacity, Is.EqualTo(29)); + Assert.That(bagel.ID, Is.EqualTo(0)); + } + + [Test] + public void RemoveTest() + { + Basket basket = new Basket(); + Bagel bagel = new Bagel(); + Bagel bagel1 = new Bagel(); + bagel.Name = "Plain"; + bagel1.Name = "Onion"; + + basket.Add(bagel); + basket.Add(bagel1); + basket.Remove(0); + + Assert.That(basket.Capacity, Is.EqualTo(29)); + } + + [Test] + public void IsFullTest() + { + Basket basket = new Basket(); + Bagel bagel = new Bagel(); + Bagel bagel1 = new Bagel(); + Bagel bagel2 = new Bagel(); + Bagel bagel3 = new Bagel(); + Bagel bagel4 = new Bagel(); + + bagel.Name = "Plain"; + bagel1.Name = "Onion"; + bagel2.Name = "Everything"; + bagel3.Name = "Everything"; + bagel4.Name = "Plain"; + + basket.Add(bagel); + basket.Add(bagel1); + basket.Add(bagel2); + basket.Add(bagel3); + basket.Add(bagel4); + bool result = basket.IsFull(); + + Assert.That(result, Is.False); + + } + [Test] + public void ChangeCapacityTest() + { + Basket basket = new Basket(); + basket.Capacity = 7; + + Assert.That(basket.Capacity, Is.EqualTo(7)); + } + + [Test] + public void RemoveExistTest() + { + Basket basket = new Basket(); + Bagel bagel = new Bagel(); + bagel.Name = "Plain"; + basket.Add(bagel); + + basket.Remove(0); + + Assert.That(basket.Capacity, Is.EqualTo(30)); + + } + + [Test] + public void TotalCostTest() + { + Basket basket = new Basket(); + Bagel bagel = new Bagel(); + Bagel bagel1 = new Bagel(); + + bagel.BagelPrice = 0.49; + bagel1.BagelPrice = 0.49; + + basket.Add(bagel); + basket.Add(bagel1); + + double price = basket.TotalCost(); + + Assert.That(price, Is.EqualTo(0.49 * 2)); + } + + [Test] + public void PriceBagelTest() + { + + Bagel bagel = new Bagel(); + + bagel.BagelPrice = 0.49; + + Assert.That(bagel.BagelPrice, Is.EqualTo(0.49)); + + + } + + [Test] + public void AddFillingTest() + { + Inventory inventory = new Inventory(); + Basket basket = new Basket(); + Bagel bagel = new Bagel(); + + basket.Add(bagel); + + Filling bacon = inventory.GetBaconFilling(); + bagel.AddFilling(bacon); + + + + Assert.That(bagel.Filling.Count, Is.EqualTo(1)); + } + + [Test] + public void SeeFillingCostTest() + { + Inventory inventory = new Inventory(); + Basket basket = new Basket(); + Bagel bagel = new Bagel(); + Filling bacon = inventory.GetBaconFilling(); + Filling cheese = inventory.GetCheeseFilling(); + bagel.AddFilling(bacon); + bagel.AddFilling(cheese); + + bagel.SeeFillingCost(); + + } + + [Test] + public void InventoryTest() + { + Basket basket = new Basket(); + Inventory inventory = new Inventory(); + Bagel bagel = inventory.getOnionBagel(); + Filling bacon = inventory.GetBaconFilling(); + Coffee coffee = inventory.getBlackCoffee(); + + bagel.AddFilling(bacon); + basket.Add(bagel); + basket.Add(coffee); + + + // 0.49 + 0.12 + 0.99 = 0.61 + + Assert.That(basket.TotalCost, Is.EqualTo(1.6)); + } +} \ No newline at end of file diff --git a/exercise.tests/UnitTest1.cs b/exercise.tests/UnitTest1.cs deleted file mode 100644 index 7bdb8968..00000000 --- a/exercise.tests/UnitTest1.cs +++ /dev/null @@ -1,15 +0,0 @@ -namespace exercise.tests; - -public class Tests -{ - [SetUp] - public void Setup() - { - } - - [Test] - public void Test1() - { - Assert.Pass(); - } -} \ No newline at end of file diff --git a/exercise.tests/exercise.tests.csproj b/exercise.tests/exercise.tests.csproj index 9fed8e17..a3a97d4f 100644 --- a/exercise.tests/exercise.tests.csproj +++ b/exercise.tests/exercise.tests.csproj @@ -17,4 +17,8 @@ + + + +