A multi-role, multi-branch Point of Sale (POS) system built with JavaFX and MySQL. ZyroPOS supports four distinct user roles with hierarchical permissions, inventory management, sales tracking, and analytics dashboards.
- Overview
- Tech Stack
- Architecture
- Project Structure
- Database Schema
- User Roles & Features
- Application Flow
- Setup & Installation
- Default Credentials
- Build & Run
- Security
- Design Patterns
- Author
ZyroPOS is a desktop POS application that manages retail operations across multiple store branches. It provides:
- Role-based access control with four user types
- Real-time inventory tracking with low-stock alerts
- POS cart and billing for cashiers
- Vendor and product catalog management
- Sales analytics with daily/weekly/monthly/yearly breakdowns
- Multi-branch management from a central super admin
| Component | Technology | Version |
|---|---|---|
| Language | Java | 19 |
| UI Framework | JavaFX | 19.0.2 |
| Build Tool | Maven | 3.11.0 |
| Database | MySQL | 8.2.0 |
| Connection Pool | HikariCP | 5.1.0 |
| UI Components | JFoenix | 9.0.10 |
| Password Security | jBCrypt | 0.4 |
| Configuration | dotenv-java | 3.0.0 |
| Logging | SLF4J + Logback | 2.0.9 |
| Testing | JUnit 5 | 5.10.0 |
ZyroPOS follows the MVC + DAO pattern:
View (FXML) <-> Controller (JavaFX) <-> DAO (Data Access) <-> MySQL (HikariCP)
- Models — Plain Java objects:
Product,Sale,Branch,Vendor,Cashier, etc. - Views — FXML files defining all UI layouts
- Controllers — Handle UI logic and call DAOs
- DAOs — Encapsulate all SQL queries and database interactions
- DatabaseConnection — Singleton managing the HikariCP connection pool
ZyroPOS/
├── src/main/java/
│ ├── database/
│ │ ├── DatabaseConnection.java # Singleton HikariCP pool
│ │ ├── DatabaseSetup.java # Schema creation & seeding
│ │ └── dao/
│ │ ├── BaseDAO.java # Shared DB access utilities
│ │ ├── LoginDAO.java # Authentication
│ │ ├── AdminDAO.java # Branch manager operations
│ │ ├── CashierDAO.java # POS transactions
│ │ ├── DataOperatorDAO.java # Inventory management
│ │ ├── SuperAdminDAO.java # System administration
│ │ └── DashboardDAO.java # Shared dashboard metrics
│ ├── org/example/zyropos/
│ │ ├── App.java # Entry point
│ │ ├── Product.java
│ │ ├── Sale.java
│ │ ├── Branch.java
│ │ ├── Vendor.java
│ │ ├── Cashier.java
│ │ ├── DataOperator.java
│ │ ├── BranchManager.java
│ │ ├── CashierProduct.java # Cart item model
│ │ ├── SplashController.java
│ │ ├── GeneralLoginController.java
│ │ ├── LoginController.java # Abstract login base
│ │ ├── DashboardController.java # Abstract dashboard base
│ │ ├── SuperAdminController.java
│ │ ├── AdminController.java
│ │ ├── CashierController.java
│ │ └── DataOperatorController.java
│ └── utilities/
│ ├── Config.java # Dotenv loader (Singleton)
│ ├── PasswordUtil.java # BCrypt helpers
│ └── Values.java # Global constants
├── src/main/resources/
│ └── org/example/zyropos/
│ ├── fxml/
│ │ ├── Splash.fxml
│ │ ├── GeneralLogin.fxml
│ │ ├── SuperAdminLogin.fxml
│ │ ├── AdminLogin.fxml
│ │ ├── CashierLogin.fxml
│ │ ├── DataOperatorLogin.fxml
│ │ ├── SuperAdmin.fxml
│ │ ├── Admin.fxml
│ │ ├── Cashier.fxml
│ │ └── DataOperator.fxml
│ ├── css/
│ │ └── styles.css
│ └── assets/ # Logos and images
├── .env # DB credentials (not committed)
├── .env.example # Credentials template
└── pom.xml
Nine tables with soft-delete support (is_deleted flag) and audit timestamps (created_at, updated_at).
| Table | Purpose |
|---|---|
super_admin |
System administrator account |
branch |
Store locations |
branch_manager |
Admins assigned to branches |
cashier |
POS operators per branch |
data_operator |
Inventory managers per branch |
vendor |
Suppliers providing products |
product |
Inventory catalog |
sales |
Sale transaction headers |
sale_details |
Line items for each sale |
branch ──< branch_manager
branch ──< cashier
branch ──< data_operator
branch ──< vendor
branch ──< product
vendor ──< product
sales ──< sale_details
sales >── cashier (by username)
sale_details >── product
| Setting | Value |
|---|---|
| Max pool size | 10 |
| Min idle | 2 |
| Idle timeout | 30 seconds |
| Max lifetime | 30 minutes |
The top-level administrator with system-wide access.
Branch Management
- Add, view, search, and soft-delete branches
- Track active branch count and total employee count
Branch Manager Management
- Add, view, search, and remove branch managers
- Assign managers to specific branches
Analytics
- System-wide revenue, profit, and items-sold charts
- Daily / weekly / monthly / yearly time ranges
- 7-day revenue trend across all branches
Manages employees and operations within their assigned branch.
Employee Management
- Add, view, search, and remove cashiers
- Add, view, search, and remove data operators
Branch Analytics
- Today's revenue
- Active cashier and data operator counts
- 7-day revenue trend for the branch
- Sales, profit, and items sold reports (daily/weekly/monthly/yearly)
Security
- Change own password with current password verification
Manages the product catalog and vendors for their branch.
Vendor Management
- Add, view, search, and soft-delete vendors
- Fields: name, company, contact person, phone, email, registration date
Product Management
- Add, view, search, and soft-delete products
- Fields: name, vendor, category, cost price, sale price, unit price, carton price, quantity
Inventory Metrics
- Total vendor and product counts
- Low-stock alerts for products with quantity below 10 (up to 10 items shown)
Handles day-to-day sales at the point of sale.
POS Operations
- Browse and search available products by name or category
- Add items to a shopping cart with quantity selection
- Choose price type per item: sale price, unit price, or carton price
- Generate an itemized bill with totals
- Print receipts
- Inventory quantities are decremented in real time on sale completion
Sales Dashboard
- Today's total revenue
- Transaction count for the day
- Total products sold today
- Last 10 recent transactions
Security
- Change own password with current password verification
App.java
└── Splash.fxml (0-100% loading animation)
└── GeneralLogin.fxml (select role)
├── SuperAdminLogin.fxml --> SuperAdmin.fxml
├── AdminLogin.fxml --> Admin.fxml
├── CashierLogin.fxml --> Cashier.fxml
└── DataOperatorLogin.fxml --> DataOperator.fxml
Authentication steps:
- User selects their role on the general login screen
- Enters username and password
LoginDAO.authenticateUser()fetches the BCrypt hash and verifies it- On first login, user is prompted to set a new password before continuing
- The appropriate role dashboard is loaded
- Java 19 or later
- Maven 3.11.0 or later
- MySQL 8.0 or later (local or cloud-hosted)
git clone https://github.com/aay-zee/ZyroPOS.git
cd ZyroPOSCopy .env.example to .env and fill in your MySQL credentials:
DB_HOST=your-mysql-host
DB_PORT=3306
DB_NAME=zyropos
DB_USER=your-username
DB_PASSWORD=your-passwordmvn exec:java -Dexec.mainClass="database.DatabaseSetup"This creates all 9 tables and inserts the default accounts listed below.
| Role | Username | Password |
|---|---|---|
| Super Admin | admin | admin123 |
| Branch Manager | manager | manager123 |
| Cashier | cashier | cashier123 |
| Data Operator | operator | operator123 |
The application will prompt you to change your password on first login.
mvn clean javafx:runThe application opens at 1280x720 with the splash screen, followed by the role selection login.
| Feature | Implementation |
|---|---|
| Password hashing | BCrypt via jBCrypt (PasswordUtil.hashPassword) |
| Password verification | Constant-time BCrypt.checkpw() |
| SQL injection prevention | Prepared statements throughout all DAOs |
| Soft deletes | is_deleted flag — records are never hard deleted |
| Role-based access | Separate login flows and dashboards per role |
| First-login enforcement | Forced password change on first login |
| Connection management | HikariCP pool with auto-recycle and idle limits |
| Pattern | Where Used |
|---|---|
| Singleton | DatabaseConnection, Config |
| DAO | AdminDAO, CashierDAO, DataOperatorDAO, SuperAdminDAO |
| MVC | FXML (View), Controllers, Models |
| Template Method | LoginController and DashboardController (abstract bases) |
| Observer | JavaFX ObservableList bound to TableView |
| Factory | FXMLLoader for dynamic view creation |
ZyroPOS was built by:
Designed with dedication for modern businesses.