My Experience in Point Of Sale System Project
Introduction
In this project, I have designed a Java-based POS system to streamline transactions for retail customers and effectively manage inventory. The name I have given to this project is Checkpoint POS System. The primary goal of this project was to create a solution that provides accuracy, efficiency, and ease of use for shop owners.
The system primarily serves small to medium-scale shop owners. It was designed with their unique needs in mind.
Access the GitHub repository from here 👈
Design Choices
Design and User Interface
I opted for a simple and modern design to make it user-friendly. The system’s design adheres to a minimalistic and clean aesthetic, ensuring it is easy to use and visually appealing.
Design Principles
I followed responsive design principles during development to ensure that the user interface adapts seamlessly to various desktop screen sizes, enhancing the user experience. Since the POS systems are typically implemented in desktops, I didn’t pay any attention to making user interfaces responsive for mobile and tablet devices.
Use cases
The use case diagram for this project involves two key actors: the Admin, who serves as the shop owner, and the Teller.
Technical Implementation
Technology Choices
In developing the system, I made the following technology choices
- Programming Languages: I used Java as the main programming language for the backend.
- Frontend Development: JavaFX for Graphical User Interface (GUI) development, and SceneBuilder for creating user interfaces.
- Database Management: MySQL was selected as the Database Management System due to its reliability and scalability.
- Build and Dependency Management: Maven was utilized for streamlined build and dependency management, ensuring a well-structured and efficient development process.
- Development Environment: I relied on IntelliJ IDEA for coding and project management. DataGrip was used for effective MySQL database management.
- Reports Generation: To generate POS bills, I integrated Jaspersoft Studio, a powerful reporting tool that enhances the system’s bill generation capabilities.
Class Hierarchy
The designed class hierarchy for the entire project is as below.
Access the GitHub repository from here 👈
Dependencies Used
Since this is a Maven project, all the dependencies were applied via the Maven repository.
<dependencies>
<dependency>
<groupId>org.openjfx</groupId>
<artifactId>javafx-fxml</artifactId>
<version>19.0.2.1</version>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>RELEASE</version>
<scope>compile</scope>
</dependency>
<!-- https://mvnrepository.com/artifact/com.mysql/mysql-connector-j -->
<dependency>
<groupId>com.mysql</groupId>
<artifactId>mysql-connector-j</artifactId>
<version>8.1.0</version>
</dependency>
<!-- https://mvnrepository.com/artifact/commons-codec/commons-codec -->
<dependency>
<groupId>commons-codec</groupId>
<artifactId>commons-codec</artifactId>
<version>1.16.0</version>
</dependency>
<!-- https://mvnrepository.com/artifact/net.sf.jasperreports/jasperreports -->
<dependency>
<groupId>net.sf.jasperreports</groupId>
<artifactId>jasperreports</artifactId>
<version>6.20.6</version>
</dependency>
</dependencies>
The following dependencies were integrated into the project.
- JavaFX — Enable GUI features
- Lombok — To make the objects follow the bean specification
- MySQL Connector — To integrate MySQL driver
- Apache Common Codec — To implement hashing encoders
- Jasper Reports — To integrate Jasper reports
Database Structure
The system’s core data management relies on a MySQL relational database. The database structure was critically designed to avoid storing null values, ensuring data integrity and enhancing overall system efficiency and stability.
Following is the Entity Relation Diagram for the database design.
For creating tables at the first connection with the database I have used the schema.sql resource file to store DDL commands.
CREATE TABLE IF NOT EXISTS user_role (
id INT AUTO_INCREMENT PRIMARY KEY ,
role VARCHAR(20) NOT NULL
);
CREATE TABLE IF NOT EXISTS user (
user_id VARCHAR(10) PRIMARY KEY ,
first_name VARCHAR(20) NOT NULL ,
last_name VARCHAR(20) NOT NULL ,
password VARCHAR(100) NOT NULL ,
user_role_id INT NOT NULL ,
gender VARCHAR(10) NOT NULL ,
CONSTRAINT fk_user_role FOREIGN KEY user (user_role_id) REFERENCES user_role (id)
);
CREATE TABLE IF NOT EXISTS user_profile_picture (
user_id VARCHAR(10) PRIMARY KEY ,
profile_picture BLOB(2500) NOT NULL ,
CONSTRAINT fk_user_profile_picture FOREIGN KEY user_profile_picture (user_id) REFERENCES user (user_id)
);
CREATE TABLE IF NOT EXISTS customer (
customer_id VARCHAR(10) PRIMARY KEY ,
name VARCHAR(100) NOT NULL ,
address VARCHAR(300) NOT NULL ,
phone VARCHAR(15) NOT NULL UNIQUE
);
CREATE TABLE IF NOT EXISTS item (
item_code VARCHAR(30) PRIMARY KEY ,
description VARCHAR(200) NOT NULL ,
qty INT NOT NULL ,
unit_price DECIMAL(8,2) NOT NULL
);
CREATE TABLE IF NOT EXISTS `order` (
order_id VARCHAR(10) PRIMARY KEY ,
date DATE NOT NULL ,
user_id VARCHAR(10) NOT NULL ,
CONSTRAINT fk_user FOREIGN KEY (user_id) REFERENCES user (user_id)
);
CREATE TABLE IF NOT EXISTS customer_order (
customer_id VARCHAR(10) ,
order_id VARCHAR(10) ,
CONSTRAINT pk_customer_order PRIMARY KEY (customer_id,order_id) ,
CONSTRAINT fk_customer FOREIGN KEY (customer_id) REFERENCES customer (customer_id) ,
CONSTRAINT fk_order FOREIGN KEY (order_id) REFERENCES `order` (order_id)
);
CREATE TABLE IF NOT EXISTS order_item (
item_code VARCHAR(30) ,
order_id VARCHAR(10) ,
qty INT NOT NULL ,
unit_price DECIMAL(8,2) NOT NULL ,
CONSTRAINT pk_order_item PRIMARY KEY (item_code, order_id) ,
CONSTRAINT fk_item_code FOREIGN KEY (item_code) REFERENCES item (item_code) ,
CONSTRAINT fk_order_id FOREIGN KEY (order_id) REFERENCES `order` (order_id)
);
Reports Integration
Jasper Reports were used to generate POS bills after every successful order. Sample POS bill generated according to the order is as below.
The following extracted Java code illustrates the process of implementation of Jasper reports in this Java project
private void printBill() {
JasperDesign jasperDesign;
try {
jasperDesign = JRXmlLoader.load(getClass().getResourceAsStream("/print/pos-bill.jrxml"));
JasperReport jasperReport = JasperCompileManager.compileReport(jasperDesign);
Map<String, Object> reportParams = new HashMap<>();
reportParams.put("id", lblOrderId.getText().replace("Order ID : ", ""));
reportParams.put("date", lblDate.getText().replace("Date : ", ""));
reportParams.put("teller-id", lblUserId.getText());
reportParams.put("teller-name", lblUserName.getText());
reportParams.put("total", lblTotal.getText().replace("TOTAL : Rs. ", ""));
JasperPrint jasperPrint = JasperFillManager.fillReport(jasperReport, reportParams, new JRBeanCollectionDataSource(tblOrderItems.getItems()));
JasperViewer.viewReport(jasperPrint, false);
} catch (JRException e) {
new Alert(Alert.AlertType.ERROR, "Failed to print the bill").show();
e.printStackTrace();
}
}
Technical Design Patterns
Since this is a desktop app, I implemented the Singleton design pattern for database connectivity to maintain a single connection to the database, promoting efficiency and preventing resource wastage.
The code is as follows
public class SingleConnectionDataSource {
private static SingleConnectionDataSource instance;
private final Connection connection;
private SingleConnectionDataSource() {
try {
Properties properties = new Properties();
properties.load(this.getClass().getResourceAsStream("/application.properties"));
String url = properties.getProperty("app.datasource.url");
String username = properties.getProperty("app.datasource.username");
String password = properties.getProperty("app.datasource.password");
connection = DriverManager.getConnection(url, username, password);
generateSchema();
} catch (Exception e) {
throw new RuntimeException(e);
}
}
private void generateSchema() throws Exception {
URL url = getClass().getResource("/schema.sql");
Path path = Paths.get(url.toURI());
String dbScript = Files.readAllLines(path).stream().reduce((prevLine, currentLine) -> prevLine + currentLine).get();
connection.createStatement().execute(dbScript);
}
public static SingleConnectionDataSource getInstance() {
return (instance==null) ? instance = new SingleConnectionDataSource() : instance;
}
public Connection getConnection() {
return connection;
}
}
Units
Specifically, I have used BigDecimal for handling ‘unit_price’, ‘discount, and ‘total’ to ensure the precision of floating-point values. This choice was essential to ensure the precision of those values eliminating the rounding errors in traditional floating data types.
public class OrderItem implements Serializable {
private String orderItemCode;
private String description;
private int qty;
private BigDecimal unitPrice;
private BigDecimal discount;
private transient Button btnDelete;
public BigDecimal getTotal() {
return unitPrice.multiply(new BigDecimal(qty)).setScale(2);
}
}
Security Measures
To enhance security, I implemented the following measures:
- Passwords are encrypted using the Sha256Hex hashing algorithm.
password = DigestUtils.sha256Hex(txtNewPassword.getText());
User newUser = new User(userId, firstName, lastName, password, userRoleId, gender);
UserDataAccess.setUser(newUser);
- Access control is implemented based on user roles to ensure that each user can only access features and data relevant to their responsibilities, enhancing overall security.
External Resources
I integrated external button icons sourced from Google Material Design Icons and www.flaticon.com. These icons played a crucial role in enhancing the system’s user interface.
The integration of external resources, specifically button icons, was essential to decorating buttons and enhancing the overall visual appeal and usability of the system, adding a touch of professionalism to the user interface.
Future Improvements
As I look ahead, my vision for the future of the Checkpoint POS System includes
- Improving user interfaces further
- Storing item data history as batches to address the price fluctuations of the same item from time to time
- Improving as a multi-user system based on client-server architecture
- Improving as a web service
Although the changing profile picture of users, and adding discounts to the order bills are already in ER diagrams, they are not implemented in this first version. Hope to add them in the next minor release.
Conclusion
In conclusion, my experience in developing the Checkpoint POS System was a journey of learning, problem-solving, and meticulous design. The system, suited to the needs of small and medium-scale shop owners, stands as a demonstration of the importance of precision, reliability, and user-friendliness in the realm of point-of-sale solutions.
My Checkpoint POS System Experience is not just a project — it’s a story of dedication, innovation, and the pursuit of excellence.