This commit is contained in:
2026-07-12 12:47:46 +03:30
parent 00f990c653
commit bbabd5c04c
26 changed files with 1290 additions and 116 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="restaurant_db@localhost" uuid="084b5896-6664-4b67-8a51-71034b21913e">
<driver-ref>postgresql</driver-ref>
<synchronize>true</synchronize>
<jdbc-driver>org.postgresql.Driver</jdbc-driver>
<jdbc-url>jdbc:postgresql://localhost:5432/restaurant_db</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="Central Repository" />
<option name="url" value="https://maven.devneeds.ir/" />
</remote-repository>
<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>
</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" project-jdk-name="21" project-jdk-type="JavaSDK" />
</project>
+7
View File
@@ -0,0 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="SqlDialectMappings">
<file url="file://$PROJECT_DIR$/database.sql" dialect="GenericSQL" />
<file url="file://$PROJECT_DIR$/restaurant_db.sql" dialect="GenericSQL" />
</component>
</project>
Generated
+6
View File
@@ -0,0 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="VcsDirectoryMappings">
<mapping directory="" vcs="Git" />
</component>
</project>
+134
View File
@@ -139,3 +139,137 @@
-- SELECT * FROM ...;
-- SELECT * FROM ...;
-- SELECT * FROM ...;
-- =======================================================
-- Restaurant Database Management System
-- PostgreSQL Schema
-- =======================================================
-- -------------------------------------------------------
-- OPTIONAL CLEANUP
-- Uncomment if you want to reset the database completely
-- -------------------------------------------------------
-- 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
-- =======================================================
-- Represents customers using the system.
-- Requirements:
-- - Unique identifier
-- - Unique username
-- - Required username and password
-- - Passwords should not be stored in plain text
CREATE TABLE users (
id SERIAL PRIMARY KEY,
username VARCHAR(100) NOT NULL UNIQUE,
password_hash VARCHAR(255) NOT NULL,
email VARCHAR(255)
);
-- =======================================================
-- MENU ITEM TABLE
-- =======================================================
-- Represents available food and drink items.
-- Requirements:
-- - Unique identifier
-- - Name required
-- - Price positive
CREATE TABLE menu_items (
id SERIAL PRIMARY KEY,
name VARCHAR(150) NOT NULL,
description TEXT,
price DOUBLE PRECISION NOT NULL CHECK (price > 0),
category VARCHAR(100)
);
-- =======================================================
-- ORDER TABLE
-- =======================================================
-- Represents orders placed by customers.
-- Requirements:
-- - Each order belongs to exactly one user
-- - A user can have multiple orders
-- - Use non-reserved table name: orders
CREATE TABLE orders (
id SERIAL PRIMARY KEY,
user_id INT NOT NULL,
created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
total_price DOUBLE PRECISION NOT NULL DEFAULT 0 CHECK (total_price >= 0),
CONSTRAINT fk_orders_user
FOREIGN KEY (user_id)
REFERENCES users(id)
ON DELETE CASCADE
);
-- =======================================================
-- ORDER DETAIL TABLE
-- =======================================================
-- Represents items inside an order.
-- Requirements:
-- - Each detail belongs to one order
-- - Each detail references one menu item
-- - Quantity > 0
-- - Store item price at purchase time
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 DOUBLE PRECISION NOT NULL CHECK (price > 0),
CONSTRAINT fk_order_details_order
FOREIGN KEY (order_id)
REFERENCES orders(id)
ON DELETE CASCADE,
CONSTRAINT fk_order_details_menu_item
FOREIGN KEY (menu_item_id)
REFERENCES menu_items(id)
);
-- =======================================================
-- INITIAL MENU DATA
-- =======================================================
-- Insert at least 3 food/drink items
INSERT INTO menu_items (name, description, price, category) VALUES
('Margherita Pizza', 'Classic pizza with tomato sauce, mozzarella, and basil', 8.99, 'Pizza'),
('Pepperoni Pizza', 'Pizza topped with pepperoni and cheese', 10.99, 'Pizza'),
('Cheeseburger', 'Beef burger with cheddar cheese and lettuce', 7.50, 'Burger'),
('Pasta Carbonara', 'Creamy pasta with bacon and parmesan', 11.50, 'Pasta'),
('Coca Cola', 'Chilled soft drink', 1.50, 'Drink');
-- =======================================================
-- OPTIONAL TEST DATA
-- =======================================================
-- Sample user for testing (password is hashed placeholder)
INSERT INTO users (username, password_hash, email) VALUES
('testuser', '$2a$10$dummyhashforTestingOnly12345678901234567890', 'testuser@example.com');
-- Sample order for testing
INSERT INTO orders (user_id, created_at, total_price)
VALUES (1, CURRENT_TIMESTAMP, 0);
-- Sample order details for testing
INSERT INTO order_details (order_id, menu_item_id, quantity, price) VALUES
(1, 1, 2, 8.99),
(1, 5, 2, 1.50);
-- Update total price for the sample order
UPDATE orders
SET total_price = (
SELECT SUM(quantity * price)
FROM order_details
WHERE order_id = 1
)
WHERE id = 1;
-- =======================================================
-- VERIFICATION QUERIES
-- =======================================================
SELECT * FROM users;
SELECT * FROM menu_items;
SELECT * FROM orders;
SELECT * FROM order_details;
+6
View File
@@ -21,6 +21,12 @@
<dependencies>
<dependency>
<groupId>org.mindrot</groupId>
<artifactId>jbcrypt</artifactId>
<version>0.4</version>
</dependency>
<dependency>
<groupId>org.postgresql</groupId>
<artifactId>postgresql</artifactId>
+110
View File
@@ -0,0 +1,110 @@
CREATE TABLE users (
id SERIAL PRIMARY KEY,
username VARCHAR(100) NOT NULL UNIQUE,
password_hash VARCHAR(255) NOT NULL,
email VARCHAR(255)
);
-- =======================================================
-- MENU ITEM TABLE
-- =======================================================
-- Represents available food and drink items.
-- Requirements:
-- - Unique identifier
-- - Name required
-- - Price positive
CREATE TABLE menu_items (
id SERIAL PRIMARY KEY,
name VARCHAR(150) NOT NULL,
description TEXT,
price DOUBLE PRECISION NOT NULL CHECK (price > 0),
category VARCHAR(100)
);
-- =======================================================
-- ORDER TABLE
-- =======================================================
-- Represents orders placed by customers.
-- Requirements:
-- - Each order belongs to exactly one user
-- - A user can have multiple orders
-- - Use non-reserved table name: orders
CREATE TABLE orders (
id SERIAL PRIMARY KEY,
user_id INT NOT NULL,
created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
total_price DOUBLE PRECISION NOT NULL DEFAULT 0 CHECK (total_price >= 0),
CONSTRAINT fk_orders_user
FOREIGN KEY (user_id)
REFERENCES users(id)
ON DELETE CASCADE
);
-- =======================================================
-- ORDER DETAIL TABLE
-- =======================================================
-- Represents items inside an order.
-- Requirements:
-- - Each detail belongs to one order
-- - Each detail references one menu item
-- - Quantity > 0
-- - Store item price at purchase time
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 DOUBLE PRECISION NOT NULL CHECK (price > 0),
CONSTRAINT fk_order_details_order
FOREIGN KEY (order_id)
REFERENCES orders(id)
ON DELETE CASCADE,
CONSTRAINT fk_order_details_menu_item
FOREIGN KEY (menu_item_id)
REFERENCES menu_items(id)
ON DELETE RESTRICT
);
-- =======================================================
-- INITIAL MENU DATA
-- =======================================================
-- Insert at least 3 food/drink items
INSERT INTO menu_items (name, description, price, category) VALUES
('Margherita Pizza', 'Classic pizza with tomato sauce, mozzarella, and basil', 8.99, 'Pizza'),
('Pepperoni Pizza', 'Pizza topped with pepperoni and cheese', 10.99, 'Pizza'),
('Cheeseburger', 'Beef burger with cheddar cheese and lettuce', 7.50, 'Burger'),
('Pasta Carbonara', 'Creamy pasta with bacon and parmesan', 11.50, 'Pasta'),
('Coca Cola', 'Chilled soft drink', 1.50, 'Drink');
-- =======================================================
-- OPTIONAL TEST DATA
-- =======================================================
-- Sample user for testing (password is hashed placeholder)
INSERT INTO users (username, password_hash, email) VALUES
('testuser', '$2a$10$dummyhashforTestingOnly12345678901234567890', 'testuser@example.com');
-- Sample order for testing
INSERT INTO orders (user_id, created_at, total_price)
VALUES (1, CURRENT_TIMESTAMP, 0);
-- Sample order details for testing
INSERT INTO order_details (order_id, menu_item_id, quantity, price) VALUES
(1, 1, 2, 8.99),
(1, 5, 2, 1.50);
-- Update total price for the sample order
UPDATE orders
SET total_price = (
SELECT SUM(quantity * price)
FROM order_details
WHERE order_id = 1
)
WHERE id = 1;
-- =======================================================
-- VERIFICATION QUERIES
-- =======================================================
SELECT * FROM users;
SELECT * FROM menu_items;
SELECT * FROM orders;
SELECT * FROM order_details;
+12 -3
View File
@@ -1,12 +1,21 @@
package dev;
import dev.ui.ConsoleMenu;
import dev.service.AuthService;
import dev.service.MenuService;
import dev.service.OrderService;
public class Main {
public class Main
{
public static void main(String[] args) {
public static void main(String[] args)
{
ConsoleMenu menu = new ConsoleMenu();
AuthService authService = new AuthService();
MenuService menuService = new MenuService();
OrderService orderService = new OrderService();
ConsoleMenu menu = new ConsoleMenu(authService, menuService, orderService);
menu.start();
}
+58 -9
View File
@@ -1,24 +1,73 @@
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 class MenuItemDao
{
public List<MenuItem> findAll() {
public List<MenuItem> findAll()
{
// TODO:
// Retrieve all menu items
return null;
String sql = "SELECT * FROM menu_items";
List<MenuItem> items = new ArrayList<>();
try (Connection conn = DatabaseConnection.getConnection();
PreparedStatement pstmt = conn.prepareStatement(sql);
ResultSet rs = pstmt.executeQuery())
{
while (rs.next())
{
items.add(new MenuItem(
rs.getInt("id"),
rs.getString("name"),
rs.getString("description"),
rs.getDouble("price"),
rs.getString("category")
));
}
}
catch (SQLException e)
{
e.printStackTrace();
}
return items;
}
public MenuItem findById(int id) {
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)
{
e.printStackTrace();
}
return null;
}
+76 -9
View File
@@ -1,25 +1,92 @@
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 class OrderDao
{
public int save(Order order) {
public int save(Order order)
{
String sql = "INSERT INTO orders (user_id, created_at, total_price) VALUES (?, ?, ?)";
// TODO:
// Insert order and return generated id
try (Connection conn = DatabaseConnection.getConnection();
PreparedStatement pstmt = conn.prepareStatement(sql, Statement.RETURN_GENERATED_KEYS))
{
pstmt.setInt(1, order.getUserId());
pstmt.setTimestamp(2, Timestamp.valueOf(order.getCreatedAt()));
pstmt.setDouble(3, order.getTotalPrice());
int affectedRows = pstmt.executeUpdate();
if (affectedRows == 0) return -1;
try (ResultSet generatedKeys = pstmt.getGeneratedKeys())
{
if (generatedKeys.next())
{
return generatedKeys.getInt(1);
}
}
}
catch (SQLException e)
{
e.printStackTrace();
}
return -1;
}
public List<Order> findByUserId(int userId) {
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);
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 void updateTotalPrice(int orderId, double totalPrice)
{
String sql = "UPDATE orders SET total_price = ? WHERE id = ?";
try (Connection conn = DatabaseConnection.getConnection();
PreparedStatement pstmt = conn.prepareStatement(sql))
{
pstmt.setDouble(1, totalPrice);
pstmt.setInt(2, orderId);
pstmt.executeUpdate();
}
catch (SQLException e)
{
e.printStackTrace();
}
}
}
+62 -4
View File
@@ -1,24 +1,82 @@
package dev.dao;
import dev.model.OrderDetail;
import dev.database.DatabaseConnection;
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) {
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) 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.getPrice());
pstmt.executeUpdate();
}
catch (SQLException e)
{
System.err.println("Error saving order detail: " + e.getMessage());
}
}
public List<OrderDetail> findByOrderId(int orderId) {
public List<OrderDetail> findByOrderId(int orderId)
{
// TODO:
// Retrieve order details
return null;
String sql = "SELECT * FROM order_details WHERE order_id = ?";
List<OrderDetail> details = new ArrayList<>();
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")
);
details.add(detail);
}
}
}
catch (SQLException e)
{
System.err.println("Error finding order details: " + e.getMessage());
}
return details;
}
}
+57 -8
View File
@@ -2,21 +2,70 @@ package dev.dao;
import dev.model.User;
public class UserDao {
import dev.database.DatabaseConnection;
public boolean save(User user) {
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
// TODO:
// Insert user into database
public class UserDao
{
public boolean save(User user)
{
String sql = "INSERT INTO users (username, password_hash) VALUES (?, ?)";
try (Connection conn = DatabaseConnection.getConnection();
PreparedStatement pstmt = conn.prepareStatement(sql))
{
pstmt.setString(1, user.getUsername());
pstmt.setString(2, user.getPasswordHash());
int affectedRows = pstmt.executeUpdate();
return affectedRows > 0;
}
catch (SQLException e)
{
e.printStackTrace();
return false;
}
return false;
}
public User findByUsername(String username) {
public User findByUsername(String username)
{
String sql = "SELECT * FROM users WHERE username = ?";
// TODO:
// Find a user by username
try (Connection conn = DatabaseConnection.getConnection();
PreparedStatement pstmt = conn.prepareStatement(sql))
{
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.setPasswordHash(rs.getString("password_hash"));
user.setEmail(rs.getString("email"));
return user;
}
}
}
catch (SQLException e)
{
e.printStackTrace();
}
return null;
}
@@ -2,14 +2,16 @@ package dev.database;
import java.sql.Connection;
import java.sql.SQLException;
import java.sql.DriverManager;
public class DatabaseConnection {
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 = "Sa123456*";
private DatabaseConnection() {
@@ -18,10 +20,8 @@ public class DatabaseConnection {
public static Connection getConnection()
throws SQLException {
// TODO:
// Return a valid PostgreSQL connection
return null;
return DriverManager.getConnection(URL, USER, PASSWORD);
}
}
+73 -1
View File
@@ -1,6 +1,7 @@
package dev.model;
public class MenuItem {
public class MenuItem
{
private int id;
@@ -12,4 +13,75 @@ public class MenuItem {
private String category;
public MenuItem() {}
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 int getId()
{
return id;
}
public String getName()
{
return name;
}
public String getDescription()
{
return description;
}
public double getPrice()
{
return price;
}
public String getCategory()
{
return category;
}
public void setId(int id)
{
this.id = id;
}
public void setName(String name)
{
this.name = name;
}
public void setDescription(String description)
{
this.description = description;
}
public void setPrice(double price)
{
this.price = price;
}
public void setCategory(String category)
{
this.category = category;
}
@Override
public String toString()
{
return "MenuItem{" +
"id=" + id +
", name='" + name + '\'' +
", price=" + price +
'}';
}
}
+69 -4
View File
@@ -2,14 +2,79 @@ package dev.model;
import java.time.LocalDateTime;
public class Order {
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.createdAt = LocalDateTime.now();
this.totalPrice = totalPrice;
}
public Order(int id, int userId, LocalDateTime createdAt, double totalPrice)
{
this.id = id;
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;
}
@Override
public String toString()
{
return "Order{" +
"id=" + id +
", userId=" + userId +
", createdAt=" + createdAt +
", totalPrice=" + totalPrice +
'}';
}
}
+82 -5
View File
@@ -1,15 +1,92 @@
package dev.model;
public class OrderDetail {
public class OrderDetail
{
private int id;
private int orderId;
private int menuItemId;
private int quantity;
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 OrderDetail(int id, int orderId, int menuItemId, int quantity, double price)
{
this.id = id;
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;
}
@Override
public String toString()
{
return "OrderDetail{" +
"id=" + id +
", orderId=" + orderId +
", menuItemId=" + menuItemId +
", quantity=" + quantity +
", price=" + price +
'}';
}
}
+71 -2
View File
@@ -1,13 +1,82 @@
package dev.model;
public class User {
public class User
{
private int id;
private String username;
private String password;
private String passwordHash;
private String email;
public User() {}
public User(String username, String passwordHash, String email)
{
this.username = username;
this.passwordHash = passwordHash;
this.email = email;
}
public User(int id, String username, String passwordHash, String email)
{
this.id = id;
this.username = username;
this.passwordHash = passwordHash;
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 username)
{
this.username = username;
}
public String getPasswordHash()
{
return passwordHash;
}
public void setPasswordHash(String passwordHash)
{
this.passwordHash = passwordHash;
}
public String getEmail()
{
return email;
}
public void setEmail(String email)
{
this.email = email;
}
@Override
public String toString()
{
return "User{" +
"id=" + id +
", username='" + username + '\'' +
", email='" + email + '\'' +
'}';
}
}
+35 -9
View File
@@ -1,23 +1,49 @@
package dev.service;
import dev.dao.UserDao;
import dev.model.User;
import org.mindrot.jbcrypt.BCrypt;
public class AuthService {
public class AuthService
{
private final UserDao userDao = new UserDao();
public boolean register(String username, String password, String email) {
public boolean register(String username, String password, String email)
{
// TODO:
// Validate and register user
return false;
if (username == null || username.isBlank()) return false;
if (password == null || password.isBlank()) return false;
if (email == null || email.isBlank()) return false;
User existing = userDao.findByUsername(username.trim());
if (existing != null) return false;
String passwordHash = BCrypt.hashpw(password, BCrypt.gensalt(12));
User user = new User();
user.setUsername(username.trim());
user.setPasswordHash(passwordHash);
user.setEmail(email.trim());
return userDao.save(user);
}
public User login(String username, String password) {
public User login(String username, String password)
{
// TODO:
// Authenticate user
if (username == null || username.isBlank()) return null;
if (password == null || password.isBlank()) return null;
User user = userDao.findByUsername(username.trim());
if (user == null) return null;
boolean ok = BCrypt.checkpw(password, user.getPasswordHash());
return ok ? user : null;
return null;
}
}
+31 -5
View File
@@ -1,12 +1,38 @@
package dev.service;
public class MenuService {
import dev.dao.MenuItemDao;
import dev.model.MenuItem;
import dev.ui.ConsoleStyle;
import java.util.List;
public void showMenu() {
public class MenuService
{
// TODO:
// Display menu items
private final MenuItemDao menuItemDao = new MenuItemDao();
public void showMenu()
{
List<MenuItem> menuItems = menuItemDao.findAll();
if (menuItems == null || menuItems.isEmpty())
{
ConsoleStyle.printError("No menu items available.");
return;
}
ConsoleStyle.printHeader("📋 MENU ITEMS");
System.out.printf("%-5s %-25s %-10s %-15s%n", "ID", "Name", "Price", "Category");
ConsoleStyle.printLine();
for (MenuItem item : menuItems)
{
System.out.printf(
"%-5d %-25s $%-9.2f %-15s%n",
item.getId(),
item.getName(),
item.getPrice(),
item.getCategory() == null ? "-" : item.getCategory()
);
}
}
}
+131 -10
View File
@@ -1,26 +1,147 @@
package dev.service;
public class OrderService {
import dev.dao.MenuItemDao;
import dev.dao.OrderDao;
import dev.dao.OrderDetailDao;
import dev.model.Order;
import dev.model.OrderDetail;
import dev.model.MenuItem;
import dev.ui.ConsoleStyle;
import java.time.LocalDateTime;
import java.util.List;
import java.util.Scanner;
public void placeOrder(int userId) {
public class OrderService
{
// TODO:
// Create order
private final OrderDao orderDao = new OrderDao();
private final OrderDetailDao orderDetailDao = new OrderDetailDao();
private final MenuItemDao menuItemDao = new MenuItemDao();
private final Scanner scanner = new Scanner(System.in);
public void placeOrder(int userId)
{
System.out.println("\n--- Create New Order ---");
Order order = new Order();
order.setUserId(userId);
order.setCreatedAt(LocalDateTime.now());
order.setTotalPrice(0.0);
int orderId = orderDao.save(order);
if (orderId == -1)
{
System.out.println("Failed to create order.");
return;
}
double total = 0;
List<OrderDetail> details = new java.util.ArrayList<>();
while (true)
{
System.out.print("Enter Menu Item ID (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("Quantity for " + item.getName() + ": ");
int quantity = scanner.nextInt();
OrderDetail detail = new OrderDetail();
detail.setOrderId(orderId);
detail.setMenuItemId(itemId);
detail.setQuantity(quantity);
detail.setPrice(item.getPrice());
orderDetailDao.save(detail);
details.add(detail);
total += (item.getPrice() * quantity);
System.out.println("Added: " + item.getName() + " x" + quantity);
}
order.setId(orderId);
order.setTotalPrice(total);
orderDao.updateTotalPrice(orderId, total);
System.out.println("Order #" + orderId + " placed successfully. Total: $" + total);
printReceipt(order, details);
}
public void printReceipt(int orderId) {
private void printReceipt(Order order, List<OrderDetail> details)
{
ConsoleStyle.printHeader("🧾 RECEIPT ");
// TODO:
// Print order receipt
System.out.println("Order ID: " + order.getId());
System.out.println("Date : " + order.getCreatedAt().toString().replace("T", " "));
ConsoleStyle.printLine();
System.out.printf("%-20s %-8s %-12s %-12s%n", "Item Name", "Qty", "Unit Price", "Total");
ConsoleStyle.printLine();
for (OrderDetail detail : details)
{
MenuItem item = menuItemDao.findById(detail.getMenuItemId());
String itemName = (item != null) ? item.getName() : "Item #" + detail.getMenuItemId();
double lineTotal = detail.getQuantity() * detail.getPrice();
System.out.printf(
"%-20s %-8d $%-11.2f $%-11.2f%n",
itemName,
detail.getQuantity(),
detail.getPrice(),
lineTotal
);
}
ConsoleStyle.printLine();
System.out.printf("%-42s $%.2f%n", "Grand Total:", order.getTotalPrice());
ConsoleStyle.printLine();
}
public void showOrderHistory(int userId) {
public void showOrderHistory(int userId)
{
System.out.println("\n--- 📜 Order History (Detailed) ---");
List<Order> history = orderDao.findByUserId(userId);
// TODO:
// Display user's order history
if (history.isEmpty())
{
System.out.println("You have no previous orders.");
return;
}
for (Order o : history) {
System.out.println("==========================================");
System.out.printf("ORDER ID: %-5d | Date: %s\n", o.getId(), o.getCreatedAt().toString().replace("T", " "));
System.out.println("Items:");
List<OrderDetail> details = orderDetailDao.findByOrderId(o.getId());
for (OrderDetail detail : details)
{
MenuItem item = menuItemDao.findById(detail.getMenuItemId());
String itemName = (item != null) ? item.getName() : "Unknown Item";
System.out.printf(" - %-20s x%-3d ($%.2f)\n", itemName, detail.getQuantity(), detail.getPrice());
}
System.out.printf("TOTAL: $%.2f\n", o.getTotalPrice());
}
System.out.println("==========================================");
}
}
+146 -35
View File
@@ -1,44 +1,155 @@
package dev.ui;
import dev.model.User;
import dev.service.AuthService;
import dev.service.OrderService;
import dev.service.MenuService;
import java.util.Scanner;
public class ConsoleMenu {
public class ConsoleMenu
{
private final Scanner scanner =
new Scanner(System.in);
public void start() {
while (true) {
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();
switch (choice) {
case 1:
// TODO
break;
case 2:
// TODO
break;
case 3:
return;
default:
System.out.println("Invalid choice");
}
}
private final AuthService authService;
private final MenuService menuService;
private final OrderService orderService;
private final Scanner scanner;
private User currentUser;
public ConsoleMenu(AuthService authService, MenuService menuService, OrderService orderService)
{
this.authService = authService;
this.menuService = menuService;
this.orderService = orderService;
this.scanner = new Scanner(System.in);
}
public void start()
{
while (true)
{
if (currentUser == null)
{
showGuestMenu();
}
else
{
showUserMenu();
}
}
}
private void showGuestMenu()
{
ConsoleStyle.printHeader("🍕 WELCOME TO JAVA PIZZERIA 🍕");
System.out.println("1. Login");
System.out.println("2. Register New Account");
System.out.println("3. Exit");
ConsoleStyle.printLine();
System.out.print("Choose an option: ");
String input = scanner.nextLine().trim();
switch (input)
{
case "1":
handleLogin();
break;
case "2":
handleRegister();
break;
case "3":
ConsoleStyle.printInfo("Goodbye! See you soon.");
System.exit(0);
break;
default:
System.out.println("Invalid choice.");
}
}
private void showUserMenu()
{
ConsoleStyle.printHeader("🍽️ MAIN MENU - Welcome, " + currentUser.getUsername() + " 🍽️");
System.out.println("1. View Menu");
System.out.println("2. Place New Order");
System.out.println("3. View Order History");
System.out.println("4. Logout");
System.out.println("5. Exit");
ConsoleStyle.printLine();
System.out.print("Choose an option: ");
String input = scanner.nextLine().trim();
switch (input)
{
case "1"->
menuService.showMenu();
case "2"->
orderService.placeOrder(currentUser.getId());
case "3" ->
orderService.showOrderHistory(currentUser.getId());
case "4"->{
currentUser = null;
ConsoleStyle.printSuccess("Logged out successfully.");
}
case "5"->{
ConsoleStyle.printInfo("Goodbye! See you soon.");
System.exit(0);
}
default->
ConsoleStyle.printError("Invalid choice.");
}
}
private void handleLogin()
{
System.out.println("\n--- Login ---");
System.out.print("Username: ");
String username = scanner.nextLine().trim();
System.out.print("Password: ");
String password = scanner.nextLine();
User user = authService.login(username, password);
if (user != null)
{
currentUser = user;
ConsoleStyle.printSuccess("Login successful! Welcome back, " + user.getUsername() + ".");
}
else
{
ConsoleStyle.printError("Invalid username or password.");
}
}
private void handleRegister()
{
System.out.println("\n--- Register ---");
System.out.print("Enter username: ");
String username = scanner.nextLine().trim();
System.out.print("Enter password: ");
String password = scanner.nextLine();
System.out.print("Enter email: ");
String email = scanner.nextLine().trim();
boolean success = authService.register(username, password, email);
if (success)
{
ConsoleStyle.printSuccess("Registration successful! You can now login.");
}
else
{
ConsoleStyle.printError("Registration failed. Username might be taken.");
}
}
}
+38
View File
@@ -0,0 +1,38 @@
package dev.ui;
public class ConsoleStyle
{
public static final String RESET = "\u001B[0m";
public static final String BOLD = "\u001B[1m";
public static final String RED = "\u001B[31m";
public static final String GREEN = "\u001B[32m";
public static final String YELLOW = "\u001B[33m";
public static final String BLUE = "\u001B[34m";
public static final String CYAN = "\u001B[36m";
public static void printHeader(String title) {
System.out.println(CYAN + "===============================================" + RESET);
System.out.println(CYAN + BOLD + " " + title + RESET);
System.out.println(CYAN + "===============================================" + RESET);
}
public static void printSuccess(String message)
{
System.out.println(GREEN + "" + message + RESET);
}
public static void printError(String message)
{
System.out.println(RED + "" + message + RESET);
}
public static void printInfo(String message) {
System.out.println(YELLOW + " " + message + RESET);
}
public static void printLine()
{
System.out.println(CYAN + "-----------------------------------------------" + RESET);
}
}