Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
95 changes: 95 additions & 0 deletions domain-model.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
# Domain models

## Core requirements

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.

| Classes | Methods/Properties | Scenario | Outputs |
|-----------|------------------------------|--------------------------------------|---------|
| Basket.cs | AddProduct(IProduct product) | Add bagel to List<IProduct> MyBasket | bool |


2. As a member of the public, So I can change my order, I'd like to remove a bagel from my basket.

| Classes | Methods/Properties | Scenario | Outputs |
|-----------|---------------------------------|-------------------------------------------|---------|
| Basket.cs | RemoveProduct(IProduct product) | Remove bagel from List<IProduct> MyBasket | bool |


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.

| Classes | Methods/Properties | Scenario | Outputs |
|-----------|----------------------------------|--------------------------------|---------|
| Basket.cs | private int _basketCapacity = 3; | Sets _basketCapacity to 3 | bool |
| Basket.cs | AddProduct(IProduct product) | If basket is full return false | bool |


4. As a Bob's Bagels manager, So that I can expand my business, I�d like to change the capacity of baskets.

| Classes | Methods/Properties | Scenario | Outputs |
|-----------|---------------------------------------|-------------------------------------|---------|
| Basket.cs | ChangeBasketCapacity(int newCapacity) | Sets _basketCapacity to newCapacity | bool |


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.

| Classes | Methods/Properties | Scenario | Outputs |
|-----------|---------------------------------|-----------------------------------|---------|
| Basket.cs | RemoveProduct(IProduct product) | If product not found return false | bool |


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.

| Classes | Methods/Properties | Scenario | Outputs |
|-----------|-------------------------------------------------------------------------|---------------------------------------------|---------|
| Basket.cs | public double TotalCost { get { return MyBasket.Sum(x => x.Price); } } | Sums the prices of the products in Mybasket | double |


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.

| Classes | Methods/Properties | Scenario | Outputs |
|----------|--------------------------------|------------------------------------------------------|---------|
| Bagel.cs | public double Price => _price; | Gets the price of the bagel before added to MyBasket | double |


8. As a customer, So I can shake things up a bit, I'd like to be able to choose fillings for my bagel.

| Classes | Methods/Properties | Scenario | Outputs |
|----------|------------------------------|-------------------------|---------|
| Bagel.cs | AddFilling(IProduct product) | Adds filling to MyBagel | bool |


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.

| Classes | Methods/Properties | Scenario | Outputs |
|------------|--------------------------------|-------------------------------------------------------------------|---------|
| Filling.cs | public double Price => _price; | Gets the price of the filling before added to MyBasket or Mybagel | double |


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.

| Classes | Methods/Properties | Scenario | Outputs |
|-----------|------------------------------|----------------------------------|---------|
| Basket.cs | AddProduct(IProduct product) | If not in inventory return false | bool |



## Extension 1: Discounts

Our goods are priced individually. In addition, some items are multi-priced: buy n of them, and they'll cost you y pounds.
Every Bagel is available for the 6 for 2.49 and 12 for 3.99 offer, but fillings still cost the extra amount per bagel.
Update and extend your program to handle these orders at Bob's Bagels.

| Classes | Methods/Properties | Scenario | Outputs |
|-----------|----------------------------------------------------------------------|-------------------------------------------------------------|---------|
| Basket.cs | private double GroupCost(KeyValuePair<string, List<IProduct>> group) | Calculate the cost for each variant with the bagel discount | double |



## Extension 2: Receipts

Update and extend your program to handle printing receipts. These receipts should print to the terminal.

