Compare commits

4 Commits
22 changed files with 692 additions and 166 deletions
+10
View File
@@ -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/
+13
View File
@@ -0,0 +1,13 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="CompilerConfiguration">
<annotationProcessing>
<profile name="Maven default annotation processors profile" enabled="true">
<sourceOutputDir name="target/generated-sources/annotations" />
<sourceTestOutputDir name="target/generated-test-sources/test-annotations" />
<outputRelativeToContentRoot value="true" />
<module name="WS-10-Database" />
</profile>
</annotationProcessing>
</component>
</project>
+12
View File
@@ -0,0 +1,12 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="DataSourceManagerImpl" format="xml" multifile-model="true">
<data-source source="LOCAL" name="postgres@localhost" uuid="7eaa055b-aec6-4a3e-a6f8-6ca90a4ee622">
<driver-ref>postgresql</driver-ref>
<synchronize>true</synchronize>
<jdbc-driver>org.postgresql.Driver</jdbc-driver>
<jdbc-url>jdbc:postgresql://localhost:5432/postgres</jdbc-url>
<working-dir>$ProjectFileDir$</working-dir>
</data-source>
</component>
</project>
+7
View File
@@ -0,0 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="Encoding">
<file url="file://$PROJECT_DIR$/src/main/java" charset="UTF-8" />
<file url="file://$PROJECT_DIR$/src/main/resources" charset="UTF-8" />
</component>
</project>
+20
View File
@@ -0,0 +1,20 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="RemoteRepositoriesConfiguration">
<remote-repository>
<option name="id" value="central" />
<option name="name" value="Maven Central repository" />
<option name="url" value="https://repo1.maven.org/maven2" />
</remote-repository>
<remote-repository>
<option name="id" value="jboss.community" />
<option name="name" value="JBoss Community repository" />
<option name="url" value="https://repository.jboss.org/nexus/content/repositories/public/" />
</remote-repository>
<remote-repository>
<option name="id" value="central" />
<option name="name" value="Central Repository" />
<option name="url" value="https://maven.myket.ir" />
</remote-repository>
</component>
</project>
+12
View File
@@ -0,0 +1,12 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="ExternalStorageConfigurationManager" enabled="true" />
<component name="MavenProjectsManager">
<option name="originalFiles">
<list>
<option value="$PROJECT_DIR$/pom.xml" />
</list>
</option>
</component>
<component name="ProjectRootManager" version="2" languageLevel="JDK_25" default="true" project-jdk-name="25" project-jdk-type="JavaSDK" />
</project>
+6
View File
@@ -0,0 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="SqlDialectMappings">
<file url="file://$PROJECT_DIR$/database.sql" dialect="GenericSQL" />
</component>
</project>
Generated
+7
View File
@@ -0,0 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="VcsDirectoryMappings">
<mapping directory="" vcs="Git" />
<mapping directory="$PROJECT_DIR$" vcs="Git" />
</component>
</project>
+64 -125
View File
@@ -1,141 +1,80 @@
-- 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.
-- =======================================================
-- 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 ...
CREATE TABLE users (
id SERIAL PRIMARY KEY,
username VARCHAR(50) UNIQUE NOT NULL,
password VARCHAR(255) NOT NULL,
email VARCHAR(100)
);
-- =======================================================
-- 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 ...
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
-- =======================================================
--
-- 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 ...
CREATE TABLE orders (
id SERIAL PRIMARY KEY,
user_id INT NOT NULL,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
total_price DECIMAL(10, 2) NOT NULL DEFAULT 0.00,
CONSTRAINT fk_user_order FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE
);
-- =======================================================
-- 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 ...
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,
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)
)
-- =======================================================
-- INITIAL MENU DATA
-- =======================================================
--
-- Insert at least 3 food or drink items.
--
-- Example categories:
-- - Pizza
-- - Burger
-- - Pasta
-- - Drink
--
-- INSERT INTO ...
INSERT INTO menu_items (name, description, price, category) VALUES
('Cheeseburger', 'Juicy beef patty with cheddar cheese', 8.99, 'Food'),
('Pepperoni Pizza', 'Classic pizza with pepperoni and mozzarella', 12.50, 'Food'),
('Iced Latte', 'Espresso with cold milk and ice', 4.25, 'Drink');
-- =======================================================
-- OPTIONAL TEST DATA
-- =======================================================
--
-- You may insert sample users and orders for testing.
-- This section is optional.
--
-- INSERT INTO ...
INSERT INTO users (username, password, email) VALUES
('mardin_dev', 'hashed_pass_123', 'mardin@example.com'),
('sara_kh', 'hashed_pass_456', 'sara@example.com');
INSERT INTO orders (user_id, total_price) VALUES
(1, 21.49),
(2, 4.25);
INSERT INTO order_details (order_id, menu_item_id, quantity, price_at_purchase) VALUES
(1, 1, 1, 8.99),
(1, 2, 1, 12.50);
INSERT INTO order_details (order_id, menu_item_id, quantity, price_at_purchase) VALUES
(2, 3, 1, 4.25);
-- =======================================================
-- VERIFICATION QUERIES
-- =======================================================
--
-- Uncomment these queries to verify your database.
--
-- SELECT * FROM ...;
-- SELECT * FROM ...;
-- SELECT * FROM ...;
-- SELECT * FROM ...;
SELECT * FROM users;
SELECT * FROM menu_items;
SELECT * FROM orders;
SELECT * FROM order_details;
SELECT
o.id AS order_number,
u.username AS customer,
m.name AS food_item,
od.quantity,
od.price_at_purchase,
(od.quantity * od.price_at_purchase) AS subtotal,
o.created_at
FROM orders o
JOIN users u ON o.user_id = u.id
JOIN order_details od ON od.order_id = o.id
JOIN menu_items m ON od.menu_item_id = m.id;
+42 -5
View File
@@ -1,23 +1,60 @@
package dev.dao;
import dev.database.DatabaseConnection;
import dev.model.MenuItem;
import java.sql.*;
import java.util.ArrayList;
import java.util.List;
public class MenuItemDao {
public List<MenuItem> findAll() {
List<MenuItem> items = new ArrayList<>();
String sql = "select * FROM menu_item";
// TODO:
// Retrieve all menu items
try (Connection connection = DatabaseConnection.getConnection();
Statement statement = connection.createStatement();
ResultSet resultSet = statement.executeQuery(sql)
) {
while (resultSet.next()) {
MenuItem item = new MenuItem(
resultSet.getInt("id"),
resultSet.getString("name"),
resultSet.getString("description"),
resultSet.getDouble("price"),
resultSet.getString("category")
);
items.add(item);
}
} catch (SQLException e) {
System.err.println("Error fetching menu items: " + e.getMessage());
}
return null;
return items;
}
public MenuItem findById(int id) {
String sql = "SELECT * FROM menu_items WHERE id = ?";
// TODO:
// Find menu item by id
try (Connection conn = DatabaseConnection.getConnection();
PreparedStatement pstmt = conn.prepareStatement(sql)) {
pstmt.setInt(1, id);
try (ResultSet rs = pstmt.executeQuery()) {
if (rs.next()) {
return new MenuItem(
rs.getInt("id"),
rs.getString("name"),
rs.getString("description"),
rs.getDouble("price"),
rs.getString("category")
);
}
}
} catch (SQLException e) {
System.err.println("Error finding menu item: " + e.getMessage());
}
return null;
}
+41 -5
View File
@@ -1,25 +1,61 @@
package dev.dao;
import dev.database.DatabaseConnection;
import dev.model.Order;
import java.sql.*;
import java.util.ArrayList;
import java.util.List;
public class OrderDao {
public int save(Order order) {
// TODO:
// Insert order and return generated id
String sql = "INSERT INTO orders (user_id, total_price) VALUES (?, ?)";
try (Connection conn = DatabaseConnection.getConnection();
PreparedStatement pstmt = conn.prepareStatement(sql, Statement.RETURN_GENERATED_KEYS)) {
pstmt.setInt(1, order.getUserId());
pstmt.setDouble(2, order.getTotalPrice());
pstmt.executeUpdate();
//Generated ID
try (ResultSet rs = pstmt.getGeneratedKeys()) {
if (rs.next()) {
return rs.getInt(1);
}
}
} catch (SQLException e) {
System.err.println("Error saving order: " + e.getMessage());
}
return -1;
}
public List<Order> findByUserId(int userId) {
List<Order> orders = new ArrayList<>();
String sql = "SELECT * FROM orders WHERE user_id = ? ORDER BY created_at DESC";
// TODO:
// Retrieve all orders of a user
try (Connection conn = DatabaseConnection.getConnection();
PreparedStatement pstmt = conn.prepareStatement(sql)) {
return null;
pstmt.setInt(1, userId);
try (ResultSet rs = pstmt.executeQuery()) {
while (rs.next()) {
Order order = new Order(
rs.getInt("id"),
rs.getInt("user_id"),
rs.getTimestamp("created_at"),
rs.getDouble("total_price")
);
orders.add(order);
}
}
} catch (SQLException e) {
System.err.println("Error retrieving orders for user: " + e.getMessage());
}
return orders;
}
}
+43 -5
View File
@@ -1,24 +1,62 @@
package dev.dao;
import dev.database.DatabaseConnection;
import dev.model.OrderDetail;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;
public class OrderDetailDao {
public void save(OrderDetail detail) {
// 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 pstmt = conn.prepareStatement(sql)) {
pstmt.setInt(1, detail.getOrderId());
pstmt.setInt(2, detail.getMenuItemId());
pstmt.setInt(3, detail.getQuantity());
pstmt.setDouble(4, detail.getPriceAtPurchase());
pstmt.executeUpdate();
} catch (SQLException e) {
System.err.println("Error saving order detail: " + e.getMessage());
}
}
public List<OrderDetail> findByOrderId(int orderId) {
// TODO:
// Retrieve order details
List<OrderDetail> details = new ArrayList<>();
String sql = "SELECT * FROM order_details WHERE order_id = ?";
return null;
try (Connection conn = DatabaseConnection.getConnection();
PreparedStatement pstmt = conn.prepareStatement(sql)) {
pstmt.setInt(1, orderId);
try (ResultSet rs = pstmt.executeQuery()) {
while (rs.next()) {
OrderDetail detail = new OrderDetail(
rs.getInt("id"),
rs.getInt("order_id"),
rs.getInt("menu_item_id"),
rs.getInt("quantity"),
rs.getDouble("price_at_purchase")
);
details.add(detail);
}
}
} catch (SQLException e) {
System.err.println("Error retrieving order details: " + e.getMessage());
}
return details;
}
}
+42 -5
View File
@@ -1,22 +1,59 @@
package dev.dao;
import dev.database.DatabaseConnection;
import dev.model.User;
import java.sql.*;
public class UserDao {
public boolean save(User user) {
// TODO:
// Insert user into database
String sql = "INSERT INTO users (username, password, email) VALUES (?, ?, ?)";
return false;
try (Connection conn = DatabaseConnection.getConnection();
PreparedStatement pstmt = conn.prepareStatement(sql)) {
pstmt.setString(1, user.getUsername());
pstmt.setString(2, user.getPassword());
if (user.getEmail() == null || user.getEmail().trim().isEmpty()) {
pstmt.setNull(3, Types.VARCHAR);
} else {
pstmt.setString(3, user.getEmail());
}
int rowsAffected = pstmt.executeUpdate();
return rowsAffected > 0;
} catch (SQLException e) {
System.err.println("Error saving user: " + e.getMessage());
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 pstmt = conn.prepareStatement(sql)) {
pstmt.setString(1, username);
try (ResultSet rs = pstmt.executeQuery()) {
if (rs.next()) {
return new User(
rs.getInt("id"),
rs.getString("username"),
rs.getString("password"),
rs.getString("email")
);
}
}
} catch (SQLException e) {
System.err.println("Error finding user by username: " + e.getMessage());
}
return null;
}
@@ -1,6 +1,7 @@
package dev.database;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
public class 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);
}
}
+27
View File
@@ -12,4 +12,31 @@ public class MenuItem {
private String category;
public MenuItem(int id, String name, String description, double price, String category) {
this.id = id;
this.name = name;
this.description = description;
this.price = price;
this.category = category;
}
public String getDescription() {
return this.description;
}
public int getId() {
return this.id;
}
public String getName() {
return this.name;
}
public double getPrice() {
return this.price;
}
public String getCategory() {
return this.category;
}
}
+15
View File
@@ -1,5 +1,6 @@
package dev.model;
import java.sql.Timestamp;
import java.time.LocalDateTime;
public class Order {
@@ -12,4 +13,18 @@ public class Order {
private double totalPrice;
public Order(int id, int userId, Timestamp createdAt, double totalPrice) {
this.id = id;
this.userId = userId;
this.createdAt = createdAt.toLocalDateTime();
this.totalPrice = totalPrice;
}
public int getUserId() {
return userId;
}
public double getTotalPrice() {
return totalPrice;
}
}
+23
View File
@@ -12,4 +12,27 @@ public class OrderDetail {
private double price;
public OrderDetail(int id, int orderId, int menuItemId, int quantity, double priceAtPurchase) {
this.id = id;
this.orderId = orderId;
this.menuItemId = menuItemId;
this.quantity = quantity;
this.price = priceAtPurchase;
}
public int getOrderId() {
return orderId;
}
public int getMenuItemId() {
return menuItemId;
}
public int getQuantity() {
return quantity;
}
public double getPriceAtPurchase() {
return price;
}
}
+22
View File
@@ -10,4 +10,26 @@ public class User {
private String email;
public User(int id, String username, String password, String email) {
this.id = id;
this.username = username;
this.password = password;
this.email = email;
}
public String getUsername() {
return this.username;
}
public int getId() {
return this.id;
}
public String getEmail() {
return this.email;
}
public String getPassword() {
return this.password;
}
}
+57 -5
View File
@@ -1,23 +1,75 @@
package dev.service;
import dev.database.DatabaseConnection;
import dev.model.User;
import java.security.MessageDigest;
import java.sql.*;
import java.util.Base64;
public class AuthService {
private String hashPassword(String password) {
try {
MessageDigest digest = MessageDigest.getInstance("SHA-256");
byte[] hash = digest.digest(password.getBytes("UTF-8"));
return Base64.getEncoder().encodeToString(hash);
} catch (Exception e) {
throw new RuntimeException("Hashing failed", e);
}
}
public boolean register(String username, String password, String email) {
// TODO:
// Validate and register user
if (username == null || username.trim().isEmpty() || password == null || password.isEmpty()) {
System.out.println("Username and password cannot be empty.");
return false;
}
return false;
String sql = "INSERT INTO users (username, password, email) VALUES (?, ?, ?)";
try (Connection conn = DatabaseConnection.getConnection();
PreparedStatement pstmt = conn.prepareStatement(sql)) {
pstmt.setString(1, username);
pstmt.setString(2, hashPassword(password));
if (email == null || email.trim().isEmpty()) {
pstmt.setNull(3, Types.VARCHAR);
} else {
pstmt.setString(3, email);
}
pstmt.executeUpdate();
return true;
} catch (SQLException e) {
System.out.println("Registration failed (Username might already exist): " + e.getMessage());
return false;
}
}
public User login(String username, String password) {
// TODO:
// Authenticate user
String sql = "SELECT * FROM users WHERE username = ? AND password = ?";
try (Connection conn = DatabaseConnection.getConnection();
PreparedStatement pstmt = conn.prepareStatement(sql)) {
pstmt.setString(1, username);
pstmt.setString(2, hashPassword(password));
try (ResultSet rs = pstmt.executeQuery()) {
if (rs.next()) {
return new User(
rs.getInt("id"),
rs.getString("username"),
rs.getString("password"),
rs.getString("email")
);
}
}
} catch (SQLException e) {
System.out.println("Login error: " + e.getMessage());
}
return null;
}
}
+18 -3
View File
@@ -1,12 +1,27 @@
package dev.service;
import dev.dao.MenuItemDao;
import dev.model.MenuItem;
import java.util.List;
public class MenuService {
public void showMenu() {
final MenuItemDao menuItemDao = new MenuItemDao();
// TODO:
// Display menu items
List<MenuItem> items = menuItemDao.findAll();
if (items.isEmpty()) {
System.out.println("The menu is currently empty.");
return;
}
System.out.println("\n===== MENU =====");
for (MenuItem item : items) {
System.out.printf("[%d] %s - $%.2f (%s)\n", item.getId(), item.getName(), item.getPrice(), item.getCategory());
if (item.getDescription() != null) {
System.out.println(" " + item.getDescription());
}
}
}
}
+138 -6
View File
@@ -1,26 +1,158 @@
package dev.service;
import dev.dao.MenuItemDao;
import dev.database.DatabaseConnection;
import dev.model.MenuItem;
import java.sql.*;
import java.util.Scanner;
public class OrderService {
private final MenuItemDao menuItemDao = new MenuItemDao();
private final Scanner scanner = new Scanner(System.in);
public void placeOrder(int userId) {
Connection conn = null;
try {
conn = DatabaseConnection.getConnection();
conn.setAutoCommit(false);
// TODO:
// Create order
String insertOrderSql = "INSERT INTO orders (user_id, total_price) VALUES (?, 0.00)";
PreparedStatement orderStmt = conn.prepareStatement(insertOrderSql, Statement.RETURN_GENERATED_KEYS);
orderStmt.setInt(1, userId);
orderStmt.executeUpdate();
ResultSet generatedKeys = orderStmt.getGeneratedKeys();
int orderId = 0;
if (generatedKeys.next()) {
orderId = generatedKeys.getInt(1);
}
double grandTotal = 0.0;
boolean addingItems = true;
String insertDetailSql = "INSERT INTO order_details (order_id, menu_item_id, quantity, price_at_purchase) VALUES (?, ?, ?, ?)";
PreparedStatement detailStmt = conn.prepareStatement(insertDetailSql);
while (addingItems) {
System.out.print("Enter Menu Item ID to add (or 0 to finish): ");
int itemId = scanner.nextInt();
if (itemId == 0) {
addingItems = false;
continue;
}
MenuItem item = menuItemDao.findById(itemId);
if (item == null) {
System.out.println("Invalid Item ID. Try again.");
continue;
}
System.out.print("Enter quantity: ");
int quantity = scanner.nextInt();
if (quantity <= 0) {
System.out.println("Quantity must be greater than zero.");
continue;
}
double subtotal = (item.getPrice()) * quantity;
grandTotal += subtotal;
detailStmt.setInt(1, orderId);
detailStmt.setInt(2, item.getId());
detailStmt.setInt(3, quantity);
detailStmt.setDouble(4, item.getPrice());
detailStmt.executeUpdate();
}
if (grandTotal == 0.0) {
System.out.println("No items selected. Canceling order.");
conn.rollback();
return;
}
String updateOrderSql = "UPDATE orders SET total_price = ? WHERE id = ?";
PreparedStatement updateStmt = conn.prepareStatement(updateOrderSql);
updateStmt.setDouble(1, grandTotal);
updateStmt.setInt(2, orderId);
updateStmt.executeUpdate();
conn.commit();
System.out.println("Order successfully saved!");
printReceipt(orderId);
} catch (SQLException e) {
System.out.println("Order failed: " + e.getMessage());
if (conn != null) {
try { conn.rollback(); } catch (SQLException ex) { ex.printStackTrace(); }
}
}
}
public void printReceipt(int orderId) {
// TODO:
// Print order receipt
String sql = "SELECT od.quantity, od.price_at_purchase, m.name, o.total_price " +
"FROM order_details od " +
"JOIN menu_items m ON od.menu_item_id = m.id " +
"JOIN orders o ON od.order_id = o.id " +
"WHERE od.order_id = ?";
try (Connection conn = DatabaseConnection.getConnection();
PreparedStatement pstmt = conn.prepareStatement(sql)) {
pstmt.setInt(1, orderId);
try (ResultSet rs = pstmt.executeQuery()) {
System.out.println("\n========= RECEIPT (Order #" + orderId + ") =========");
double grandTotal = 0.0;
boolean hasRows = false;
while (rs.next()) {
hasRows = true;
String name = rs.getString("name");
int qty = rs.getInt("quantity");
double price = rs.getDouble("price_at_purchase");
double subtotal = qty * price;
grandTotal = rs.getDouble("total_price");
System.out.printf("- %s x%d @ $%.2f = $%.2f\n", name, qty, price, subtotal);
}
if (!hasRows) {
System.out.println("Order not found.");
return;
}
System.out.println("----------------------------------------");
System.out.printf("GRAND TOTAL: $%.2f\n", grandTotal);
System.out.println("========================================");
}
} catch (SQLException e) {
System.out.println("Error generating receipt: " + e.getMessage());
}
}
public void showOrderHistory(int userId) {
String sql = "SELECT id, created_at, total_price FROM orders WHERE user_id = ? ORDER BY created_at DESC";
// TODO:
// Display user's order history
try (Connection conn = DatabaseConnection.getConnection();
PreparedStatement pstmt = conn.prepareStatement(sql)) {
pstmt.setInt(1, userId);
try (ResultSet rs = pstmt.executeQuery()) {
System.out.println("\n===== YOUR ORDER HISTORY =====");
boolean hasHistory = false;
while (rs.next()) {
hasHistory = true;
System.out.printf("Order #%d | Date: %s | Total Spent: $%.2f\n",
rs.getInt("id"),
rs.getTimestamp("created_at").toString(),
rs.getDouble("total_price")
);
}
if (!hasHistory) {
System.out.println("You haven't placed any orders yet.");
}
}
} catch (SQLException e) {
System.out.println("Error fetching history: " + e.getMessage());
}
}
}
+71 -2
View File
@@ -1,11 +1,20 @@
package dev.ui;
import dev.model.MenuItem;
import dev.model.User;
import dev.service.AuthService;
import dev.service.MenuService;
import dev.service.OrderService;
import java.util.Scanner;
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() {
@@ -22,11 +31,11 @@ public class ConsoleMenu {
switch (choice) {
case 1:
// TODO
handleLogin();
break;
case 2:
// TODO
handleRegister();
break;
case 3:
@@ -41,4 +50,64 @@ public class ConsoleMenu {
}
private void handleRegister() {
System.out.print("Choose Username: ");
String user = scanner.nextLine();
System.out.print("Choose Password: ");
String pass = scanner.nextLine();
System.out.print("Email (Optional, press Enter to skip): ");
String email = scanner.nextLine();
if (authService.register(user, pass, email)) {
System.out.println("Registration successful! You can now log in.");
}
}
private void handleLogin() {
System.out.print("Username: ");
String user = scanner.nextLine();
System.out.print("Password: ");
String pass = scanner.nextLine();
User loggedInUser = authService.login(user, pass);
if (loggedInUser != null) {
System.out.println("Welcome back, " + loggedInUser.getUsername() + "!");
showCustomerDashboard(loggedInUser);
} else {
System.out.println("Invalid username or password.");
}
}
private void showCustomerDashboard(User user) {
while (true) {
System.out.println("\n===== CUSTOMER MENU =====");
System.out.println("1. Browse Menu");
System.out.println("2. Place 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(user.getId());
break;
case 3:
orderService.showOrderHistory(user.getId());
break;
case 4:
System.out.println("Logged out successfully.");
return;
default:
System.out.println("Invalid choice.");
}
}
}
}