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
Binary file added class_diagram.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
62 changes: 62 additions & 0 deletions domain-model.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
## Class diagram
![](./class_diagram.jpg)



### Item class
| Method | Scenario | Output |
|----------|-------------------|--------|
| `Item()` | Class constructor | - |


### Menu class
| Method | Scenario | Output |
|-------------------------------|-----------------------------------------------------|----------------|
| `getMenu()` | - | List of menu |
| `itemExists(itemId: String)` | Item exists in menu<br/>Item does not exist in menu | true<br/>false |
| `getItemMenu(itemId: String)` | Item exists in menu<br/>Item does not exist in menu | Item<br/>null |


### Basket class
| Method | Scenario | Outcome | Output |
|---------------------------------------------------------|--------------------------------------------------------------------------------------------------------------------------------------------------|----------------------------------------------------------------------------------------------------------------------------|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| `addItem(itemId: String, quantity: int)` | Item exists in menu but not in basketItems<br/>Item exists in menu and in basketItems<br/>Item does not exist in menu<br/>Basket is full | Item is added to basketItems with the correct quantity<br/>The quantity of the item in basketItems is changed<br/>- <br/>- | "'quantity' 'itemVariant' 'itemName' added to basket."<br/>"'quantity' 'itemVariant' 'itemName' added to basket."<br/>"This item is not on the menu."<br/>"Basket is full." |
| `removeItem(itemId: String, removeDuplicates: Boolean)` | Item exists in basketItems and removeDuplicates=true<br/>Item exists in basketItems and removeDuplicates=false<br/>Item does not exist in basket | Entry is removed from basketItems<br/>The quantity of the item in basketItems is subtracted 1.<br/>- | "'quantity' 'itemVariant' 'itemName's removed from basket."<br/>"'itemVariant' 'itemName' removed from basket."<br/>"This item does not exist in your basket." |
| `setBasketSize(int)` | Basket capacity is changed to a positive integer by a "manager"<br/>Basket capacity value is not positive | | Return true<br/>Return false |


### CashRegister class
| Method | Scenario | Output |
|----------------------------|------------------------------------------------------------------|---------------------------------------------------------------|
| `sumOrder()` | basketItems is not empty<br/>basketItems is empty | "The sum of your order is: 'sum'"<br/>"Your basket is empty." |
| `getDiscountBagel()` | 12 or more bagels of same type<br/>6 or more bagels of same type | Discounted price is 3.99<br/>Discounted price is 2.49 |
| `getDiscountCoffeeBagel()` | Minimum one coffee and one bagel remaining in basket | Discounted price is 1.25 |
| `getRemainingSum()` | Remaining items in basket | Calculate price |


### Receipt interface
| Method | Scenario | Output |
|-----------------------------------------------------------------|------------------------------------------------------|--------------------------|
| `getReceiptLine(itemName: String, quantity: int, price: float)` | Minimum one coffee and one bagel remaining in basket | Discounted price is 1.25 |
| `getDiscountedSum()` | Remaining items in basket | Calculate price |
| `createFinalReceipt()` | | |
| `printReceipt()` | | |
| `getFinalReceipt()` | | |


### NormalReceipt class (implements Receipt)
| Method | Scenario | Output |
|-----------------------------------------------------------------|------------------------------------------------------------------|---------------------------------------------------------------|


### DiscountReceipt class (implements Receipt)
| Method | Scenario | Output |
|-----------------------------------------------------------------|------------------------------------------------------------------|---------------------------------------------------------------|



### Assumptions:

- Fillings can be added regardless of the presence of a bagel in the basket.
- Fillings, coffee, and bagels count toward the maximum basket size.
- The "manager" role is purely fictional and not actually implemented
94 changes: 94 additions & 0 deletions src/main/java/com/booleanuk/core/Basket.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
package com.booleanuk.core;

import java.util.HashMap;

import static com.booleanuk.core.Menu.*;

