Forked from chainavawongse/Ncontracts Code Challenge.cs
Last active
September 3, 2020 03:02
-
-
Save cpboyd/126ea2121eef0d3e3145698ebe6f4419 to your computer and use it in GitHub Desktop.
Ncontracts - Code Challenge
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// Ncontracts Code Challenge | |
// Please take a look at the code below and refactor it to your liking. | |
// Please spend no more than 40 minutes on this exercise. | |
// If you finish early, try adding another calculation for "Office Supply" category. | |
// Once done, please send me a link to your gists. | |
using System; | |
using System.Collections.Generic; | |
namespace CodingChallenge.Shopping | |
{ | |
public enum ItemCategory | |
{ | |
Unspecified, | |
Christmas, | |
Food, | |
OfficeSupplies | |
} | |
class Program | |
{ | |
static void Main(string[] args) | |
{ | |
var program = new Program(); | |
program.ChristmasShoppingAtTheGroceryStore(); | |
program.BuyingFood(); | |
program.BuyingOfficeSupplies(); | |
} | |
void BuyingOfficeSupplies() | |
{ | |
var carts = new List<CartItem> | |
{ | |
new OfficeItem("Pens (3-pack)", 4.99m, 10), | |
new OfficeItem("Desk", 189m, 1), | |
new OfficeItem("Stapler", 7m, 3), | |
}; | |
var calculator = new GroceryStoreCheckoutCalculator(); | |
var total = calculator.Calculate(carts, new DateTime(2020, 7, 30)); | |
Console.WriteLine(total); | |
var totalInAugust = calculator.Calculate(carts, new DateTime(2020, 8, 30)); | |
Console.WriteLine(totalInAugust); | |
} | |
void ChristmasShoppingAtTheGroceryStore() | |
{ | |
var carts = new List<CartItem> | |
{ | |
new ChristmasItem("Lights", 5.99m, 10), | |
new ChristmasItem("Tree", 169m, 1), | |
new ChristmasItem("Ornaments", 8m, 15), | |
}; | |
var calculator = new GroceryStoreCheckoutCalculator(); | |
var total = calculator.Calculate(carts, new DateTime(2020, 11, 30)); | |
Console.WriteLine(total); | |
var totalAfterChristmas = calculator.Calculate(carts, new DateTime(2020, 12, 30)); | |
Console.WriteLine(totalAfterChristmas); | |
} | |
void BuyingFood() | |
{ | |
var carts = new List<CartItem> | |
{ | |
new FoodItem("Apple", 3.27m, 0.79m), | |
new FoodItem("Scallop", 18m, 1.5m), | |
new FoodItem("Salad", 6.99m, 1), | |
new FoodItem("Ground Beef", 7.99m, 1.5m), | |
new FoodItem("Red Wine", 25.99m, 1) | |
}; | |
var calculator = new GroceryStoreCheckoutCalculator(); | |
var total = calculator.Calculate(carts, new DateTime(2020, 11, 30)); | |
Console.WriteLine(total); | |
var seniorHourTotal = calculator.Calculate(carts, new DateTime(2020, 11, 30, 7, 11, 0)); | |
Console.WriteLine(seniorHourTotal); | |
} | |
} | |
public class GroceryStoreCheckoutCalculator | |
{ | |
private decimal ChristmasDiscount(int day) | |
{ | |
if (day < 15) | |
{ | |
return 20m; | |
} | |
if (day <= 25) | |
{ | |
return 60m; | |
} | |
return 90m; | |
} | |
private decimal DiscountFor(ItemCategory category, DateTime checkOutDate) | |
{ | |
switch (category) | |
{ | |
case ItemCategory.Christmas when checkOutDate.Month == 12: | |
return 1m - ChristmasDiscount(checkOutDate.Day) / 100m; | |
case ItemCategory.Food when checkOutDate.TimeOfDay.Hours > 6 && checkOutDate.TimeOfDay.Hours <= 8: | |
// senior discount | |
return 0.9m; | |
case ItemCategory.OfficeSupplies when checkOutDate.Month == 8: | |
// back-to-school discount: | |
return 0.85m; | |
default: | |
return 1m; | |
} | |
} | |
public decimal Calculate(List<CartItem> carts, DateTime checkOutDate) | |
{ | |
decimal itemTotal = 0m; | |
foreach (var item in carts) | |
{ | |
var discount = DiscountFor(item.Category, checkOutDate); | |
switch (item.Category) | |
{ | |
case ItemCategory.Food when item.Weight != 0: | |
itemTotal += item.Weight * item.Price * discount; | |
break; | |
case ItemCategory.Unspecified: | |
// oh no! this should not happen! | |
break; | |
default: | |
itemTotal += item.Quantity * item.Price * discount; | |
break; | |
} | |
} | |
return itemTotal; | |
} | |
} | |
public class OfficeItem : CartItem | |
{ | |
public OfficeItem(string productName, decimal price, int quantity) | |
{ | |
Category = ItemCategory.OfficeSupplies; | |
ProductName = productName; | |
Price = price; | |
Quantity = quantity; | |
} | |
} | |
public class FoodItem : CartItem | |
{ | |
public FoodItem(string productName, decimal price, int quantity) | |
{ | |
Category = ItemCategory.Food; | |
ProductName = productName; | |
Price = price; | |
Quantity = quantity; | |
} | |
public FoodItem(string productName, decimal price, decimal weight) | |
{ | |
Category = ItemCategory.Food; | |
ProductName = productName; | |
Price = price; | |
Weight = weight; | |
} | |
} | |
public class ChristmasItem : CartItem | |
{ | |
public ChristmasItem(string productName, decimal price, int quantity) | |
{ | |
Category = ItemCategory.Christmas; | |
ProductName = productName; | |
Price = price; | |
Quantity = quantity; | |
} | |
} | |
public class CartItem | |
{ | |
public string ProductName { get; set; } | |
public decimal Price { get; set; } | |
public int Quantity { get; set; } | |
public ItemCategory Category { get; set; } | |
public decimal Weight { get; set; } | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment