Added CRUD to Products and added Validation to dialog

This commit is contained in:
Alex
2026-02-03 20:02:46 -07:00
parent 310b66329f
commit 07a6d3bfc6
14 changed files with 1147 additions and 145 deletions

View File

@@ -11,17 +11,15 @@ import org.example.petshopdesktop.models.Product;
public class ProductDTO {
private SimpleIntegerProperty prodId;
private SimpleStringProperty prodName;
private SimpleStringProperty prodSku;
private SimpleDoubleProperty prodPrice;
private SimpleIntegerProperty categoryId; //used for edit and delete
private SimpleStringProperty categoryName;
private SimpleStringProperty prodDesc;
//constructor
public ProductDTO(int prodId, String prodName, String prodSku, double prodPrice, int categoryId, String categoryName, String prodDesc) {
public ProductDTO(int prodId, String prodName, double prodPrice, int categoryId, String categoryName, String prodDesc) {
this.prodId = new SimpleIntegerProperty(prodId);
this.prodName = new SimpleStringProperty(prodName);
this.prodSku = new SimpleStringProperty(prodSku);
this.prodPrice = new SimpleDoubleProperty(prodPrice);
this.categoryId = new SimpleIntegerProperty(categoryId);
this.categoryName = new SimpleStringProperty(categoryName);
@@ -53,18 +51,6 @@ public class ProductDTO {
this.prodName.set(prodName);
}
public String getProdSku() {
return prodSku.get();
}
public SimpleStringProperty prodSkuProperty() {
return prodSku;
}
public void setProdSku(String prodSku) {
this.prodSku.set(prodSku);
}
public double getProdPrice() {
return prodPrice.get();
}
@@ -121,7 +107,6 @@ public class ProductDTO {
Product product = new Product(
getProdId(),
getProdName(),
getProdSku(),
getProdPrice(),
getCategoryId(),
getProdDesc()

View File

@@ -0,0 +1,131 @@
package org.example.petshopdesktop;
public class Validator {
/**
* Checks if string is not empty
* @param value string to check
* @param name name of the input
* @return error msg if string is not empty, otherwise empty
*/
public static String isPresent(String value, String name){
String msg =""; //OK so far
if(value.isEmpty() || name.isBlank()){
msg += name + " is required. \n";
}
return msg;
}
/**
* Checks if the input is a non-negative double
* @param value input of string
* @param name name of input
* @return error msg if input is not a number or negative, otherwise empty
*/
public static String isNonNegativeDouble(String value, String name){
String msg =""; //OK so far
double result;
try{
result = Double.parseDouble(value);
if (result < 0){
msg += name + " must be greater than or equal 0. \n";
}
}
catch (NumberFormatException e){
msg += name + " must be a number.\n";
}
return msg;
}
/**
* Checks if the input is a double in 2 different range
* @param value input of string
* @param name name of inpt
* @param minValue min value of range
* @param maxValue max value of range
* @return error msg if input is out of range, otherwise empty
*/
public static String isDoubleInRange(String value, String name, double minValue, double maxValue){
String msg =""; //OK so far
double result;
try{
result = Double.parseDouble(value);
if (result < minValue || result > maxValue){
msg += name + " must be between " + minValue + " and " + maxValue + "\n";
}
}
catch (NumberFormatException e){
msg += name + " must be a number.\n";
}
return msg;
}
/**
* Checks if the input is a non-negative integer
* @param value input of string
* @param name name of input
* @return error msg if input is not a number or negative, otherwise empty
*/
public static String isNonNegativeInteger(String value, String name){
String msg =""; //OK so far
int result;
try{
result = Integer.parseInt(value);
if (result < 0){
msg += name + " must be greater than or equal 0. \n";
}
}
catch (NumberFormatException e){
msg += name + " must be a whole number.\n";
}
return msg;
}
/**
* check if the string is a given amount of characters or fewer
* @param value input of string
* @param name name of input
* @return error msg if input is more than given characters length
*/
public static String isLessThanVarChars(String value, String name, int length){
String msg ="";
if (value.length() > length){
msg += name + " must be less than " + length + " characters. \n";
}
return msg;
}
/**
* Checks if the input is a valid email format
* @param value input of string
* @param name name of input
* @return error msg if input is not a valid email format, otherwise empty
*/
public static String isValidEmail(String value, String name){
String msg = ""; //OK so far
// Email regex
String regex = "^[A-Za-z0-9+_.-]+@[A-Za-z0-9.-]+\\.[A-Za-z]{2,}$";
if (!value.matches(regex)){
msg += name + " is not in a valid format. \n";
}
return msg;
}
/**
* Checks if the input is a valid phone number in format XXX-XXX-XXXX
* @param value input of string
* @param name name of input
* @return error msg if input is not in valid phone format, otherwise empty
*/
public static String isValidPhoneNumber(String value, String name){
String msg = ""; //OK so far
// Phone regex
String regex = "^\\d{3}-\\d{3}-\\d{4}$";
if (!value.matches(regex)){
msg += name + " must be in format XXX-XXX-XXXX. \n";
}
return msg;
}
}

View File

@@ -4,16 +4,24 @@ import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.event.ActionEvent;
import javafx.fxml.FXML;
import javafx.scene.control.Button;
import javafx.scene.control.TableColumn;
import javafx.scene.control.TableView;
import javafx.scene.control.TextField;
import javafx.fxml.FXMLLoader;
import javafx.scene.Scene;
import javafx.scene.control.*;
import javafx.scene.control.cell.PropertyValueFactory;
import javafx.stage.Modality;
import javafx.stage.Stage;
import org.example.petshopdesktop.DTOs.ProductDTO;
import org.example.petshopdesktop.controllers.dialogcontrollers.ProductDialogController;
import org.example.petshopdesktop.controllers.dialogcontrollers.SupplierDialogController;
import org.example.petshopdesktop.database.ProductDB;
import org.example.petshopdesktop.database.SupplierDB;
import org.example.petshopdesktop.models.Product;
import org.example.petshopdesktop.models.Supplier;
import java.io.IOException;
import java.sql.SQLException;
import java.sql.SQLIntegrityConstraintViolationException;
import java.util.Optional;
/**
* The controller for any operations in the products view
@@ -44,9 +52,6 @@ public class ProductController {
@FXML
private TableColumn<ProductDTO, Double> colProductPrice;
@FXML
private TableColumn<ProductDTO, String> colProductSKU;
@FXML
private TableView<ProductDTO> tvProducts;
@@ -68,19 +73,31 @@ public class ProductController {
//set up table columns
colProductId.setCellValueFactory(new PropertyValueFactory<ProductDTO,Integer>("prodId"));
colProductName.setCellValueFactory(new PropertyValueFactory<ProductDTO,String>("prodName"));
colProductSKU.setCellValueFactory(new PropertyValueFactory<ProductDTO,String>("prodSku"));
colProductPrice.setCellValueFactory(new PropertyValueFactory<ProductDTO,Double>("prodPrice"));
colProductCategory.setCellValueFactory(new PropertyValueFactory<ProductDTO,String>("categoryName"));
colProductDesc.setCellValueFactory(new PropertyValueFactory<ProductDTO,String>("prodDesc"));
displayProducts();
displayProduct();
//EventListener to Enable buttons when a row is selected
tvProducts.getSelectionModel().selectedItemProperty().addListener(
(observable, oldValue, newValue) -> {
btnEdit.setDisable(false);
btnDelete.setDisable(false);
}
);
//EventListener to search when text is changed on searchbar
txtSearch.textProperty().addListener((observable, oldValue, newValue) -> {
displayFilteredProduct(newValue);
});
}
/**
* Display the productDTO to table view
*/
private void displayProducts(){
private void displayProduct(){
//Erase old content
data.clear();
@@ -95,20 +112,148 @@ public class ProductController {
tvProducts.setItems(data);
}
/**
* open a new dialog for adding a product
* @param event
*/
@FXML
void btnAddClicked(ActionEvent event) {
mode = "Add";
openDialog(null,mode);
}
/**
* Delete a selected product when delete is clicked
* @param event click event for button
*/
@FXML
void btnDeleteClicked(ActionEvent event) {
int numRows = 0;
//set selected product
ProductDTO selectedProduct = tvProducts.getSelectionModel().getSelectedItem();
//ask user to confirm
Alert question = new Alert(Alert.AlertType.CONFIRMATION);
question.setHeaderText("Please confirm delete");
question.setContentText("Are you sure you want to delete this product?");
Optional<ButtonType> result = question.showAndWait(); //show alert and wait for response
//if confirmed,start deletion
if (result.isPresent() && result.get() == ButtonType.OK) {
int prodId = selectedProduct.getProdId();
//try deleting
try{
numRows = ProductDB.deleteProduct(prodId);
}
catch (SQLIntegrityConstraintViolationException e){
Alert alert = new Alert(Alert.AlertType.ERROR);
alert.setHeaderText("Database Operation Error");
alert.setContentText("Delete failed\n" +
"the selected product is being referred in another table");
alert.showAndWait();
return;
}
catch (SQLException e) {
throw new RuntimeException(e);
}
//prompt user of any errors
if (numRows == 0){
Alert alert = new Alert(Alert.AlertType.ERROR);
alert.setHeaderText("Database Operation Error");
alert.setContentText("Delete failed");
alert.showAndWait();
}
else{
//prompt user of delete conformation
Alert alert = new Alert(Alert.AlertType.CONFIRMATION);
alert.setHeaderText("Database Operation Confirmed");
alert.setContentText("Delete successful");
alert.showAndWait();
//refresh display and reset inputs
displayProduct();
btnDelete.setDisable(true);
btnEdit.setDisable(true);
txtSearch.setText("");
}
}
}
/**
* Open a new dialog for editing a product
* @param event click event for button
*/
@FXML
void btnEditClicked(ActionEvent event) {
//set selected product
ProductDTO selectedProduct = tvProducts.getSelectionModel().getSelectedItem();
if (selectedProduct != null) {
mode = "Edit";
openDialog(selectedProduct, mode);
}
}
/**
* Filter the table given the string from the searchbar
* @param filter word to filter table
*/
private void displayFilteredProduct(String filter){
data.clear();
try{
if (txtSearch.getText() == null || txtSearch.getText().isEmpty()){
displayProduct(); //If search bar is empty just display everything
}
else{
//Filter the using the keyword
data = ProductDB.getFilteredProductDTOs(filter);
tvProducts.setItems(data);
}
} catch (Exception e) {
throw new RuntimeException(e);
}
}
/**
* Function to open the new Dialog for edit or adding
* depending on the mode given
* @param product the product entity for editing, null if adding
* @param mode the mode the dialog should be in
*/
private void openDialog(ProductDTO product, String mode){
//Get new view
FXMLLoader fxmlLoader = new FXMLLoader(getClass().getResource("/org/example/petshopdesktop/dialogviews/product-dialog-view.fxml"));
Scene scene = null;
try{
scene = new Scene(fxmlLoader.load());
} catch (IOException e) {
throw new RuntimeException(e);
}
ProductDialogController dialogController = fxmlLoader.getController(); //controller associated with this view
dialogController.setMode(mode);
//Open the dialog depending on the mode
if(mode.equals("Edit")){
//Make it display suppliers details in dialog
dialogController.displayProductDetails(product);
}
Stage dialogStage = new Stage();
dialogStage.initModality(Modality.APPLICATION_MODAL); //make it modal
if(mode.equals("Add")){
dialogStage.setTitle("Add Product");
}
else {
dialogStage.setTitle("Edit Product");
}
dialogStage.setScene(scene);
dialogStage.showAndWait();
//When dialog closes update table view and disable edit and delete buttons, and reset search bar
displayProduct();
btnDelete.setDisable(true);
btnEdit.setDisable(true);
txtSearch.setText("");
}
}

View File

@@ -74,7 +74,7 @@ public class SupplierController {
displaySupplier();
// Enable buttons when a row is selected
//EventListener to Enable buttons when a row is selected
tvSuppliers.getSelectionModel().selectedItemProperty().addListener(
(observable, oldValue, newValue) -> {
btnEdit.setDisable(false);
@@ -82,6 +82,11 @@ public class SupplierController {
}
);
//EventListener to search when text is changed on searchbar
txtSearch.textProperty().addListener((observable, oldValue, newValue) -> {
displayFilteredSupplier(newValue);
});
}
@@ -100,10 +105,30 @@ public class SupplierController {
tvSuppliers.setItems(data);
}
/**
* Filter the table given the string from the searchbar
* @param filter word to filter table
*/
private void displayFilteredSupplier(String filter){
data.clear();
try{
if (txtSearch.getText() == null || txtSearch.getText().isEmpty()){
displaySupplier(); //If search bar is empty just display everything
}
else{
//Filter the using the keyword
data = SupplierDB.getFilteredSuppliers(filter);
tvSuppliers.setItems(data);
}
} catch (Exception e) {
throw new RuntimeException(e);
}
}
/**
* open a new dialog for adding a supplier
* @param event
* @param event click event for button
*/
@FXML
void btnAddClicked(ActionEvent event) {
@@ -112,8 +137,8 @@ public class SupplierController {
}
/**
*
* @param event
* Delete a selected supplier when delete is clicked
* @param event click event for button
*/
@FXML
void btnDeleteClicked(ActionEvent event) {
@@ -162,13 +187,16 @@ public class SupplierController {
alert.showAndWait();
//refresh display
displaySupplier();
btnDelete.setDisable(true);
btnEdit.setDisable(true);
txtSearch.setText("");
}
}
}
/**
* Open a new dialog for editing a supplier
* @param event click event
* @param event click event for button
*/
@FXML
void btnEditClicked(ActionEvent event) {
@@ -184,12 +212,12 @@ public class SupplierController {
/**
* Function to open the new Dialog for edit or adding
* depending on the mode given
* @param supplier the supplier entity fo editing, null if adding
* @param supplier the supplier entity for editing, null if adding
* @param mode the mode the dialog should be in
*/
private void openDialog(Supplier supplier, String mode){
//Get new view
FXMLLoader fxmlLoader = new FXMLLoader(getClass().getResource("/org/example/petshopdesktop/dialogviews/supplier-dialog-view.fxml")); //CHECK
FXMLLoader fxmlLoader = new FXMLLoader(getClass().getResource("/org/example/petshopdesktop/dialogviews/supplier-dialog-view.fxml"));
Scene scene = null;
try{
scene = new Scene(fxmlLoader.load());
@@ -215,10 +243,11 @@ public class SupplierController {
dialogStage.setScene(scene);
dialogStage.showAndWait();
//When dialog closes update table view and disable edit and delete buttons
//When dialog closes update table view and disable edit and delete buttons, and reset search bar
displaySupplier();
btnDelete.setDisable(true);
btnEdit.setDisable(true);
txtSearch.setText("");
}
}
}

View File

@@ -0,0 +1,211 @@
package org.example.petshopdesktop.controllers.dialogcontrollers;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.event.EventHandler;
import javafx.fxml.FXML;
import javafx.scene.Node;
import javafx.scene.control.*;
import javafx.scene.input.MouseEvent;
import javafx.stage.Stage;
import org.example.petshopdesktop.DTOs.ProductDTO;
import org.example.petshopdesktop.Validator;
import org.example.petshopdesktop.database.CategoryDB;
import org.example.petshopdesktop.database.ProductDB;
import org.example.petshopdesktop.models.Category;
import org.example.petshopdesktop.models.Product;
import org.example.petshopdesktop.models.Supplier;
import java.sql.SQLException;
import java.util.ArrayList;
public class ProductDialogController {
@FXML
private Button btnCancel;
@FXML
private Button btnSave;
@FXML
private ComboBox<Category> cbProdCategory;
@FXML
private Label lblMode;
@FXML
private Label lblProdId;
@FXML
private TextField txtProdDesc;
@FXML
private TextField txtProdName;
@FXML
private TextField txtProdPrice;
private String mode = null;
/**
* Add event listeners to buttons when dialog loads
*/
@FXML
void initialize() {
//Set up mouse handlers for buttons
btnSave.setOnMouseClicked(new EventHandler<MouseEvent>() {
@Override
public void handle(MouseEvent mouseEvent) {
buttonSaveClicked(mouseEvent);
}
});
btnCancel.setOnMouseClicked(new EventHandler<MouseEvent>() {
@Override
public void handle(MouseEvent mouseEvent) {
closeStage(mouseEvent);
}
});
//Set up combobox for selecting category
try {
//set up combobox
ObservableList<Category> categories = FXCollections.observableArrayList(); //empty list
categories = CategoryDB.getCategories();
cbProdCategory.setItems(categories);
} catch (SQLException e) {
throw new RuntimeException(e);
}
}
private void buttonSaveClicked(MouseEvent mouseEvent) {
int numRow = 0; //how many rows affected
String errorMsg = ""; //error message for validation
//Check Validation (input required)
errorMsg += Validator.isPresent(txtProdName.getText(), "Product Name");
errorMsg += Validator.isPresent(txtProdPrice.getText(), "Product Price");
if (cbProdCategory.getSelectionModel().getSelectedItem() == null) {
errorMsg += "Category is required \n";
}
//Check validation (length size)
errorMsg += Validator.isLessThanVarChars(txtProdName.getText(), "Product Name", 100);
errorMsg += Validator.isLessThanVarChars(txtProdDesc.getText(), "Description", 100);
errorMsg += Validator.isLessThanVarChars(txtProdPrice.getText(), "Product Price", 12);
//Check Validation (format)
errorMsg += Validator.isNonNegativeDouble(txtProdPrice.getText(), "Product Price");
if (errorMsg.isEmpty()) { //no validation errors detected
Product product = collectProduct(); //get product info
if (mode.equals("Add")){ //add mode
try{
numRow = ProductDB.insertProduct(product);
} catch (SQLException e) {
throw new RuntimeException(e);
}
}
else { //edit
try{
numRow = ProductDB.updateProduct(product.getProdId(),product);
} catch (SQLException e) {
throw new RuntimeException(e);
}
}
//if no rows were affected then there was an error (prompt user of error)
if (numRow == 0){
Alert alert = new Alert(Alert.AlertType.ERROR);
alert.setHeaderText("Database Operation Error");
alert.setContentText(mode + " failed");
alert.showAndWait();
closeStage(mouseEvent);
}
else {
//tell the user operation was successful
Alert alert = new Alert(Alert.AlertType.CONFIRMATION);
alert.setHeaderText("Database Operation Confirmed");
alert.setContentText(mode + " succeeded");
alert.showAndWait();
closeStage(mouseEvent);
}
}
else{ //Display validation errors
Alert alert = new Alert(Alert.AlertType.ERROR);
alert.setHeaderText("Input Error");
alert.setContentText(errorMsg);
alert.showAndWait();
}
}
/**
* Collect the product info
* @return product info with the id or the new product
*/
private Product collectProduct(){
int prodId = 0;
Product product = null;
if(lblProdId.isVisible()){ //Edit mode
//get product id from lblId (split the string so we only get the int)
prodId = Integer.parseInt(lblProdId.getText().split(": ")[1]);
}
product = new Product(
prodId,
txtProdName.getText(),
Double.parseDouble(txtProdPrice.getText()),
cbProdCategory.getSelectionModel().getSelectedItem().getCategoryId(),
txtProdDesc.getText()
);
return product;
}
/**
* Display the product data in text fields and combobox
* @param product the supplier entity containing data to display
*/
public void displayProductDetails(ProductDTO product){
if (product!=null){
lblProdId.setText("ID: " + product.getProdId());
txtProdName.setText(product.getProdName());
txtProdDesc.setText(product.getProdDesc());
txtProdPrice.setText(product.getProdPrice() + "");
//get the right combobox selection
for (Category category : cbProdCategory.getItems()) {
if(category.getCategoryId() == product.getCategoryId()){
cbProdCategory.setValue(category);
}
}
}
}
/**
* Close the window
* @param mouseEvent mouse event to close
*/
private void closeStage(MouseEvent mouseEvent) {
Node node = (Node) mouseEvent.getSource();
Stage stage = (Stage) node.getScene().getWindow();
stage.close();
}
/**
* Set the mode of the dialog
* @param mode the mode to for the dialog
*/
public void setMode(String mode) {
this.mode = mode;
lblMode.setText(mode + " Product");
if(mode.equals("Add")) {
lblProdId.setVisible(false);
}
else if(mode.equals("Edit")) {
lblProdId.setVisible(true);
}
}
}

View File

@@ -9,6 +9,7 @@ import javafx.scene.control.Label;
import javafx.scene.control.TextField;
import javafx.scene.input.MouseEvent;
import javafx.stage.Stage;
import org.example.petshopdesktop.Validator;
import org.example.petshopdesktop.database.SupplierDB;
import org.example.petshopdesktop.models.Supplier;
@@ -45,6 +46,9 @@ public class SupplierDialogController {
private String mode = null;
/**
* Add event listeners to buttons when dialog loads
*/
@FXML
void initialize() {
//Set up mouse handlers for buttons
@@ -67,7 +71,22 @@ public class SupplierDialogController {
int numRow = 0; //how many rows affected
String errorMsg = ""; //error message for validation
//TODO: Import validation class and validate text fields here
//Check validation (input required)
errorMsg += Validator.isPresent(txtCompanyName.getText(), "Company Name");
errorMsg += Validator.isPresent(txtContactFirstName.getText(), "Contact First Name");
errorMsg += Validator.isPresent(txtContactLastName.getText(), "Contact Last Name");
errorMsg += Validator.isPresent(txtEmail.getText(), "Email Address");
errorMsg += Validator.isPresent(txtPhone.getText(), "Phone Number");
//Check validation (Length size)
errorMsg += Validator.isLessThanVarChars(txtCompanyName.getText(),"Company Name", 100);
errorMsg += Validator.isLessThanVarChars(txtContactFirstName.getText(), "Contact First Name", 50);
errorMsg += Validator.isLessThanVarChars(txtContactLastName.getText(), "Contact Last Name", 50);
errorMsg += Validator.isLessThanVarChars(txtEmail.getText(), "Email Address", 100);
//Check validation (format)
errorMsg += Validator.isValidEmail(txtEmail.getText(), "Email Address");
errorMsg += Validator.isValidPhoneNumber(txtPhone.getText(), "Phone Number");
if(errorMsg.isEmpty()){ //no validation errors detected
Supplier supplier = collectSupplier(); //get supplier info

View File

@@ -0,0 +1,41 @@
package org.example.petshopdesktop.database;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import org.example.petshopdesktop.models.Category;
import org.example.petshopdesktop.models.Product;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
public class CategoryDB {
/**
* gets all the category into an observable list
* @return a list of all the category
* @throws SQLException if failed to find categories in the database
*/
public static ObservableList<Category> getCategories() throws SQLException{
//Connect to the database
ObservableList<Category> categories = FXCollections.observableArrayList();
Connection conn = ConnectionDB.getConnection();
//Execute Query
Statement stmt = conn.createStatement();
ResultSet rs = stmt.executeQuery("SELECT * FROM category");
//While there is still data add categories to the list
while(rs.next()){
Category category = new Category(
rs.getInt(1),
rs.getString(2),
rs.getString(3));
categories.add(category);
}
//close connection and return categories
conn.close();
return categories;
}
}

View File

@@ -4,11 +4,9 @@ import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import org.example.petshopdesktop.DTOs.ProductDTO;
import org.example.petshopdesktop.models.Product;
import org.example.petshopdesktop.models.Supplier;
import java.io.FileInputStream;
import java.io.IOException;
import java.sql.*;
import java.util.Properties;
/**
* A class containing all the methods relating to CRUD on Products table
@@ -34,10 +32,9 @@ public class ProductDB {
Product product = new Product(
rs.getInt(1),
rs.getString(2),
rs.getString(3),
rs.getDouble(4),
rs.getInt(5),
rs.getString(6));
rs.getDouble(3),
rs.getInt(4),
rs.getString(5));
products.add(product);
}
@@ -58,7 +55,7 @@ public class ProductDB {
//Execute Query
Statement stmt = conn.createStatement();
String sql = "SELECT p.prodId, p.prodName, p.prodSku, p.prodPrice, p.categoryId, c.categoryName, p.prodDesc " +
String sql = "SELECT p.prodId, p.prodName, p.prodPrice, p.categoryId, c.categoryName, p.prodDesc " +
"FROM product p " +
"LEFT JOIN category c ON p.categoryId = c.categoryId";
ResultSet rs = stmt.executeQuery(sql);
@@ -68,11 +65,10 @@ public class ProductDB {
ProductDTO product = new ProductDTO(
rs.getInt(1),
rs.getString(2),
rs.getString(3),
rs.getDouble(4),
rs.getInt(5),
rs.getString(6),
rs.getString(7));
rs.getDouble(3),
rs.getInt(4),
rs.getString(5),
rs.getString(6));
products.add(product);
}
@@ -80,4 +76,137 @@ public class ProductDB {
conn.close();
return products;
}
/**
* Inserts a new product to the database
* @param product product entity to be inserted
* @return number of rows affected in the database
* @throws SQLException if insertion failed
*/
public static int insertProduct(Product product) throws SQLException {
int numRows = 0;
Connection conn = ConnectionDB.getConnection();
String sql = "INSERT INTO product (prodId, prodName, prodPrice, categoryId, prodDesc)" +
"VALUES (?, ?, ?, ?, ?)";
//These are the values from product to put into the query above
PreparedStatement stmt = conn.prepareStatement(sql);
stmt.setInt(1, product.getProdId());
stmt.setString(2, product.getProdName());
stmt.setDouble(3, product.getProdPrice());
stmt.setInt(4, product.getCategoryId());
stmt.setString(5, product.getProdDesc());
//update the number of rows affected, return and close connection
numRows = stmt.executeUpdate();
conn.close();
return numRows;
}
/**
* Update an existing product to the database
* @param prodId id of product
* @param product new product data
* @return number of rows affected in the database
* @throws SQLException if update failed
*/
public static int updateProduct(int prodId, Product product) throws SQLException {
int numRows = 0;
Connection conn = ConnectionDB.getConnection();
String sql = "UPDATE product SET " +
" prodName = ?, " +
" prodPrice = ?, " +
" categoryId = ?, " +
" prodDesc = ? " +
" WHERE prodId = ?";
//update values to query
PreparedStatement stmt = conn.prepareStatement(sql);
stmt.setString(1, product.getProdName());
stmt.setDouble(2, product.getProdPrice());
stmt.setInt(3, product.getCategoryId());
stmt.setString(4, product.getProdDesc());
stmt.setInt(5, prodId);
//Update rows and close connection
numRows = stmt.executeUpdate();
conn.close();
return numRows;
}
/**
* Delete a product from the database
* @param prodId product id to be deleted
* @return number of rows affected in the database
* @throws SQLException if delete failed
*/
public static int deleteProduct(int prodId) throws SQLException {
int numRows = 0;
Connection conn = ConnectionDB.getConnection();
String sql = "DELETE FROM product WHERE prodId = ?";
PreparedStatement stmt = conn.prepareStatement(sql);
stmt.setInt(1, prodId);
//close connection and update rows affected
numRows = stmt.executeUpdate();
conn.close();
return numRows;
}
/**
* Gets a list of productDTOs that is filtered by a given string
* @param filter the word to filter table
* @return ObservableList of ProductDTOs with the filtered data
* @throws SQLException if getting products failed
*/
public static ObservableList<ProductDTO> getFilteredProductDTOs(String filter) throws SQLException {
//Connect to the database
ObservableList<ProductDTO> products = FXCollections.observableArrayList();
Connection conn = ConnectionDB.getConnection();
//Get SQL query for filtered word
String sql =
"SELECT p.prodId, p.prodName, p.prodPrice, p.categoryId, c.categoryName, p.prodDesc" +
" FROM product p" +
" LEFT JOIN category c ON p.categoryId = c.categoryId" +
" WHERE " +
"prodName LIKE ? OR " +
"prodPrice LIKE ? OR " +
"categoryName LIKE ? OR " +
"prodDesc LIKE ?";
//add % wildcard so the query can use LIKE to filter data
String filteredString = "%" + filter + "%";
PreparedStatement stmt = conn.prepareStatement(sql);
stmt.setString(1, filteredString);
stmt.setString(2, filteredString);
stmt.setString(3, filteredString);
stmt.setString(4, filteredString);
//execute query
ResultSet rs = stmt.executeQuery();
//While there is still data add products to the list
while(rs.next()){
ProductDTO product = new ProductDTO(
rs.getInt(1),
rs.getString(2),
rs.getDouble(3),
rs.getInt(4),
rs.getString(5),
rs.getString(6));
products.add(product);
}
conn.close();
return products;
}
}

View File

@@ -26,7 +26,7 @@ public class SupplierDB {
Statement stmt = conn.createStatement();
ResultSet rs = stmt.executeQuery("SELECT * FROM supplier");
//While there is still data add products to the list
//While there is still data add suppliers to the list
while(rs.next()){
Supplier supplier = new Supplier(
rs.getInt(1),
@@ -127,4 +127,54 @@ public class SupplierDB {
return numRows;
}
/**
* Gets a list of Suppliers that is filtered by a given string
* @param filter the word to filter table
* @return ObservableList of suppliers with the filtered data
* @throws SQLException if getting suppliers failed
*/
public static ObservableList<Supplier> getFilteredSuppliers(String filter) throws SQLException {
//Connect to the database
ObservableList<Supplier> suppliers = FXCollections.observableArrayList();
Connection conn = ConnectionDB.getConnection();
//Get SQL query for filtered word
String sql =
"SELECT * FROM supplier" +
" WHERE " +
"supCompany LIKE ? OR " +
"supContactFirstName LIKE ? OR " +
"supContactLastName LIKE ? OR " +
"supEmail LIKE ? OR " +
"supPhone LIKE ?";
//add % wildcard so the query can use LIKE to filter data
String filteredString = "%" + filter + "%";
PreparedStatement stmt = conn.prepareStatement(sql);
stmt.setString(1, filteredString);
stmt.setString(2, filteredString);
stmt.setString(3, filteredString);
stmt.setString(4, filteredString);
stmt.setString(5, filteredString);
//execute query
ResultSet rs = stmt.executeQuery();
//While there is still data add suppliers to the list
while(rs.next()){
Supplier supplier = new Supplier(
rs.getInt(1),
rs.getString(2),
rs.getString(3),
rs.getString(4),
rs.getString(5),
rs.getString(6));
suppliers.add(supplier);
}
conn.close();
return suppliers;
}
}

View File

@@ -0,0 +1,59 @@
package org.example.petshopdesktop.models;
import javafx.beans.property.SimpleIntegerProperty;
import javafx.beans.property.SimpleStringProperty;
public class Category {
private SimpleIntegerProperty categoryId;
private SimpleStringProperty categoryName;
private SimpleStringProperty categoryType;
//Constrctor
public Category(int categoryId, String categoryName, String categoryType) {
this.categoryId = new SimpleIntegerProperty(categoryId);
this.categoryName = new SimpleStringProperty(categoryName);
this.categoryType = new SimpleStringProperty(categoryType);
}
//getters and setters
public int getCategoryId() {
return categoryId.get();
}
public SimpleIntegerProperty categoryIdProperty() {
return categoryId;
}
public void setCategoryId(int categoryId) {
this.categoryId.set(categoryId);
}
public String getCategoryName() {
return categoryName.get();
}
public SimpleStringProperty categoryNameProperty() {
return categoryName;
}
public void setCategoryName(String categoryName) {
this.categoryName.set(categoryName);
}
public String getCategoryType() {
return categoryType.get();
}
public SimpleStringProperty categoryTypeProperty() {
return categoryType;
}
public void setCategoryType(String categoryType) {
this.categoryType.set(categoryType);
}
@Override
public String toString() {
return getCategoryName();
}
}

View File

@@ -10,16 +10,14 @@ import javafx.beans.property.SimpleStringProperty;
public class Product {
private SimpleIntegerProperty prodId;
private SimpleStringProperty prodName;
private SimpleStringProperty prodSku;
private SimpleDoubleProperty prodPrice;
private SimpleIntegerProperty categoryId;
private SimpleStringProperty prodDesc;
//constructor
public Product(int prodId, String prodName, String prodSku, double prodPrice, int categoryId, String prodDesc) {
public Product(int prodId, String prodName, double prodPrice, int categoryId, String prodDesc) {
this.prodId = new SimpleIntegerProperty(prodId);
this.prodName = new SimpleStringProperty(prodName);
this.prodSku = new SimpleStringProperty(prodSku);
this.prodPrice = new SimpleDoubleProperty(prodPrice);
this.categoryId = new SimpleIntegerProperty(categoryId);
this.prodDesc = new SimpleStringProperty(prodDesc);
@@ -50,18 +48,6 @@ public class Product {
this.prodName.set(prodName);
}
public String getProdSku() {
return prodSku.get();
}
public SimpleStringProperty prodSkuProperty() {
return prodSku;
}
public void setProdSku(String prodSku) {
this.prodSku.set(prodSku);
}
public double getProdPrice() {
return prodPrice.get();
}