public class Basket {
private int maxBasketSize;
private HashMap<String, Integer> basketItems;


public Basket(){
this.maxBasketSize = 15;
this.basketItems = new HashMap<>();
}

public HashMap<String, Integer> getBasketItems(){
return this.basketItems;
}

public void setBasketItems(HashMap<String, Integer> basketItems) {
this.basketItems = basketItems;
}

public Boolean setMaxBasketSize(int size){
if (size<0){
return false;
}
this.maxBasketSize = size;
return true;
}

public int getMaxBasketSize(){
return this.maxBasketSize;
}

public int getBasketSize(){
if (basketItems.isEmpty()){
return 0;
}

int basketSize = 0;
for (HashMap.Entry<String, Integer> entry : basketItems.entrySet()){
basketSize += entry.getValue();
}
return basketSize;
}

public boolean isEmpty(){
return getBasketSize() == 0;
}


public String addItem(String itemId, int quantity) {
if (getBasketSize() == maxBasketSize){
return "Basket is full.";
}

if (!itemExistsMenu(itemId)){
return "This item is not on the menu.";
}

basketItems.merge(itemId, quantity, Integer::sum);
Item item = getMenuItem(itemId);

return quantity + " " + item.getItemVariant()
+ " " + item.getItemName() + " added to basket.";
}


public String removeItem(String itemId, Boolean removeDuplicates){

if (!basketItems.containsKey(itemId)){
return "This item does not exist in your basket.";
}

Item item = getMenuItem(itemId);
int quantity = basketItems.get(itemId);

if (quantity==0){
basketItems.remove(itemId);
return "This item does not exist in your basket.";
}

if (removeDuplicates){
basketItems.remove(itemId);
return quantity + " " + item.getItemVariant() + " " + item.getItemName() + " removed from basket.";
}

basketItems.merge(itemId, -1, Integer::sum);
return "1 " + item.getItemVariant() + " " + item.getItemName() + " removed from basket.";
}

}
162 changes: 162 additions & 0 deletions src/main/java/com/booleanuk/core/CashRegister.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,162 @@
package com.booleanuk.core;

import java.util.HashMap;

import static com.booleanuk.core.Menu.*;


public class CashRegister {
Basket basket;
Receipt receipt;
private float discountedSum = 0;
private float totalDiscount = 0;

public CashRegister(Basket basket, Receipt receipt){
this.basket = basket;
this.receipt = receipt;
}

public void printReceipt(){
sumOrder();
receipt.createFinalReceipt();
receipt.printReceipt();

}

public String sumOrder() {
discountedSum = 0;
totalDiscount = 0;

if (basket.isEmpty()) {
return "Your basket is empty.";
}

if (!basket.isEmpty()){
getDiscountBagel();
}
if (!basket.isEmpty()) {
getDiscountCoffeeBagel();
}
if (!basket.isEmpty()) {
getRemainingSum();
}

receipt.getDiscountedSum(discountedSum);
receipt.setTotalSaved(totalDiscount);

return "The sum of your order is: " + String.format("%.2f", discountedSum);
}

public void getDiscountBagel(){
for (HashMap.Entry<String, Integer> entry : basket.getBasketItems().entrySet()){
Item bagel = getMenuItem(entry.getKey());

if (bagel.getItemName().equals("Bagel")){
int bagelOfferCount = 0;
int twelveOfferCount = 0;
int sixOfferCount = 0;
while (entry.getValue() >= 12){
discountedSum += 3.99f;

for (int i = 0; i<12; i++){
basket.removeItem(bagel.getItemSKU(), false);
}
bagelOfferCount += 12;
twelveOfferCount++;
}

while (entry.getValue() >= 6){
discountedSum += 2.49f;

for (int i = 0; i<6; i++){
basket.removeItem(bagel.getItemSKU(), false);
}
bagelOfferCount += 6;
sixOfferCount++;
}
if (bagelOfferCount>0){
float totalDiscountPrice = sixOfferCount*2.49f + twelveOfferCount*3.99f;
float priceWithoutDiscount = bagelOfferCount*bagel.getItemPrice();
float saved = priceWithoutDiscount-totalDiscountPrice;
String fullName = bagel.getItemVariant() + " " + bagel.getItemName();
receipt.addReceiptLine(fullName, bagelOfferCount, totalDiscountPrice);
receipt.addReceiptLine("", 0, saved);
totalDiscount += saved;
}
}
}
}

public void getDiscountCoffeeBagel(){
int bagelCount = 0;
int coffeeCount = 0;

for (HashMap.Entry<String, Integer> entry : basket.getBasketItems().entrySet()) {
Item item = getMenuItem(entry.getKey());

if (item.getItemName().equals("Bagel")){
bagelCount += entry.getValue();
}

if (item.getItemName().equals("Coffee")){
coffeeCount += entry.getValue();
}
}
int coffeeBagelOffer = 0;

float coffeePrice = 0;
float bagelPrice = 0;
while (bagelCount!=0 && coffeeCount!=0){
for (HashMap.Entry<String, Integer> entry : basket.getBasketItems().entrySet()){
Item bagel = getMenuItem(entry.getKey());

if (bagel.getItemName().equals("Bagel") && entry.getValue()!= 0){
bagelPrice = bagel.getItemPrice();
basket.removeItem(bagel.getItemSKU(), false);
break;
}
}

for (HashMap.Entry<String, Integer> entry2 : basket.getBasketItems().entrySet()){
Item coffee = getMenuItem(entry2.getKey());

if (coffee.getItemName().equals("Coffee") && entry2.getValue()!= 0){
coffeePrice = coffee.getItemPrice();
discountedSum += 1.25f;
basket.removeItem(coffee.getItemSKU(), false);
coffeeBagelOffer++;
break;
}
}
bagelCount--;
coffeeCount--;
}

if (coffeeBagelOffer>0){
String offerName = "Coffee & Bagel";
float originalSum = coffeePrice+bagelPrice;
float saved = originalSum - 1.25f;
receipt.addReceiptLine(offerName, coffeeBagelOffer, 1.25f*coffeeBagelOffer);
receipt.addReceiptLine("", 0, saved);
totalDiscount+=saved;
}
}

public void getRemainingSum(){
for (HashMap.Entry<String, Integer> entry : basket.getBasketItems().entrySet()){
if (entry.getValue() != 0){
Item item = getMenuItem(entry.getKey());
int quantity = entry.getValue();
float price = item.getItemPrice();

discountedSum += quantity*price;
String fullName = item.getItemVariant() + " " + item.getItemName();
receipt.addReceiptLine(fullName, quantity, quantity*price);

for (int i = 0; i < quantity; i++){
basket.removeItem(entry.getKey(), false);
}
}
}
}
}
69 changes: 69 additions & 0 deletions src/main/java/com/booleanuk/core/DiscountReceipt.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
package com.booleanuk.core;

