diff --git a/.idea/.gitignore b/.idea/.gitignore new file mode 100644 index 0000000..ab1f416 --- /dev/null +++ b/.idea/.gitignore @@ -0,0 +1,10 @@ +# Default ignored files +/shelf/ +/workspace.xml +# Ignored default folder with query files +/queries/ +# Datasource local storage ignored files +/dataSources/ +/dataSources.local.xml +# Editor-based HTTP Client requests +/httpRequests/ diff --git a/.idea/compiler.xml b/.idea/compiler.xml new file mode 100644 index 0000000..bf2c501 --- /dev/null +++ b/.idea/compiler.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file 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/inspectionProfiles/Project_Default.xml b/.idea/inspectionProfiles/Project_Default.xml new file mode 100644 index 0000000..5cb71ef --- /dev/null +++ b/.idea/inspectionProfiles/Project_Default.xml @@ -0,0 +1,6 @@ + + + + \ No newline at end of file diff --git a/.idea/jarRepositories.xml b/.idea/jarRepositories.xml new file mode 100644 index 0000000..712ab9d --- /dev/null +++ b/.idea/jarRepositories.xml @@ -0,0 +1,20 @@ + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/misc.xml b/.idea/misc.xml new file mode 100644 index 0000000..4efc77f --- /dev/null +++ b/.idea/misc.xml @@ -0,0 +1,12 @@ + + + + + + + + \ 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/database.sql b/database.sql index 2169346..0ca07ca 100644 --- a/database.sql +++ b/database.sql @@ -8,7 +8,10 @@ -- 5. Insert at least 3 menu items. -- 6. The script should be executable from start to finish without errors. - +DROP TABLE IF EXISTS order_details CASCADE; +DROP TABLE IF EXISTS orders CASCADE; +DROP TABLE IF EXISTS menu_items CASCADE; +DROP TABLE IF EXISTS users CASCADE; -- ======================================================= -- USER TABLE @@ -30,6 +33,12 @@ -- -- CREATE TABLE ... +CREATE TABLE users ( + id SERIAL PRIMARY KEY, + username VARCHAR(50) NOT NULL UNIQUE, + password VARCHAR(255) NOT NULL, + email VARCHAR(100) +); -- ======================================================= @@ -52,7 +61,13 @@ -- -- CREATE TABLE ... - +CREATE TABLE menu_items ( + id SERIAL PRIMARY KEY, + name VARCHAR(100) NOT NULL, + description TEXT, + price DECIMAL(10, 2) NOT NULL CHECK (price > 0), + category VARCHAR(50) +); -- ======================================================= -- ORDER TABLE @@ -77,7 +92,13 @@ -- -- CREATE TABLE ... - +CREATE TABLE orders ( + id SERIAL PRIMARY KEY, + user_id INT NOT NULL, + order_date TIMESTAMP DEFAULT CURRENT_TIMESTAMP, + total_amount DECIMAL(10, 2) NOT NULL DEFAULT 0.00 CHECK (total_amount >= 0), + CONSTRAINT fk_order_user FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE + ); -- ======================================================= -- ORDER DETAIL TABLE @@ -100,7 +121,15 @@ -- -- CREATE TABLE ... - +CREATE TABLE order_details ( + id SERIAL PRIMARY KEY, + order_id INT NOT NULL, + menu_item_id INT NOT NULL, + quantity INT NOT NULL CHECK (quantity > 0), + price_at_purchase DECIMAL(10, 2) NOT NULL CHECK (price_at_purchase > 0), + CONSTRAINT fk_detail_order FOREIGN KEY (order_id) REFERENCES orders(id) ON DELETE CASCADE, + CONSTRAINT fk_detail_menu FOREIGN KEY (menu_item_id) REFERENCES menu_items(id) ON DELETE RESTRICT +); -- ======================================================= -- INITIAL MENU DATA @@ -116,7 +145,11 @@ -- -- INSERT INTO ... - +INSERT INTO menu_items (name, description, price, category) VALUES +('Pizza', 'Delicious cheese and pepperoni pizza', 10.00, 'Pizza'), +('Burger', 'Juicy grilled beef burger with fries', 8.00, 'Burger'), +('Pasta', 'Creamy Alfredo pasta with chicken', 12.00, 'Pasta'), +('Coca Cola', 'Chilled soft drink', 2.50, 'Drink'); -- ======================================================= -- OPTIONAL TEST DATA @@ -127,7 +160,14 @@ -- -- INSERT INTO ... +INSERT INTO users (username, password, email) VALUES +('fatemeh_demo', '$2a$10$EixZaYVK1upmZ7zpKgH97O5F', 'fatemeh@example.com'); +INSERT INTO orders (user_id, total_amount) VALUES +(1, 20.00); + +INSERT INTO order_details (order_id, menu_item_id, quantity, price_at_purchase) VALUES +(1, 1, 2, 10.00); -- ======================================================= -- VERIFICATION QUERIES @@ -135,7 +175,7 @@ -- -- Uncomment these queries to verify your database. -- --- SELECT * FROM ...; --- SELECT * FROM ...; --- SELECT * FROM ...; --- SELECT * FROM ...; \ No newline at end of file +SELECT * FROM users; +SELECT * FROM menu_items; +SELECT * FROM orders; +SELECT * FROM orders; \ No newline at end of file diff --git a/src/main/java/dev/dao/MenuItemDao.java b/src/main/java/dev/dao/MenuItemDao.java index 3bbebe9..50b5cc3 100644 --- a/src/main/java/dev/dao/MenuItemDao.java +++ b/src/main/java/dev/dao/MenuItemDao.java @@ -3,6 +3,10 @@ package dev.dao; import dev.model.MenuItem; import java.util.List; +import dev.database.DatabaseConnection; +import java.lang.reflect.Field; +import java.sql.*; +import java.util.ArrayList; public class MenuItemDao { @@ -10,16 +14,61 @@ public class MenuItemDao { // TODO: // Retrieve all menu items - - return null; + List items = new ArrayList<>(); + String sql = "SELECT * FROM menu_items"; + try (Connection conn = DatabaseConnection.getConnection(); PreparedStatement stmt = conn.prepareStatement(sql); ResultSet rs = stmt.executeQuery()){ + while (rs.next()) { + MenuItem item = new MenuItem(); + mapResultSetToMenuItem(rs, item); + items.add(item); + } + } + catch (SQLException ex){ + ex.printStackTrace(); + } + return items; } public MenuItem findById(int id) { // TODO: // Find menu item by id - + String sql = "SELECT * FROM menu_items WHERE id = ?"; + try (Connection conn = DatabaseConnection.getConnection(); PreparedStatement stmt = conn.prepareStatement(sql)){ + stmt.setInt(1, id); + try (ResultSet rs = stmt.executeQuery()){ + if (rs.next()){ + MenuItem item = new MenuItem(); + mapResultSetToMenuItem(rs, item); + return item; + } + } + } + catch (SQLException ex){ + ex.printStackTrace(); + } return null; } - + private void mapResultSetToMenuItem(ResultSet rs, MenuItem item){ + try { + Field idField = MenuItem.class.getDeclaredField("id"); + Field nameField = MenuItem.class.getDeclaredField("name"); + Field descField = MenuItem.class.getDeclaredField("description"); + Field priceField = MenuItem.class.getDeclaredField("price"); + Field catField = MenuItem.class.getDeclaredField("category"); + idField.setAccessible(true); + nameField.setAccessible(true); + descField.setAccessible(true); + priceField.setAccessible(true); + catField.setAccessible(true); + idField.set(item, rs.getInt("id")); + nameField.set(item, rs.getString("name")); + descField.set(item, rs.getString("description")); + priceField.set(item, rs.getDouble("price")); + catField.set(item, rs.getString("category")); + } + catch (Exception ex){ + ex.printStackTrace(); + } + } } \ No newline at end of file diff --git a/src/main/java/dev/dao/OrderDao.java b/src/main/java/dev/dao/OrderDao.java index 00999a2..a816e81 100644 --- a/src/main/java/dev/dao/OrderDao.java +++ b/src/main/java/dev/dao/OrderDao.java @@ -3,6 +3,10 @@ package dev.dao; import dev.model.Order; import java.util.List; +import dev.database.DatabaseConnection; +import java.lang.reflect.Field; +import java.sql.*; +import java.util.ArrayList; public class OrderDao { @@ -10,6 +14,25 @@ public class OrderDao { // TODO: // Insert order and return generated id + String sql = "INSERT INTO orders (user_id, total_amount) VALUES (?, ?)"; + try (Connection conn = DatabaseConnection.getConnection(); PreparedStatement stmt = conn.prepareStatement(sql, Statement.RETURN_GENERATED_KEYS)){ + Field userIdField = Order.class.getDeclaredField("userId"); + Field totalPriceField = Order.class.getDeclaredField("totalPrice"); + userIdField.setAccessible(true); + totalPriceField.setAccessible(true); + stmt.setInt(1, (int) userIdField.get(order)); + stmt.setDouble(2, (double) totalPriceField.get(order)); + stmt.executeUpdate(); + + try (ResultSet generatedKeys = stmt.getGeneratedKeys()){ + if (generatedKeys.next()){ + return generatedKeys.getInt(1); + } + } + } + catch (SQLException | NoSuchFieldException | IllegalAccessException ex){ + ex.printStackTrace(); + } return -1; } @@ -18,8 +41,37 @@ public class OrderDao { // TODO: // Retrieve all orders of a user + List orders = new ArrayList<>(); + String sql = "SELECT * FROM orders WHERE user_id = ? ORDER BY order_date DESC"; + try (Connection conn = DatabaseConnection.getConnection(); PreparedStatement stmt = conn.prepareStatement(sql)){ + stmt.setInt(1, userId); + try (ResultSet rs = stmt.executeQuery()){ + while (rs.next()){ + Order order = new Order(); + Field idField = Order.class.getDeclaredField("id"); + Field userIdField = Order.class.getDeclaredField("userId"); + Field createdAtField = Order.class.getDeclaredField("createdAt"); + Field totalPriceField = Order.class.getDeclaredField("totalPrice"); + idField.setAccessible(true); + userIdField.setAccessible(true); + createdAtField.setAccessible(true); + totalPriceField.setAccessible(true); + idField.set(order, rs.getInt("id")); + userIdField.set(order, rs.getInt("user_id")); + Timestamp timestamp = rs.getTimestamp("order_date"); + if (timestamp != null){ + createdAtField.set(order, timestamp.toLocalDateTime()); + } - return null; + totalPriceField.set(order, rs.getDouble("total_amount")); + orders.add(order); + } + } + } + catch(SQLException | NoSuchFieldException | IllegalAccessException ex){ + ex.printStackTrace(); + } + return orders; } } \ No newline at end of file diff --git a/src/main/java/dev/dao/OrderDetailDao.java b/src/main/java/dev/dao/OrderDetailDao.java index ed42f56..526021e 100644 --- a/src/main/java/dev/dao/OrderDetailDao.java +++ b/src/main/java/dev/dao/OrderDetailDao.java @@ -3,6 +3,10 @@ package dev.dao; import dev.model.OrderDetail; import java.util.List; +import dev.database.DatabaseConnection; +import java.lang.reflect.Field; +import java.sql.*; +import java.util.ArrayList; public class OrderDetailDao { @@ -10,15 +14,61 @@ public class OrderDetailDao { // TODO: // Insert order detail - + String sql = "INSERT INTO order_details (order_id, menu_item_id, quantity, price_at_purchase) VALUES (?, ?, ?, ?)"; + try (Connection conn = DatabaseConnection.getConnection(); PreparedStatement stmt = conn.prepareStatement(sql)){ + Field orderIdField = OrderDetail.class.getDeclaredField("orderId"); + Field menuItemIdField = OrderDetail.class.getDeclaredField("menuItemId"); + Field quantityField = OrderDetail.class.getDeclaredField("quantity"); + Field priceField = OrderDetail.class.getDeclaredField("price"); + orderIdField.setAccessible(true); + menuItemIdField.setAccessible(true); + quantityField.setAccessible(true); + priceField.setAccessible(true); + stmt.setInt(1, (int) orderIdField.get(detail)); + stmt.setInt(2, (int) menuItemIdField.get(detail)); + stmt.setInt(3, (int) quantityField.get(detail)); + stmt.setDouble(4, (double) priceField.get(detail)); + stmt.executeUpdate(); + } + catch (SQLException | NoSuchFieldException | IllegalAccessException ex){ + ex.printStackTrace(); + } } public List findByOrderId(int orderId) { // TODO: // Retrieve order details - - return null; + List details = new ArrayList<>(); + String sql = "SELECT * FROM order_details WHERE order_id = ?"; + try (Connection conn = DatabaseConnection.getConnection(); PreparedStatement stmt = conn.prepareStatement(sql)){ + stmt.setInt(1, orderId); + try (ResultSet rs = stmt.executeQuery()){ + while (rs.next()){ + OrderDetail detail = new OrderDetail(); + Field idField = OrderDetail.class.getDeclaredField("id"); + Field ordIdField = OrderDetail.class.getDeclaredField("orderId"); + Field itemField = OrderDetail.class.getDeclaredField("menuItemId"); + Field qtyField = OrderDetail.class.getDeclaredField("quantity"); + Field prcField = OrderDetail.class.getDeclaredField("price"); + idField.setAccessible(true); + ordIdField.setAccessible(true); + itemField.setAccessible(true); + qtyField.setAccessible(true); + prcField.setAccessible(true); + idField.set(detail, rs.getInt("id")); + ordIdField.set(detail, rs.getInt("order_id")); + itemField.set(detail, rs.getInt("menu_item_id")); + qtyField.set(detail, rs.getInt("quantity")); + prcField.set(detail, rs.getDouble("price_at_purchase")); + details.add(detail); + } + } + } + catch (SQLException | NoSuchFieldException | IllegalAccessException ex){ + ex.printStackTrace(); + } + return details; } } \ No newline at end of file diff --git a/src/main/java/dev/dao/UserDao.java b/src/main/java/dev/dao/UserDao.java index af08106..5ba18b7 100644 --- a/src/main/java/dev/dao/UserDao.java +++ b/src/main/java/dev/dao/UserDao.java @@ -1,6 +1,9 @@ package dev.dao; import dev.model.User; +import dev.database.DatabaseConnection; +import java.lang.reflect.Field; +import java.sql.*; public class UserDao { @@ -8,14 +11,56 @@ public class UserDao { // TODO: // Insert user into database + String sql = "insert into users (username, password, email) values (?, ?, ?) "; + try (Connection conn = DatabaseConnection.getConnection(); PreparedStatement stmt = conn.prepareStatement(sql)){ + Field usernameField = User.class.getDeclaredField("username"); + Field passwordField = User.class.getDeclaredField("password"); + Field emailField = User.class.getDeclaredField("email"); + usernameField.setAccessible(true); + passwordField.setAccessible(true); + emailField.setAccessible(true); + stmt.setString(1, (String) usernameField.get(user)); + stmt.setString(2, (String) passwordField.get(user)); + stmt.setString(3, (String) emailField.get(user)); - return false; + int rowsInserted = stmt.executeUpdate(); + return rowsInserted > 0; + } + catch (SQLException | NoSuchFieldException | IllegalAccessException ex){ + ex.printStackTrace(); + return false; + } } public User findByUsername(String username) { // TODO: // Find a user by username + String sql = "SELECT * FROM users WHERE username = ?"; + try (Connection conn = DatabaseConnection.getConnection(); PreparedStatement stmt = conn.prepareStatement(sql)){ + stmt.setString(1, username); + try (ResultSet rs = stmt.executeQuery()){ + if (rs.next()){ + User user = new User(); + Field idField = User.class.getDeclaredField("id"); + Field usernameField = User.class.getDeclaredField("username"); + Field passwordField = User.class.getDeclaredField("password"); + Field emailField = User.class.getDeclaredField("email"); + idField.setAccessible(true); + usernameField.setAccessible(true); + passwordField.setAccessible(true); + emailField.setAccessible(true); + idField.set(user, rs.getInt("id")); + usernameField.set(user, rs.getString("username")); + passwordField.set(user, rs.getString("password")); + emailField.set(user, rs.getString("email")); + return user; + } + } + } + catch (SQLException | NoSuchFieldException | IllegalAccessException e){ + e.printStackTrace(); + } return null; } diff --git a/src/main/java/dev/database/DatabaseConnection.java b/src/main/java/dev/database/DatabaseConnection.java index da45535..05d5cdc 100644 --- a/src/main/java/dev/database/DatabaseConnection.java +++ b/src/main/java/dev/database/DatabaseConnection.java @@ -2,6 +2,7 @@ package dev.database; import java.sql.Connection; import java.sql.SQLException; +import java.sql.DriverManager; public class DatabaseConnection { @@ -9,7 +10,7 @@ public class DatabaseConnection { private static final String USER = "postgres"; // Your Username - private static final String PASSWORD = "password"; // Your Password + private static final String PASSWORD = "angelo"; // Your Password private DatabaseConnection() { @@ -21,7 +22,7 @@ public class DatabaseConnection { // TODO: // Return a valid PostgreSQL connection - return null; + return DriverManager.getConnection(URL, USER, PASSWORD); } } \ No newline at end of file diff --git a/src/main/java/dev/service/AuthService.java b/src/main/java/dev/service/AuthService.java index bee866a..9930908 100644 --- a/src/main/java/dev/service/AuthService.java +++ b/src/main/java/dev/service/AuthService.java @@ -1,23 +1,82 @@ package dev.service; import dev.model.User; +import dev.dao.UserDao; +import java.lang.reflect.Field; +import java.security.*; public class AuthService { - + private final UserDao userDao = new UserDao(); public boolean register(String username, String password, String email) { // TODO: // Validate and register user - - return false; + if (userDao.findByUsername(username) != null){ + System.out.println("Error: Username already exists!"); + return false; + } + String hashedPassword = hashPassword(password); + if (hashedPassword == null){ + return false; + } + User user = new User(); + try { + Field usernameField = User.class.getDeclaredField("username"); + Field passwordField = User.class.getDeclaredField("password"); + Field emailField = User.class.getDeclaredField("email"); + usernameField.setAccessible(true); + passwordField.setAccessible(true); + emailField.setAccessible(true); + usernameField.set(user, username); + passwordField.set(user, hashedPassword); + emailField.set(user, email); + return userDao.save(user); + } + catch (Exception ex){ + ex.printStackTrace(); + return false; + } } public User login(String username, String password) { // TODO: // Authenticate user + User user = userDao.findByUsername(username); + if (user == null){ + return null; + } + try { + Field passwordField = User.class.getDeclaredField("password"); + passwordField.setAccessible(true); + String storedPassword = (String) passwordField.get(user); + if (storedPassword.equals(hashPassword(password))){ + return user; + } + } + catch (Exception ex){ + ex.printStackTrace(); + } return null; } - + private String hashPassword(String password){ + try { + MessageDigest digest = MessageDigest.getInstance("SHA-256"); + byte[] encodedhash = digest.digest(password.getBytes()); + StringBuilder hexString = new StringBuilder(2 * encodedhash.length); + for (byte b : encodedhash){ + String hex = Integer.toHexString(0xff & b); + if (hex.length() == 1) { + hexString.append('0'); + } + hexString.append(hex); + } + return hexString.toString(); + } + catch (NoSuchAlgorithmException ex){ + ex.printStackTrace(); + return null; + } + } } \ No newline at end of file diff --git a/src/main/java/dev/service/MenuService.java b/src/main/java/dev/service/MenuService.java index 6dbf4da..00c1695 100644 --- a/src/main/java/dev/service/MenuService.java +++ b/src/main/java/dev/service/MenuService.java @@ -1,12 +1,38 @@ package dev.service; +import dev.dao.MenuItemDao; +import dev.model.MenuItem; +import java.lang.reflect.Field; +import java.util.List; public class MenuService { - + private final MenuItemDao menuItemDao = new MenuItemDao(); public void showMenu() { // TODO: // Display menu items + List items = menuItemDao.findAll(); + System.out.println("\n--- RESTAURANT MENU ---"); + if (items.isEmpty()){ + System.out.println("No items available."); + return; + } + try { + Field idField = MenuItem.class.getDeclaredField("id"); + Field nameField = MenuItem.class.getDeclaredField("name"); + Field priceField = MenuItem.class.getDeclaredField("price"); + Field descField = MenuItem.class.getDeclaredField("description"); + idField.setAccessible(true); + nameField.setAccessible(true); + priceField.setAccessible(true); + descField.setAccessible(true); + for (MenuItem item : items){ + System.out.printf("%d. %s - $%.2f (%s)\n", idField.get(item), nameField.get(item), priceField.get(item), descField.get(item) != null ? descField.get(item) : "No description"); + } + } + catch (Exception ex){ + ex.printStackTrace(); + } } } \ No newline at end of file diff --git a/src/main/java/dev/service/OrderService.java b/src/main/java/dev/service/OrderService.java index 14708f8..80e793c 100644 --- a/src/main/java/dev/service/OrderService.java +++ b/src/main/java/dev/service/OrderService.java @@ -1,11 +1,98 @@ package dev.service; +import dev.dao.MenuItemDao; +import dev.dao.OrderDao; +import dev.dao.OrderDetailDao; +import dev.model.Order; +import dev.model.MenuItem; +import dev.model.OrderDetail; +import java.lang.reflect.Field; +import java.util.ArrayList; +import java.util.List; +import java.util.Scanner; public class OrderService { - + private final MenuItemDao menuItemDao = new MenuItemDao(); + private final OrderDao orderDao = new OrderDao(); + private final OrderDetailDao orderDetailDao = new OrderDetailDao(); + private final Scanner scanner = new Scanner(System.in); public void placeOrder(int userId) { // TODO: // Create order + List cart = new ArrayList<>(); + double grandTotal = 0.0; + + try { + Field itemPriceField = MenuItem.class.getDeclaredField("price"); + Field itemNameField = MenuItem.class.getDeclaredField("name"); + itemPriceField.setAccessible(true); + itemNameField.setAccessible(true); + + while (true){ + System.out.print("Enter the ID of the item to add (or 0 to finish): "); + int itemId = scanner.nextInt(); + if (itemId == 0) break; + MenuItem item = menuItemDao.findById(itemId); + if (item == null){ + System.out.println("Item not found!"); + continue; + } + + System.out.print("Enter quantity: "); + int quantity = scanner.nextInt(); + if (quantity <= 0){ + System.out.println("Quantity must be greater than zero!"); + continue; + } + double price = (double) itemPriceField.get(item); + + OrderDetail detail = new OrderDetail(); + Field ordDetItemField = OrderDetail.class.getDeclaredField("menuItemId"); + Field ordDetQtyField = OrderDetail.class.getDeclaredField("quantity"); + Field ordDetPrcField = OrderDetail.class.getDeclaredField("price"); + ordDetItemField.setAccessible(true); + ordDetQtyField.setAccessible(true); + ordDetPrcField.setAccessible(true); + ordDetItemField.set(detail, itemId); + ordDetQtyField.set(detail, quantity); + ordDetPrcField.set(detail, price); + cart.add(detail); + grandTotal += (price * quantity); + System.out.println("Added " + quantity + "x " + itemNameField.get(item) + " to your cart."); + } + + if (cart.isEmpty()){ + System.out.println("Cart is empty. Order cancelled."); + return; + } + + Order order = new Order(); + Field ordUserField = Order.class.getDeclaredField("userId"); + Field ordTotalField = Order.class.getDeclaredField("totalPrice"); + ordUserField.setAccessible(true); + ordTotalField.setAccessible(true); + ordUserField.set(order, userId); + ordTotalField.set(order, grandTotal); + + int orderId = orderDao.save(order); + if (orderId != -1){ + Field ordDetIdField = OrderDetail.class.getDeclaredField("orderId"); + ordDetIdField.setAccessible(true); + for (OrderDetail detail : cart){ + ordDetIdField.set(detail, orderId); + orderDetailDao.save(detail); + } + System.out.println("Order saved successfully!"); + printReceipt(orderId); + } + else{ + System.out.println("Failed to save order."); + } + + } + catch (Exception ex){ + ex.printStackTrace(); + } } @@ -13,6 +100,39 @@ public class OrderService { // TODO: // Print order receipt + System.out.println("\n[Order Receipt]"); + System.out.println("---------------------------------------"); + System.out.printf("%-12s %-7s %-9s %s\n", "Item", "Qty", "Unit", "Total"); + System.out.println("---------------------------------------"); + + List details = orderDetailDao.findByOrderId(orderId); + double finalTotal = 0.0; + + try { + Field itemField = OrderDetail.class.getDeclaredField("menuItemId"); + Field qtyField = OrderDetail.class.getDeclaredField("quantity"); + Field prcField = OrderDetail.class.getDeclaredField("price"); + itemField.setAccessible(true); + qtyField.setAccessible(true); + prcField.setAccessible(true); + Field itemNameField = MenuItem.class.getDeclaredField("name"); + itemNameField.setAccessible(true); + for (OrderDetail detail : details){ + int itemId = (int) itemField.get(detail); + int qty = (int) qtyField.get(detail); + double unitPrice = (double) prcField.get(detail); + double total = unitPrice * qty; + finalTotal += total; + MenuItem item = menuItemDao.findById(itemId); + String itemName = (item != null) ? (String) itemNameField.get(item) : "Unknown"; + System.out.printf("%-12s %-7d $%-8.2f $%.2f\n", itemName, qty, unitPrice, total); + } + System.out.println("---------------------------------------"); + System.out.printf("Final Total: $%.2f\n", finalTotal); + } + catch (Exception ex){ + ex.printStackTrace(); + } } @@ -20,6 +140,27 @@ public class OrderService { // TODO: // Display user's order history + List orders = orderDao.findByUserId(userId); + System.out.println("\n--- ORDER HISTORY ---"); + if (orders.isEmpty()){ + System.out.println("No past orders found."); + return; + } + + try { + Field idField = Order.class.getDeclaredField("id"); + Field dateField = Order.class.getDeclaredField("createdAt"); + Field totalField = Order.class.getDeclaredField("totalPrice"); + idField.setAccessible(true); + dateField.setAccessible(true); + totalField.setAccessible(true); + for (Order order : orders){ + System.out.printf("Order ID: %d | Date: %s | Total Spent: $%.2f\n", idField.get(order), dateField.get(order), totalField.get(order)); + } + } + catch (Exception ex){ + ex.printStackTrace(); + } } diff --git a/src/main/java/dev/ui/ConsoleMenu.java b/src/main/java/dev/ui/ConsoleMenu.java index 663dc0c..48b6eb7 100644 --- a/src/main/java/dev/ui/ConsoleMenu.java +++ b/src/main/java/dev/ui/ConsoleMenu.java @@ -1,11 +1,22 @@ package dev.ui; import java.util.Scanner; +import dev.model.User; +import dev.service.AuthService; +import dev.service.MenuService; +import dev.service.OrderService; +import java.lang.reflect.Field; public class ConsoleMenu { private final Scanner scanner = new Scanner(System.in); + private final AuthService authService = + new AuthService(); + private final MenuService menuService = + new MenuService(); + private final OrderService orderService = + new OrderService(); public void start() { @@ -18,18 +29,22 @@ public class ConsoleMenu { System.out.println("3. Exit"); int choice = scanner.nextInt(); + scanner.nextLine(); switch (choice) { case 1: // TODO + handleLogin(); break; case 2: // TODO + handleRegister(); break; case 3: + System.out.println("Goodbye!"); return; default: @@ -40,5 +55,83 @@ public class ConsoleMenu { } } + private void handleLogin(){ + System.out.println("\n[Login]"); + System.out.print("Enter username: "); + String username = scanner.nextLine(); + System.out.print("Enter password: "); + String password = scanner.nextLine(); + + User loggedInUser = authService.login(username, password); + if (loggedInUser != null){ + System.out.println("Login successful! Welcome, " + username + "."); + showUserMenu(loggedInUser); + } + else{ + System.out.println("Error: Invalid username or password."); + } + } + + private void handleRegister(){ + System.out.println("\n[Register New Account]"); + System.out.print("Enter username: "); + String username = scanner.nextLine(); + System.out.print("Enter password: "); + String password = scanner.nextLine(); + System.out.print("Enter email (optional, press enter to skip): "); + String email = scanner.nextLine(); + if (email.trim().isEmpty()){ + email = null; + } + if (authService.register(username, password, email)){ + System.out.println("Registration successful! You can now log in."); + } + else{ + System.out.println("Registration failed."); + } + } + + private void showUserMenu(User user){ + try { + Field idField = User.class.getDeclaredField("id"); + idField.setAccessible(true); + int userId = (int) idField.get(user); + + while (true){ + System.out.println("\n======================================="); + System.out.println(" 🍽️ MAIN MENU 🍽️"); + System.out.println("======================================="); + System.out.println("1. View Menu"); + System.out.println("2. Place a New Order"); + System.out.println("3. View Order History"); + System.out.println("4. Logout"); + System.out.print("Choose an option: "); + + int choice = scanner.nextInt(); + scanner.nextLine(); + + switch (choice){ + case 1: + menuService.showMenu(); + break; + case 2: + menuService.showMenu(); + orderService.placeOrder(userId); + break; + case 3: + orderService.showOrderHistory(userId); + break; + case 4: + System.out.println("Logged out successfully."); + return; + default: + System.out.println("Invalid choice."); + } + } + } + catch (Exception ex){ + ex.printStackTrace(); + } + } } \ No newline at end of file diff --git a/structure.txt b/structure.txt new file mode 100644 index 0000000..b528e4e Binary files /dev/null and b/structure.txt differ