Compare commits

7 Commits
Author SHA1 Message Date
HadiSharifi 78a1c5e678 complete consoleMenu class 2026-06-29 21:57:17 +03:30
HadiSharifi 95e75c02ba complete consoleMenu class 2026-06-29 21:31:02 +03:30
HadiSharifi ccf7343a26 complete service classes 2026-06-29 21:28:54 +03:30
HadiSharifi f458a48ee2 complete dao classes 2026-06-29 21:27:04 +03:30
HadiSharifi d7c2790562 complete model classes 2026-06-29 21:24:01 +03:30
HadiSharifi 735139f4a4 complete user class 2026-06-29 21:17:57 +03:30
HadiSharifi fc297103fa feat: database.sql 2026-06-29 21:13:09 +03:30
15 changed files with 467 additions and 217 deletions
+2
View File
@@ -2,6 +2,8 @@
# Compiled class file
*.class
.idea/
# Log file
*.log
+32 -120
View File
@@ -1,141 +1,53 @@
-- 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) NOT NULL UNIQUE,
password_hash 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 NUMERIC(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 REFERENCES users(id) ON DELETE CASCADE,
created_at TIMESTAMP NOT NULL DEFAULT NOW(),
total_price NUMERIC(10, 2) NOT NULL CHECK (total_price >= 0)
);
-- =======================================================
-- 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 REFERENCES orders(id) ON DELETE CASCADE,
menu_item_id INT NOT NULL REFERENCES menu_items(id),
quantity INT NOT NULL CHECK (quantity > 0),
unit_price NUMERIC(10, 2) NOT NULL CHECK (unit_price > 0)
);
-- =======================================================
-- 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 ...;
INSERT INTO menu_items (name, description, price, category) VALUES
('Margherita Pizza', 'Classic tomato sauce and mozzarella', 10.00, 'Pizza'),
('BBQ Burger', 'Juicy beef patty with BBQ sauce', 8.50, 'Burger'),
('Spaghetti Carbonara', 'Creamy pasta with pancetta and egg', 12.00, 'Pasta'),
('Tiramisu', 'Italian coffee dessert', 5.50, 'Dessert'),
('Cola', 'Ice-cold soft drink', 2.50, 'Drink');
+40 -6
View File
@@ -1,25 +1,59 @@
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_items ORDER BY category, name";
// TODO:
// Retrieve all menu items
try (Connection conn = DatabaseConnection.getConnection();
PreparedStatement ps = conn.prepareStatement(sql);
ResultSet rs = ps.executeQuery()) {
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) {
System.out.println("Error fetching menu: " + e.getMessage());
}
return items;
}
public MenuItem findById(int id) {
String sql = "SELECT * FROM menu_items WHERE id = ?";
try (Connection conn = DatabaseConnection.getConnection();
PreparedStatement ps = conn.prepareStatement(sql)) {
// TODO:
// Find menu item by id
ps.setInt(1, id);
ResultSet rs = ps.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) {
System.out.println("Error finding menu item: " + e.getMessage());
}
return null;
}
}
+34 -6
View File
@@ -1,25 +1,53 @@
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) {
String sql = "INSERT INTO orders (user_id, total_price) VALUES (?, ?) RETURNING id";
try (Connection conn = DatabaseConnection.getConnection();
PreparedStatement ps = conn.prepareStatement(sql)) {
// TODO:
// Insert order and return generated id
ps.setInt(1, order.getUserId());
ps.setDouble(2, order.getTotalPrice());
ResultSet rs = ps.executeQuery();
if (rs.next()) return rs.getInt(1); // return generated id
} catch (SQLException e) {
System.out.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 ps = conn.prepareStatement(sql)) {
return null;
ps.setInt(1, userId);
ResultSet rs = ps.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) {
System.out.println("Error fetching orders: " + e.getMessage());
}
return orders;
}
}
+35 -6
View File
@@ -1,24 +1,53 @@
package dev.dao;
import dev.database.DatabaseConnection;
import dev.model.OrderDetail;
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, unit_price) VALUES (?, ?, ?, ?)";
try (Connection conn = DatabaseConnection.getConnection();
PreparedStatement ps = conn.prepareStatement(sql)) {
// TODO:
// Insert order detail
ps.setInt(1, detail.getOrderId());
ps.setInt(2, detail.getMenuItemId());
ps.setInt(3, detail.getQuantity());
ps.setDouble(4, detail.getPrice());
ps.executeUpdate();
} catch (SQLException e) {
System.out.println("Error saving order detail: " + e.getMessage());
}
}
public List<OrderDetail> findByOrderId(int orderId) {
List<OrderDetail> details = new ArrayList<>();
String sql = "SELECT * FROM order_details WHERE order_id = ?";
// TODO:
// Retrieve order details
try (Connection conn = DatabaseConnection.getConnection();
PreparedStatement ps = conn.prepareStatement(sql)) {
return null;
ps.setInt(1, orderId);
ResultSet rs = ps.executeQuery();
while (rs.next()) {
OrderDetail d = new OrderDetail();
d.setId(rs.getInt("id"));
d.setOrderId(rs.getInt("order_id"));
d.setMenuItemId(rs.getInt("menu_item_id"));
d.setQuantity(rs.getInt("quantity"));
d.setPrice(rs.getDouble("unit_price"));
details.add(d);
}
} catch (SQLException e) {
System.out.println("Error fetching order details: " + e.getMessage());
}
return details;
}
}
+31 -6
View File
@@ -1,23 +1,48 @@
package dev.dao;
import dev.database.DatabaseConnection;
import dev.model.User;
import java.sql.*;
public class UserDao {
public boolean save(User user) {
String sql = "INSERT INTO users (username, password_hash, email) VALUES (?, ?, ?)";
try (Connection conn = DatabaseConnection.getConnection();
PreparedStatement ps = conn.prepareStatement(sql)) {
// TODO:
// Insert user into database
ps.setString(1, user.getUsername());
ps.setString(2, user.getPassword());
ps.setString(3, user.getEmail());
return ps.executeUpdate() > 0;
return false;
} catch (SQLException e) {
System.out.println("Error saving user: " + e.getMessage());
return false;
}
}
public User findByUsername(String username) {
String sql = "SELECT * FROM users WHERE username = ?";
try (Connection conn = DatabaseConnection.getConnection();
PreparedStatement ps = conn.prepareStatement(sql)) {
// TODO:
// Find a user by username
ps.setString(1, username);
ResultSet rs = ps.executeQuery();
if (rs.next()) {
User user = new User();
user.setId(rs.getInt("id"));
user.setUsername(rs.getString("username"));
user.setPassword(rs.getString("password_hash"));
user.setEmail(rs.getString("email"));
return user;
}
} catch (SQLException e) {
System.out.println("Error finding user: " + e.getMessage());
}
return null;
}
}
@@ -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 URL = "jdbc:postgresql://localhost:5432/restaurant_db";
private static final String USER = "postgres"; // Your Username
private static final String USER = "postgres";
private static final String PASSWORD = "password"; // Your Password
private static final String PASSWORD = "password";
private DatabaseConnection() {
@@ -18,10 +19,7 @@ public class DatabaseConnection {
public static Connection getConnection()
throws SQLException {
// TODO:
// Return a valid PostgreSQL connection
return null;
return DriverManager.getConnection(URL, USER, PASSWORD);
}
}
+17 -6
View File
@@ -1,15 +1,26 @@
package dev.model;
public class MenuItem {
private int id;
private int id;
private String name;
private String description;
private double price;
private String category;
public MenuItem() {}
public int getId(){ return id; }
public void setId(int id){ this.id = id; }
public String getName(){ return name; }
public void setName(String n){ this.name = n; }
public String getDescription(){ return description; }
public void setDescription(String d){ this.description = d; }
public double getPrice(){ return price; }
public void setPrice(double p){ this.price = p; }
public String getCategory(){ return category; }
public void setCategory(String c){ this.category = c; }
}
+19 -4
View File
@@ -3,13 +3,28 @@ package dev.model;
import java.time.LocalDateTime;
public class Order {
private int id;
private int userId;
private LocalDateTime createdAt;
private double totalPrice;
public Order() {}
public Order(int userId, double totalPrice) {
this.userId = userId;
this.totalPrice = totalPrice;
this.createdAt = LocalDateTime.now();
}
public int getId(){ return id; }
public void setId(int id){ this.id = id; }
public int getUserId() { return userId; }
public void setUserId(int uid){ this.userId = uid; }
public LocalDateTime getCreatedAt(){ return createdAt; }
public void setCreatedAt(LocalDateTime t){ this.createdAt = t; }
public double getTotalPrice(){ return totalPrice; }
public void setTotalPrice(double p){ this.totalPrice = p; }
}
+23 -5
View File
@@ -1,15 +1,33 @@
package dev.model;
public class OrderDetail {
private int id;
private int orderId;
private int menuItemId;
private int quantity;
private double price; // unit price at purchase time
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 o){ this.orderId = o; }
public int getMenuItemId(){ return menuItemId; }
public void setMenuItemId(int m){ this.menuItemId = m; }
public int getQuantity(){ return quantity; }
public void setQuantity(int q){ this.quantity = q; }
public double getPrice(){ return price; }
public void setPrice(double p){ this.price = p; }
}
+20 -5
View File
@@ -1,13 +1,28 @@
package dev.model;
public class User {
private int id;
private String username;
private String password;
private String password; // holds the hash when loaded from DB
private String email;
public User() {}
public User(String username, String password, String email) {
this.username = username;
this.password = password;
this.email = email;
}
public int getId(){ return id; }
public void setId(int id) { this.id = id; }
public String getUsername(){ return username; }
public void setUsername(String u){ this.username = u; }
public String getPassword() { return password; }
public void setPassword(String p){ this.password = p; }
public String getEmail(){ return email; }
public void setEmail(String e){ this.email = e; }
}
+39 -11
View File
@@ -1,23 +1,51 @@
package dev.service;
import dev.dao.UserDao;
import dev.model.User;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
public class AuthService {
private final UserDao userDao = new UserDao();
private String hashPassword(String password) {
try {
MessageDigest md = MessageDigest.getInstance("SHA-256");
byte[] hash = md.digest(password.getBytes());
StringBuilder sb = new StringBuilder();
for (byte b : hash) sb.append(String.format("%02x", b));
return sb.toString();
} catch (NoSuchAlgorithmException e) {
throw new RuntimeException("Hashing error", e);
}
}
public boolean register(String username, String password, String email) {
// TODO:
// Validate and register user
return false;
if (username == null || username.isBlank() || password == null || password.isBlank()) {
System.out.println("Username and password are required.");
return false;
}
if (userDao.findByUsername(username) != null) {
System.out.println("Username already taken.");
return false;
}
User user = new User(username, hashPassword(password), email.isBlank() ? null : email);
return userDao.save(user);
}
public User login(String username, String password) {
// TODO:
// Authenticate user
return null;
User user = userDao.findByUsername(username);
if (user == null) {
System.out.println("User not found.");
return null;
}
if (!user.getPassword().equals(hashPassword(password))) {
System.out.println("Incorrect password.");
return null;
}
return user;
}
}
+19 -4
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() {
// TODO:
// Display menu items
private final MenuItemDao menuItemDao = new MenuItemDao();
public List<MenuItem> getMenuItems() {
return menuItemDao.findAll();
}
public void showMenu() {
List<MenuItem> items = getMenuItems();
System.out.println("\n--- MENU ---");
System.out.printf("%-5s %-25s %-12s %s%n", "ID", "Name", "Price", "Category");
System.out.println("-".repeat(55));
for (MenuItem item : items) {
System.out.printf("%-5d %-25s $%-11.2f %s%n",
item.getId(), item.getName(), item.getPrice(), item.getCategory());
}
System.out.println("-".repeat(55));
}
}
+86 -8
View File
@@ -1,26 +1,104 @@
package dev.service;
import dev.dao.MenuItemDao;
import dev.dao.OrderDao;
import dev.dao.OrderDetailDao;
import dev.model.MenuItem;
import dev.model.Order;
import dev.model.OrderDetail;
import java.util.*;
public class OrderService {
private final MenuItemDao menuItemDao = new MenuItemDao();
private final OrderDao orderDao = new OrderDao();
private final OrderDetailDao orderDetailDao = new OrderDetailDao();
private final MenuService menuService = new MenuService();
private final Scanner scanner;
public OrderService(Scanner scanner) {
this.scanner = scanner;
}
public void placeOrder(int userId) {
menuService.showMenu();
// TODO:
// Create order
Map<Integer, int[]> cart = new LinkedHashMap<>(); // int[] = {quantity}
Map<Integer, MenuItem> itemMap = new HashMap<>();
while (true) {
System.out.print("\nEnter item ID to add (0 to finish): ");
int id = scanner.nextInt();
if (id == 0) break;
MenuItem item = menuItemDao.findById(id);
if (item == null) {
System.out.println("Item not found, try again.");
continue;
}
System.out.print("Enter quantity: ");
int qty = scanner.nextInt();
if (qty <= 0) { System.out.println("Quantity must be > 0."); continue; }
cart.merge(id, new int[]{qty}, (a, b) -> new int[]{a[0] + b[0]});
itemMap.put(id, item);
System.out.printf("Added %dx %s%n", qty, item.getName());
}
if (cart.isEmpty()) { System.out.println("No items selected."); return; }
// Calculate total
double total = cart.entrySet().stream()
.mapToDouble(e -> itemMap.get(e.getKey()).getPrice() * e.getValue()[0])
.sum();
// Save order
Order order = new Order(userId, total);
int orderId = orderDao.save(order);
if (orderId == -1) { System.out.println("Failed to save order."); return; }
// Save order details
for (Map.Entry<Integer, int[]> entry : cart.entrySet()) {
MenuItem item = itemMap.get(entry.getKey());
OrderDetail detail = new OrderDetail(orderId, item.getId(), entry.getValue()[0], item.getPrice());
orderDetailDao.save(detail);
}
printReceipt(orderId);
}
public void printReceipt(int orderId) {
List<OrderDetail> details = orderDetailDao.findByOrderId(orderId);
System.out.println("\n--- RECEIPT ---");
System.out.printf("%-20s %5s %8s %8s%n", "Item", "Qty", "Unit", "Total");
System.out.println("-".repeat(47));
// TODO:
// Print order receipt
double grandTotal = 0;
for (OrderDetail d : details) {
MenuItem item = menuItemDao.findById(d.getMenuItemId());
String name = (item != null) ? item.getName() : "Unknown";
double subtotal = d.getPrice() * d.getQuantity();
grandTotal += subtotal;
System.out.printf("%-20s %5d $%7.2f $%7.2f%n",
name, d.getQuantity(), d.getPrice(), subtotal);
}
System.out.println("-".repeat(47));
System.out.printf("%-20s %18s $%7.2f%n", "TOTAL", "", grandTotal);
System.out.println("Order saved successfully!");
}
public void showOrderHistory(int userId) {
List<Order> orders = orderDao.findByUserId(userId);
if (orders.isEmpty()) { System.out.println("No past orders."); return; }
// TODO:
// Display user's order history
System.out.println("\n--- ORDER HISTORY ---");
System.out.printf("%-8s %-25s %s%n", "Order#", "Date", "Total");
System.out.println("-".repeat(45));
for (Order o : orders) {
System.out.printf("%-8d %-25s $%.2f%n",
o.getId(), o.getCreatedAt().toString().replace("T", " "), o.getTotalPrice());
}
System.out.println("-".repeat(45));
}
}
+65 -23
View File
@@ -1,44 +1,86 @@
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 final Scanner scanner =
new Scanner(System.in);
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(scanner);
public void start() {
while (true) {
System.out.println();
System.out.println("===== JAVA PIZZERIA =====");
System.out.println("\n===========================");
System.out.println(" 🍕 JAVA PIZZERIA 🍕");
System.out.println("===========================");
System.out.println("1. Login");
System.out.println("2. Register");
System.out.println("3. Exit");
System.out.print("Choose: ");
int choice = scanner.nextInt();
scanner.nextLine(); // consume newline
switch (choice) {
case 1:
// TODO
break;
case 2:
// TODO
break;
case 3:
return;
default:
System.out.println("Invalid choice");
case 1 -> {
User user = handleLogin();
if (user != null) showMainMenu(user);
}
case 2 -> handleRegister();
case 3 -> { System.out.println("Goodbye!"); return; }
default -> System.out.println("Invalid choice.");
}
}
}
private void handleRegister() {
System.out.println("\n[Register]");
System.out.print("Username: "); String username = scanner.nextLine();
System.out.print("Password: "); String password = scanner.nextLine();
System.out.print("Email (optional, press Enter to skip): "); String email = scanner.nextLine();
if (authService.register(username, password, email)) {
System.out.println("Registration successful! Please log in.");
}
}
private User handleLogin() {
System.out.println("\n[Login]");
System.out.print("Username: "); String username = scanner.nextLine();
System.out.print("Password: "); String password = scanner.nextLine();
User user = authService.login(username, password);
if (user != null) System.out.println("Welcome, " + user.getUsername() + "!");
return user;
}
private void showMainMenu(User 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 Order");
System.out.println("3. Order History");
System.out.println("4. Logout");
System.out.print("Choose: ");
int choice = scanner.nextInt();
scanner.nextLine();
switch (choice) {
case 1 -> menuService.showMenu();
case 2 -> orderService.placeOrder(user.getId());
case 3 -> orderService.showOrderHistory(user.getId());
case 4 -> { System.out.println("Logged out."); return; }
default -> System.out.println("Invalid choice.");
}
}
}
}