From b9f01b6e0a0a5a3ad5b817c4353871610f4d3c7d Mon Sep 17 00:00:00 2001 From: navid Date: Mon, 6 Jul 2026 16:39:32 +0330 Subject: [PATCH] complete Restaurant Management System with PostgreSQL and JDBC --- .idea/.gitignore | 10 + .idea/compiler.xml | 13 ++ .idea/encodings.xml | 7 + .idea/inspectionProfiles/Project_Default.xml | 6 + .idea/jarRepositories.xml | 20 ++ .idea/misc.xml | 12 ++ .idea/vcs.xml | 7 + database.sql | 187 +++++------------- src/main/java/dev/dao/MenuItemDao.java | 49 ++++- src/main/java/dev/dao/OrderDao.java | 68 ++++++- src/main/java/dev/dao/OrderDetailDao.java | 47 ++++- src/main/java/dev/dao/UserDao.java | 59 +++++- .../java/dev/database/DatabaseConnection.java | 11 +- src/main/java/dev/model/MenuItem.java | 49 +++++ src/main/java/dev/model/Order.java | 40 ++++ src/main/java/dev/model/OrderDetail.java | 49 +++++ src/main/java/dev/model/User.java | 41 ++++ src/main/java/dev/service/AuthService.java | 43 +++- src/main/java/dev/service/MenuService.java | 23 ++- src/main/java/dev/service/OrderService.java | 124 +++++++++++- src/main/java/dev/ui/ConsoleMenu.java | 111 +++++++++-- 21 files changed, 772 insertions(+), 204 deletions(-) create mode 100644 .idea/.gitignore create mode 100644 .idea/compiler.xml create mode 100644 .idea/encodings.xml create mode 100644 .idea/inspectionProfiles/Project_Default.xml create mode 100644 .idea/jarRepositories.xml create mode 100644 .idea/misc.xml create mode 100644 .idea/vcs.xml 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..4158879 --- /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..eba6e1f --- /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..8306744 --- /dev/null +++ b/.idea/vcs.xml @@ -0,0 +1,7 @@ + + + + + + + \ No newline at end of file diff --git a/database.sql b/database.sql index 2169346..e0fd875 100644 --- a/database.sql +++ b/database.sql @@ -1,141 +1,50 @@ --- Restaurant Database Management System --- --- Instructions: --- 1. Create all required tables. --- 2. Design appropriate PRIMARY KEY and FOREIGN KEY relationships. --- 3. Add suitable constraints based on the requirements. --- 4. Insert initial mock data. --- 5. Insert at least 3 menu items. --- 6. The script should be executable from start to finish without errors. +CREATE TABLE users ( + id SERIAL PRIMARY KEY, + username VARCHAR(50) UNIQUE NOT NULL, + password VARCHAR(255) NOT NULL, -- هش شده با SHA-256 + Base64 + email VARCHAR(100) +); + +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) +); + +CREATE TABLE orders ( + id SERIAL PRIMARY KEY, + user_id INTEGER NOT NULL REFERENCES users(id) ON DELETE CASCADE, + created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP, + total_price DECIMAL(10,2) NOT NULL CHECK (total_price >= 0) +); + +CREATE TABLE order_details ( + id SERIAL PRIMARY KEY, + order_id INTEGER NOT NULL REFERENCES orders(id) ON DELETE CASCADE, + menu_item_id INTEGER NOT NULL REFERENCES menu_items(id), + quantity INTEGER NOT NULL CHECK (quantity > 0), + price DECIMAL(10,2) NOT NULL CHECK (price >= 0) -- قیمت در زمان خرید +); + +INSERT INTO menu_items (name, description, price, category) VALUES + ('Pizza', 'Classic Margherita with mozzarella and basil', 10.00, 'Main'), + ('Burger', 'Juicy beef burger with lettuce and cheese', 8.00, 'Main'), + ('Pasta', 'Creamy Alfredo pasta with chicken', 12.00, 'Main'), + ('Salad', 'Fresh garden salad with vinaigrette', 6.50, 'Appetizer'), + ('Soda', 'Carbonated soft drink', 2.50, 'Beverage'); + +INSERT INTO users (username, password, email) VALUES + ('john_doe', 'XohImNooBHFR0OVvjcYpJ3NgPQ1qq73WKhHvch0VQtg=', 'john@example.com'); + +INSERT INTO orders (user_id, total_price) VALUES + ((SELECT id FROM users WHERE username = 'john_doe'), 18.00); - --- ======================================================= --- USER TABLE --- ======================================================= --- --- Represents customers using the system. --- --- Required information: --- - Unique identifier --- - Username --- - Password --- - Email (optional) --- --- Requirements: --- - Each user must have a unique identifier. --- - Usernames must be unique. --- - Username and password are required. --- - Passwords should not be stored in plain text. --- --- CREATE TABLE ... - - - --- ======================================================= --- MENU ITEM TABLE --- ======================================================= --- --- Represents available food and drink items. --- --- Required information: --- - Unique identifier --- - Name --- - Description (optional) --- - Price --- - Category (optional) --- --- Requirements: --- - Each menu item must have a unique identifier. --- - Name is required. --- - Price must always be positive. --- --- CREATE TABLE ... - - - --- ======================================================= --- ORDER TABLE --- ======================================================= --- --- Represents orders placed by customers. --- --- Required information: --- - Unique identifier --- - Reference to customer --- - Creation date and time --- - Total price --- --- Requirements: --- - Each order must belong to exactly one user. --- - A user can have multiple orders. --- - The relationship between User and Order must be implemented. --- --- Note: --- Avoid using reserved SQL keywords as table names. --- Consider using a name such as "orders" or "customer_orders". --- --- CREATE TABLE ... - - - --- ======================================================= --- ORDER DETAIL TABLE --- ======================================================= --- --- Represents items inside an order. --- --- Required information: --- - Unique identifier --- - Reference to an order --- - Reference to a menu item --- - Quantity --- - Item price at purchase time --- --- Requirements: --- - Each detail record must belong to one order. --- - Each detail record must reference one menu item. --- - Quantity must always be greater than zero. --- - Store the item's price at the moment of purchase. --- --- CREATE TABLE ... - - - --- ======================================================= --- INITIAL MENU DATA --- ======================================================= --- --- Insert at least 3 food or drink items. --- --- Example categories: --- - Pizza --- - Burger --- - Pasta --- - Drink --- --- INSERT INTO ... - - - --- ======================================================= --- OPTIONAL TEST DATA --- ======================================================= --- --- You may insert sample users and orders for testing. --- This section is optional. --- --- INSERT INTO ... - - - --- ======================================================= --- VERIFICATION QUERIES --- ======================================================= --- --- Uncomment these queries to verify your database. --- --- SELECT * FROM ...; --- SELECT * FROM ...; --- SELECT * FROM ...; --- SELECT * FROM ...; \ No newline at end of file +INSERT INTO order_details (order_id, menu_item_id, quantity, price) +VALUES + ((SELECT id FROM orders WHERE user_id = (SELECT id FROM users WHERE username = 'john_doe') ORDER BY id LIMIT 1), + (SELECT id FROM menu_items WHERE name = 'Pizza'), 2, 10.00), + ((SELECT id FROM orders WHERE user_id = (SELECT id FROM users WHERE username = 'john_doe') ORDER BY id LIMIT 1), + (SELECT id FROM menu_items WHERE name = 'Burger'), 1, 8.00); \ 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..03a5263 100644 --- a/src/main/java/dev/dao/MenuItemDao.java +++ b/src/main/java/dev/dao/MenuItemDao.java @@ -4,22 +4,57 @@ import dev.model.MenuItem; import java.util.List; +import dev.database.DatabaseConnection; + +import java.sql.*; +import java.util.ArrayList; + public class MenuItemDao { public List findAll() { + List items = new ArrayList<>(); + String sql = "SELECT * FROM menu_items ORDER BY id"; + try (Connection conn = DatabaseConnection.getConnection(); + Statement stmt = conn.createStatement(); + ResultSet rs = stmt.executeQuery(sql)) { - // TODO: - // Retrieve all menu items - - return null; + while (rs.next()) { + MenuItem item = new MenuItem(); + item.setId(rs.getInt("id")); + item.setName(rs.getString("name")); + item.setDescription(rs.getString("description")); + item.setPrice(rs.getDouble("price")); + item.setCategory(rs.getString("category")); + items.add(item); + } + } catch (SQLException e) { + e.printStackTrace(); + } + return items; } public MenuItem findById(int id) { + String sql = "SELECT * FROM menu_items WHERE id = ?"; + try (Connection conn = DatabaseConnection.getConnection(); + PreparedStatement pstmt = conn.prepareStatement(sql)) { - // TODO: - // Find menu item by id - + pstmt.setInt(1, id); + try (ResultSet rs = pstmt.executeQuery()) { + if (rs.next()) { + MenuItem item = new MenuItem(); + item.setId(rs.getInt("id")); + item.setName(rs.getString("name")); + item.setDescription(rs.getString("description")); + item.setPrice(rs.getDouble("price")); + item.setCategory(rs.getString("category")); + return item; + } + } + } catch (SQLException e) { + e.printStackTrace(); + } return null; + } } \ 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..42da41e 100644 --- a/src/main/java/dev/dao/OrderDao.java +++ b/src/main/java/dev/dao/OrderDao.java @@ -4,21 +4,81 @@ import dev.model.Order; import java.util.List; +import dev.database.DatabaseConnection; + +import java.sql.*; +import java.time.LocalDateTime; +import java.util.ArrayList; + public class OrderDao { public int save(Order order) { + String sql = "INSERT INTO orders (user_id, created_at, total_price) VALUES (?, ?, ?)"; + try (Connection conn = DatabaseConnection.getConnection(); + PreparedStatement pstmt = conn.prepareStatement(sql, Statement.RETURN_GENERATED_KEYS)) { - // TODO: - // Insert order and return generated id + pstmt.setInt(1, order.getUserId()); + pstmt.setTimestamp(2, Timestamp.valueOf(order.getCreatedAt())); + pstmt.setDouble(3, order.getTotalPrice()); + int affectedRows = pstmt.executeUpdate(); + if (affectedRows > 0) { + try (ResultSet generatedKeys = pstmt.getGeneratedKeys()) { + if (generatedKeys.next()) { + int id = generatedKeys.getInt(1); + order.setId(id); + return id; + } + } + } + } catch (SQLException e) { + e.printStackTrace(); + } return -1; } public List findByUserId(int userId) { + List orders = new ArrayList<>(); + String sql = "SELECT * FROM orders WHERE user_id = ? ORDER BY created_at DESC"; + try (Connection conn = DatabaseConnection.getConnection(); + PreparedStatement pstmt = conn.prepareStatement(sql)) { - // TODO: - // Retrieve all orders of a user + pstmt.setInt(1, userId); + try (ResultSet rs = pstmt.executeQuery()) { + while (rs.next()) { + Order order = new Order(); + order.setId(rs.getInt("id")); + order.setUserId(rs.getInt("user_id")); + order.setCreatedAt(rs.getTimestamp("created_at").toLocalDateTime()); + order.setTotalPrice(rs.getDouble("total_price")); + orders.add(order); + } + } + } catch (SQLException e) { + e.printStackTrace(); + } + return orders; + } + public Order findById(int orderId) { + String sql = "SELECT * FROM orders WHERE id = ?"; + try (Connection conn = DatabaseConnection.getConnection(); + PreparedStatement pstmt = conn.prepareStatement(sql)) { + + pstmt.setInt(1, orderId); + try (ResultSet rs = pstmt.executeQuery()) { + if (rs.next()) { + Order order = new Order(); + order.setId(rs.getInt("id")); + order.setUserId(rs.getInt("user_id")); + order.setCreatedAt(rs.getTimestamp("created_at").toLocalDateTime()); + order.setTotalPrice(rs.getDouble("total_price")); + return order; + } + } + } catch (SQLException e) { + e.printStackTrace(); + } return null; } diff --git a/src/main/java/dev/dao/OrderDetailDao.java b/src/main/java/dev/dao/OrderDetailDao.java index ed42f56..0cf477f 100644 --- a/src/main/java/dev/dao/OrderDetailDao.java +++ b/src/main/java/dev/dao/OrderDetailDao.java @@ -1,24 +1,59 @@ package dev.dao; import dev.model.OrderDetail; +import dev.database.DatabaseConnection; + +import java.sql.*; +import java.util.ArrayList; import java.util.List; public class OrderDetailDao { public void save(OrderDetail detail) { + String sql = "INSERT INTO order_details (order_id, menu_item_id, quantity, price) VALUES (?, ?, ?, ?)"; + try (Connection conn = DatabaseConnection.getConnection(); + PreparedStatement pstmt = conn.prepareStatement(sql, Statement.RETURN_GENERATED_KEYS)) { - // TODO: - // Insert order detail + pstmt.setInt(1, detail.getOrderId()); + pstmt.setInt(2, detail.getMenuItemId()); + pstmt.setInt(3, detail.getQuantity()); + pstmt.setDouble(4, detail.getPrice()); + + pstmt.executeUpdate(); + try (ResultSet generatedKeys = pstmt.getGeneratedKeys()) { + if (generatedKeys.next()) { + detail.setId(generatedKeys.getInt(1)); + } + } + } catch (SQLException e) { + e.printStackTrace(); + } } public List findByOrderId(int orderId) { + List details = new ArrayList<>(); + String sql = "SELECT * FROM order_details WHERE order_id = ?"; + try (Connection conn = DatabaseConnection.getConnection(); + PreparedStatement pstmt = conn.prepareStatement(sql)) { - // TODO: - // Retrieve order details - - return null; + pstmt.setInt(1, orderId); + try (ResultSet rs = pstmt.executeQuery()) { + while (rs.next()) { + OrderDetail detail = new OrderDetail(); + detail.setId(rs.getInt("id")); + detail.setOrderId(rs.getInt("order_id")); + detail.setMenuItemId(rs.getInt("menu_item_id")); + detail.setQuantity(rs.getInt("quantity")); + detail.setPrice(rs.getDouble("price")); + details.add(detail); + } + } + } catch (SQLException e) { + e.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..6ac94b0 100644 --- a/src/main/java/dev/dao/UserDao.java +++ b/src/main/java/dev/dao/UserDao.java @@ -1,23 +1,70 @@ package dev.dao; import dev.model.User; +import dev.database.DatabaseConnection; + +import java.sql.*; +import java.util.Base64; public class UserDao { public boolean save(User user) { + String sql = "INSERT INTO users (username, password, email) VALUES (?, ?, ?)"; + try (Connection conn = DatabaseConnection.getConnection(); + PreparedStatement pstmt = conn.prepareStatement(sql, Statement.RETURN_GENERATED_KEYS)) { - // TODO: - // Insert user into database - return false; + String hashedPassword = hashPassword(user.getPassword()); + pstmt.setString(1, user.getUsername()); + pstmt.setString(2, hashedPassword); + pstmt.setString(3, user.getEmail()); + + int affectedRows = pstmt.executeUpdate(); + if (affectedRows > 0) { + try (ResultSet generatedKeys = pstmt.getGeneratedKeys()) { + if (generatedKeys.next()) { + user.setId(generatedKeys.getInt(1)); + } + } + return true; + } + return false; + } catch (SQLException e) { + e.printStackTrace(); + return false; + } } public User findByUsername(String username) { + String sql = "SELECT * FROM users WHERE username = ?"; + try (Connection conn = DatabaseConnection.getConnection(); + PreparedStatement pstmt = conn.prepareStatement(sql)) { - // TODO: - // Find a user by username - + pstmt.setString(1, username); + try (ResultSet rs = pstmt.executeQuery()) { + if (rs.next()) { + User user = new User(); + user.setId(rs.getInt("id")); + user.setUsername(rs.getString("username")); + user.setPassword(rs.getString("password")); + user.setEmail(rs.getString("email")); + return user; + } + } + } catch (SQLException e) { + e.printStackTrace(); + } return null; } + private String hashPassword(String password) { + try { + java.security.MessageDigest md = java.security.MessageDigest.getInstance("SHA-256"); + byte[] hash = md.digest(password.getBytes(java.nio.charset.StandardCharsets.UTF_8)); + return Base64.getEncoder().encodeToString(hash); + } catch (java.security.NoSuchAlgorithmException e) { + throw new RuntimeException("Hashing algorithm not found", e); + } + } + } \ No newline at end of file diff --git a/src/main/java/dev/database/DatabaseConnection.java b/src/main/java/dev/database/DatabaseConnection.java index da45535..21289a2 100644 --- a/src/main/java/dev/database/DatabaseConnection.java +++ b/src/main/java/dev/database/DatabaseConnection.java @@ -1,15 +1,16 @@ package dev.database; import java.sql.Connection; +import java.sql.DriverManager; import java.sql.SQLException; public class DatabaseConnection { private static final String URL = "jdbc:postgresql://localhost:5432/restaurant_db"; // DB Server - private static final String USER = "postgres"; // Your Username + private static final String USER = "navid299"; - private static final String PASSWORD = "password"; // Your Password + private static final String PASSWORD = "7777"; private DatabaseConnection() { @@ -17,11 +18,7 @@ public class DatabaseConnection { public static Connection getConnection() throws SQLException { - - // 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/model/MenuItem.java b/src/main/java/dev/model/MenuItem.java index 265ecc1..5a0816d 100644 --- a/src/main/java/dev/model/MenuItem.java +++ b/src/main/java/dev/model/MenuItem.java @@ -12,4 +12,53 @@ public class MenuItem { private String category; + public MenuItem() {} + + public MenuItem(String name, String description, double price, String category) { + this.name = name; + this.description = description; + this.price = price; + this.category = category; + } + + public int getId() { + return id; + } + + public void setId(int id) { + this.id = id; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getDescription() { + return description; + } + + public void setDescription(String description) { + this.description = description; + } + + public double getPrice() { + return price; + } + + public void setPrice(double price) { + this.price = price; + } + + public String getCategory() { + return category; + } + + public void setCategory(String category) { + this.category = category; + } + } \ No newline at end of file diff --git a/src/main/java/dev/model/Order.java b/src/main/java/dev/model/Order.java index 32049cb..7837c6c 100644 --- a/src/main/java/dev/model/Order.java +++ b/src/main/java/dev/model/Order.java @@ -12,4 +12,44 @@ public class Order { private double totalPrice; + public Order() {} + + public Order(int userId, LocalDateTime createdAt, double totalPrice) { + this.userId = userId; + this.createdAt = createdAt; + this.totalPrice = totalPrice; + } + + public int getId() { + return id; + } + + public void setId(int id) { + this.id = id; + } + + public int getUserId() { + return userId; + } + + public void setUserId(int userId) { + this.userId = userId; + } + + public LocalDateTime getCreatedAt() { + return createdAt; + } + + public void setCreatedAt(LocalDateTime createdAt) { + this.createdAt = createdAt; + } + + public double getTotalPrice() { + return totalPrice; + } + + public void setTotalPrice(double totalPrice) { + this.totalPrice = totalPrice; + } + } \ No newline at end of file diff --git a/src/main/java/dev/model/OrderDetail.java b/src/main/java/dev/model/OrderDetail.java index b5b8bbe..c8a957a 100644 --- a/src/main/java/dev/model/OrderDetail.java +++ b/src/main/java/dev/model/OrderDetail.java @@ -12,4 +12,53 @@ public class OrderDetail { private double price; + public OrderDetail() {} + + public OrderDetail(int orderId, int menuItemId, int quantity, double price) { + this.orderId = orderId; + this.menuItemId = menuItemId; + this.quantity = quantity; + this.price = price; + } + + public int getId() { + return id; + } + + public void setId(int id) { + this.id = id; + } + + public int getOrderId() { + return orderId; + } + + public void setOrderId(int orderId) { + this.orderId = orderId; + } + + public int getMenuItemId() { + return menuItemId; + } + + public void setMenuItemId(int menuItemId) { + this.menuItemId = menuItemId; + } + + public int getQuantity() { + return quantity; + } + + public void setQuantity(int quantity) { + this.quantity = quantity; + } + + public double getPrice() { + return price; + } + + public void setPrice(double price) { + this.price = price; + } + } \ No newline at end of file diff --git a/src/main/java/dev/model/User.java b/src/main/java/dev/model/User.java index 0ab60c6..2a6848c 100644 --- a/src/main/java/dev/model/User.java +++ b/src/main/java/dev/model/User.java @@ -2,12 +2,53 @@ package dev.model; public class User { + public User() {} + + public User(String username, String password, String email) { + this.username = username; + this.password = password; + this.email = email; + } + private int id; + public int getId() { + return id; + } + public void setId(int id) { + this.id = id; + } + private String username; + public String getUsername() { + return username; + } + + public void setUsername(String username) { + this.username = username; + } + private String password; + + public String getPassword() { + return password; + } + + + public void setPassword(String password) { + this.password = password; + } + private String email; + public String getEmail() { + return email; + } + + public void setEmail(String email) { + this.email = email; + } + } \ 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..86cbd0e 100644 --- a/src/main/java/dev/service/AuthService.java +++ b/src/main/java/dev/service/AuthService.java @@ -1,23 +1,52 @@ package dev.service; import dev.model.User; +import dev.dao.UserDao; +import java.util.Base64; public class AuthService { + private UserDao userDao = new UserDao(); public boolean register(String username, String password, String email) { + if (username == null || username.trim().isEmpty() || password == null || password.trim().isEmpty()) { + System.out.println("Username and password are required."); + return false; + } - // TODO: - // Validate and register user + User existing = userDao.findByUsername(username); + if (existing != null) { + System.out.println("Username already exists."); + return false; + } - return false; + User user = new User(username, password, email); + return userDao.save(user); } public User login(String username, String password) { + User user = userDao.findByUsername(username); + if (user == null) { + System.out.println("Invalid username or password."); + return null; + } - // TODO: - // Authenticate user - - return null; + String hashedInput = hashPassword(password); + if (hashedInput.equals(user.getPassword())) { + System.out.println("Login successful! Welcome, " + username); + return user; + } else { + System.out.println("Invalid username or password."); + return null; + } + } + private String hashPassword(String password) { + try { + java.security.MessageDigest md = java.security.MessageDigest.getInstance("SHA-256"); + byte[] hash = md.digest(password.getBytes(java.nio.charset.StandardCharsets.UTF_8)); + return Base64.getEncoder().encodeToString(hash); + } catch (java.security.NoSuchAlgorithmException e) { + throw new RuntimeException("Hashing algorithm not found", e); + } } } \ 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..04aac01 100644 --- a/src/main/java/dev/service/MenuService.java +++ b/src/main/java/dev/service/MenuService.java @@ -1,12 +1,27 @@ package dev.service; +import dev.dao.MenuItemDao; +import dev.model.MenuItem; +import java.util.List; public class MenuService { - + private MenuItemDao menuItemDao = new MenuItemDao(); public void showMenu() { + List items = menuItemDao.findAll(); + if (items.isEmpty()) { + System.out.println("No menu items available."); + return; + } + System.out.println("\n--- Menu ---"); + System.out.printf("%-4s %-25s %-10s %s\n", "ID", "Name", "Price", "Category"); + System.out.println("------------------------------------------------"); + for (MenuItem item : items) { + System.out.printf("%-4d %-25s $%-9.2f %s\n", + item.getId(), item.getName(), item.getPrice(), item.getCategory()); + } + } - // TODO: - // Display menu items - + public MenuItem getMenuItemById(int id) { + return menuItemDao.findById(id); } } \ 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..6cca3d8 100644 --- a/src/main/java/dev/service/OrderService.java +++ b/src/main/java/dev/service/OrderService.java @@ -1,26 +1,136 @@ package dev.service; +import dev.dao.OrderDao; +import dev.dao.OrderDetailDao; +import dev.dao.MenuItemDao; +import dev.model.MenuItem; +import dev.model.Order; +import dev.model.OrderDetail; + +import java.time.LocalDateTime; +import java.util.ArrayList; +import java.util.List; +import java.util.Scanner; + public class OrderService { + private OrderDao orderDao = new OrderDao(); + private OrderDetailDao orderDetailDao = new OrderDetailDao(); + private MenuItemDao menuItemDao = new MenuItemDao(); + private MenuService menuService = new MenuService(); public void placeOrder(int userId) { - // TODO: - // Create order + Scanner scanner = new Scanner(System.in); + List cart = new ArrayList<>(); + double total = 0.0; + + System.out.println("\n[Placing Order]"); + while (true) { + menuService.showMenu(); + 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("Invalid item ID. Try again."); + continue; + } + + System.out.print("Enter quantity: "); + int qty = scanner.nextInt(); + if (qty <= 0) { + System.out.println("Quantity must be greater than zero."); + continue; + } + + double subtotal = item.getPrice() * qty; + OrderDetail detail = new OrderDetail(); + detail.setMenuItemId(itemId); + detail.setQuantity(qty); + detail.setPrice(item.getPrice()); + cart.add(detail); + + total += subtotal; + System.out.printf("Added %dx %s to your cart.\n", qty, item.getName()); + } + + if (cart.isEmpty()) { + System.out.println("No items selected. Order cancelled."); + return; + } + + + Order order = new Order(); + order.setUserId(userId); + order.setCreatedAt(LocalDateTime.now()); + order.setTotalPrice(total); + + int orderId = orderDao.save(order); + if (orderId == -1) { + System.out.println("Failed to save order."); + return; + } + + + for (OrderDetail detail : cart) { + detail.setOrderId(orderId); + orderDetailDao.save(detail); + } + + System.out.println("Order saved successfully!"); + printReceipt(orderId); } public void printReceipt(int orderId) { + Order order = orderDao.findById(orderId); + if (order == null) { + System.out.println("Order not found."); + return; + } - // TODO: - // Print order receipt + List details = orderDetailDao.findByOrderId(orderId); + if (details.isEmpty()) { + System.out.println("No details found for this order."); + return; + } + + System.out.println("\n[Order Summary / Receipt]"); + System.out.println("Order ID: " + orderId); + System.out.println("Date: " + order.getCreatedAt()); + System.out.println("---------------------------------------"); + System.out.printf("%-20s %-5s %-10s %-10s\n", "Item", "Qty", "Unit", "Total"); + System.out.println("---------------------------------------"); + + double grandTotal = 0.0; + for (OrderDetail detail : details) { + MenuItem item = menuItemDao.findById(detail.getMenuItemId()); + String itemName = (item != null) ? item.getName() : "Unknown"; + double lineTotal = detail.getPrice() * detail.getQuantity(); + System.out.printf("%-20s %-5d $%-9.2f $%-9.2f\n", + itemName, detail.getQuantity(), detail.getPrice(), lineTotal); + grandTotal += lineTotal; + } + System.out.println("---------------------------------------"); + System.out.printf("Final Total: $%.2f\n", grandTotal); } public void showOrderHistory(int userId) { + List orders = orderDao.findByUserId(userId); + if (orders.isEmpty()) { + System.out.println("No orders found for this user."); + return; + } - // TODO: - // Display user's order history - + System.out.println("\n[Order History]"); + System.out.printf("%-8s %-20s %-12s\n", "Order ID", "Date", "Total"); + System.out.println("--------------------------------------"); + for (Order order : orders) { + System.out.printf("%-8d %-20s $%-10.2f\n", + order.getId(), order.getCreatedAt().toString(), order.getTotalPrice()); + } } } \ No newline at end of file diff --git a/src/main/java/dev/ui/ConsoleMenu.java b/src/main/java/dev/ui/ConsoleMenu.java index 663dc0c..f30d2f1 100644 --- a/src/main/java/dev/ui/ConsoleMenu.java +++ b/src/main/java/dev/ui/ConsoleMenu.java @@ -1,44 +1,121 @@ package dev.ui; +import dev.model.User; +import dev.service.AuthService; +import dev.service.MenuService; +import dev.service.OrderService; + + import java.util.Scanner; public class ConsoleMenu { + private AuthService authService = new AuthService(); + private MenuService menuService = new MenuService(); + private OrderService orderService = new OrderService(); + private User loggedInUser = null; private final Scanner scanner = new Scanner(System.in); public void start() { while (true) { + if (loggedInUser == null) { - System.out.println(); - System.out.println("===== JAVA PIZZERIA ====="); - System.out.println("1. Login"); - System.out.println("2. Register"); - System.out.println("3. Exit"); + System.out.println(); + System.out.println("===== JAVA PIZZERIA ====="); + System.out.println("1. Login"); + System.out.println("2. Register"); + System.out.println("3. Exit"); - int choice = scanner.nextInt(); + int choice = scanner.nextInt(); + scanner.nextLine(); - switch (choice) { + switch (choice) { - case 1: - // TODO - break; + case 1: + login(); + break; - case 2: - // TODO - break; + case 2: + register(); + break; - case 3: - return; + case 3: + System.out.println("Goodbye!"); + return; - default: - System.out.println("Invalid choice"); + default: + System.out.println("Invalid choice"); + } + }else{ + showMainMenu(); } } } + private void login() { + System.out.println("\n[Login]"); + System.out.print("Enter username: "); + String username = scanner.nextLine(); + System.out.print("Enter password: "); + String password = scanner.nextLine(); + + User user = authService.login(username, password); + if (user != null) { + loggedInUser = user; + } + } + + private void register() { + System.out.println("\n[Register]"); + System.out.print("Enter username: "); + String username = scanner.nextLine(); + System.out.print("Enter password: "); + String password = scanner.nextLine(); + System.out.print("Enter email (optional): "); + String email = scanner.nextLine(); + + boolean success = authService.register(username, password, email); + if (success) { + System.out.println("Registration successful! You can now login."); + } else { + System.out.println("Registration failed."); + } + } + + private void showMainMenu() { + System.out.println(); + System.out.println("======================================="); + 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: + orderService.placeOrder(loggedInUser.getId()); + break; + case 3: + orderService.showOrderHistory(loggedInUser.getId()); + break; + case 4: + loggedInUser = null; + System.out.println("Logged out."); + break; + default: + System.out.println("Invalid choice."); + } + } } \ No newline at end of file -- 2.54.0