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
54 changes: 54 additions & 0 deletions exercise.main/Basket.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
using exercise.main.Inventory;
using exercise.main.Products;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;


namespace exercise.main
{
public class Basket
{
private readonly List<IProduct> _items = new();
private int _capacity;

public Basket(int capacity = 4)
{
_capacity = capacity;
}

public int Capacity { get { return _capacity; } set { _capacity = value; } }

public string AddProduct(IProduct product)
{
if(_items.Count >= _capacity)
{
return $"the basket is full";
} else
{
_items.Add(product);
return $"Item {product.Name} was successfully added to the basket.";
}
}

// add by SKU with in-stock check
public string AddProduct(ICatalog catalog, string sku)
{
if (catalog == null) return "no catalog";
if (!catalog.ProductExists(sku)) return "item not found";

var item = catalog.Get(sku);
if (!item.InStock) return $"{item.Name} - {item.Variant} is out of stock.";

// create & add (capacity check + message reused)
var product = catalog.CreateProduct(sku);
return AddProduct(product);
}

public List<IProduct> Products => _items;

public decimal TotalPrice => _items.Sum(p => p.Price);
}
}
122 changes: 122 additions & 0 deletions exercise.main/Inventory/Catalog.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,122 @@
using exercise.main.Products;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace exercise.main.Inventory
{
public class Catalog : ICatalog
{
private static int _nextId = 1;
private readonly Dictionary<string, CatalogItem> _items;

public Catalog()
{
_items = new(StringComparer.OrdinalIgnoreCase)
{
["BGLO"] = new("BGLO", 0.49m, "Bagel", "Onion", ProductType.Bagel, true),
["BGLP"] = new("BGLP", 0.39m, "Bagel", "Plain", ProductType.Bagel, true),
["BGLE"] = new("BGLE", 0.49m, "Bagel", "Everything", ProductType.Bagel, true),
["BGLS"] = new("BGLS", 0.49m, "Bagel", "Sesame", ProductType.Bagel, true),

["COFB"] = new("COFB", 0.99m, "Coffee", "Black", ProductType.Coffee, true),
["COFW"] = new("COFW", 1.19m, "Coffee", "White", ProductType.Coffee, true),
["COFC"] = new("COFC", 1.29m, "Coffee", "Cappuccino", ProductType.Coffee, false),
["COFL"] = new("COFL", 1.29m, "Coffee", "Latte", ProductType.Coffee, false),

["FILB"] = new("FILB", 0.12m, "Filling", "Bacon", ProductType.Filling, true),
["FILE"] = new("FILE", 0.12m, "Filling", "Egg", ProductType.Filling, true),
["FILC"] = new("FILC", 0.12m, "Filling", "Cheese", ProductType.Filling, true),
["FILX"] = new("FILX", 0.12m, "Filling", "Cream Cheese", ProductType.Filling, true),
["FILS"] = new("FILS", 0.12m, "Filling", "Smoked Salmon", ProductType.Filling, true),
["FILH"] = new("FILH", 0.12m, "Filling", "Ham", ProductType.Filling, true),
};
}

public bool ProductExists(string sku)
{
return _items.ContainsKey(sku);
}

public CatalogItem Get(string sku)
{
CatalogItem item;
if (_items.TryGetValue(sku, out item))
{
return item;
}
return null;
}

// Returns all items of a specific type, optionally filtering out those that are not in stock.
public IEnumerable<CatalogItem> GetByType(ProductType type, bool onlyInStock = true)
{
var result = new List<CatalogItem>();

foreach (var i in _items.Values)
{
if (i.Type == type)
{
if (onlyInStock && !i.InStock)
{
continue;
}
result.Add(i);
}
}

return result;
}

// Returns all sold-out items of a specific type.
public IEnumerable<CatalogItem> GetSoldOutByType(ProductType type)
{
var result = new List<CatalogItem>();

foreach (var i in _items.Values)
{
if (i.Type == type && !i.InStock)
{
result.Add(i);
}
}

return result;
}

// Creates a product instance based on the SKU.
// Returns null if the SKU doesn't exist, the item is out of stock, or the type is unsupported.
public IProduct CreateProduct(string sku)
{
if (!_items.TryGetValue(sku, out var item))
{
// SKU not found
return null;
}

// Not in stock
if (!item.InStock)
{
return null;
}

// Unique id in case of multible of the same sku
var id = _nextId++;

// Create the correct product type
if (item.Type == ProductType.Bagel)
return new Bagel(id, item.Sku, item.Variant, item.Price);
if (item.Type == ProductType.Coffee)
return new Coffee(id, item.Sku, item.Variant, item.Price);
if (item.Type == ProductType.Filling)
return new Filling(id, item.Sku, item.Variant, item.Price);

return null;
}


public decimal GetPrice(string sku) => Get(sku).Price;
}
}
31 changes: 31 additions & 0 deletions exercise.main/Inventory/CatalogItem.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

using exercise.main.Products;

namespace exercise.main.Inventory
{
public class CatalogItem
{
public string Sku { get; }
public decimal Price { get; }
public string Name { get; }
public string Variant { get; }
public ProductType Type { get; }
public bool InStock { get; set; }

public CatalogItem(string sku, decimal price, string name, string variant, ProductType type, bool inStock = true)
{
Sku = sku;
Price = price;
Name = name;
Variant = variant;
Type = type;
InStock = inStock;
}
}
}

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

namespace exercise.main.Inventory
{
public interface ICatalog
{
bool ProductExists(string sku);
CatalogItem Get(string sku);
IEnumerable<CatalogItem> GetByType(ProductType type, bool onlyInStock = true);
IEnumerable<CatalogItem> GetSoldOutByType(ProductType type);
IProduct CreateProduct(string sku);
decimal GetPrice(string sku);
}
}
15 changes: 15 additions & 0 deletions exercise.main/Products/Bagel.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace exercise.main.Products
{
public class Bagel : Product
{
public Bagel(int id, string sku, string variant, decimal price)
: base(id, sku, "Bagel", variant, price, ProductType.Bagel) { }
}
}

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

namespace exercise.main.Products
{
public class Coffee : Product
{
public Coffee(int id, string sku, string variant, decimal price)
: base(id, sku, "Coffee", variant, price, ProductType.Coffee) { }
}
}

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

namespace exercise.main.Products
{
public class Filling : Product
{
public Filling(int id, string sku, string variant, decimal price)
: base(id, sku, "Filling", variant, price, ProductType.Filling) { }
}
}

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

namespace exercise.main.Products
{
public interface IDiscountable
{

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

namespace exercise.main.Products
{
public interface IProduct
{
int Id { get; }
string Sku { get; }
string Name { get; }
string Variant { get; }
decimal Price { get; }
ProductType Type { get; }
}
}

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

namespace exercise.main.Products
{
public abstract class Product : IProduct
{
public int Id { get; }
public string Sku { get; }
public string Name { get; }
public string Variant { get; }
public decimal Price { get; }
public ProductType Type { get; }

protected Product(int id, string sku, string name, string variant, decimal price, ProductType type)
{
Id = id;
Sku = sku;
Name = name;
Variant = variant;
Price = price;
Type = type;
}

public override string ToString() => $"{Name} - {Variant} ({Sku}) ${Price:0.00}";
}
}

16 changes: 16 additions & 0 deletions exercise.main/Products/ProductType.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.Products
{
public enum ProductType
{
Bagel = 1,
Coffee = 2,
Filling = 3
}
}

Loading