diff --git a/BagelDomain.md b/BagelDomain.md new file mode 100644 index 000000000..a2e0027b9 --- /dev/null +++ b/BagelDomain.md @@ -0,0 +1,28 @@ + +| Classes | variables | Methods | Scenario | Outputs | +| ------------ | ----------------------------------------------------------- | ---------------------------------------------------------------------------- | ------------------------------------------------- | ---------------------------------------------------------------------- | +| Basket | Map> orders | Basket() | create method | empty Basket | +| | int orderLimit | addOrder("String bagelName, int amount) | if bagelName is not correct or int amount is <= 0 | returns false | +| | | | if basket size is gone over | returns false | +| | | | if both valid and storeItem is not in basket yet | returns true, and the storeItem is added to the basket | +| | | | if both are valid and storeItem is already in basket | returns true, and the amount is added to the storeItem in basket | +| | | changeOrder(String bagelOrderToBeChanged, String new bagelOrder, int amount) | if all are valid | the storeItem version is changed and set to a new amount, true is returned | +| | | | | nothing happens and false is returned | +| | | removeOrder(String bagelName) | If name is in basket | the order is removed and true is returnd | +| | | | if not | returns false | +| | | changeSizeLimit(int newSizeLimit) | if >0 | returns true | +| | | | if < 0 | returns false | +| | | getTotalCost | empty or full | it calculated and returns the cost of all storeItems and fillings | +| | | | | | +| Bagel | String type | Bagel(String type) | if valid storeItem type | set as that storeItem | +| | | | if not | sets as default storeItem | +| | String filling | setBagelType(STring new type) | if valid storeItem | return true | +| | | | if not valid storeItem | returns false | +| | | setFillingType | if valid filiing | return true | +| | | | if not valid filling | return false | +| | | | | | +| StoreManager | Map priceListBagels | getBagelPrices() | | returns map of storeItem and prices | +| | Map priceListFilling | getFillingPrices() | | returns map of fillings and prices | +| | | getBagelPrice() | if valid | returns price | +| | | getFillingPrice() | if valid | returns price | +| | | | if not | returns -1 | diff --git a/EXTENSION1.md b/EXTENSION1.md index 9e2c3cfd5..2afdd2b4e 100644 --- a/EXTENSION1.md +++ b/EXTENSION1.md @@ -2,7 +2,7 @@ In a normal supermarket, things are identified using Stock Keeping Units, or SKUs. -In Bob's Bagels, we'll use the first 3 letters of a bagel with an extra letter for the variant. For example: an 'everything bagel' has a SKU of `BGLE`. +In Bob's Bagels, we'll use the first 3 letters of a storeItem with an extra letter for the variant. For example: an 'everything storeItem' has a SKU of `BGLE`. Our goods are priced individually. In addition, some items are multi-priced: buy n of them, and they'll cost you y pounds. @@ -15,7 +15,7 @@ Our goods are priced individually. In addition, some items are multi-priced: buy | BGLE | Bagel | Everything | .49 | 6 for 2.49 | | COFB | Coffee | Black | .99 | Coffee & Bagel for 1.25 | -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. +Every Bagel is available for the `6 for 2.49` and `12 for 3.99` offer, but fillings still cost the extra amount per storeItem. #### Example orders ``` diff --git a/README.md b/README.md index e2aa7ee51..d3133aeb1 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ # Bob's Bagels - Object-oriented Programming -![](./assets/bagels.jpg) +![](./assets/storeItems.jpg) ## Learning Objectives - Design a domain from user stories @@ -26,21 +26,21 @@ ``` 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. +So I can order a storeItem before work, +I'd like to add a specific type of storeItem 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. +I'd like to remove a storeItem from my basket. ``` ``` 3. As a member of the public, -So that I can not overfill my small bagel basket +So that I can not overfill my small storeItem basket I'd like to know when my basket is full when I try adding an item beyond my basket capacity. ``` @@ -69,21 +69,21 @@ 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. +I'd like to know the cost of a storeItem 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. +I'd like to be able to choose fillings for my storeItem. ``` ``` 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. +I'd like to know the cost of each filling before I add it to my storeItem order. ``` ``` diff --git a/src/main/java/com/booleanuk/core/BaconFilling.java b/src/main/java/com/booleanuk/core/BaconFilling.java new file mode 100644 index 000000000..1090483a8 --- /dev/null +++ b/src/main/java/com/booleanuk/core/BaconFilling.java @@ -0,0 +1,7 @@ +package com.booleanuk.core; + +public class BaconFilling extends Filling{ + public BaconFilling() { + super ("Bacon Filling", "FILB"); + } +} diff --git a/src/main/java/com/booleanuk/core/Basket.java b/src/main/java/com/booleanuk/core/Basket.java new file mode 100644 index 000000000..baa95f942 --- /dev/null +++ b/src/main/java/com/booleanuk/core/Basket.java @@ -0,0 +1,90 @@ +package com.booleanuk.core; + +import java.util.HashMap; +import java.util.Map; + +public class Basket { + + Map> orders; + + public Basket() { + orders = new HashMap<>(); + } + + public Map> getOrders() { + return orders; + } + + public boolean addOrder(String sku, int amount) { + int orderLimit = StoreManager.getBasketSize(); + + StoreItem storeItem = StoreItem.getBagelFromSKU(sku); + if (storeItem != null && amount > 0 && getOrderSize() + amount <= orderLimit) { + orders.merge(sku, Map.entry(storeItem, amount), + (a, b) -> Map.entry(storeItem, a.getValue()+b.getValue())); + return true; + } + return false; + } + + public boolean changeOrder(String prevSKU, String newBagelSKU, int amount) { + int prevAmount = 0; + StoreItem newStoreItem = StoreItem.getBagelFromSKU(newBagelSKU); + if (orders.containsKey(prevSKU) && newStoreItem != null && amount > 0) { + + if (prevSKU.equals(newBagelSKU)) { + return addOrder(newBagelSKU, amount); + } else { + if (addOrder(newBagelSKU, amount)){ + orders.remove(prevSKU); + return true; + } + } + } + return false; + } + + public boolean removeOrder(String bagelSKU) { + if (orders.containsKey(bagelSKU)) { + orders.remove(bagelSKU); + return true; + } + return false; + } + + + + private int getOrderSize() { + int count =0; + for (var order : orders.entrySet()) { + count+= order.getValue().getValue(); + } + return count; + } + + public boolean setFilling(String bagelSKU, String fillingSKU) { + if (orders.containsKey(bagelSKU)) { + var set = orders.get(bagelSKU); + StoreItem storeItem = set.getKey(); + if (storeItem.setFilling(fillingSKU)) { + orders.remove(bagelSKU); + orders.put(storeItem.getSKU() + fillingSKU, set); + return true; + } + } + return false; + } + + public float getTotalCost() { + float cost =0; + for (var order : orders.entrySet()) { + var singleOrder = order.getValue(); + StoreItem storeItem = singleOrder.getKey(); + int amount = singleOrder.getValue(); + + cost += storeItem.getCost() * amount; + } + return cost; + } + +} diff --git a/src/main/java/com/booleanuk/core/CheeseFilling.java b/src/main/java/com/booleanuk/core/CheeseFilling.java new file mode 100644 index 000000000..88cca1a30 --- /dev/null +++ b/src/main/java/com/booleanuk/core/CheeseFilling.java @@ -0,0 +1,7 @@ +package com.booleanuk.core; + +public class CheeseFilling extends Filling{ + public CheeseFilling() { + super("Cheese Filling", "FILC"); + } +} diff --git a/src/main/java/com/booleanuk/core/CoffeeBlack.java b/src/main/java/com/booleanuk/core/CoffeeBlack.java new file mode 100644 index 000000000..6b2787770 --- /dev/null +++ b/src/main/java/com/booleanuk/core/CoffeeBlack.java @@ -0,0 +1,12 @@ +package com.booleanuk.core; + +public class CoffeeBlack extends StoreItem { + public CoffeeBlack() { + super("Coffee Black", "COFB", 0.99f); + } + + @Override + public boolean setFilling(String filling) { + return false; + } +} diff --git a/src/main/java/com/booleanuk/core/CoffeeCapuccino.java b/src/main/java/com/booleanuk/core/CoffeeCapuccino.java new file mode 100644 index 000000000..c4f3d2794 --- /dev/null +++ b/src/main/java/com/booleanuk/core/CoffeeCapuccino.java @@ -0,0 +1,12 @@ +package com.booleanuk.core; + +public class CoffeeCapuccino extends StoreItem{ + public CoffeeCapuccino() { + super("Coffee Cappuccino", "COFC", 1.29f); + } + + @Override + public boolean setFilling(String filling) { + return false; + } +} diff --git a/src/main/java/com/booleanuk/core/CoffeeLatte.java b/src/main/java/com/booleanuk/core/CoffeeLatte.java new file mode 100644 index 000000000..3dcae01b3 --- /dev/null +++ b/src/main/java/com/booleanuk/core/CoffeeLatte.java @@ -0,0 +1,12 @@ +package com.booleanuk.core; + +public class CoffeeLatte extends StoreItem{ + public CoffeeLatte() { + super("Coffee Latte", "COFL", 1.29f); + } + + @Override + public boolean setFilling(String filling) { + return false; + } +} diff --git a/src/main/java/com/booleanuk/core/CoffeeWhite.java b/src/main/java/com/booleanuk/core/CoffeeWhite.java new file mode 100644 index 000000000..ad7c9a8a8 --- /dev/null +++ b/src/main/java/com/booleanuk/core/CoffeeWhite.java @@ -0,0 +1,12 @@ +package com.booleanuk.core; + +public class CoffeeWhite extends StoreItem{ + public CoffeeWhite() { + super("Coffee White", "COFW", 1.19f); + } + + @Override + public boolean setFilling(String filling) { + return false; + } +} diff --git a/src/main/java/com/booleanuk/core/CreamCheeseFilling.java b/src/main/java/com/booleanuk/core/CreamCheeseFilling.java new file mode 100644 index 000000000..080437f40 --- /dev/null +++ b/src/main/java/com/booleanuk/core/CreamCheeseFilling.java @@ -0,0 +1,7 @@ +package com.booleanuk.core; + +public class CreamCheeseFilling extends Filling{ + public CreamCheeseFilling() { + super("Cream Cheese Filling", "FILX"); + } +} diff --git a/src/main/java/com/booleanuk/core/EggFilling.java b/src/main/java/com/booleanuk/core/EggFilling.java new file mode 100644 index 000000000..4cb9df31a --- /dev/null +++ b/src/main/java/com/booleanuk/core/EggFilling.java @@ -0,0 +1,7 @@ +package com.booleanuk.core; + +public class EggFilling extends Filling{ + public EggFilling() { + super("Egg Filling", "FILE"); + } +} diff --git a/src/main/java/com/booleanuk/core/EverythingBagel.java b/src/main/java/com/booleanuk/core/EverythingBagel.java new file mode 100644 index 000000000..b307f9a9f --- /dev/null +++ b/src/main/java/com/booleanuk/core/EverythingBagel.java @@ -0,0 +1,8 @@ +package com.booleanuk.core; + +public class EverythingBagel extends StoreItem { + public EverythingBagel() { + super("Everything Bagel","BGLE" , 0.49f); + } + +} diff --git a/src/main/java/com/booleanuk/core/Filling.java b/src/main/java/com/booleanuk/core/Filling.java new file mode 100644 index 000000000..a065521af --- /dev/null +++ b/src/main/java/com/booleanuk/core/Filling.java @@ -0,0 +1,49 @@ +package com.booleanuk.core; + +import com.booleanuk.extension.ReceiptItem; + +import java.util.HashMap; +import java.util.Map; + +public abstract class Filling implements ReceiptItem { + + private final String filling; + private final String sku; + + public Filling(String filling, String sku) { + this.filling = filling; + this.sku = sku; + } + + public String getName(){return filling;} + + public float getCost() { + return 0.12f;} + + public String getSKU() { + return sku; + } + + + public static Filling getFillingFromSKU(String sku) { + return switch (sku) { + case "FILB" -> new BaconFilling(); + case "FILX" -> new CreamCheeseFilling(); + case "FILE" -> new EggFilling(); + case "FILC" -> new CheeseFilling(); + case "FILS" -> new SmokedSalmonFilling(); + case "FILH" -> new HamFilling(); + default -> null; + }; + } + + public static Map getFillingPrices() { + Filling[] fillings = {new BaconFilling(), new CreamCheeseFilling(), new EggFilling(), + new CheeseFilling(), new SmokedSalmonFilling(), new HamFilling()}; + Map priceList = new HashMap<>(); + for (Filling filling: fillings) { + priceList.put(filling.getName(), filling.getCost()); + } + return priceList; + } +} diff --git a/src/main/java/com/booleanuk/core/HamFilling.java b/src/main/java/com/booleanuk/core/HamFilling.java new file mode 100644 index 000000000..8ed658396 --- /dev/null +++ b/src/main/java/com/booleanuk/core/HamFilling.java @@ -0,0 +1,9 @@ +package com.booleanuk.core; + +public class HamFilling extends Filling { + public HamFilling() { + super("Ham Filling", "FILH"); + } + + +} diff --git a/src/main/java/com/booleanuk/core/OnionBagel.java b/src/main/java/com/booleanuk/core/OnionBagel.java new file mode 100644 index 000000000..94d30da2e --- /dev/null +++ b/src/main/java/com/booleanuk/core/OnionBagel.java @@ -0,0 +1,7 @@ +package com.booleanuk.core; + +public class OnionBagel extends StoreItem { + public OnionBagel() { + super("Onion Bagel", "BGLO", 0.49f); + } +} diff --git a/src/main/java/com/booleanuk/core/PlainBagel.java b/src/main/java/com/booleanuk/core/PlainBagel.java new file mode 100644 index 000000000..11bffd7cf --- /dev/null +++ b/src/main/java/com/booleanuk/core/PlainBagel.java @@ -0,0 +1,10 @@ +package com.booleanuk.core; + +public class PlainBagel extends StoreItem { + + public PlainBagel() { + super("Plain Bagel", "BGLP", 0.39f); + } + + +} diff --git a/src/main/java/com/booleanuk/core/SesameBagel.java b/src/main/java/com/booleanuk/core/SesameBagel.java new file mode 100644 index 000000000..26c5c6941 --- /dev/null +++ b/src/main/java/com/booleanuk/core/SesameBagel.java @@ -0,0 +1,7 @@ +package com.booleanuk.core; + +public class SesameBagel extends StoreItem { + public SesameBagel() { + super("Sesame Bagel", "BGLS", 0.49f); + } +} diff --git a/src/main/java/com/booleanuk/core/SmokedSalmonFilling.java b/src/main/java/com/booleanuk/core/SmokedSalmonFilling.java new file mode 100644 index 000000000..09189579b --- /dev/null +++ b/src/main/java/com/booleanuk/core/SmokedSalmonFilling.java @@ -0,0 +1,7 @@ +package com.booleanuk.core; + +public class SmokedSalmonFilling extends Filling{ + public SmokedSalmonFilling() { + super("Smoked Salmon Filling", "FILS"); + } +} diff --git a/src/main/java/com/booleanuk/core/StoreItem.java b/src/main/java/com/booleanuk/core/StoreItem.java new file mode 100644 index 000000000..503222d37 --- /dev/null +++ b/src/main/java/com/booleanuk/core/StoreItem.java @@ -0,0 +1,77 @@ +package com.booleanuk.core; + +import com.booleanuk.extension.ReceiptItem; + +import java.util.HashMap; +import java.util.Map; + +public abstract class StoreItem implements ReceiptItem { + + private final String bagelName; + private final String sku; + private final float cost; + + private Filling filling; + + protected StoreItem(String bagelName, String sku, float cost) { + this.sku = sku; + this.bagelName = bagelName; + this.cost = cost; + } + + public String getName() { + return bagelName; + } + + public String getSKU() { + return sku; + } + + public float getCost() { + return this.cost; + } + + public Filling getFilling() { + return this.filling; + } + + + public boolean setFilling(String fillingSKU) { + Filling filling = Filling.getFillingFromSKU(fillingSKU); + if (filling != null) { + this.filling = filling; + return true; + } + return false; + } + + public void removeFilling() { + this.filling = null; + } + + public static StoreItem getBagelFromSKU(String sku) { + return switch (sku) { + case "BGLP" -> new PlainBagel(); + case "BGLO" -> new OnionBagel(); + case "BGLE" -> new EverythingBagel(); + case "BGLS" -> new SesameBagel(); + case "COFB" -> new CoffeeBlack(); + case "COFW" -> new CoffeeWhite(); + case "COFC" -> new CoffeeCapuccino(); + case "COFL" -> new CoffeeLatte(); + default -> null; + }; + } + + public static Map getStoreItemPrices() { + StoreItem[] storeItems = {new PlainBagel(), new OnionBagel(), new SesameBagel(), new EverythingBagel(), + new CoffeeBlack(), new CoffeeWhite(), new CoffeeCapuccino(), new CoffeeLatte()}; + Map priceList = new HashMap<>(); + for (StoreItem storeItem : storeItems) { + priceList.put(storeItem.getName(), storeItem.getCost()); + } + return priceList; + } + + +} diff --git a/src/main/java/com/booleanuk/core/StoreManager.java b/src/main/java/com/booleanuk/core/StoreManager.java new file mode 100644 index 000000000..c4a374020 --- /dev/null +++ b/src/main/java/com/booleanuk/core/StoreManager.java @@ -0,0 +1,19 @@ +package com.booleanuk.core; + +public abstract class StoreManager { + + static private int basketSize = 25; + + public static int getBasketSize() { + return basketSize; + } + + public static boolean setBasketSize(int newBasketSize, boolean isManager) { + if (!isManager) + return false; + basketSize = newBasketSize; + return true; + } + + +} diff --git a/src/main/java/com/booleanuk/extension/BundleEverythingBagle.java b/src/main/java/com/booleanuk/extension/BundleEverythingBagle.java new file mode 100644 index 000000000..320c871aa --- /dev/null +++ b/src/main/java/com/booleanuk/extension/BundleEverythingBagle.java @@ -0,0 +1,9 @@ +package com.booleanuk.extension; + +import com.booleanuk.core.StoreItem; + +public class BundleEverythingBagle extends StoreItem { + public BundleEverythingBagle() { + super("Bundle: 6 Everything Bagle", "BBGLE", 6); + } +} diff --git a/src/main/java/com/booleanuk/extension/BundledCoffeeBagel.java b/src/main/java/com/booleanuk/extension/BundledCoffeeBagel.java new file mode 100644 index 000000000..7ef58400e --- /dev/null +++ b/src/main/java/com/booleanuk/extension/BundledCoffeeBagel.java @@ -0,0 +1,10 @@ +package com.booleanuk.extension; + +import com.booleanuk.core.StoreItem; + +public class BundledCoffeeBagel extends StoreItem { + + public BundledCoffeeBagel(){ + super("Bundle: Coffee and Bagel", "BCOFB", 1.25f); + } +} diff --git a/src/main/java/com/booleanuk/extension/BundledOnionBagle.java b/src/main/java/com/booleanuk/extension/BundledOnionBagle.java new file mode 100644 index 000000000..cd25bafe0 --- /dev/null +++ b/src/main/java/com/booleanuk/extension/BundledOnionBagle.java @@ -0,0 +1,10 @@ +package com.booleanuk.extension; + +import com.booleanuk.core.StoreItem; + +public class BundledOnionBagle extends StoreItem { + + public BundledOnionBagle(){ + super("Bundle: 6 Onion Bagles", "BBGLO", 2.49f); + } +} diff --git a/src/main/java/com/booleanuk/extension/BundledPlainBagle.java b/src/main/java/com/booleanuk/extension/BundledPlainBagle.java new file mode 100644 index 000000000..8d9ad3a3a --- /dev/null +++ b/src/main/java/com/booleanuk/extension/BundledPlainBagle.java @@ -0,0 +1,9 @@ +package com.booleanuk.extension; + +import com.booleanuk.core.StoreItem; + +public class BundledPlainBagle extends StoreItem { + public BundledPlainBagle() { + super("Bundle: 12 Plain Bagles", "BBGLP", 3.99f); + } +} diff --git a/src/main/java/com/booleanuk/extension/ExtentionBasket.java b/src/main/java/com/booleanuk/extension/ExtentionBasket.java new file mode 100644 index 000000000..b7c023a22 --- /dev/null +++ b/src/main/java/com/booleanuk/extension/ExtentionBasket.java @@ -0,0 +1,164 @@ +package com.booleanuk.extension; + +import com.booleanuk.core.*; + +import java.util.*; + +public class ExtentionBasket extends Basket { + + public ExtentionBasket() { + super(); + } + + @Override + public float getTotalCost() { + var receipt = getReceipt(); + float cost = 0; + for (var entry : receipt) { + ReceiptItem item = entry.getKey(); + float costPerItem = item.getCost() * entry.getValue(); + cost += costPerItem; + } + + return cost; + + } + + public float countCostBundle(StoreItem originalStoreItem, StoreItem bundleStoreItem, int count, int neededToBundleCount) { + int bundleCount = count % neededToBundleCount; + float bundleCost = bundleStoreItem.getCost() * bundleCount; + float originalCost = originalStoreItem.getCost() * (count - (bundleCount * neededToBundleCount)); + return bundleCost + originalCost; + + + + } + + public List> getReceipt() { + Map> receipt = new HashMap<>(); + + for (var set: super.getOrders().entrySet()) { + StoreItem storeItem = set.getValue().getKey(); + int amount = set.getValue().getValue(); + Filling filling = storeItem.getFilling(); + receipt.merge(storeItem.getSKU(), Map.entry(storeItem, amount), + (a,b) -> + Map.entry(storeItem,a.getValue() + b.getValue() ) + ); + if (filling != null) { + receipt.merge(filling.getSKU(), Map.entry(filling, amount), + (a,b) -> + Map.entry(filling, a.getValue() + b.getValue())); + } + + } + + receipt = bundleReceipts(receipt); + + return receipt.values().stream().sorted( + Comparator.comparing(a -> a.getKey().getName()) + ).toList(); + } + + private Map> bundleReceipts(Map> receipt) { + var returnValue = new HashMap<>(receipt); + for (var set : receipt.values()) { + ReceiptItem bagel = set.getKey(); + int count = set.getValue(); + if (bagel.getSKU().equals("BGLO") && count >= 6) { + turnIntoBundle(returnValue, count, bagel, 6, new BundledOnionBagle()); + } else if (bagel.getSKU().equals("BGLP") && count >= 12) { + turnIntoBundle(returnValue, count, bagel, 12, new BundledPlainBagle()); + } else if (bagel.getSKU().equals("BGLE")&& count >= 6) { + turnIntoBundle(returnValue, count, bagel, 6, new BundleEverythingBagle()); + } + } + + return coffeeBundleCreator(returnValue); + + } + + private static Map> coffeeBundleCreator(Map> receipt) { + var localReceipt = new HashMap<>(receipt); + var bagel = receipt.getOrDefault("BGLP", null); + var coffee = receipt.getOrDefault("COFB", null); + + if (bagel != null && coffee != null) { + int overlap = Math.min(bagel.getValue(), coffee.getValue()); + + int newBagelCount = bagel.getValue() - overlap; + int newCoffeeCount = coffee.getValue() - overlap; + + if (newBagelCount > 0) { + localReceipt.put(bagel.getKey().getSKU(), Map.entry(bagel.getKey(), newBagelCount)); + } else { + localReceipt.remove(bagel.getKey().getSKU()); + } + + if (newCoffeeCount > 0) { + localReceipt.put(coffee.getKey().getSKU(), Map.entry(coffee.getKey(), newBagelCount)); + } else { + localReceipt.remove(coffee.getKey().getSKU()); + } + ReceiptItem bundleCoffee = new BundledCoffeeBagel(); + localReceipt.put(bundleCoffee.getSKU(), Map.entry(bundleCoffee, overlap)); + + + + } + + + + return localReceipt; + } + + private static Map> turnIntoBundle(Map> receipt, int count, + ReceiptItem bagel, int needToHave, StoreItem bundle) { + int bundleCount = count / needToHave; + receipt.put(bundle.getSKU(), Map.entry(bundle, bundleCount)); + receipt.replace(bagel.getSKU(), + Map.entry(bagel, (count - (bundleCount * needToHave))) + ); + return receipt; + } + + + public String getReceiptToString() { + StringBuilder sb = new StringBuilder(); + sb.append("\n~~~ Bob's Bagels ~~~\n\n----------------------------\n\n"); + var receipt = getReceipt(); + for (var entry : receipt) { + var item = entry.getKey(); + sb.append(item.getName() + " \t" + entry.getValue() + " "); + sb.append(String.format("%.2f", item.getCost() * entry.getValue())); + sb.append("\n"); + if (entry.getKey() instanceof BundleEverythingBagle) { + sb.append("\t\t\t\t (-$"); + float priceSavings = new EverythingBagel().getCost() * 6 - item.getCost(); + sb.append(String.format("%.2f", priceSavings * entry.getValue())); + sb.append(")\n"); + } else if (entry.getKey() instanceof BundledPlainBagle) { + sb.append("\t\t\t\t (-$"); + float priceSavings = new EverythingBagel().getCost() * 12 - item.getCost(); + sb.append(String.format("%.2f", priceSavings * entry.getValue())); + sb.append(")\n"); + } else if (entry.getKey() instanceof BundledOnionBagle) { + sb.append("\t\t\t\t (-$"); + float priceSavings = new EverythingBagel().getCost() * 6 - item.getCost(); + sb.append(String.format("%.2f", priceSavings * entry.getValue())); + sb.append(")\n"); + } else if (entry.getKey() instanceof BundledCoffeeBagel) { + sb.append("\t\t\t\t (-$"); + float priceSavings = new PlainBagel().getCost() + new CoffeeBlack().getCost() - item.getCost(); + sb.append(String.format("%.2f", priceSavings * entry.getValue())); + sb.append(")\n"); + } + + } + + sb.append("\nTotal \t\t\t " ); + sb.append(String.format("%.2f", getTotalCost())); + sb.append("\nThank you\nfor your order!\n"); + return sb.toString(); + } +} diff --git a/src/main/java/com/booleanuk/extension/ReceiptItem.java b/src/main/java/com/booleanuk/extension/ReceiptItem.java new file mode 100644 index 000000000..3d1e54cf4 --- /dev/null +++ b/src/main/java/com/booleanuk/extension/ReceiptItem.java @@ -0,0 +1,8 @@ +package com.booleanuk.extension; + +public interface ReceiptItem { + + String getName(); + String getSKU(); + float getCost(); +} diff --git a/src/test/java/com/booleanuk/core/BasketTest.java b/src/test/java/com/booleanuk/core/BasketTest.java new file mode 100644 index 000000000..7b0e4d2a6 --- /dev/null +++ b/src/test/java/com/booleanuk/core/BasketTest.java @@ -0,0 +1,76 @@ +package com.booleanuk.core; + +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; + +class BasketTest { + + + @Test + void addAndGetOrders() { + Basket basket = new Basket(); + Assertions.assertEquals(0, basket.getOrders().size()); + Assertions.assertTrue(basket.addOrder("BGLP",1)); + Assertions.assertEquals(1, basket.getOrders().size()); + Assertions.assertTrue(basket.addOrder("BGLP",1)); + Assertions.assertEquals(1, basket.getOrders().size()); + Assertions.assertFalse(basket.addOrder("BGLO",0)); + Assertions.assertEquals(1, basket.getOrders().size()); + Assertions.assertTrue(basket.addOrder("BGLO", 2)); + Assertions.assertEquals(2, basket.getOrders().size()); + } + + @Test + void changeOrder() { + Basket basket = new Basket(); + basket.addOrder("BGLP",1); + Assertions.assertTrue(basket.changeOrder("BGLP", "BGLO",1)); + Assertions.assertEquals(1, basket.getOrders().size()); + Assertions.assertFalse(basket.changeOrder("BGLP", "BGLP",1)); + Assertions.assertFalse(basket.changeOrder("krekrje", "BGLP",1)); + Assertions.assertFalse(basket.changeOrder("BGLO", "BGLO",-8)); + Assertions.assertTrue(basket.changeOrder("BGLO", "BGLO",2)); + Assertions.assertEquals(3, basket.getOrders().get("BGLO").getValue()); + } + + @Test + void removeOrder() { + Basket basket = new Basket(); + Assertions.assertEquals(0, basket.getOrders().size()); + basket.addOrder("BGLP",1); + Assertions.assertEquals(1, basket.getOrders().size()); + Assertions.assertFalse(basket.removeOrder("BGLO")); + Assertions.assertEquals(1, basket.getOrders().size()); + Assertions.assertTrue(basket.removeOrder("BGLP")); + Assertions.assertEquals(0, basket.getOrders().size()); + } + + @Test + void setFilling() { + Basket basket = new Basket(); + basket.addOrder("BGLP",1); + Assertions.assertNull( basket.getOrders().get("BGLP").getKey().getFilling()); + Assertions.assertFalse(basket.setFilling("re", "Bacon")); + Assertions.assertFalse(basket.setFilling("BGLP", "er")); + Assertions.assertNull( basket.getOrders().get("BGLP").getKey().getFilling()); + Assertions.assertTrue(basket.setFilling("BGLP", "FILB")); + Assertions.assertEquals("Bacon Filling", basket.getOrders().get("BGLPFILB").getKey().getFilling().getName()); + Assertions.assertTrue(basket.setFilling("BGLPFILB", "FILH")); + Assertions.assertEquals("Ham Filling", basket.getOrders().get("BGLPFILH").getKey().getFilling().getName()); + + + } + + @Test + void getTotalCost() { + Basket basket = new Basket(); + Assertions.assertEquals(0, basket.getTotalCost()); + basket.addOrder("BGLP", 1); + Assertions.assertEquals(0.39f, basket.getTotalCost()); + basket.setFilling("BGLP", "FILB"); + Assertions.assertEquals(0.39f, basket.getTotalCost()); + basket.addOrder("BGLO", 2); + Assertions.assertEquals(1.37f, basket.getTotalCost()); + } + +} \ No newline at end of file diff --git a/src/test/java/com/booleanuk/core/FillingTest.java b/src/test/java/com/booleanuk/core/FillingTest.java new file mode 100644 index 000000000..7daaed8e0 --- /dev/null +++ b/src/test/java/com/booleanuk/core/FillingTest.java @@ -0,0 +1,40 @@ +package com.booleanuk.core; + +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; + +class FillingTest { + + @Test + void getName() { + Filling fillingHam = new HamFilling(); + Assertions.assertEquals("Ham Filling", fillingHam.getName()); + Filling fillingCheese = new CheeseFilling(); + Assertions.assertEquals("Cheese Filling", fillingCheese.getName()); + } + + @Test + void getCost() { + Filling fillingHam = new HamFilling(); + Assertions.assertEquals(0.12f, fillingHam.getCost()); + Filling fillingCheese = new CheeseFilling(); + Assertions.assertEquals(0.12f, fillingCheese.getCost()); + + + } + + @Test + void getFillingFromSKU() { + Assertions.assertEquals("Cheese Filling", Filling.getFillingFromSKU("FILC").getName()); + Assertions.assertEquals("Cream Cheese Filling", Filling.getFillingFromSKU("FILX").getName()); + Assertions.assertNull(Filling.getFillingFromSKU("not a filling")); + + + } + + @Test + void getFillingPrices() { + var fillings = Filling.getFillingPrices(); + Assertions.assertEquals(6, fillings.size()); + } +} \ No newline at end of file diff --git a/src/test/java/com/booleanuk/core/StoreItemTest.java b/src/test/java/com/booleanuk/core/StoreItemTest.java new file mode 100644 index 000000000..de5b6700a --- /dev/null +++ b/src/test/java/com/booleanuk/core/StoreItemTest.java @@ -0,0 +1,60 @@ +package com.booleanuk.core; + +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; + +public class StoreItemTest { + @Test + void getName() { + StoreItem storeItem = new PlainBagel(); + Assertions.assertEquals("Plain Bagel", storeItem.getName()); + StoreItem onionStoreItem = new OnionBagel(); + Assertions.assertEquals("Onion Bagel", onionStoreItem.getName()); + } + + @Test + void getSKU() { + StoreItem storeItem = new PlainBagel(); + Assertions.assertEquals("BGLP", storeItem.getSKU()); + StoreItem onionStoreItem = new OnionBagel(); + Assertions.assertEquals("BGLO", onionStoreItem.getSKU()); + } + + @Test + void getCost() { + StoreItem storeItem = new PlainBagel(); + Assertions.assertEquals(0.39f, storeItem.getCost()); + StoreItem onionStoreItem = new OnionBagel(); + Assertions.assertEquals(0.49f, onionStoreItem.getCost()); + } + + @Test + void getFilling() { + Assertions.assertNull(new PlainBagel().getFilling()); + Assertions.assertNull(new SesameBagel().getFilling()); + } + + @Test + void setFilling() { + StoreItem storeItem = new PlainBagel(); + Assertions.assertFalse(storeItem.setFilling("not a filling")); + Assertions.assertNull(storeItem.getFilling()); + Assertions.assertTrue(storeItem.setFilling("FILX")); + Assertions.assertEquals("Cream Cheese Filling", storeItem.getFilling().getName()); + + } + + @Test + void getBagelFromSKU() { + Assertions.assertEquals("Plain Bagel", StoreItem.getBagelFromSKU("BGLP").getName()); + Assertions.assertNull(StoreItem.getBagelFromSKU("now a bagel")); + Assertions.assertEquals("Sesame Bagel", StoreItem.getBagelFromSKU("BGLS").getName()); + } + + @Test + void getStoreItemPrices() { + var bagels = StoreItem.getStoreItemPrices(); + Assertions.assertEquals(8, bagels.size()); + } + +} diff --git a/src/test/java/com/booleanuk/core/StoreManagerTest.java b/src/test/java/com/booleanuk/core/StoreManagerTest.java new file mode 100644 index 000000000..def5cd703 --- /dev/null +++ b/src/test/java/com/booleanuk/core/StoreManagerTest.java @@ -0,0 +1,22 @@ +package com.booleanuk.core; + +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; + +import static org.junit.jupiter.api.Assertions.*; + +class StoreManagerTest { + + @Test + void getBasketSize() { + Assertions.assertEquals(25, StoreManager.getBasketSize());; + } + + @Test + void setBasketSize() { + Assertions.assertTrue(StoreManager.setBasketSize(2, true)); + Assertions.assertEquals(2, StoreManager.getBasketSize()); + + + } +} \ No newline at end of file diff --git a/src/test/java/com/booleanuk/extension/ExtentionBasketTest.java b/src/test/java/com/booleanuk/extension/ExtentionBasketTest.java new file mode 100644 index 000000000..bbf027c9a --- /dev/null +++ b/src/test/java/com/booleanuk/extension/ExtentionBasketTest.java @@ -0,0 +1,60 @@ +package com.booleanuk.extension; + +import com.booleanuk.core.PlainBagel; +import com.booleanuk.core.StoreManager; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; + +class ExtentionBasketTest { + + @Test + void getTotalCost() { + ExtentionBasket basket = new ExtentionBasket(); + basket.addOrder("BGLO", 3); + basket.setFilling("BGLO", "FILH"); + Assertions.assertEquals(1.83f, basket.getTotalCost()); + basket.addOrder("BGLP", 3); + basket.setFilling("BGLP", "FILH"); + Assertions.assertEquals(3.36f, basket.getTotalCost(), 0.0001); + basket.addOrder("BGLP", 11); + Assertions.assertEquals(6.96f, basket.getTotalCost(), 0.0001); + } + + @Test + void countCostBundle() { + ExtentionBasket basket = new ExtentionBasket(); + StoreManager.setBasketSize(99, true); + basket.addOrder("BGLP", 13); + Assertions.assertEquals(4.38, basket.countCostBundle(new PlainBagel(), new BundledPlainBagle(), 13, 12), 0.001); + } + + @Test + void getReceipt() { + ExtentionBasket basket = new ExtentionBasket(); + basket.addOrder("BGLO", 3); + basket.setFilling("BGLO", "FILH"); + Assertions.assertEquals(2, basket.getReceipt().size()); + basket.addOrder("BGLP", 3); + basket.setFilling("BGLP", "FILH"); + basket.addOrder("BGLP", 11); + Assertions.assertEquals(4, basket.getReceipt().size()); + + } +// This was for me personally to test the to string :) +// @Test +// void getReceiptToString() { +// ExtentionBasket basket = new ExtentionBasket(); +// basket.addOrder("BGLO", 3); +// basket.setFilling("BGLO", "FILH"); +// basket.addOrder("BGLP", 3); +// basket.setFilling("BGLP", "FILH"); +// basket.addOrder("BGLP", 11); +// basket.addOrder("COFB", 1); +// Assertions.assertEquals("", basket.getReceiptToString()); +// +// +// } + + + +} \ No newline at end of file