| Classes | Methods/Properties | Scenario | Outputs |
|-------------|--------------------|------------------------------------|---------|
| Receipts.cs | PrintReceipt() | Prints the recipts to the terminal | bool |
151 changes: 151 additions & 0 deletions exercise.main/Basket.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,151 @@
using Microsoft.VisualBasic;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace exercise.main
{
public class Basket
{
private int _basketCapacity = 3;

public List<IProduct> MyBasket { get; set; } = new List<IProduct>();

public Dictionary<string, List<IProduct>> MyGroupedBasket => MyBasket.GroupBy(p => p.SKU).OrderBy(g => g.Key).ToDictionary(g => g.Key, g => g.ToList());

public double TotalCost
{
get
{
double totalCost = 0;

foreach (var group in MyGroupedBasket)
{
totalCost += GroupCost(group);
}

return totalCost;
}
}

private double GroupCost(KeyValuePair<string, List<IProduct>> group)
{
{
double groupCost = 0;

int quantity = group.Value.Count();

if (quantity >= 6 && group.Value.First().Name == "Bagel")
{
int numOf12Deals = quantity / 12;
groupCost += (numOf12Deals * 3.99);

quantity -= numOf12Deals * 12;
int numOf6Deals = quantity / 6;
groupCost += (numOf6Deals * 2.49);

quantity -= numOf6Deals * 6;
}

groupCost += (quantity * group.Value.First().Price);

return groupCost;
}
}

public bool AddProduct(IProduct product)
{
InventoryDictionary inventoryDictionary = new InventoryDictionary();

if ((inventoryDictionary.SKU_Info(product.SKU).Item1 == ""))
{
Console.WriteLine("Item not in inventory");
return false;
}

if (MyBasket.Count < _basketCapacity)
{
MyBasket.Add(product);
return true;
}
else
{
Console.WriteLine("Basket is full");
return false;
}
}

public bool RemoveProduct(IProduct product)
{
if (MyBasket.Contains(product))
{
MyBasket.Remove(product);
return true;
}
else
{
Console.WriteLine("Product not found");
return false;
}
}

public void ChangeBasketCapacity(int newCapacity)
{
_basketCapacity = newCapacity;
}

public bool PrintReceipt()
{
if (MyBasket.Count == 0)
{
Console.WriteLine("No items in the basket, could not print receipt");
return false;
}
else
{
Console.WriteLine(" ~~~ Bob's Bagels ~~~ ");
Console.WriteLine(" ");
Console.WriteLine($" {DateTime.Now.Year:D4}-{DateTime.Now.Month:D2}-{DateTime.Now.Day:D2} {DateTime.Now.Hour:D2}:{DateTime.Now.Minute:D2}:{DateTime.Now.Second:D2} ");
Console.WriteLine(" ");
Console.WriteLine(" -------------------------------------- ");
Console.WriteLine(" ");

foreach (var group in MyGroupedBasket)
{
var product = group.Value.First();
var quantity = group.Value.Count();
string col1 = $" {product.Variant} {product.Name}";
string col2 = $"{quantity}";

var groupCost = GroupCost(group);
string col3 = $"£{(groupCost):0.00}";
//string col3 = $"£{(product.Price * quantity):0.00}";

Console.WriteLine("{0,-27} {1,-5} {2,-15}", col1, col2, col3);
}

Console.WriteLine(" ");
Console.WriteLine(" -------------------------------------- ");

string totalCost = $"£{TotalCost:0.00}";
if (TotalCost >= 10.0)
{
Console.WriteLine("{0,-31} {1,0} {2,-15}", " Total", "", totalCost);
}
else
{
Console.WriteLine("{0,-32} {1,0} {2,-15}", " Total", "", totalCost);
}

Console.WriteLine(" ");
Console.WriteLine(" Thank you ");
Console.WriteLine(" for your order! ");

return true;
}
}
}
}

16 changes: 16 additions & 0 deletions exercise.main/IProduct.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace exercise.main
{
public interface IProduct
{
string SKU { get; }
string Name { get; }
string Variant { get; }
double Price { get; }
}
}
54 changes: 54 additions & 0 deletions exercise.main/InventoryDictionary.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace exercise.main
{
public class InventoryDictionary
{
Dictionary<string, (string Variant, double Price)> inventoryDictionary;
public InventoryDictionary()
{
inventoryDictionary = new Dictionary<string, (string Variant, double Price)>();

double bagelPrice = 0.49;
inventoryDictionary.Add("BGLO", ("Onion", bagelPrice));
inventoryDictionary.Add("BGLP", ("Plain", 0.39));
inventoryDictionary.Add("BGLE", ("Everything", bagelPrice));
inventoryDictionary.Add("BGLS", ("Sesame", bagelPrice));

double fillingPrice = 0.12;
inventoryDictionary.Add("FILB", ("Bacon", fillingPrice));
inventoryDictionary.Add("FILE", ("Egg", fillingPrice));
inventoryDictionary.Add("FILC", ("Cheese", fillingPrice));
inventoryDictionary.Add("FILX", ("Cream Cheese", fillingPrice));
inventoryDictionary.Add("FILS", ("Smoked Salmon", fillingPrice));
inventoryDictionary.Add("FILH", ("Ham", fillingPrice));

double coffeePrice = 1.29;
inventoryDictionary.Add("COFB", ("Black", 0.99));
inventoryDictionary.Add("COFW", ("White", 1.19));
inventoryDictionary.Add("COFC", ("Capuccino", coffeePrice));
inventoryDictionary.Add("COFL", ("Latte", coffeePrice));

/*foreach (KeyValuePair<string, (string, double)> kvp in inventoryDictionary)
{
Console.WriteLine($"Key: {kvp.Key} Value: {kvp.Value}");
}*/
}

public (string, double) SKU_Info(string SKU)
{
if (inventoryDictionary.ContainsKey(SKU))
{
(string, double) info;
info = inventoryDictionary[SKU];
return info;
}

return ("", 0.00);
}
}
}
50 changes: 50 additions & 0 deletions exercise.main/Products/Bagel.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace exercise.main.Products
{
public class Bagel : IProduct
{
private string _SKU;
private string _name;
private string _variant;
private double _price;


public Bagel(string SKU)
{
_SKU = SKU;
_name = "Bagel";

InventoryDictionary inventoryDictionary = new InventoryDictionary();
(string, double) result = inventoryDictionary.SKU_Info(SKU);

_variant = result.Item1;
_price = result.Item2;
}

public List<IProduct> MyBagel { get; set; } = new List<IProduct>();

public string SKU => _SKU;
public string Name => _name;
public string Variant => _variant;
public double Price => _price + MyBagel.Sum(x => x.Price);

public bool AddFilling(IProduct product)
{
InventoryDictionary inventoryDictionary = new InventoryDictionary();

if ((inventoryDictionary.SKU_Info(product.SKU).Item1 == ""))
{
Console.WriteLine("Item not in inventory");
return false;
}

MyBagel.Add(product);
return true;
}
}
}
Loading