From e9e883c092328ef63a82da0eb21ecbad1e725d5b Mon Sep 17 00:00:00 2001 From: Snorre Aldstedt Date: Mon, 11 Aug 2025 08:16:45 +0200 Subject: [PATCH 01/21] add domain-model --- domain-model.md | 14 ++++++++++++++ exercise.main/Program.cs | 1 + 2 files changed, 15 insertions(+) create mode 100644 domain-model.md diff --git a/domain-model.md b/domain-model.md new file mode 100644 index 00000000..9eb20ca0 --- /dev/null +++ b/domain-model.md @@ -0,0 +1,14 @@ +# Domain Model + +## Core +| Class | Method/Property | Scenario | Output | +|-------|-----------------|----------|--------| +| Basket | AddItem(StoreItem item) | Add an Item to a Basket | void | +| Basket | RemoveItem(StoreItem item) | Remove an Item to a Basket | void | +| Basket | IsFull() | Checks if basket is full | bool | +| Store | ChangeCap() | Changes capacity of baskets | void | +| Basket | BasketHas(StoreItem item) | Checks if basket has item | bool | +| Basket | TotalCost() | Returns total cost of Basket | int | +| Store | Price(StoreItem item) | Returns price of Item | int | +| Bagel | AddFillings(Filling filling) | Add filling to bagel | void | +| StoreItem | checkCost() | function that checks cost for an Item | int | diff --git a/exercise.main/Program.cs b/exercise.main/Program.cs index 3751555c..3ed0e5d7 100644 --- a/exercise.main/Program.cs +++ b/exercise.main/Program.cs @@ -1,2 +1,3 @@ // See https://aka.ms/new-console-template for more information Console.WriteLine("Hello, World!"); + From 9b331b09ac1e24e899c8db45bb04af432284117c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Snorre=20=C3=85ldstedt?= <73837062+SnorreAldstedt@users.noreply.github.com> Date: Mon, 11 Aug 2025 08:24:16 +0200 Subject: [PATCH 02/21] Add user stories to domain-model --- domain-model.md | 68 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 68 insertions(+) diff --git a/domain-model.md b/domain-model.md index 9eb20ca0..40bba729 100644 --- a/domain-model.md +++ b/domain-model.md @@ -1,5 +1,73 @@ # Domain Model +``` +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. +``` ## Core | Class | Method/Property | Scenario | Output | |-------|-----------------|----------|--------| From 24b0634a53bf9da2796a071a86e7cfbf35c60872 Mon Sep 17 00:00:00 2001 From: Snorre Aldstedt Date: Mon, 11 Aug 2025 11:25:53 +0200 Subject: [PATCH 03/21] Add classes to create tests after the domain model --- domain-model.md | 6 +++++- exercise.main/Basket.cs | 12 ++++++++++++ exercise.main/Store.cs | 12 ++++++++++++ exercise.main/StoreItem/Bagel.cs | 13 +++++++++++++ exercise.main/StoreItem/Coffee.cs | 12 ++++++++++++ exercise.main/StoreItem/Filling.cs | 12 ++++++++++++ exercise.main/StoreItem/IStoreItem.cs | 17 +++++++++++++++++ exercise.tests/BagelTests.cs | 15 +++++++++++++++ exercise.tests/{UnitTest1.cs => BasketTests.cs} | 0 exercise.tests/StoreItemTests.cs | 15 +++++++++++++++ exercise.tests/StoreTests.cs | 15 +++++++++++++++ 11 files changed, 128 insertions(+), 1 deletion(-) create mode 100644 exercise.main/Basket.cs create mode 100644 exercise.main/Store.cs create mode 100644 exercise.main/StoreItem/Bagel.cs create mode 100644 exercise.main/StoreItem/Coffee.cs create mode 100644 exercise.main/StoreItem/Filling.cs create mode 100644 exercise.main/StoreItem/IStoreItem.cs create mode 100644 exercise.tests/BagelTests.cs rename exercise.tests/{UnitTest1.cs => BasketTests.cs} (100%) create mode 100644 exercise.tests/StoreItemTests.cs create mode 100644 exercise.tests/StoreTests.cs diff --git a/domain-model.md b/domain-model.md index 9eb20ca0..0066aef4 100644 --- a/domain-model.md +++ b/domain-model.md @@ -8,7 +8,11 @@ | Basket | IsFull() | Checks if basket is full | bool | | Store | ChangeCap() | Changes capacity of baskets | void | | Basket | BasketHas(StoreItem item) | Checks if basket has item | bool | +| Basket | Remove(StoreItem item) | Removes item from basket if the basket has that item | void | | Basket | TotalCost() | Returns total cost of Basket | int | | Store | Price(StoreItem item) | Returns price of Item | int | | Bagel | AddFillings(Filling filling) | Add filling to bagel | void | -| StoreItem | checkCost() | function that checks cost for an Item | int | +| IStoreItem | Interface with methods for products | Interface for bagel, filling and coffee | | +| IStoreItem | Price | attribute that has the price of an IStoreItem | int | +| Store | GetInventory() | function that returns the inventory of the store | List | + diff --git a/exercise.main/Basket.cs b/exercise.main/Basket.cs new file mode 100644 index 00000000..7df61043 --- /dev/null +++ b/exercise.main/Basket.cs @@ -0,0 +1,12 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace exercise.main +{ + internal class Basket + { + } +} diff --git a/exercise.main/Store.cs b/exercise.main/Store.cs new file mode 100644 index 00000000..ecaa5e17 --- /dev/null +++ b/exercise.main/Store.cs @@ -0,0 +1,12 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace exercise.main +{ + internal class Store + { + } +} diff --git a/exercise.main/StoreItem/Bagel.cs b/exercise.main/StoreItem/Bagel.cs new file mode 100644 index 00000000..d5055ad1 --- /dev/null +++ b/exercise.main/StoreItem/Bagel.cs @@ -0,0 +1,13 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace exercise.main.StoreItem +{ + public class Bagel + + { + } +} diff --git a/exercise.main/StoreItem/Coffee.cs b/exercise.main/StoreItem/Coffee.cs new file mode 100644 index 00000000..8c1cfcfc --- /dev/null +++ b/exercise.main/StoreItem/Coffee.cs @@ -0,0 +1,12 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace exercise.main.StoreItem +{ + internal class Coffee + { + } +} diff --git a/exercise.main/StoreItem/Filling.cs b/exercise.main/StoreItem/Filling.cs new file mode 100644 index 00000000..996ef714 --- /dev/null +++ b/exercise.main/StoreItem/Filling.cs @@ -0,0 +1,12 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace exercise.main.StoreItem +{ + public class Filling + { + } +} diff --git a/exercise.main/StoreItem/IStoreItem.cs b/exercise.main/StoreItem/IStoreItem.cs new file mode 100644 index 00000000..b6e9294e --- /dev/null +++ b/exercise.main/StoreItem/IStoreItem.cs @@ -0,0 +1,17 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace exercise.main.StoreItem +{ + public interface IStoreItem + { + public string Name { get; } + public string Sku { get; } + public decimal Price { get; } + public string Variant { get; } + + } +} diff --git a/exercise.tests/BagelTests.cs b/exercise.tests/BagelTests.cs new file mode 100644 index 00000000..a08b91f8 --- /dev/null +++ b/exercise.tests/BagelTests.cs @@ -0,0 +1,15 @@ +namespace exercise.tests; + +public class ItemsTests +{ + [SetUp] + public void Setup() + { + } + + [Test] + public void Test1() + { + Assert.Pass(); + } +} diff --git a/exercise.tests/UnitTest1.cs b/exercise.tests/BasketTests.cs similarity index 100% rename from exercise.tests/UnitTest1.cs rename to exercise.tests/BasketTests.cs diff --git a/exercise.tests/StoreItemTests.cs b/exercise.tests/StoreItemTests.cs new file mode 100644 index 00000000..6e341108 --- /dev/null +++ b/exercise.tests/StoreItemTests.cs @@ -0,0 +1,15 @@ +namespace exercise.tests; + +public class NUnitTestItem1 +{ + [SetUp] + public void Setup() + { + } + + [Test] + public void Test1() + { + Assert.Pass(); + } +} diff --git a/exercise.tests/StoreTests.cs b/exercise.tests/StoreTests.cs new file mode 100644 index 00000000..6e341108 --- /dev/null +++ b/exercise.tests/StoreTests.cs @@ -0,0 +1,15 @@ +namespace exercise.tests; + +public class NUnitTestItem1 +{ + [SetUp] + public void Setup() + { + } + + [Test] + public void Test1() + { + Assert.Pass(); + } +} From b46e87b62ae1f41cd779f10f446e1a95f0263412 Mon Sep 17 00:00:00 2001 From: Snorre Aldstedt Date: Mon, 11 Aug 2025 13:29:31 +0200 Subject: [PATCH 04/21] Add tests for StoreItems and Basket --- domain-model.md | 9 +-- exercise.main/Basket.cs | 38 ++++++++++- exercise.main/StoreItem/Bagel.cs | 24 ++++++- exercise.main/StoreItem/Coffee.cs | 13 +++- exercise.main/StoreItem/Filling.cs | 14 +++- exercise.main/StoreItem/IStoreItem.cs | 7 +- exercise.sln | 4 ++ exercise.tests/BagelTests.cs | 15 ----- exercise.tests/BasketTests.cs | 97 +++++++++++++++++++++++++-- exercise.tests/StoreItemTests.cs | 55 +++++++++++++-- exercise.tests/StoreTests.cs | 4 +- exercise.tests/exercise.tests.csproj | 4 ++ 12 files changed, 244 insertions(+), 40 deletions(-) delete mode 100644 exercise.tests/BagelTests.cs diff --git a/domain-model.md b/domain-model.md index 095468f3..ca62b96e 100644 --- a/domain-model.md +++ b/domain-model.md @@ -71,15 +71,16 @@ I want customers to only be able to order things that we stock in our inventory. ## Core | Class | Method/Property | Scenario | Output | |-------|-----------------|----------|--------| -| Basket | AddItem(StoreItem item) | Add an Item to a Basket | void | -| Basket | RemoveItem(StoreItem item) | Remove an Item to a Basket | void | +| Basket | AddItem(IStoreItem item) | Add an Item to a Basket | void | +| Basket | RemoveItem(IStoreItem item) | Remove an Item to a Basket | void | | Basket | IsFull() | Checks if basket is full | bool | | Store | ChangeCap() | Changes capacity of baskets | void | -| Basket | BasketHas(StoreItem item) | Checks if basket has item | bool | +| Basket | BasketHas(IStoreItem item) | Checks if basket has item | bool | | Basket | Remove(StoreItem item) | Removes item from basket if the basket has that item | void | | Basket | TotalCost() | Returns total cost of Basket | int | -| Store | Price(StoreItem item) | Returns price of Item | int | +| Store | Price(IStoreItem item) | Returns price of Item | int | | Bagel | AddFillings(Filling filling) | Add filling to bagel | void | +| Bagel | GetTotalPrice() | Get total cost of bagel including fillings | Decimal | | IStoreItem | Interface with methods for products | Interface for bagel, filling and coffee | | | IStoreItem | Price | attribute that has the price of an IStoreItem | int | | Store | GetInventory() | function that returns the inventory of the store | List | diff --git a/exercise.main/Basket.cs b/exercise.main/Basket.cs index 7df61043..80cb88d7 100644 --- a/exercise.main/Basket.cs +++ b/exercise.main/Basket.cs @@ -1,4 +1,5 @@ -using System; +using exercise.main.StoreItem; +using System; using System.Collections.Generic; using System.Linq; using System.Text; @@ -6,7 +7,40 @@ namespace exercise.main { - internal class Basket + public class Basket { + public int ItemCount; + + public Basket(int v = 5) + { + V = v; + } + + public int V { get; } + + public void Add(Bagel bagel1) + { + throw new NotImplementedException(); + } + + public bool BasketHas(Bagel bagel1) + { + throw new NotImplementedException(); + } + + public bool IsFull() + { + throw new NotImplementedException(); + } + + public void Remove(Bagel bagel2) + { + throw new NotImplementedException(); + } + + public decimal TotalCost() + { + throw new NotImplementedException(); + } } } diff --git a/exercise.main/StoreItem/Bagel.cs b/exercise.main/StoreItem/Bagel.cs index d5055ad1..9b4a0b3e 100644 --- a/exercise.main/StoreItem/Bagel.cs +++ b/exercise.main/StoreItem/Bagel.cs @@ -6,8 +6,30 @@ namespace exercise.main.StoreItem { - public class Bagel + public class Bagel : IStoreItem { + public string Sku { get; set; } + public string Variant { get; set; } + public decimal Price { get; set; } + + public List Fillings = new List(); + + public Bagel(string sku, string variant, decimal price) + { + Sku = sku; + Variant = variant; + Price = price; + } + + public void AddFilling(Filling testFilling) + { + throw new NotImplementedException(); + } + + public decimal GetTotalPrice() + { + throw new NotImplementedException(); + } } } diff --git a/exercise.main/StoreItem/Coffee.cs b/exercise.main/StoreItem/Coffee.cs index 8c1cfcfc..fb7542d2 100644 --- a/exercise.main/StoreItem/Coffee.cs +++ b/exercise.main/StoreItem/Coffee.cs @@ -6,7 +6,18 @@ namespace exercise.main.StoreItem { - internal class Coffee + public class Coffee : IStoreItem + { + public string Sku { get; set; } + public string Variant { get; set; } + public decimal Price { get; set; } + + public Coffee(string sku, string variant, decimal price) + { + Sku = sku; + Variant = variant; + Price = price; + } } } diff --git a/exercise.main/StoreItem/Filling.cs b/exercise.main/StoreItem/Filling.cs index 996ef714..109722cc 100644 --- a/exercise.main/StoreItem/Filling.cs +++ b/exercise.main/StoreItem/Filling.cs @@ -6,7 +6,19 @@ namespace exercise.main.StoreItem { - public class Filling + public class Filling : IStoreItem + { + public string Sku { get; set; } + public string Variant { get; set; } + public decimal Price { get; set; } + + public Filling(string sku, string variant, decimal price) + { + Sku = sku; + Variant = variant; + Price = price; + } } } + diff --git a/exercise.main/StoreItem/IStoreItem.cs b/exercise.main/StoreItem/IStoreItem.cs index b6e9294e..9821f28b 100644 --- a/exercise.main/StoreItem/IStoreItem.cs +++ b/exercise.main/StoreItem/IStoreItem.cs @@ -8,10 +8,9 @@ namespace exercise.main.StoreItem { public interface IStoreItem { - public string Name { get; } - public string Sku { get; } - public decimal Price { get; } - public string Variant { get; } + string Sku { get; set; } + decimal Price { get; set; } + string Variant { get; set; } } } diff --git a/exercise.sln b/exercise.sln index 0efb5453..a4ab1ec1 100644 --- a/exercise.sln +++ b/exercise.sln @@ -9,6 +9,7 @@ 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 + domain-model.md = domain-model.md extension1.md = extension1.md extension2.md = extension2.md extension3.md = extension3.md @@ -34,4 +35,7 @@ Global GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {920D886A-597D-4644-84C5-CCCDE72D64DC} + EndGlobalSection EndGlobal diff --git a/exercise.tests/BagelTests.cs b/exercise.tests/BagelTests.cs deleted file mode 100644 index a08b91f8..00000000 --- a/exercise.tests/BagelTests.cs +++ /dev/null @@ -1,15 +0,0 @@ -namespace exercise.tests; - -public class ItemsTests -{ - [SetUp] - public void Setup() - { - } - - [Test] - public void Test1() - { - Assert.Pass(); - } -} diff --git a/exercise.tests/BasketTests.cs b/exercise.tests/BasketTests.cs index 7bdb8968..81e90cfa 100644 --- a/exercise.tests/BasketTests.cs +++ b/exercise.tests/BasketTests.cs @@ -1,15 +1,104 @@ +using exercise.main; +using exercise.main.StoreItem; +using System.Reflection.Emit; + namespace exercise.tests; public class Tests { - [SetUp] - public void Setup() + [Test] + public void AddTwoBagelTest() + { + Bagel bagel1 = new Bagel("TEST1", "testBagel1", 0.59m); + Bagel bagel2 = new Bagel("TEST2", "testBagel2", 0.59m); + Basket basket = new Basket(); + basket.Add(bagel1); + basket.Add(bagel2); + + int ItemsInBasket = basket.ItemCount; + + Assert.That(ItemsInBasket == 2 && basket.BasketHas(bagel1) && basket.BasketHas(bagel2)); + } + public void AddBagelWithFillingTest() + { + Bagel bagel = new Bagel("TEST", "testBagel", 0.59m); + Filling filling = new Filling("FILL", "testFill", 0.15m); + Basket basket = new Basket(); + bagel.AddFilling(filling); + basket.Add(bagel); + + int ItemsInBasket = basket.ItemCount; + + Assert.That(ItemsInBasket == 1 && basket.BasketHas(bagel)); + } + + [Test] + public void RemoveOneBagelTest() { + Bagel bagel1 = new Bagel("TEST1", "testBagel1", 0.59m); + Bagel bagel2 = new Bagel("TEST2", "testBagel2", 0.59m); + Basket basket = new Basket(); + basket.Add(bagel1); + basket.Add(bagel2); + basket.Remove(bagel2); + int ItemsInBasket = basket.ItemCount; + + Assert.That(ItemsInBasket == 1 && basket.BasketHas(bagel1) && !basket.BasketHas(bagel2)); } [Test] - public void Test1() + public void BasketNotFullTest() { - Assert.Pass(); + Bagel bagel = new Bagel("TEST", "testBagel", 0.59m); + Basket basket = new Basket(); + basket.Add(bagel); + + Assert.That(!basket.IsFull()); + } + + [Test] + public void BasketFullTest() + { + Bagel bagel1 = new Bagel("TEST1", "testBagel1", 0.59m); + Bagel bagel2 = new Bagel("TEST2", "testBagel2", 0.59m); + Bagel bagel3 = new Bagel("TEST3", "testBagel3", 0.59m); + + Basket basket = new Basket(3); + basket.Add(bagel1); + basket.Add(bagel2); + basket.Add(bagel3); + + Assert.That(basket.IsFull()); + } + + [Test] + public void BasketPriceTest() + { + Bagel bagel1 = new Bagel("TEST1", "testBagel1", 0.59m); + Bagel bagel2 = new Bagel("TEST2", "testBagel2", 0.49m); + Bagel bagel3 = new Bagel("TEST3", "testBagel3", 0.59m); + + Basket basket = new Basket(); + basket.Add(bagel1); + basket.Add(bagel2); + basket.Add(bagel3); + Decimal expectedPrice = 1.67m; + Decimal actualPrice = basket.TotalCost(); + + Assert.That(expectedPrice == actualPrice); + } + + [Test] + public void BasketWithFillTest() + { + Bagel bagel = new Bagel("TEST", "testBagel", 0.59m); + Filling filling = new Filling("FILL", "testFill", 0.16m); + bagel.AddFilling(filling); + Basket basket = new Basket(); + basket.Add(bagel); + + Decimal expectedPrice = 0.75m; + Decimal actualPrice = basket.TotalCost(); + Assert.That(expectedPrice == actualPrice); } } \ No newline at end of file diff --git a/exercise.tests/StoreItemTests.cs b/exercise.tests/StoreItemTests.cs index 6e341108..767d070e 100644 --- a/exercise.tests/StoreItemTests.cs +++ b/exercise.tests/StoreItemTests.cs @@ -1,15 +1,58 @@ -namespace exercise.tests; +using exercise.main.StoreItem; -public class NUnitTestItem1 +namespace exercise.tests; +public class StoreItemTests { - [SetUp] - public void Setup() + + [Test] + public void FillingTest() { + Filling testFilling = new Filling("TEST", "testFilling", 1.99m); + Decimal expectedPrice = 1.99m; + string expectedSku = "TEST"; + string expectedVariant = "testFilling"; + Assert.That( + testFilling.Sku == expectedSku && + testFilling.Variant == expectedVariant && + testFilling.Price == expectedPrice); } [Test] - public void Test1() + public void CoffeeTest() + { + Coffee testCoffee = new Coffee("TEST", "testCoffee", 1.95m); + Decimal expectedPrice = 1.59m; + string expectedSku = "TEST"; + string expectedVariant = "testCoffee"; + Assert.That( + testCoffee.Sku == expectedSku && + testCoffee.Variant == expectedVariant && + testCoffee.Price == expectedPrice); + } + [Test] + public void BagelTest() { - Assert.Pass(); + Bagel testBagel = new Bagel("TEST", "testBagel", 0.59m); + Decimal expectedPrice = 0.59m; + string expectedSku = "TEST"; + string expectedVariant = "testBagel"; + Assert.That( + testBagel.Sku == expectedSku && + testBagel.Variant == expectedVariant && + testBagel.Price == expectedPrice); + } + + [Test] + public void BagelFillingTest() + { + Bagel testBagel = new Bagel("TEST", "testBagel", 0.59m); + Filling testFilling = new Filling("TEST", "testFilling", 0.11m); + + testBagel.AddFilling(testFilling); + + Decimal expectedPrice = 0.70m; + Decimal bagelPrice = testBagel.GetTotalPrice(); + + Assert.That(bagelPrice == expectedPrice && testBagel.Fillings.Contains(testFilling)); } } diff --git a/exercise.tests/StoreTests.cs b/exercise.tests/StoreTests.cs index 6e341108..1b0a439b 100644 --- a/exercise.tests/StoreTests.cs +++ b/exercise.tests/StoreTests.cs @@ -1,6 +1,6 @@ namespace exercise.tests; -public class NUnitTestItem1 +public class StoreTests { [SetUp] public void Setup() @@ -10,6 +10,6 @@ public void Setup() [Test] public void Test1() { - Assert.Pass(); + Assert.Fail(); } } 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 @@ + + + + From da863d33776e986cd1d2159b8cef988ce54a0a70 Mon Sep 17 00:00:00 2001 From: Snorre Aldstedt Date: Mon, 11 Aug 2025 13:31:26 +0200 Subject: [PATCH 05/21] Rename Tests to BasketTests in BasketTests.cs --- exercise.tests/BasketTests.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/exercise.tests/BasketTests.cs b/exercise.tests/BasketTests.cs index 81e90cfa..ccf6ba7a 100644 --- a/exercise.tests/BasketTests.cs +++ b/exercise.tests/BasketTests.cs @@ -4,7 +4,7 @@ namespace exercise.tests; -public class Tests +public class BasketTests { [Test] public void AddTwoBagelTest() From 4e7ac430aabef2aceab89eff642615eebd1e2d77 Mon Sep 17 00:00:00 2001 From: Snorre Aldstedt Date: Mon, 11 Aug 2025 13:42:51 +0200 Subject: [PATCH 06/21] Add test for removing fillings --- exercise.main/StoreItem/Bagel.cs | 5 +++++ exercise.tests/BasketTests.cs | 1 + exercise.tests/StoreItemTests.cs | 20 +++++++++++++++++++- 3 files changed, 25 insertions(+), 1 deletion(-) diff --git a/exercise.main/StoreItem/Bagel.cs b/exercise.main/StoreItem/Bagel.cs index 9b4a0b3e..3b822415 100644 --- a/exercise.main/StoreItem/Bagel.cs +++ b/exercise.main/StoreItem/Bagel.cs @@ -27,6 +27,11 @@ public void AddFilling(Filling testFilling) throw new NotImplementedException(); } + public void RemoveFilling(Filling testFilling) + { + throw new NotImplementedException(); + } + public decimal GetTotalPrice() { throw new NotImplementedException(); diff --git a/exercise.tests/BasketTests.cs b/exercise.tests/BasketTests.cs index ccf6ba7a..4a5ab52a 100644 --- a/exercise.tests/BasketTests.cs +++ b/exercise.tests/BasketTests.cs @@ -24,6 +24,7 @@ public void AddBagelWithFillingTest() Bagel bagel = new Bagel("TEST", "testBagel", 0.59m); Filling filling = new Filling("FILL", "testFill", 0.15m); Basket basket = new Basket(); + bagel.AddFilling(filling); basket.Add(bagel); diff --git a/exercise.tests/StoreItemTests.cs b/exercise.tests/StoreItemTests.cs index 767d070e..213be74d 100644 --- a/exercise.tests/StoreItemTests.cs +++ b/exercise.tests/StoreItemTests.cs @@ -20,7 +20,7 @@ public void FillingTest() [Test] public void CoffeeTest() { - Coffee testCoffee = new Coffee("TEST", "testCoffee", 1.95m); + Coffee testCoffee = new Coffee("TEST", "testCoffee", 1.59m); Decimal expectedPrice = 1.59m; string expectedSku = "TEST"; string expectedVariant = "testCoffee"; @@ -55,4 +55,22 @@ public void BagelFillingTest() Assert.That(bagelPrice == expectedPrice && testBagel.Fillings.Contains(testFilling)); } + + [Test] + public void BagelRemoveFillingTest() + { + Bagel testBagel = new Bagel("TEST", "testBagel", 0.59m); + Filling testFilling1 = new Filling("TEST", "testFilling1", 0.11m); + Filling testFilling2 = new Filling("TEST", "testFilling2", 0.11m); + + + testBagel.AddFilling(testFilling1); + testBagel.AddFilling(testFilling2); + + testBagel.RemoveFilling(testFilling1); + Decimal expectedPrice = 0.70m; + Decimal bagelPrice = testBagel.GetTotalPrice(); + + Assert.That(bagelPrice == expectedPrice && testBagel.Fillings.Contains(testFilling2) && !testBagel.Fillings.Contains(testFilling1)); + } } From fd0d75423dc78ae08496f67b01f6e16b68e1e938 Mon Sep 17 00:00:00 2001 From: Snorre Aldstedt Date: Mon, 11 Aug 2025 13:47:47 +0200 Subject: [PATCH 07/21] Pass all StoreItemTests --- exercise.main/StoreItem/Bagel.cs | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) diff --git a/exercise.main/StoreItem/Bagel.cs b/exercise.main/StoreItem/Bagel.cs index 3b822415..cc455457 100644 --- a/exercise.main/StoreItem/Bagel.cs +++ b/exercise.main/StoreItem/Bagel.cs @@ -22,19 +22,26 @@ public Bagel(string sku, string variant, decimal price) Price = price; } - public void AddFilling(Filling testFilling) + public void AddFilling(Filling filling) { - throw new NotImplementedException(); + Fillings.Add(filling); } - public void RemoveFilling(Filling testFilling) + public void RemoveFilling(Filling filling) { - throw new NotImplementedException(); + if (Fillings.Contains(filling)) + { + Fillings.Remove(filling); + } } public decimal GetTotalPrice() { - throw new NotImplementedException(); + decimal totalPrice = Price; + foreach (Filling filling in Fillings) { + totalPrice += filling.Price; + } + return totalPrice; } } } From e61bc23810d35deaa5bc1791ce008009e674791f Mon Sep 17 00:00:00 2001 From: Snorre Aldstedt Date: Mon, 11 Aug 2025 14:12:18 +0200 Subject: [PATCH 08/21] Pass all Basket-, and StoreItem-tests --- exercise.main/Basket.cs | 33 +++++++++++++++++---------- exercise.main/StoreItem/Bagel.cs | 7 +++--- exercise.main/StoreItem/IStoreItem.cs | 2 +- 3 files changed, 26 insertions(+), 16 deletions(-) diff --git a/exercise.main/Basket.cs b/exercise.main/Basket.cs index 80cb88d7..ccab5e7e 100644 --- a/exercise.main/Basket.cs +++ b/exercise.main/Basket.cs @@ -9,38 +9,47 @@ namespace exercise.main { public class Basket { - public int ItemCount; + private List _storeItems = new List(); + public int ItemCount { get { return _storeItems.Count; } } - public Basket(int v = 5) + public Basket(int capacity = 5) { - V = v; + Capacity = capacity; } - public int V { get; } + public int Capacity { get; set; } - public void Add(Bagel bagel1) + public void Add(IStoreItem storeItem) { - throw new NotImplementedException(); + _storeItems.Add(storeItem); } - public bool BasketHas(Bagel bagel1) + public bool BasketHas(IStoreItem storeItem) { - throw new NotImplementedException(); + return _storeItems.Contains(storeItem); } public bool IsFull() { - throw new NotImplementedException(); + return _storeItems.Count >= Capacity; } - public void Remove(Bagel bagel2) + public void Remove(IStoreItem storeItem) { - throw new NotImplementedException(); + if (_storeItems.Contains(storeItem)) + { + _storeItems.Remove(storeItem); + } } public decimal TotalCost() { - throw new NotImplementedException(); + decimal totalPrice = 0; + foreach(IStoreItem storeItem in _storeItems) + { + totalPrice += storeItem.Price; + } + return totalPrice; } } } diff --git a/exercise.main/StoreItem/Bagel.cs b/exercise.main/StoreItem/Bagel.cs index cc455457..37be165a 100644 --- a/exercise.main/StoreItem/Bagel.cs +++ b/exercise.main/StoreItem/Bagel.cs @@ -11,7 +11,8 @@ public class Bagel : IStoreItem { public string Sku { get; set; } public string Variant { get; set; } - public decimal Price { get; set; } + private decimal _bagelPrice { get; set; } + public decimal Price { get { return GetTotalPrice();} } public List Fillings = new List(); @@ -19,7 +20,7 @@ public Bagel(string sku, string variant, decimal price) { Sku = sku; Variant = variant; - Price = price; + _bagelPrice = price; } public void AddFilling(Filling filling) @@ -37,7 +38,7 @@ public void RemoveFilling(Filling filling) public decimal GetTotalPrice() { - decimal totalPrice = Price; + decimal totalPrice = _bagelPrice; foreach (Filling filling in Fillings) { totalPrice += filling.Price; } diff --git a/exercise.main/StoreItem/IStoreItem.cs b/exercise.main/StoreItem/IStoreItem.cs index 9821f28b..3a3e958d 100644 --- a/exercise.main/StoreItem/IStoreItem.cs +++ b/exercise.main/StoreItem/IStoreItem.cs @@ -9,7 +9,7 @@ namespace exercise.main.StoreItem public interface IStoreItem { string Sku { get; set; } - decimal Price { get; set; } + decimal Price { get; } string Variant { get; set; } } From 41894628cfdad883fbe87025a4fc3e8c4266178f Mon Sep 17 00:00:00 2001 From: Snorre Aldstedt Date: Mon, 11 Aug 2025 14:30:33 +0200 Subject: [PATCH 09/21] Add copy method in domain model --- domain-model.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/domain-model.md b/domain-model.md index ca62b96e..3f4ec700 100644 --- a/domain-model.md +++ b/domain-model.md @@ -84,4 +84,4 @@ I want customers to only be able to order things that we stock in our inventory. | IStoreItem | Interface with methods for products | Interface for bagel, filling and coffee | | | IStoreItem | Price | attribute that has the price of an IStoreItem | int | | Store | GetInventory() | function that returns the inventory of the store | List | - +| IStoreItem | Copy() | function to copy a storeItem, makes it easier to choose a bagel/coffee/filling from a menu | IStoreItem | From 280613b34e6b03e4af91d996b968e24b16d42842 Mon Sep 17 00:00:00 2001 From: Snorre Aldstedt Date: Mon, 11 Aug 2025 14:48:02 +0200 Subject: [PATCH 10/21] Add tests for checking Copy() and Equivalent(item) --- domain-model.md | 2 ++ exercise.main/StoreItem/IStoreItem.cs | 3 ++ exercise.tests/StoreItemTests.cs | 45 +++++++++++++++++++++++++++ 3 files changed, 50 insertions(+) diff --git a/domain-model.md b/domain-model.md index 3f4ec700..74b661d2 100644 --- a/domain-model.md +++ b/domain-model.md @@ -85,3 +85,5 @@ I want customers to only be able to order things that we stock in our inventory. | IStoreItem | Price | attribute that has the price of an IStoreItem | int | | Store | GetInventory() | function that returns the inventory of the store | List | | IStoreItem | Copy() | function to copy a storeItem, makes it easier to choose a bagel/coffee/filling from a menu | IStoreItem | +| IStoreItem | Equivalent(IstoreItem item) | Checks wheter an item is equivalent to the instance it's called on| bool | + diff --git a/exercise.main/StoreItem/IStoreItem.cs b/exercise.main/StoreItem/IStoreItem.cs index 3a3e958d..6c7daa68 100644 --- a/exercise.main/StoreItem/IStoreItem.cs +++ b/exercise.main/StoreItem/IStoreItem.cs @@ -12,5 +12,8 @@ public interface IStoreItem decimal Price { get; } string Variant { get; set; } + bool Equivalent(IStoreItem item); + + IStoreItem Copy(); } } diff --git a/exercise.tests/StoreItemTests.cs b/exercise.tests/StoreItemTests.cs index 213be74d..efad2acf 100644 --- a/exercise.tests/StoreItemTests.cs +++ b/exercise.tests/StoreItemTests.cs @@ -73,4 +73,49 @@ public void BagelRemoveFillingTest() Assert.That(bagelPrice == expectedPrice && testBagel.Fillings.Contains(testFilling2) && !testBagel.Fillings.Contains(testFilling1)); } + + [Test] + public void BagelEquivalentTest() + { + Assert.Fail(); + } + + [Test] + public void CoffeeEquivalentTest() + { + Assert.Fail(); + } + + [Test] + public void FillingEquivalentTest() + { + Assert.Fail(); + } + + [Test] + public void BagelWithFillingEquivalentTest() + { + Assert.Fail(); + } + + [Test] + public void CopyBagelTest() + { + Assert.Fail(); + } + [Test] + public void CopyCoffeeTest() + { + Assert.Fail(); + } + [Test] + public void CopyFillingTest() + { + Assert.Fail(); + } + [Test] + public void CopyBagelWithFillingTest() + { + Assert.Fail(); + } } From 00bcdd025c441aba7b624173cb79c3eee325e233 Mon Sep 17 00:00:00 2001 From: Snorre Aldstedt Date: Mon, 11 Aug 2025 15:31:40 +0200 Subject: [PATCH 11/21] Pass all tests regarding equivalent items --- exercise.main/StoreItem/Bagel.cs | 31 ++++++++++++++++ exercise.main/StoreItem/Coffee.cs | 14 ++++++++ exercise.main/StoreItem/Filling.cs | 14 ++++++++ exercise.main/StoreItem/IStoreItem.cs | 2 +- exercise.tests/StoreItemTests.cs | 52 ++++++++++++++++++++++++--- 5 files changed, 108 insertions(+), 5 deletions(-) diff --git a/exercise.main/StoreItem/Bagel.cs b/exercise.main/StoreItem/Bagel.cs index 37be165a..dc8b2005 100644 --- a/exercise.main/StoreItem/Bagel.cs +++ b/exercise.main/StoreItem/Bagel.cs @@ -44,5 +44,36 @@ public decimal GetTotalPrice() } return totalPrice; } + + // To keep it simple a bagel is equivalent only if it has the equivalent filling in the same order + // The fillings doesnt have to be the same Filling object, but be equivalent. This means that this function + // doesn't consider an egg and bacon bagel to be equivalent to a bacon and egg bagel + public bool Equivalent(Bagel item) + { + + //HashSet fillingSet = new HashSet(Fillings); + bool sameFillings = item.Fillings.Count == Fillings.Count; + if (sameFillings) + { + for (int i = 0; i < Fillings.Count; i++) + { + if (!item.Fillings[i].Equivalent(Fillings[i])) + { + sameFillings = false; + } + } + } + return( + item.GetType() == this.GetType() && + item.Sku == this.Sku && + item.Variant == this.Variant && + item.Price == this.Price && + sameFillings); + } + + public IStoreItem Copy() + { + throw new NotImplementedException(); + } } } diff --git a/exercise.main/StoreItem/Coffee.cs b/exercise.main/StoreItem/Coffee.cs index fb7542d2..15cee5dc 100644 --- a/exercise.main/StoreItem/Coffee.cs +++ b/exercise.main/StoreItem/Coffee.cs @@ -19,5 +19,19 @@ public Coffee(string sku, string variant, decimal price) Variant = variant; Price = price; } + + public bool Equivalent(IStoreItem item) + { + return ( + item.GetType() == this.GetType() && + item.Sku == this.Sku && + item.Variant == this.Variant && + item.Price == this.Price); + } + + public IStoreItem Copy() + { + throw new NotImplementedException(); + } } } diff --git a/exercise.main/StoreItem/Filling.cs b/exercise.main/StoreItem/Filling.cs index 109722cc..0fda19bf 100644 --- a/exercise.main/StoreItem/Filling.cs +++ b/exercise.main/StoreItem/Filling.cs @@ -19,6 +19,20 @@ public Filling(string sku, string variant, decimal price) Variant = variant; Price = price; } + + public bool Equivalent(IStoreItem item) + { + return ( + item.GetType() == this.GetType() && + item.Sku == this.Sku && + item.Variant == this.Variant && + item.Price == this.Price); + } + + public IStoreItem Copy() + { + throw new NotImplementedException(); + } } } diff --git a/exercise.main/StoreItem/IStoreItem.cs b/exercise.main/StoreItem/IStoreItem.cs index 6c7daa68..c54a0ac6 100644 --- a/exercise.main/StoreItem/IStoreItem.cs +++ b/exercise.main/StoreItem/IStoreItem.cs @@ -12,7 +12,7 @@ public interface IStoreItem decimal Price { get; } string Variant { get; set; } - bool Equivalent(IStoreItem item); + //bool Equivalent(IStoreItem item); IStoreItem Copy(); } diff --git a/exercise.tests/StoreItemTests.cs b/exercise.tests/StoreItemTests.cs index efad2acf..5e599cf2 100644 --- a/exercise.tests/StoreItemTests.cs +++ b/exercise.tests/StoreItemTests.cs @@ -77,25 +77,69 @@ public void BagelRemoveFillingTest() [Test] public void BagelEquivalentTest() { - Assert.Fail(); + Bagel bagel1 = new Bagel("TEST", "testBagel", 0.59m); + Bagel bagel2 = new Bagel("TEST", "testBagel", 0.59m); + + bool shouldBeTrue = bagel1.Equivalent(bagel2); + Assert.That(shouldBeTrue == true); } [Test] public void CoffeeEquivalentTest() { - Assert.Fail(); + Coffee coffee1 = new Coffee("TEST", "testCoffee", 0.59m); + Coffee coffee2 = new Coffee("TEST", "testCoffee", 0.59m); + + bool shouldBeTrue = coffee1.Equivalent(coffee2); + Assert.That(shouldBeTrue == true); } [Test] public void FillingEquivalentTest() { - Assert.Fail(); + Filling filling1 = new Filling("TEST", "testFilling", 0.59m); + Filling filling2 = new Filling("TEST", "testFilling", 0.59m); + + bool shouldBeTrue = filling1.Equivalent(filling2); + Assert.That(shouldBeTrue == true); } [Test] public void BagelWithFillingEquivalentTest() { - Assert.Fail(); + { + Bagel bagel1 = new Bagel("TEST", "testBagel", 0.59m); + Bagel bagel2 = new Bagel("TEST", "testBagel", 0.59m); + Filling filling1 = new Filling("TEST", "testFilling", 0.59m); + Filling filling2 = new Filling("TEST", "testFilling", 0.59m); + + bagel1.AddFilling(filling1); + bagel2.AddFilling(filling2); + + bool fillingEquivalent = filling1.Equivalent(filling2); + bool shouldBeTrue = bagel1.Equivalent(bagel2); + Assert.That(shouldBeTrue == true && fillingEquivalent); + } + } + + [Test] + public void BagelWithSameFillingEquivalentTest() + { + { + Bagel bagel1 = new Bagel("TEST", "testBagel", 0.59m); + Bagel bagel2 = new Bagel("TEST", "testBagel", 0.59m); + Filling filling1 = new Filling("TEST", "testFilling", 0.59m); + Filling filling2 = new Filling("TEST", "testFilling", 0.59m); + + bagel1.AddFilling(filling1); + bagel1.AddFilling(filling2); + + bagel2.AddFilling(filling1); + bagel2.AddFilling(filling2); + + bool shouldBeTrue = bagel1.Equivalent(bagel2); + Assert.That(shouldBeTrue == true); + } } [Test] From 6e528a9d7c8023af56f42812e7eaba34edd9b971 Mon Sep 17 00:00:00 2001 From: Snorre Aldstedt Date: Mon, 11 Aug 2025 16:05:23 +0200 Subject: [PATCH 12/21] Pass Equivalent and Copy tests --- exercise.main/StoreItem/Bagel.cs | 9 +++++++- exercise.main/StoreItem/Coffee.cs | 2 +- exercise.main/StoreItem/Filling.cs | 2 +- exercise.tests/StoreItemTests.cs | 33 ++++++++++++++++++++++++++---- 4 files changed, 39 insertions(+), 7 deletions(-) diff --git a/exercise.main/StoreItem/Bagel.cs b/exercise.main/StoreItem/Bagel.cs index dc8b2005..c0025583 100644 --- a/exercise.main/StoreItem/Bagel.cs +++ b/exercise.main/StoreItem/Bagel.cs @@ -73,7 +73,14 @@ public bool Equivalent(Bagel item) public IStoreItem Copy() { - throw new NotImplementedException(); + Bagel copyBagel = new Bagel(Sku, Variant, _bagelPrice); + List copyFillings = new List(); + foreach (Filling filling in Fillings) + { + Filling copyFilling = (Filling)filling.Copy(); + copyBagel.AddFilling(copyFilling); + } + return copyBagel; } } } diff --git a/exercise.main/StoreItem/Coffee.cs b/exercise.main/StoreItem/Coffee.cs index 15cee5dc..5c80e775 100644 --- a/exercise.main/StoreItem/Coffee.cs +++ b/exercise.main/StoreItem/Coffee.cs @@ -31,7 +31,7 @@ public bool Equivalent(IStoreItem item) public IStoreItem Copy() { - throw new NotImplementedException(); + return new Coffee(Sku, Variant, Price); } } } diff --git a/exercise.main/StoreItem/Filling.cs b/exercise.main/StoreItem/Filling.cs index 0fda19bf..74a96b58 100644 --- a/exercise.main/StoreItem/Filling.cs +++ b/exercise.main/StoreItem/Filling.cs @@ -31,7 +31,7 @@ public bool Equivalent(IStoreItem item) public IStoreItem Copy() { - throw new NotImplementedException(); + return new Filling(Sku, Variant, Price); } } } diff --git a/exercise.tests/StoreItemTests.cs b/exercise.tests/StoreItemTests.cs index 5e599cf2..d0149856 100644 --- a/exercise.tests/StoreItemTests.cs +++ b/exercise.tests/StoreItemTests.cs @@ -145,21 +145,46 @@ public void BagelWithSameFillingEquivalentTest() [Test] public void CopyBagelTest() { - Assert.Fail(); + Bagel bagel = new Bagel("TEST", "testBagel", 0.59m); + Bagel copyBagel = (Bagel)bagel.Copy(); + + Assert.That(bagel != copyBagel && bagel.Equivalent(copyBagel)); + } + [Test] + public void CopyBagelNotEquivalentTest() + { + Bagel bagel = new Bagel("TEST", "testBagel", 0.59m); + Bagel copyBagel = (Bagel)bagel.Copy(); + Filling filling = new Filling("TEST", "testFilling", 0.59m); + bagel.AddFilling(filling); + + + Assert.That(bagel != copyBagel && !bagel.Equivalent(copyBagel)); } [Test] public void CopyCoffeeTest() { - Assert.Fail(); + Coffee coffee = new Coffee("TEST", "testCoffee", 0.59m); + Coffee copyCoffee = (Coffee)coffee.Copy(); + + Assert.That(coffee != copyCoffee && coffee.Equivalent(copyCoffee)); } [Test] public void CopyFillingTest() { - Assert.Fail(); + Filling filling = new Filling("TEST", "testFilling", 0.59m); + Filling copyFilling = (Filling)filling.Copy(); + + Assert.That(filling != copyFilling && filling.Equivalent(copyFilling)); } [Test] public void CopyBagelWithFillingTest() { - Assert.Fail(); + Bagel bagel = new Bagel("TEST", "testBagel", 0.59m); + Filling filling = new Filling("TEST", "testFilling", 0.59m); + bagel.AddFilling(filling); + Bagel copyBagel = (Bagel)bagel.Copy(); + + Assert.That(bagel != copyBagel && bagel.Equivalent(copyBagel)); } } From 93339d7e8ff03c1eada8a54de60c1674efeb3688 Mon Sep 17 00:00:00 2001 From: Snorre Aldstedt Date: Tue, 12 Aug 2025 09:34:40 +0200 Subject: [PATCH 13/21] Expand Domain-Model --- domain-model.md | 5 +++++ exercise.main/Basket.cs | 2 ++ exercise.main/Store.cs | 3 ++- 3 files changed, 9 insertions(+), 1 deletion(-) diff --git a/domain-model.md b/domain-model.md index 74b661d2..4e887052 100644 --- a/domain-model.md +++ b/domain-model.md @@ -86,4 +86,9 @@ I want customers to only be able to order things that we stock in our inventory. | Store | GetInventory() | function that returns the inventory of the store | List | | IStoreItem | Copy() | function to copy a storeItem, makes it easier to choose a bagel/coffee/filling from a menu | IStoreItem | | IStoreItem | Equivalent(IstoreItem item) | Checks wheter an item is equivalent to the instance it's called on| bool | +| Store | MaxCapacity | Attribute that should be handed over when creatiing a basket at the store | int | +| Store | Name | Attribute that holds the name of the store | string | +| Store | Inventory | List of all Items available | List | +| Store | StoreHasItem(IStoreItem item) | Method that checks if the Item exists in Inventory | bool | +| Basket | ClearBasket() | Removes all items from basket | void | diff --git a/exercise.main/Basket.cs b/exercise.main/Basket.cs index ccab5e7e..a0fe6fcc 100644 --- a/exercise.main/Basket.cs +++ b/exercise.main/Basket.cs @@ -42,6 +42,8 @@ public void Remove(IStoreItem storeItem) } } + + public decimal TotalCost() { decimal totalPrice = 0; diff --git a/exercise.main/Store.cs b/exercise.main/Store.cs index ecaa5e17..3ca85472 100644 --- a/exercise.main/Store.cs +++ b/exercise.main/Store.cs @@ -6,7 +6,8 @@ namespace exercise.main { - internal class Store + public class Store + { } } From dcc118c48e83874e49c36a2420480a12a85df69a Mon Sep 17 00:00:00 2001 From: Snorre Aldstedt Date: Tue, 12 Aug 2025 11:18:07 +0200 Subject: [PATCH 14/21] Add to domain-model --- domain-model.md | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/domain-model.md b/domain-model.md index 4e887052..434a25b7 100644 --- a/domain-model.md +++ b/domain-model.md @@ -86,9 +86,18 @@ I want customers to only be able to order things that we stock in our inventory. | Store | GetInventory() | function that returns the inventory of the store | List | | IStoreItem | Copy() | function to copy a storeItem, makes it easier to choose a bagel/coffee/filling from a menu | IStoreItem | | IStoreItem | Equivalent(IstoreItem item) | Checks wheter an item is equivalent to the instance it's called on| bool | +| Inventory | SKU | Attribute that has the Sku of an Inventory instance | string | +| Inventory | Price | Attribute that has the Price of an Inventory instance | decimal | +| Inventory | Name | Attribute that has the Name of an Inventory instance | string | +| Inventory | Variant | Attribute that has the Variant of an Inventory instance | string | | Store | MaxCapacity | Attribute that should be handed over when creatiing a basket at the store | int | | Store | Name | Attribute that holds the name of the store | string | -| Store | Inventory | List of all Items available | List | +| Store | InventoryList | List of all Items available | List | | Store | StoreHasItem(IStoreItem item) | Method that checks if the Item exists in Inventory | bool | | Basket | ClearBasket() | Removes all items from basket | void | +| Store | CreateBagel(Inventory inventoryItem) | Creates a bagel from inventory | Bagel | +| Store | CreateCoffee(Inventory inventoryItem) | Creates a coffee from inventory | Coffee | +| Store | CreateFilling(Inventory inventoryItem) | Creates a filling from inventory | Filling | +| Store | AddFillToBagel(Bagel bagel, Filling fill) | Adds a filling to a bagel | void | + From b7eb18d9fbc63bbde8c82daea55e62682f236852 Mon Sep 17 00:00:00 2001 From: Snorre Aldstedt Date: Tue, 12 Aug 2025 11:38:25 +0200 Subject: [PATCH 15/21] Add test for InventoryItem --- exercise.main/Inventory.cs | 24 ++++++++++++++++++++++++ exercise.main/StoreItem/Bagel.cs | 1 - exercise.tests/InventoryTests.cs | 18 ++++++++++++++++++ 3 files changed, 42 insertions(+), 1 deletion(-) create mode 100644 exercise.main/Inventory.cs create mode 100644 exercise.tests/InventoryTests.cs diff --git a/exercise.main/Inventory.cs b/exercise.main/Inventory.cs new file mode 100644 index 00000000..c47f8b4e --- /dev/null +++ b/exercise.main/Inventory.cs @@ -0,0 +1,24 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace exercise.main +{ + public class Inventory + { + public Inventory(string sku, decimal price, string name, string variant) + { + Sku = sku; + Price = price; + Name = name; + Variant = variant; + } + + public string Sku { get; } + public decimal Price { get; } + public string Name { get; } + public string Variant { get; } + } +} diff --git a/exercise.main/StoreItem/Bagel.cs b/exercise.main/StoreItem/Bagel.cs index c0025583..4c0f7ce8 100644 --- a/exercise.main/StoreItem/Bagel.cs +++ b/exercise.main/StoreItem/Bagel.cs @@ -51,7 +51,6 @@ public decimal GetTotalPrice() public bool Equivalent(Bagel item) { - //HashSet fillingSet = new HashSet(Fillings); bool sameFillings = item.Fillings.Count == Fillings.Count; if (sameFillings) { diff --git a/exercise.tests/InventoryTests.cs b/exercise.tests/InventoryTests.cs new file mode 100644 index 00000000..8985f84a --- /dev/null +++ b/exercise.tests/InventoryTests.cs @@ -0,0 +1,18 @@ +using exercise.main; + +namespace exercise.tests; + +public class InventoryTests +{ + [SetUp] + public void Setup() + { + } + + [Test] + public void CreateInventoryItemTest() + { + Inventory testInv = new Inventory("TEST", 0.50m, "Bagel", "TestBagel"); + Assert.That(testInv.Sku == "TEST" && testInv.Price == 0.50m && testInv.Name == "Bagel" && testInv.Variant == "TestBagel"); + } +} From 7054dec2c4440a37cdc1987094481aba0f4eb851 Mon Sep 17 00:00:00 2001 From: Snorre Aldstedt Date: Tue, 12 Aug 2025 13:06:49 +0200 Subject: [PATCH 16/21] Add tests for store and clearBasket --- domain-model.md | 8 +-- exercise.main/Basket.cs | 7 ++- exercise.main/Store.cs | 52 +++++++++++++++- exercise.tests/BasketTests.cs | 17 +++++ exercise.tests/StoreTests.cs | 114 ++++++++++++++++++++++++++++++++-- 5 files changed, 187 insertions(+), 11 deletions(-) diff --git a/domain-model.md b/domain-model.md index 434a25b7..2cc60cac 100644 --- a/domain-model.md +++ b/domain-model.md @@ -78,7 +78,6 @@ I want customers to only be able to order things that we stock in our inventory. | Basket | BasketHas(IStoreItem item) | Checks if basket has item | bool | | Basket | Remove(StoreItem item) | Removes item from basket if the basket has that item | void | | Basket | TotalCost() | Returns total cost of Basket | int | -| Store | Price(IStoreItem item) | Returns price of Item | int | | Bagel | AddFillings(Filling filling) | Add filling to bagel | void | | Bagel | GetTotalPrice() | Get total cost of bagel including fillings | Decimal | | IStoreItem | Interface with methods for products | Interface for bagel, filling and coffee | | @@ -95,9 +94,10 @@ I want customers to only be able to order things that we stock in our inventory. | Store | InventoryList | List of all Items available | List | | Store | StoreHasItem(IStoreItem item) | Method that checks if the Item exists in Inventory | bool | | Basket | ClearBasket() | Removes all items from basket | void | -| Store | CreateBagel(Inventory inventoryItem) | Creates a bagel from inventory | Bagel | -| Store | CreateCoffee(Inventory inventoryItem) | Creates a coffee from inventory | Coffee | -| Store | CreateFilling(Inventory inventoryItem) | Creates a filling from inventory | Filling | +| Store | CreateBagel(string sku) | Creates a bagel from inventory | Bagel | +| Store | CreateCoffee(string sku) | Creates a coffee from inventory | Coffee | +| Store | CreateFilling(string sku) | Creates a filling from inventory | Filling | +| Store | CreateNewBasket() | Creates a new basket with max capacity from the store | Basket | | Store | AddFillToBagel(Bagel bagel, Filling fill) | Adds a filling to a bagel | void | diff --git a/exercise.main/Basket.cs b/exercise.main/Basket.cs index a0fe6fcc..d7b28155 100644 --- a/exercise.main/Basket.cs +++ b/exercise.main/Basket.cs @@ -12,7 +12,7 @@ public class Basket private List _storeItems = new List(); public int ItemCount { get { return _storeItems.Count; } } - public Basket(int capacity = 5) + public Basket(int capacity = 20) { Capacity = capacity; } @@ -53,5 +53,10 @@ public decimal TotalCost() } return totalPrice; } + + public void ClearBasket() + { + throw new NotImplementedException(); + } } } diff --git a/exercise.main/Store.cs b/exercise.main/Store.cs index 3ca85472..03c71de5 100644 --- a/exercise.main/Store.cs +++ b/exercise.main/Store.cs @@ -1,4 +1,5 @@ -using System; +using exercise.main.StoreItem; +using System; using System.Collections.Generic; using System.Linq; using System.Text; @@ -9,5 +10,54 @@ namespace exercise.main public class Store { + public Store(string name, int cap) + { + Name = name; + MaxCapacity = cap; + } + + public string Name { get; set; } + public int MaxCapacity { get; set; } + public Dictionary InventoryDict { get; set;} + + public void AddFillToBagel(Bagel bagel, Filling fill) + { + throw new NotImplementedException(); + } + + public void AddInventory(Inventory invItem) + { + throw new NotImplementedException(); + } + + public void AddItemToBasket(Bagel bagel, Basket basket) + { + throw new NotImplementedException(); + } + + public Bagel CreateBagel(string v) + { + throw new NotImplementedException(); + } + + public Basket CreateBasket() + { + throw new NotImplementedException(); + } + + public Coffee CreateCoffee(string v) + { + throw new NotImplementedException(); + } + + public Filling CreateFilling(string v) + { + throw new NotImplementedException(); + } + + public bool StoreHasItem(IStoreItem storeItem) + { + throw new NotImplementedException(); + } } } diff --git a/exercise.tests/BasketTests.cs b/exercise.tests/BasketTests.cs index 4a5ab52a..fb575693 100644 --- a/exercise.tests/BasketTests.cs +++ b/exercise.tests/BasketTests.cs @@ -102,4 +102,21 @@ public void BasketWithFillTest() Decimal actualPrice = basket.TotalCost(); Assert.That(expectedPrice == actualPrice); } + [Test] + public void BasketClearTest() + { + Bagel bagel1 = new Bagel("TEST1", "testBagel1", 0.59m); + Bagel bagel2 = new Bagel("TEST2", "testBagel2", 0.59m); + Bagel bagel3 = new Bagel("TEST3", "testBagel3", 0.59m); + + Basket basket = new Basket(3); + basket.Add(bagel1); + basket.Add(bagel2); + basket.Add(bagel3); + bool isFullBeforeClear = basket.IsFull(); + basket.ClearBasket(); + int ItemsInBasket = basket.ItemCount; + Assert.That(isFullBeforeClear && ItemsInBasket == 0); + } + } \ No newline at end of file diff --git a/exercise.tests/StoreTests.cs b/exercise.tests/StoreTests.cs index 1b0a439b..4b152f6e 100644 --- a/exercise.tests/StoreTests.cs +++ b/exercise.tests/StoreTests.cs @@ -1,15 +1,119 @@ -namespace exercise.tests; +using exercise.main; +using exercise.main.StoreItem; + +namespace exercise.tests; public class StoreTests { - [SetUp] - public void Setup() + [Test] + public void CreateStoreTest() { + Store testStore = new Store("testStore", 50); + + Assert.That(testStore.Name == "testStore" && testStore.MaxCapacity == 50 && testStore.InventoryDict.Values.Count == 0); } [Test] - public void Test1() + public void AddInventoryTest() { - Assert.Fail(); + Store testStore = new Store("testStore", 50); + Inventory InvItem = new Inventory("TEST", 0.50m, "Bagel", "testBagel"); + testStore.AddInventory(InvItem); + + Assert.That(testStore.InventoryDict.Values.Count == 1); + } + + [Test] + public void StoreHasItemTest() + { + Store testStore = new Store("testStore", 50); + Coffee coffee = new Coffee("COFF", "testCoffee", 1.09m); + Bagel bagel = new Bagel("TEST", "testBagel", 0.50m); + Inventory InvItemB = new Inventory("TEST", 0.50m, "Bagel", "testBagel"); + Inventory InvItemC = new Inventory("COFF", 1.09m, "Coffee", "testCoffee"); + + testStore.AddInventory(InvItemB); + testStore.AddInventory(InvItemC); + bool resultB = testStore.StoreHasItem(bagel); + bool resultC = testStore.StoreHasItem(coffee); + + Assert.That(resultB && resultC && testStore.InventoryDict.Values.Count == 2); + } + + [Test] + public void CreateBagelItemTest() + { + Store testStore = new Store("testStore", 50); + Inventory InvItemB = new Inventory("TEST", 0.50m, "Bagel", "testBagel"); + testStore.AddInventory(InvItemB); + Bagel bagel = testStore.CreateBagel("TEST"); + + Assert.That(bagel.Sku == "TEST" && bagel.Price == 0.50m && bagel.Variant == "testBagel"); + } + + [Test] + public void CreateCoffeeTest() + { + Store testStore = new Store("testStore", 50); + Inventory InvItemC = new Inventory("TEST", 0.50m, "Coffee", "testCoffee"); + testStore.AddInventory(InvItemC); + Coffee coffee = testStore.CreateCoffee("TEST"); + + Assert.That(coffee.Sku == "TEST" && coffee.Price == 0.50m && coffee.Variant == "testBagel"); + } + + [Test] + public void CreateFillingTest() + { + Store testStore = new Store("testStore", 50); + Inventory InvItemF = new Inventory("TEST", 0.50m, "Filling", "testCoffee"); + testStore.AddInventory(InvItemF); + Filling filling = testStore.CreateFilling("TEST"); + + Assert.That(filling.Sku == "TEST" && filling.Price == 0.50m && filling.Variant == "testBagel"); + } + + [Test] + public void CreateBasketTest() + { + Store testStore = new Store("testStore", 50); + Basket basket = testStore.CreateBasket(); + + Assert.That(basket.Capacity == 50); + } + + [Test] + public void AddFillToBagelTest() + { + Store testStore = new Store("testStore", 50); + Inventory InvItemB = new Inventory("TEST", 0.50m, "Bagel", "testBagel"); + Inventory InvItemF = new Inventory("FILL", 0.39m, "Filling", "testFilling"); + + testStore.AddInventory(InvItemB); + testStore.AddInventory(InvItemF); + + Bagel bagel = testStore.CreateBagel("TEST"); + Filling fill = testStore.CreateFilling("TEST"); + testStore.AddFillToBagel(bagel, fill); + + Assert.That(bagel.Sku == "TEST" && bagel.Price == 0.80m && bagel.Variant == "testBagel" && bagel.Fillings.Contains(fill)); + } + [Test] + public void AddItemToBasketTest() + { + Store testStore = new Store("testStore", 50); + Basket basket = testStore.CreateBasket(); + Inventory InvItemB = new Inventory("TEST", 0.50m, "Bagel", "testBagel"); + Inventory InvItemF = new Inventory("FILL", 0.39m, "Filling", "testFilling"); + + testStore.AddInventory(InvItemB); + testStore.AddInventory(InvItemF); + + Bagel bagel = testStore.CreateBagel("TEST"); + Filling fill = testStore.CreateFilling("TEST"); + testStore.AddFillToBagel(bagel, fill); + + testStore.AddItemToBasket(bagel, basket); + Assert.That(basket.BasketHas(bagel) && basket.TotalCost() == 0.89m); } } From 80445450171a62a41ec52894b7d22d20ba1f70cb Mon Sep 17 00:00:00 2001 From: Snorre Aldstedt Date: Tue, 12 Aug 2025 13:36:49 +0200 Subject: [PATCH 17/21] Pass tests --- exercise.main/Basket.cs | 2 +- exercise.main/Store.cs | 68 +++++++++++++++++++++++++++--------- exercise.tests/StoreTests.cs | 12 +++---- 3 files changed, 59 insertions(+), 23 deletions(-) diff --git a/exercise.main/Basket.cs b/exercise.main/Basket.cs index d7b28155..db669a79 100644 --- a/exercise.main/Basket.cs +++ b/exercise.main/Basket.cs @@ -56,7 +56,7 @@ public decimal TotalCost() public void ClearBasket() { - throw new NotImplementedException(); + _storeItems.Clear(); } } } diff --git a/exercise.main/Store.cs b/exercise.main/Store.cs index 03c71de5..7a849b40 100644 --- a/exercise.main/Store.cs +++ b/exercise.main/Store.cs @@ -14,50 +14,86 @@ public Store(string name, int cap) { Name = name; MaxCapacity = cap; + InventoryDict = new Dictionary(); } public string Name { get; set; } public int MaxCapacity { get; set; } public Dictionary InventoryDict { get; set;} - public void AddFillToBagel(Bagel bagel, Filling fill) + public void AddInventory(Inventory invItem) { - throw new NotImplementedException(); + InventoryDict[invItem.Sku] = invItem; } - public void AddInventory(Inventory invItem) + public void AddItemToBasket(Bagel bagel, Basket basket) { - throw new NotImplementedException(); + basket.Add(bagel); } - public void AddItemToBasket(Bagel bagel, Basket basket) + public Bagel CreateBagel(string sku) { - throw new NotImplementedException(); + Inventory invItem = InventoryDict[sku]; + if (invItem.Name == "Bagel") + { + return new Bagel(sku, invItem.Variant, invItem.Price); + } + else { + throw new Exception("Sku doesn't exist or isn't a Bagel"); + } + } - public Bagel CreateBagel(string v) + public Coffee CreateCoffee(string sku) { - throw new NotImplementedException(); + Inventory invItem = InventoryDict[sku]; + if (invItem.Name == "Coffee") + { + return new Coffee(sku, invItem.Variant, invItem.Price); + } + else + { + throw new Exception("Sku doesn't exist or isn't a Coffee"); + } + } - public Basket CreateBasket() + + public Filling CreateFilling(string sku) { - throw new NotImplementedException(); + Inventory invItem = InventoryDict[sku]; + if (invItem.Name == "Filling") + { + return new Filling(sku, invItem.Variant, invItem.Price); + } + else + { + throw new Exception("Sku doesn't exist or isn't a Filling"); + } + } - public Coffee CreateCoffee(string v) + + public bool StoreHasItem(IStoreItem storeItem) { - throw new NotImplementedException(); + //bool hasItem = true; + string sku = storeItem.Sku; + if (InventoryDict.ContainsKey(sku)) + { + Inventory invItem = InventoryDict[sku]; + return (storeItem.Price == invItem.Price && storeItem.Variant == invItem.Variant); + } + return false; } - public Filling CreateFilling(string v) + public Basket CreateBasket() { - throw new NotImplementedException(); + return new Basket(MaxCapacity); } - public bool StoreHasItem(IStoreItem storeItem) + public void AddFillToBagel(Bagel bagel, Filling fill) { - throw new NotImplementedException(); + bagel.AddFilling(fill); } } } diff --git a/exercise.tests/StoreTests.cs b/exercise.tests/StoreTests.cs index 4b152f6e..abd48389 100644 --- a/exercise.tests/StoreTests.cs +++ b/exercise.tests/StoreTests.cs @@ -59,18 +59,18 @@ public void CreateCoffeeTest() testStore.AddInventory(InvItemC); Coffee coffee = testStore.CreateCoffee("TEST"); - Assert.That(coffee.Sku == "TEST" && coffee.Price == 0.50m && coffee.Variant == "testBagel"); + Assert.That(coffee.Sku == "TEST" && coffee.Price == 0.50m && coffee.Variant == "testCoffee"); } [Test] public void CreateFillingTest() { Store testStore = new Store("testStore", 50); - Inventory InvItemF = new Inventory("TEST", 0.50m, "Filling", "testCoffee"); + Inventory InvItemF = new Inventory("TEST", 0.50m, "Filling", "testFilling"); testStore.AddInventory(InvItemF); Filling filling = testStore.CreateFilling("TEST"); - Assert.That(filling.Sku == "TEST" && filling.Price == 0.50m && filling.Variant == "testBagel"); + Assert.That(filling.Sku == "TEST" && filling.Price == 0.50m && filling.Variant == "testFilling"); } [Test] @@ -93,10 +93,10 @@ public void AddFillToBagelTest() testStore.AddInventory(InvItemF); Bagel bagel = testStore.CreateBagel("TEST"); - Filling fill = testStore.CreateFilling("TEST"); + Filling fill = testStore.CreateFilling("FILL"); testStore.AddFillToBagel(bagel, fill); - Assert.That(bagel.Sku == "TEST" && bagel.Price == 0.80m && bagel.Variant == "testBagel" && bagel.Fillings.Contains(fill)); + Assert.That(bagel.Sku == "TEST" && bagel.Price == 0.89m && bagel.Variant == "testBagel" && bagel.Fillings.Contains(fill)); } [Test] public void AddItemToBasketTest() @@ -110,7 +110,7 @@ public void AddItemToBasketTest() testStore.AddInventory(InvItemF); Bagel bagel = testStore.CreateBagel("TEST"); - Filling fill = testStore.CreateFilling("TEST"); + Filling fill = testStore.CreateFilling("FILL"); testStore.AddFillToBagel(bagel, fill); testStore.AddItemToBasket(bagel, basket); From 7b4275f2d1a8bf4450476c4b7c9fd9745b27ccf8 Mon Sep 17 00:00:00 2001 From: Snorre Aldstedt Date: Tue, 12 Aug 2025 16:35:03 +0200 Subject: [PATCH 18/21] Add and pass discount-tests --- exercise.main/Basket.cs | 28 ++-- exercise.main/BasketCheckout.cs | 118 +++++++++++++++++ exercise.main/Store.cs | 4 +- exercise.tests/DiscountTests.cs | 228 ++++++++++++++++++++++++++++++++ 4 files changed, 366 insertions(+), 12 deletions(-) create mode 100644 exercise.main/BasketCheckout.cs create mode 100644 exercise.tests/DiscountTests.cs diff --git a/exercise.main/Basket.cs b/exercise.main/Basket.cs index db669a79..6e53fa06 100644 --- a/exercise.main/Basket.cs +++ b/exercise.main/Basket.cs @@ -9,8 +9,8 @@ namespace exercise.main { public class Basket { - private List _storeItems = new List(); - public int ItemCount { get { return _storeItems.Count; } } + public List storeItems = new List(); + public int ItemCount { get { return storeItems.Count; } } public Basket(int capacity = 20) { @@ -21,33 +21,41 @@ public Basket(int capacity = 20) public void Add(IStoreItem storeItem) { - _storeItems.Add(storeItem); + storeItems.Add(storeItem); } public bool BasketHas(IStoreItem storeItem) { - return _storeItems.Contains(storeItem); + return storeItems.Contains(storeItem); } public bool IsFull() { - return _storeItems.Count >= Capacity; + return storeItems.Count >= Capacity; } public void Remove(IStoreItem storeItem) { - if (_storeItems.Contains(storeItem)) + if (storeItems.Contains(storeItem)) { - _storeItems.Remove(storeItem); + storeItems.Remove(storeItem); } } - + public int CountOccurences(string sku) + { + int count = 0; + foreach(IStoreItem item in storeItems) + { + if (item.Sku == sku) count++; + } + return count; + } public decimal TotalCost() { decimal totalPrice = 0; - foreach(IStoreItem storeItem in _storeItems) + foreach(IStoreItem storeItem in storeItems) { totalPrice += storeItem.Price; } @@ -56,7 +64,7 @@ public decimal TotalCost() public void ClearBasket() { - _storeItems.Clear(); + storeItems.Clear(); } } } diff --git a/exercise.main/BasketCheckout.cs b/exercise.main/BasketCheckout.cs new file mode 100644 index 00000000..0dbff73b --- /dev/null +++ b/exercise.main/BasketCheckout.cs @@ -0,0 +1,118 @@ +using exercise.main.StoreItem; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace exercise.main +{ + public class BasketCheckout + { + private Basket _basket; + private decimal _originalCost; + private decimal _discountCost; + public decimal discountTotal{ get { return _originalCost - _discountCost; } } + public Store Store { get; set; } + + public BasketCheckout(Basket basket, Store store) + { + _basket = basket; + _originalCost = _basket.TotalCost(); + Store = store; + } + + private bool hasTwelveOfSameBagel(string sku) + { + bool isBagel = Store.InventoryDict[sku].Name == "Bagel"; + int occurences = _basket.CountOccurences(sku); + return (isBagel && occurences >= 12); + } + private bool hasSixOfSameBagel(string sku) + { + bool isBagel = Store.InventoryDict[sku].Name == "Bagel"; + int occurences = _basket.CountOccurences(sku); + return (isBagel && occurences >= 6); + } + + private bool hasCoffeeAndBagel() + { + bool hasBagel = _basket.storeItems.Any(i => Store.InventoryDict.ContainsKey(i.Sku) && Store.InventoryDict[i.Sku].Name == "Bagel"); + bool hasCoffee = _basket.storeItems.Any(i => Store.InventoryDict.ContainsKey(i.Sku) && Store.InventoryDict[i.Sku].Name == "Coffee"); + + return (hasBagel && hasCoffee); + } + + + + + public List coffeeSorted() + { + List onlyCoffee = _basket.storeItems.FindAll(i => Store.InventoryDict[i.Sku].Name == "Coffee"); + List coffeeSorted = onlyCoffee.OrderByDescending(i => i.Price).ToList(); + return coffeeSorted; + } + public List bagelSorted() + { + List onlyBagel = _basket.storeItems.FindAll(i => Store.InventoryDict[i.Sku].Name == "Bagel"); + List bagelSorted = onlyBagel.OrderByDescending(i => i.Price).ToList(); + return bagelSorted; + } + + + public decimal calculateDiscountCAndB() + { + decimal discount = 0; + if (hasCoffeeAndBagel()) + { + decimal maxCoffeePrice = coffeeSorted().First().Price; + decimal maxBagelPrice = bagelSorted().First().Price; + discount = (maxCoffeePrice + maxBagelPrice) - 1.25m ; + } + return discount; + } + + public decimal calculateDiscountBagels() + { + decimal discount = 0; + List bagelSort = bagelSorted(); + foreach(IStoreItem bagel in bagelSort) + { + if (hasTwelveOfSameBagel(bagel.Sku)) + { + if(discount < (bagel.Price*12) - 3.99m) + { + discount = (bagel.Price * 12) - 3.99m; + } + } + else if (hasSixOfSameBagel(bagel.Sku)) + { + if (discount < (bagel.Price * 6) - 2.49m) + { + discount = (bagel.Price * 6) - 2.49m; + } + } + } + return discount; + } + + public void applyDiscount() + { + decimal maxDiscount = 0; + if (hasCoffeeAndBagel()) + { + decimal currentDiscount = calculateDiscountCAndB(); + if (currentDiscount > maxDiscount) + { + maxDiscount = currentDiscount; + } + } + decimal bagelDiscount = calculateDiscountBagels(); + if(bagelDiscount > maxDiscount) + { + maxDiscount = bagelDiscount; + } + _discountCost = _originalCost - maxDiscount; + } + } +} diff --git a/exercise.main/Store.cs b/exercise.main/Store.cs index 7a849b40..01545c35 100644 --- a/exercise.main/Store.cs +++ b/exercise.main/Store.cs @@ -26,9 +26,9 @@ public void AddInventory(Inventory invItem) InventoryDict[invItem.Sku] = invItem; } - public void AddItemToBasket(Bagel bagel, Basket basket) + public void AddItemToBasket(IStoreItem item, Basket basket) { - basket.Add(bagel); + basket.Add(item); } public Bagel CreateBagel(string sku) diff --git a/exercise.tests/DiscountTests.cs b/exercise.tests/DiscountTests.cs new file mode 100644 index 00000000..39cf624f --- /dev/null +++ b/exercise.tests/DiscountTests.cs @@ -0,0 +1,228 @@ +using exercise.main; +using exercise.main.StoreItem; + +namespace exercise.tests; + +public class DiscountTests +{ + [SetUp] + public void Setup() + { + } + + [Test] + public void TestCoffeeAndBagel() + { + Store store = new Store("Bob's TestBagels", 50); + Basket storeBasket = store.CreateBasket(); + Inventory onionBagel = new Inventory("BGLO", 0.49m, "Bagel", "Onion"); + Inventory plainBagel = new Inventory("BGLP", 0.39m, "Bagel", "Plain"); + Inventory coffeeLatte = new Inventory("COFL", 1.29m, "Coffee", "Latte"); + Inventory coffeeWhite = new Inventory("COFW", 1.19m, "Coffee", "White"); + Inventory coffeeBlack = new Inventory("COFB", 0.99m, "Coffee", "Black"); + + store.AddInventory(onionBagel); + store.AddInventory(plainBagel); + store.AddInventory(coffeeLatte); + store.AddInventory(coffeeWhite); + store.AddInventory(coffeeBlack); + + Bagel myBagel = store.CreateBagel("BGLO"); + Coffee myCoffee = store.CreateCoffee("COFW"); + + store.AddItemToBasket(myBagel, storeBasket); + store.AddItemToBasket(myCoffee, storeBasket); + + BasketCheckout checkout = new BasketCheckout(storeBasket, store); + + checkout.applyDiscount(); + decimal discountTest = checkout.discountTotal; + + Assert.That(discountTest == 0.43m); + } + + [Test] + public void TestSixBagelsAndCoffee() + { + Store store = new Store("Bob's TestBagels", 50); + Basket storeBasket = store.CreateBasket(); + Inventory onionBagel = new Inventory("BGLO", 0.49m, "Bagel", "Onion"); + Inventory plainBagel = new Inventory("BGLP", 0.39m, "Bagel", "Plain"); + Inventory coffeeLatte = new Inventory("COFL", 1.29m, "Coffee", "Latte"); + Inventory coffeeWhite = new Inventory("COFW", 1.19m, "Coffee", "White"); + Inventory coffeeBlack = new Inventory("COFB", 0.99m, "Coffee", "Black"); + + store.AddInventory(onionBagel); + store.AddInventory(plainBagel); + store.AddInventory(coffeeLatte); + store.AddInventory(coffeeWhite); + store.AddInventory(coffeeBlack); + + for(int i = 0; i<6; i++) + { + Bagel myBagel = store.CreateBagel("BGLO"); + store.AddItemToBasket(myBagel, storeBasket); + } + Bagel myPlainBagel = store.CreateBagel("BGLP"); + store.AddItemToBasket(myPlainBagel, storeBasket); + + Coffee myCoffee = store.CreateCoffee("COFW"); + + store.AddItemToBasket(myCoffee, storeBasket); + + BasketCheckout checkout = new BasketCheckout(storeBasket, store); + + checkout.applyDiscount(); + decimal discountTest = checkout.discountTotal; + + Assert.AreEqual(discountTest, 0.45m); + } + [Test] + public void TestSixBagelsNoCoffee() + { + Store store = new Store("Bob's TestBagels", 50); + Basket storeBasket = store.CreateBasket(); + Inventory onionBagel = new Inventory("BGLO", 0.49m, "Bagel", "Onion"); + Inventory plainBagel = new Inventory("BGLP", 0.39m, "Bagel", "Plain"); + Inventory coffeeLatte = new Inventory("COFL", 1.29m, "Coffee", "Latte"); + Inventory coffeeWhite = new Inventory("COFW", 1.19m, "Coffee", "White"); + Inventory coffeeBlack = new Inventory("COFB", 0.99m, "Coffee", "Black"); + + store.AddInventory(onionBagel); + store.AddInventory(plainBagel); + store.AddInventory(coffeeLatte); + store.AddInventory(coffeeWhite); + store.AddInventory(coffeeBlack); + + for (int i = 0; i < 6; i++) + { + Bagel myBagel = store.CreateBagel("BGLO"); + store.AddItemToBasket(myBagel, storeBasket); + } + Bagel myPlainBagel = store.CreateBagel("BGLP"); + store.AddItemToBasket(myPlainBagel, storeBasket); + + BasketCheckout checkout = new BasketCheckout(storeBasket, store); + + checkout.applyDiscount(); + decimal discountTest = checkout.discountTotal; + + decimal discountBagels = checkout.calculateDiscountBagels(); + + Assert.AreEqual(discountTest, discountBagels); + Assert.AreEqual(discountTest, 0.45m); + } + + [Test] + public void TestTwelveOnionBagelsAndCoffee() + { + Store store = new Store("Bob's TestBagels", 50); + Basket storeBasket = store.CreateBasket(); + Inventory onionBagel = new Inventory("BGLO", 0.49m, "Bagel", "Onion"); + Inventory plainBagel = new Inventory("BGLP", 0.39m, "Bagel", "Plain"); + Inventory coffeeLatte = new Inventory("COFL", 1.29m, "Coffee", "Latte"); + Inventory coffeeWhite = new Inventory("COFW", 1.19m, "Coffee", "White"); + Inventory coffeeBlack = new Inventory("COFB", 0.99m, "Coffee", "Black"); + + store.AddInventory(onionBagel); + store.AddInventory(plainBagel); + store.AddInventory(coffeeLatte); + store.AddInventory(coffeeWhite); + store.AddInventory(coffeeBlack); + + for (int i = 0; i < 12; i++) + { + Bagel myBagel = store.CreateBagel("BGLO"); + store.AddItemToBasket(myBagel, storeBasket); + } + Bagel myPlainBagel = store.CreateBagel("BGLP"); + store.AddItemToBasket(myPlainBagel, storeBasket); + + Coffee myCoffee = store.CreateCoffee("COFW"); + store.AddItemToBasket(myCoffee, storeBasket); + + BasketCheckout checkout = new BasketCheckout(storeBasket, store); + + checkout.applyDiscount(); + decimal discountTest = checkout.discountTotal; + + decimal discountBagels = checkout.calculateDiscountBagels(); + + Assert.AreEqual(discountTest, discountBagels); + Assert.AreEqual(discountTest, 1.89m); + } + [Test] + public void TestTwelvePlainBagels() + { + Store store = new Store("Bob's TestBagels", 50); + Basket storeBasket = store.CreateBasket(); + Inventory onionBagel = new Inventory("BGLO", 0.49m, "Bagel", "Onion"); + Inventory plainBagel = new Inventory("BGLP", 0.39m, "Bagel", "Plain"); + Inventory coffeeLatte = new Inventory("COFL", 1.29m, "Coffee", "Latte"); + Inventory coffeeWhite = new Inventory("COFW", 1.19m, "Coffee", "White"); + Inventory coffeeBlack = new Inventory("COFB", 0.99m, "Coffee", "Black"); + + store.AddInventory(onionBagel); + store.AddInventory(plainBagel); + store.AddInventory(coffeeLatte); + store.AddInventory(coffeeWhite); + store.AddInventory(coffeeBlack); + + for (int i = 0; i < 12; i++) + { + Bagel myBagel = store.CreateBagel("BGLP"); + store.AddItemToBasket(myBagel, storeBasket); + } + Bagel myPlainBagel = store.CreateBagel("BGLO"); + store.AddItemToBasket(myPlainBagel, storeBasket); + + BasketCheckout checkout = new BasketCheckout(storeBasket, store); + + checkout.applyDiscount(); + decimal discountTest = checkout.discountTotal; + + decimal discountBagels = checkout.calculateDiscountBagels(); + + Assert.AreEqual(discountTest, discountBagels); + Assert.AreEqual(discountTest, 0.69m); + } + [Test] + public void TestTwelveBagelsAndCoffee() + { + Store store = new Store("Bob's TestBagels", 50); + Basket storeBasket = store.CreateBasket(); + Inventory onionBagel = new Inventory("BGLO", 0.49m, "Bagel", "Onion"); + Inventory plainBagel = new Inventory("BGLP", 0.39m, "Bagel", "Plain"); + Inventory coffeeLatte = new Inventory("COFL", 1.29m, "Coffee", "Latte"); + Inventory coffeeWhite = new Inventory("COFW", 1.19m, "Coffee", "White"); + Inventory coffeeBlack = new Inventory("COFB", 0.99m, "Coffee", "Black"); + + store.AddInventory(onionBagel); + store.AddInventory(plainBagel); + store.AddInventory(coffeeLatte); + store.AddInventory(coffeeWhite); + store.AddInventory(coffeeBlack); + + for (int i = 0; i < 12; i++) + { + Bagel myOnionBagel = store.CreateBagel("BGLO"); + store.AddItemToBasket(myOnionBagel, storeBasket); + } + Bagel myBagel = store.CreateBagel("BGLO"); + Coffee myCoffee = store.CreateCoffee("COFW"); + + store.AddItemToBasket(myBagel, storeBasket); + store.AddItemToBasket(myCoffee, storeBasket); + + BasketCheckout checkout = new BasketCheckout(storeBasket, store); + checkout.applyDiscount(); + + decimal discountTest = checkout.discountTotal; + + decimal discountBagels = checkout.calculateDiscountBagels(); + + Assert.AreEqual(discountTest, discountBagels); + Assert.AreEqual(discountTest, 1.89m); + + } +} From b7f177ec207b9656fcd74ddf2de67bab52eb19e0 Mon Sep 17 00:00:00 2001 From: Snorre Aldstedt Date: Wed, 13 Aug 2025 08:36:33 +0200 Subject: [PATCH 19/21] Add user stories etc for the extensions --- domain-model.md | 12 ++++++++++++ exercise.main/Interface1.cs | 11 +++++++++++ exercise.main/Receipt.cs | 12 ++++++++++++ 3 files changed, 35 insertions(+) create mode 100644 exercise.main/Interface1.cs create mode 100644 exercise.main/Receipt.cs diff --git a/domain-model.md b/domain-model.md index 2cc60cac..bcf3037e 100644 --- a/domain-model.md +++ b/domain-model.md @@ -100,4 +100,16 @@ I want customers to only be able to order things that we stock in our inventory. | Store | CreateNewBasket() | Creates a new basket with max capacity from the store | Basket | | Store | AddFillToBagel(Bagel bagel, Filling fill) | Adds a filling to a bagel | void | +## Extension +### Discounts +- I want to be able to get discounts when buying large amounts of bagels +- I want to have a breakfast deal with a coffee and a bagel + +| BasketCheckout | ApplyDiscount() | Method that applies discount on the basket | void | +| BasketCheckout | CalculateDiscount() | Mrthod that calculates and returns Discount | int | + +### Receipts + +- As a customer I want to get an receipt to be able to verify that my order is correct +- As an employee at Bob's Bagels I want to assure the customer that they got the right order \ No newline at end of file diff --git a/exercise.main/Interface1.cs b/exercise.main/Interface1.cs new file mode 100644 index 00000000..1102b482 --- /dev/null +++ b/exercise.main/Interface1.cs @@ -0,0 +1,11 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace exercise.main +{ + public interface IReceipt { + } +} diff --git a/exercise.main/Receipt.cs b/exercise.main/Receipt.cs new file mode 100644 index 00000000..229deed8 --- /dev/null +++ b/exercise.main/Receipt.cs @@ -0,0 +1,12 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace exercise.main +{ + public class Receipt + { + } +} From 463046698f45205f48c42cc2fea74b305250bc97 Mon Sep 17 00:00:00 2001 From: Snorre Aldstedt Date: Wed, 13 Aug 2025 10:10:58 +0200 Subject: [PATCH 20/21] Add receipt --- exercise.main/BasketCheckout.cs | 28 +++++----- exercise.main/IReceipt.cs | 18 +++++++ exercise.main/Interface1.cs | 11 ---- exercise.main/Receipt.cs | 95 ++++++++++++++++++++++++++++++++- exercise.tests/ReceiptTest.cs | 52 ++++++++++++++++++ 5 files changed, 178 insertions(+), 26 deletions(-) create mode 100644 exercise.main/IReceipt.cs delete mode 100644 exercise.main/Interface1.cs create mode 100644 exercise.tests/ReceiptTest.cs diff --git a/exercise.main/BasketCheckout.cs b/exercise.main/BasketCheckout.cs index 0dbff73b..f25bc981 100644 --- a/exercise.main/BasketCheckout.cs +++ b/exercise.main/BasketCheckout.cs @@ -9,36 +9,36 @@ namespace exercise.main { public class BasketCheckout { - private Basket _basket; - private decimal _originalCost; - private decimal _discountCost; - public decimal discountTotal{ get { return _originalCost - _discountCost; } } + public Basket basket; + public decimal originalCost; + public decimal discountCost; + public decimal discountTotal{ get { return originalCost - discountCost; } } public Store Store { get; set; } - public BasketCheckout(Basket basket, Store store) + public BasketCheckout(Basket b, Store store) { - _basket = basket; - _originalCost = _basket.TotalCost(); + basket = b; + originalCost = basket.TotalCost(); Store = store; } private bool hasTwelveOfSameBagel(string sku) { bool isBagel = Store.InventoryDict[sku].Name == "Bagel"; - int occurences = _basket.CountOccurences(sku); + int occurences = basket.CountOccurences(sku); return (isBagel && occurences >= 12); } private bool hasSixOfSameBagel(string sku) { bool isBagel = Store.InventoryDict[sku].Name == "Bagel"; - int occurences = _basket.CountOccurences(sku); + int occurences = basket.CountOccurences(sku); return (isBagel && occurences >= 6); } private bool hasCoffeeAndBagel() { - bool hasBagel = _basket.storeItems.Any(i => Store.InventoryDict.ContainsKey(i.Sku) && Store.InventoryDict[i.Sku].Name == "Bagel"); - bool hasCoffee = _basket.storeItems.Any(i => Store.InventoryDict.ContainsKey(i.Sku) && Store.InventoryDict[i.Sku].Name == "Coffee"); + bool hasBagel = basket.storeItems.Any(i => Store.InventoryDict.ContainsKey(i.Sku) && Store.InventoryDict[i.Sku].Name == "Bagel"); + bool hasCoffee = basket.storeItems.Any(i => Store.InventoryDict.ContainsKey(i.Sku) && Store.InventoryDict[i.Sku].Name == "Coffee"); return (hasBagel && hasCoffee); } @@ -48,13 +48,13 @@ private bool hasCoffeeAndBagel() public List coffeeSorted() { - List onlyCoffee = _basket.storeItems.FindAll(i => Store.InventoryDict[i.Sku].Name == "Coffee"); + List onlyCoffee = basket.storeItems.FindAll(i => Store.InventoryDict[i.Sku].Name == "Coffee"); List coffeeSorted = onlyCoffee.OrderByDescending(i => i.Price).ToList(); return coffeeSorted; } public List bagelSorted() { - List onlyBagel = _basket.storeItems.FindAll(i => Store.InventoryDict[i.Sku].Name == "Bagel"); + List onlyBagel = basket.storeItems.FindAll(i => Store.InventoryDict[i.Sku].Name == "Bagel"); List bagelSorted = onlyBagel.OrderByDescending(i => i.Price).ToList(); return bagelSorted; } @@ -112,7 +112,7 @@ public void applyDiscount() { maxDiscount = bagelDiscount; } - _discountCost = _originalCost - maxDiscount; + discountCost = originalCost - maxDiscount; } } } diff --git a/exercise.main/IReceipt.cs b/exercise.main/IReceipt.cs new file mode 100644 index 00000000..92ed46d6 --- /dev/null +++ b/exercise.main/IReceipt.cs @@ -0,0 +1,18 @@ +using exercise.main.StoreItem; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace exercise.main +{ + public interface IReceipt { + + string buildReceipt(); + + void printReceipt(); + + + } +} diff --git a/exercise.main/Interface1.cs b/exercise.main/Interface1.cs deleted file mode 100644 index 1102b482..00000000 --- a/exercise.main/Interface1.cs +++ /dev/null @@ -1,11 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; - -namespace exercise.main -{ - public interface IReceipt { - } -} diff --git a/exercise.main/Receipt.cs b/exercise.main/Receipt.cs index 229deed8..6f553d9a 100644 --- a/exercise.main/Receipt.cs +++ b/exercise.main/Receipt.cs @@ -3,10 +3,103 @@ using System.Linq; using System.Text; using System.Threading.Tasks; +using exercise.main.StoreItem; namespace exercise.main { - public class Receipt + public class Receipt : IReceipt { + private BasketCheckout _checkout; + private DateTime dateTime; + private Dictionary _itemOccurences; + private Dictionary _itemsPrices; + private string receiptString = ""; + + + public Receipt(BasketCheckout c) + { + _checkout = c; + _itemOccurences = new Dictionary(); + _itemsPrices = new Dictionary(); + updateAttributes(); + } + + private void updateAttributes() + { + List items = _checkout.basket.storeItems; + foreach (IStoreItem item in items) + { + string s = item.Sku; + if (_itemOccurences.ContainsKey(s)) + { + _itemOccurences[s]++; + _itemsPrices[s] += item.Price; + } + else + { + _itemOccurences[s] = 1; + _itemsPrices[s] = item.Price; + } + } + } + public string buildReceipt() + { + int totalLength = 30; + List alreadyAdded = new List(); + List items = _checkout.basket.storeItems; + dateTime = DateTime.Now; + StringBuilder receipt = new StringBuilder(); + string name = _checkout.Store.Name; + receipt.AppendLine(" ---- "+name+" ---- "); + receipt.AppendLine(); + int dateTimePadding = (int)Math.Ceiling((double)(40 - dateTime.ToString().Length) / 2); + receipt.Append(' ', dateTimePadding); + receipt.Append(dateTime); + receipt.Append(' ', dateTimePadding); + receipt.AppendLine(); + receipt.Append('-', 40); + receipt.AppendLine(); + foreach (IStoreItem item in items) { + if (!alreadyAdded.Contains(item.Sku)) { + string itemName = _checkout.Store.InventoryDict[item.Sku].Name+" "+item.Variant; + int itemOcc = _itemOccurences[item.Sku]; + decimal itemPrice = Math.Round(_itemsPrices[item.Sku], 2); + int namePadding = 20 - itemName.Length; + int digitCount = itemOcc.ToString().Length; + int decimalCount = itemPrice.ToString().Length; + int pricePadding = 10 - (digitCount - decimalCount); + receipt.Append(itemName); + receipt.Append(' ', namePadding); + receipt.Append(itemOcc.ToString()); + receipt.Append(' ', pricePadding); + receipt.Append(itemPrice.ToString()); + receipt.AppendLine(); + alreadyAdded.Add(item.Sku); + } + } + receipt.Append('-', 40); + receipt.AppendLine(); + receipt.Append("Total"); + receipt.Append(' ', 40 - (7 + _checkout.originalCost.ToString().Length)); + receipt.Append(_checkout.originalCost.ToString()); + receipt.AppendLine(); + receipt.Append('-', 40); + receipt.AppendLine(); + + string thanks = "Thank you for your order!"; + receipt.AppendLine(" "+thanks); + + return receipt.ToString(); + } + + public void setReceipt() + { + receiptString = string.Empty; + } + + public void printReceipt() + { + Console.Write(buildReceipt()); + } } } diff --git a/exercise.tests/ReceiptTest.cs b/exercise.tests/ReceiptTest.cs new file mode 100644 index 00000000..0c77e538 --- /dev/null +++ b/exercise.tests/ReceiptTest.cs @@ -0,0 +1,52 @@ +using exercise.main; +using exercise.main.StoreItem; + +namespace exercise.tests; + +public class ReceiptTest +{ + [SetUp] + public void Setup() + { + } + + [Test] + public void BuildReceipt() + { + Store store = new Store("Bob's TestBagels", 50); + Basket storeBasket = store.CreateBasket(); + Inventory onionBagel = new Inventory("BGLO", 0.49m, "Bagel", "Onion"); + Inventory plainBagel = new Inventory("BGLP", 0.39m, "Bagel", "Plain"); + Inventory coffeeLatte = new Inventory("COFL", 1.29m, "Coffee", "Latte"); + Inventory coffeeWhite = new Inventory("COFW", 1.19m, "Coffee", "White"); + Inventory coffeeBlack = new Inventory("COFB", 0.99m, "Coffee", "Black"); + + store.AddInventory(onionBagel); + store.AddInventory(plainBagel); + store.AddInventory(coffeeLatte); + store.AddInventory(coffeeWhite); + store.AddInventory(coffeeBlack); + + for (int i = 0; i < 12; i++) + { + Bagel myBagel = store.CreateBagel("BGLO"); + store.AddItemToBasket(myBagel, storeBasket); + } + Bagel myPlainBagel = store.CreateBagel("BGLP"); + store.AddItemToBasket(myPlainBagel, storeBasket); + + Coffee myCoffee = store.CreateCoffee("COFW"); + store.AddItemToBasket(myCoffee, storeBasket); + + BasketCheckout checkout = new BasketCheckout(storeBasket, store); + + checkout.applyDiscount(); + + Receipt receipt = new Receipt(checkout); + + string receiptString = receipt.buildReceipt(); + + Assert.AreEqual(receiptString.GetType(), typeof(string)); + receipt.printReceipt(); + } +} From 0f296e17c46da14477f7aa832a51aff143edbb79 Mon Sep 17 00:00:00 2001 From: Snorre Aldstedt Date: Wed, 13 Aug 2025 10:20:14 +0200 Subject: [PATCH 21/21] Add discounts to receipt(put it in the original receipt class) --- exercise.main/Receipt.cs | 19 ++++++++++++++----- 1 file changed, 14 insertions(+), 5 deletions(-) diff --git a/exercise.main/Receipt.cs b/exercise.main/Receipt.cs index 6f553d9a..39ac6088 100644 --- a/exercise.main/Receipt.cs +++ b/exercise.main/Receipt.cs @@ -50,9 +50,9 @@ public string buildReceipt() dateTime = DateTime.Now; StringBuilder receipt = new StringBuilder(); string name = _checkout.Store.Name; - receipt.AppendLine(" ---- "+name+" ---- "); + receipt.AppendLine(" ---- "+name+" ---- "); receipt.AppendLine(); - int dateTimePadding = (int)Math.Ceiling((double)(40 - dateTime.ToString().Length) / 2); + int dateTimePadding = (int)Math.Ceiling((double)(36 - dateTime.ToString().Length) / 2); receipt.Append(' ', dateTimePadding); receipt.Append(dateTime); receipt.Append(' ', dateTimePadding); @@ -77,17 +77,26 @@ public string buildReceipt() alreadyAdded.Add(item.Sku); } } + receipt.Append('-', 40); receipt.AppendLine(); - receipt.Append("Total"); - receipt.Append(' ', 40 - (7 + _checkout.originalCost.ToString().Length)); + receipt.Append(' ', 38 - (_checkout.originalCost.ToString().Length)); receipt.Append(_checkout.originalCost.ToString()); receipt.AppendLine(); + receipt.Append("Discount:"); + receipt.Append(' ', 26 - (_checkout.discountTotal.ToString().Length)); + receipt.Append(" - "+_checkout.discountTotal.ToString()); + receipt.AppendLine(); + receipt.AppendLine(); + receipt.Append("Total"); + receipt.Append(' ', 33-(_checkout.discountCost.ToString().Length)); + receipt.Append(_checkout.discountCost.ToString()); + receipt.AppendLine(); receipt.Append('-', 40); receipt.AppendLine(); string thanks = "Thank you for your order!"; - receipt.AppendLine(" "+thanks); + receipt.AppendLine(" "+thanks); return receipt.ToString(); }