import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;

public class DiscountReceipt implements Receipt{
private ArrayList<String> receiptLines;
private LocalDateTime dateTime;
private float totalSum;
private ArrayList<String> finalReceipt;
private float totalSaved;

public DiscountReceipt(){
this.receiptLines = new ArrayList<>();
this.finalReceipt = new ArrayList<>();
this.totalSum = 0;
this.totalSaved = 0;
}

public void setTotalSaved(float totalSaved) {
this.totalSaved = totalSaved;
}

public ArrayList<String> getFinalReceipt() {
return finalReceipt;
}

public void addReceiptLine(String itemName, int quantity, float price) {
if (price != 0 && quantity != 0){
this.receiptLines.add(String.format("%-18s %3s %8s", itemName, quantity, "$"+price));
}
else if (quantity == 0 && price != 0){
this.receiptLines.add(String.format("%-18s %3s %8s", "", "", "(-$"+String.format("%.2f", price)+")"));
}

}


public void getDiscountedSum(float sum) {
this.totalSum = sum;
}


public void createFinalReceipt() {
dateTime = LocalDateTime.now();
this.finalReceipt.add(String.format("%-8s %10s", " ", "~Bob's Bagels~"));
this.finalReceipt.add(String.format("%-5s %10s", " ", dateTime.format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"))));
this.finalReceipt.add("-------------------------------");
this.finalReceipt.add(" ");
this.finalReceipt.addAll(receiptLines);
this.finalReceipt.add(" ");
this.finalReceipt.add("-------------------------------");
this.finalReceipt.add(String.format("%-15s %2s %12s", "Total", " ", "$"+totalSum));
this.finalReceipt.add(" ");
this.finalReceipt.add(String.format("%-10s %4s", " You saved a total of ", "$"+String.format("%.2f", totalSaved)));
this.finalReceipt.add(String.format("%-10s %10s", " ", "on this shop"));
this.finalReceipt.add(" ");
this.finalReceipt.add(String.format("%-10s %10s", " ", "Thank you"));
this.finalReceipt.add(String.format("%-7s %16s", " ", "for your order!"));
}


public void printReceipt() {
for (String s : finalReceipt){
System.out.println(s);
}
}
}
Loading