diff --git a/.idea/encodings.xml b/.idea/encodings.xml new file mode 100644 index 0000000..aa00ffa --- /dev/null +++ b/.idea/encodings.xml @@ -0,0 +1,7 @@ + + + + + + + \ No newline at end of file diff --git a/.idea/misc.xml b/.idea/misc.xml index 4b151ab..efb1e13 100644 --- a/.idea/misc.xml +++ b/.idea/misc.xml @@ -1,6 +1,14 @@ - + + + + + \ No newline at end of file diff --git a/.idea/vcs.xml b/.idea/vcs.xml new file mode 100644 index 0000000..35eb1dd --- /dev/null +++ b/.idea/vcs.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/pom.xml b/pom.xml index f21bb22..1a42885 100644 --- a/pom.xml +++ b/pom.xml @@ -13,5 +13,18 @@ 21 UTF-8 + + + + org.apache.maven.plugins + maven-compiler-plugin + + 21 + 21 + --enable-preview + + + + \ No newline at end of file diff --git a/src/main/java/org/codedifferently/Main.java b/src/main/java/org/codedifferently/Main.java deleted file mode 100644 index 435139b..0000000 --- a/src/main/java/org/codedifferently/Main.java +++ /dev/null @@ -1,17 +0,0 @@ -package org.codedifferently; - -//TIP To Run code, press or -// click the icon in the gutter. -public class Main { - public static void main(String[] args) { - //TIP Press with your caret at the highlighted text - // to see how IntelliJ IDEA suggests fixing it. - System.out.printf("Hello and welcome!"); - - for (int i = 1; i <= 5; i++) { - //TIP Press to start debugging your code. We have set one breakpoint - // for you, but you can always add more by pressing . - System.out.println("i = " + i); - } - } -} \ No newline at end of file diff --git a/src/main/java/org/codedifferently/cafedebleu/CoffeeItem.java b/src/main/java/org/codedifferently/cafedebleu/CoffeeItem.java new file mode 100644 index 0000000..51f9b4d --- /dev/null +++ b/src/main/java/org/codedifferently/cafedebleu/CoffeeItem.java @@ -0,0 +1,38 @@ +package org.codedifferently.cafedebleu; + +public class CoffeeItem { + + private String name; + private double price; + + public CoffeeItem(String name, double price) { + this.name = name; + this.price = price; + } + + public String getName() { + return name; // + } + + public void setName(String name) { // Setter for name (controlled update) + if (name != null && !name.isBlank()) { // Validate: must not be null/blank + this.name = name; + } + } + + public double getPrice() { // Getter for price + return price; // Return the private field safely + } + + public void setPrice(double price) { // Setter for price (controlled update) + if (price >= 0) { // Validate: price cannot be negative + this.price = price; // Update the field + } + } + + @Override // We are overriding Java’s default toString() + public String toString() { // How this object prints as text + return String.format("%s - $%.2f", name, price); // Example: Latte - $5.50 + } + } + diff --git a/src/main/java/org/codedifferently/cafedebleu/Customer.java b/src/main/java/org/codedifferently/cafedebleu/Customer.java new file mode 100644 index 0000000..5afdcf5 --- /dev/null +++ b/src/main/java/org/codedifferently/cafedebleu/Customer.java @@ -0,0 +1,89 @@ +package org.codedifferently.cafedebleu; + + + +public class Customer { + private String name; + private String email; + + private int drinksPurchased; + private int lifetimeDrinks; + + // Tiers + public enum Tier { + BRONZE, SILVER, GOLD, PLATINUM + } + + // Constructor + public Customer(String name, String email) { + this.name = name; + this.email = email; + this.drinksPurchased = 0; + this.lifetimeDrinks = 0; + } + + // Getters + public int getLifetimeDrinks() { + return lifetimeDrinks; + } + + public int getDrinksPurchased() { + return drinksPurchased; + } + + public String getEmail() { + return email; + } + + public String getName() { + return name; + } + + // Determine tier based on lifetime drinks + public Tier getTier() { + if (lifetimeDrinks >= 50) + return Tier.PLATINUM; + if (lifetimeDrinks >= 25) + return Tier.GOLD; + if (lifetimeDrinks >= 10) + return Tier.SILVER; + return Tier.BRONZE; + } + + // Threshold for reward based on tier + public int getReward() { + return switch (getTier()) { + case BRONZE -> 5; + case SILVER -> 4; + case GOLD -> 3; + case PLATINUM -> 2; + }; + } + + // Add paid drinks + public void incrementDrinksPurchased(int amount) { + if (amount > 0) { + drinksPurchased += amount; + lifetimeDrinks += amount; + } + } + + // Add bonus progress (Golden Ticket) + public void addBonusProgress(int amount) { + if (amount > 0) { + drinksPurchased += amount; + } + } + + // Check if eligible for reward + public boolean isEligibleForReward() { + return drinksPurchased >= getReward(); + } + + // Redeem reward + public void redeemReward() { + if (isEligibleForReward()) { + drinksPurchased -= getReward(); + } + } +} \ No newline at end of file diff --git a/src/main/java/org/codedifferently/cafedebleu/Main.java b/src/main/java/org/codedifferently/cafedebleu/Main.java new file mode 100644 index 0000000..b2116a4 --- /dev/null +++ b/src/main/java/org/codedifferently/cafedebleu/Main.java @@ -0,0 +1,180 @@ +package org.codedifferently.cafedebleu; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Scanner; + +public class Main { + public static void main(String[] args) { + + Scanner scanner = new Scanner(System.in); + + System.out.println("============Welcome to Cafe De Bleu================="); + + + // -------- Menu Items -------- + List menu = new ArrayList<>(); + menu.add(new CoffeeItem("Drip Coffee", 3.25)); + menu.add(new CoffeeItem("Latte", 5.50)); + menu.add(new CoffeeItem("Cold Brew", 4.75)); + menu.add(new CoffeeItem("Mocha", 6.25)); + menu.add(new CoffeeItem("Caramel Macchiato", 6.75)); + + // -------- Remember Customers (stored from input only) -------- + Map customersByEmail = new HashMap<>(); + + System.out.println("=== The Cafe De Bleu Rewards (Tiered + Saved Customers) ==="); + + boolean shopOpen = true; + + while (shopOpen) { + System.out.println("\n1) Purchase (New/Returning Customer)"); + System.out.println("2) Look Up Customer Rewards"); + System.out.println("3) List All Customers"); + System.out.println("4) Close Shop"); + + int option = readIntInRange(scanner, "Choose: ", 1, 4); + + // ---- Option 4: Close Shop ---- + if (option == 4) { + shopOpen = false; + break; + } + + // ---- Option 3: List All Customers ---- + if (option == 3) { + if (customersByEmail.isEmpty()) { + System.out.println("No customers saved yet."); + } else { + System.out.println("\n--- Saved Customers ---"); + for (Customer cust : customersByEmail.values()) { + System.out.println( + cust.getName() + " | " + cust.getEmail() + + " | Tier: " + cust.getTier() + + " | Progress: " + cust.getDrinksPurchased() + + " | Lifetime: " + cust.getLifetimeDrinks() + ); + } + } + continue; // back to main menu loop + } + + // ---- Option 2: Look Up Customer Rewards ---- + if (option == 2) { + String lookupEmail = readNonEmpty(scanner, "Enter email: ").toLowerCase(); + Customer found = customersByEmail.get(lookupEmail); + + if (found == null) { + System.out.println("No customer found with that email yet."); + } else { + System.out.println("Customer: " + found.getName()); + System.out.println("Email: " + found.getEmail()); + System.out.println("Tier: " + found.getTier()); + System.out.println("Threshold: " + found.getReward() + " paid drinks"); + System.out.println("Progress: " + found.getDrinksPurchased()); + System.out.println("Lifetime: " + found.getLifetimeDrinks()); + System.out.println("Eligible now? " + (found.isEligibleForReward() ? "YES" : "NO")); + } + continue; // back to main menu loop + } + + // ---- Option 1: Purchase Flow ---- + String email = readNonEmpty(scanner, "Customer email: ").toLowerCase(); + + // Try to load an existing customer + Customer customer = customersByEmail.get(email); + + // If not found, create customer from input and save + if (customer == null) { + String name = readNonEmpty(scanner, "Customer name: "); + customer = new Customer(name, email); + customersByEmail.put(email, customer); + System.out.println("New customer saved!"); + } else { + System.out.println("Welcome back, " + customer.getName() + "!"); + } + + // Show current loyalty status + System.out.println("Tier: " + customer.getTier()); + System.out.println("Free drink after " + customer.getReward() + " paid drinks."); + System.out.println("Current progress: " + customer.getDrinksPurchased()); + + // Show menu + System.out.println("\n--- MENU ---"); + for (int i = 0; i < menu.size(); i++) { + System.out.printf("%d) %s%n", i + 1, menu.get(i)); + } + + int itemChoice = readIntInRange(scanner, "Select a drink: ", 1, menu.size()); + CoffeeItem item = menu.get(itemChoice - 1); + + int qty = readIntInRange(scanner, "How many? (1-20): ", 1, 20); + + double fullPrice = item.getPrice() * qty; + double total; + + // Reward pricing: 1 free drink if eligible + if (customer.isEligibleForReward()) { + total = fullPrice - item.getPrice(); // one drink free + customer.redeemReward(); // subtract tier threshold from progress + System.out.println("Reward applied! 1 drink is FREE."); + } else { + total = fullPrice; + } + + // Count paid drinks only + int paidDrinks = (total < fullPrice) ? (qty - 1) : qty; + + // Paid drinks increase progress + lifetime + customer.incrementDrinksPurchased(paidDrinks); + + // Golden Ticket: spend > $20 => bonus progress point (not lifetime) + if (total > 20.0) { + customer.addBonusProgress(1); + System.out.println("Golden Ticket! +1 bonus progress toward next reward."); + } + + // Receipt + System.out.println("\n--- Receipt ---"); + System.out.println("Customer: " + customer.getName()); + System.out.println("Item: " + item.getName()); + System.out.println("Quantity: " + qty); + System.out.printf("Total due: $%.2f%n", total); + System.out.println("Tier now: " + customer.getTier()); + System.out.println("Progress now: " + customer.getDrinksPurchased()); + System.out.println("Lifetime drinks: " + customer.getLifetimeDrinks()); + System.out.println("Eligible next? " + (customer.isEligibleForReward() ? "YES" : "NO")); + } + + System.out.println("\nShop closed. Have a good day, Goodbye!"); + scanner.close(); + } + + // -------- Input Validation Helpers -------- + private static int readIntInRange(Scanner scanner, String prompt, int min, int max) { + while (true) { + System.out.print(prompt); + String input = scanner.nextLine().trim(); + try { + int value = Integer.parseInt(input); + if (value < min || value > max) { + System.out.printf("Enter a number between %d and %d.%n", min, max); + continue; + } + return value; + } catch (NumberFormatException e) { + System.out.println("Invalid number. Try again."); + } + } + } + + private static String readNonEmpty(Scanner scanner, String prompt) { + while (true) { + System.out.print(prompt); + String s = scanner.nextLine().trim(); + if (!s.isEmpty()) return s; + System.out.println("Input cannot be empty. Try again."); + } } + }