From 07a6d3bfc6dba02149487fee69a7946ddce29187 Mon Sep 17 00:00:00 2001 From: Alex Date: Tue, 3 Feb 2026 20:02:46 -0700 Subject: [PATCH] Added CRUD to Products and added Validation to dialog --- Petstoredata.sql | 215 ++++++++++++------ .../petshopdesktop/DTOs/ProductDTO.java | 17 +- .../org/example/petshopdesktop/Validator.java | 131 +++++++++++ .../controllers/ProductController.java | 169 +++++++++++++- .../controllers/SupplierController.java | 47 +++- .../ProductDialogController.java | 211 +++++++++++++++++ .../SupplierDialogController.java | 21 +- .../petshopdesktop/database/CategoryDB.java | 41 ++++ .../petshopdesktop/database/ProductDB.java | 155 +++++++++++-- .../petshopdesktop/database/SupplierDB.java | 52 ++++- .../petshopdesktop/models/Category.java | 59 +++++ .../petshopdesktop/models/Product.java | 16 +- .../dialogviews/product-dialog-view.fxml | 149 ++++++++++++ .../modelviews/product-view.fxml | 9 +- 14 files changed, 1147 insertions(+), 145 deletions(-) create mode 100644 src/main/java/org/example/petshopdesktop/Validator.java create mode 100644 src/main/java/org/example/petshopdesktop/controllers/dialogcontrollers/ProductDialogController.java create mode 100644 src/main/java/org/example/petshopdesktop/database/CategoryDB.java create mode 100644 src/main/java/org/example/petshopdesktop/models/Category.java create mode 100644 src/main/resources/org/example/petshopdesktop/dialogviews/product-dialog-view.fxml diff --git a/Petstoredata.sql b/Petstoredata.sql index 763c21cf..c1d1046b 100644 --- a/Petstoredata.sql +++ b/Petstoredata.sql @@ -7,24 +7,24 @@ USE Petstoredb; CREATE TABLE storeLocation ( storeId INT AUTO_INCREMENT PRIMARY KEY, storeName VARCHAR(100) NOT NULL, - address VARCHAR(255), - phone VARCHAR(20), - email VARCHAR(100) + address VARCHAR(255) NOT NULL, + phone VARCHAR(20) NOT NULL, + email VARCHAR(100) NOT NULL ); CREATE TABLE employee ( employeeId INT AUTO_INCREMENT PRIMARY KEY, firstName VARCHAR(50) NOT NULL, lastName VARCHAR(50) NOT NULL, - email VARCHAR(100), - phone VARCHAR(20), - role VARCHAR(50), - isActive BOOLEAN DEFAULT TRUE + email VARCHAR(100) NOT NULL, + phone VARCHAR(20) NOT NULL, + role VARCHAR(50) NOT NULL, + isActive BOOLEAN DEFAULT TRUE NOT NULL ); CREATE TABLE employeeStore ( - employeeId INT, - storeId INT, + employeeId INT NOT NULL, + storeId INT NOT NULL, PRIMARY KEY (employeeId, storeId), FOREIGN KEY (employeeId) REFERENCES employee(employeeId), FOREIGN KEY (storeId) REFERENCES storeLocation(storeId) @@ -34,26 +34,26 @@ CREATE TABLE customer ( customerId INT AUTO_INCREMENT PRIMARY KEY, firstName VARCHAR(50) NOT NULL, lastName VARCHAR(50) NOT NULL, - email VARCHAR(100), - phone VARCHAR(20) + email VARCHAR(100) NOT NULL, + phone VARCHAR(20) NOT NULL ); CREATE TABLE pet ( petId INT AUTO_INCREMENT PRIMARY KEY, - petName VARCHAR(50), - petSpecies VARCHAR(50), - petBreed VARCHAR(50), - petAge INT, - petStatus VARCHAR(20), - petPrice DECIMAL(10, 2) + petName VARCHAR(50) NOT NULL, + petSpecies VARCHAR(50) NOT NULL, + petBreed VARCHAR(50) NOT NULL, + petAge INT NOT NULL, + petStatus VARCHAR(20) NOT NULL, + petPrice DECIMAL(10, 2) NOT NULL ); CREATE TABLE adoption ( adoptionId INT AUTO_INCREMENT PRIMARY KEY, - petId INT, - customerId INT, - adoptionDate DATE, - adoptionStatus VARCHAR(20), + petId INT NOT NULL, + customerId INT NOT NULL, + adoptionDate DATE NOT NULL, + adoptionStatus VARCHAR(20) NOT NULL, FOREIGN KEY (petId) REFERENCES pet(petId), FOREIGN KEY (customerId) REFERENCES customer(customerId) ); @@ -61,31 +61,30 @@ CREATE TABLE adoption ( CREATE TABLE supplier ( supId INT AUTO_INCREMENT PRIMARY KEY, supCompany VARCHAR(100) NOT NULL, - supContactFirstName VARCHAR(50), - supContactLastName VARCHAR(50), - supEmail VARCHAR(100), - supPhone VARCHAR(20) + supContactFirstName VARCHAR(50) NOT NULL, + supContactLastName VARCHAR(50) NOT NULL, + supEmail VARCHAR(100) NOT NULL, + supPhone VARCHAR(20) NOT NULL ); CREATE TABLE category ( categoryId INT AUTO_INCREMENT PRIMARY KEY, categoryName VARCHAR(100) NOT NULL, - categoryType VARCHAR(50) + categoryType VARCHAR(50) NOT NULL ); CREATE TABLE product ( prodId INT AUTO_INCREMENT PRIMARY KEY, prodName VARCHAR(100) NOT NULL, - prodSku VARCHAR(50) UNIQUE, - prodPrice DECIMAL(10, 2), - categoryId INT, + prodPrice DECIMAL(10, 2) NOT NULL, + categoryId INT NOT NULL, prodDesc TEXT, FOREIGN KEY (categoryId) REFERENCES category(categoryId) ); CREATE TABLE productSupplier ( - supId INT, - prodId INT, + supId INT NOT NULL, + prodId INT NOT NULL, PRIMARY KEY (supId, prodId), FOREIGN KEY (supId) REFERENCES supplier(supId), FOREIGN KEY (prodId) REFERENCES product(prodId) @@ -93,8 +92,8 @@ CREATE TABLE productSupplier ( CREATE TABLE inventory ( inventoryId INT AUTO_INCREMENT PRIMARY KEY, - prodId INT, - quantity INT DEFAULT 0, + prodId INT NOT NULL, + quantity INT DEFAULT 0 NOT NULL, FOREIGN KEY (prodId) REFERENCES product(prodId) ); @@ -102,24 +101,24 @@ CREATE TABLE service ( serviceId INT AUTO_INCREMENT PRIMARY KEY, serviceName VARCHAR(100) NOT NULL, serviceDesc TEXT, - serviceDuration INT, - servicePrice DECIMAL(10, 2) + serviceDuration INT NOT NULL, + servicePrice DECIMAL(10, 2) NOT NULL ); CREATE TABLE appointment ( appointmentId INT AUTO_INCREMENT PRIMARY KEY, - serviceId INT, - customerId INT, - appointmentDate DATE, - appointmentTime TIME, - appointmentStatus VARCHAR(20), + serviceId INT NOT NULL, + customerId INT NOT NULL, + appointmentDate DATE NOT NULL, + appointmentTime TIME NOT NULL, + appointmentStatus VARCHAR(20) NOT NULL, FOREIGN KEY (serviceId) REFERENCES service(serviceId), FOREIGN KEY (customerId) REFERENCES customer(customerId) ); CREATE TABLE appointmentPet ( - appointmentId INT, - petId INT, + appointmentId INT NOT NULL, + petId INT NOT NULL, PRIMARY KEY (appointmentId, petId), FOREIGN KEY (appointmentId) REFERENCES appointment(appointmentId), FOREIGN KEY (petId) REFERENCES pet(petId) @@ -127,30 +126,30 @@ CREATE TABLE appointmentPet ( CREATE TABLE sale ( saleId INT AUTO_INCREMENT PRIMARY KEY, - saleDate DATETIME, - totalAmount DECIMAL(10, 2), - paymentMethod VARCHAR(50), - employeeId INT, - storeId INT, + saleDate DATETIME NOT NULL, + totalAmount DECIMAL(10, 2) NOT NULL, + paymentMethod VARCHAR(50) NOT NULL, + employeeId INT NOT NULL, + storeId INT NOT NULL, FOREIGN KEY (employeeId) REFERENCES employee(employeeId), FOREIGN KEY (storeId) REFERENCES storeLocation(storeId) ); CREATE TABLE saleItem ( saleItemId INT AUTO_INCREMENT PRIMARY KEY, - saleId INT, - prodId INT, - quantity INT, - unitPrice DECIMAL(10, 2), + saleId INT NOT NULL, + prodId INT NOT NULL, + quantity INT NOT NULL, + unitPrice DECIMAL(10, 2) NOT NULL, FOREIGN KEY (saleId) REFERENCES sale(saleId), FOREIGN KEY (prodId) REFERENCES product(prodId) ); CREATE TABLE activityLog ( logId INT AUTO_INCREMENT PRIMARY KEY, - employeeId INT, - activity TEXT, - logTimestamp TIMESTAMP DEFAULT CURRENT_TIMESTAMP, + employeeId INT NOT NULL, + activity TEXT NOT NULL, + logTimestamp TIMESTAMP DEFAULT CURRENT_TIMESTAMP NOT NULL, FOREIGN KEY (employeeId) REFERENCES employee(employeeId) ); @@ -159,78 +158,148 @@ CREATE TABLE activityLog ( INSERT INTO storeLocation (storeName, address, phone, email) VALUES ('Downtown Branch', '123 Main St', '123-456-7890', 'downtown@petshop.com'), -('North Branch', '456 North Ave', '987-654-3210', 'north@petshop.com'); +('North Branch', '456 North Ave', '987-654-3210', 'north@petshop.com'), +('West Side Store', '789 West Blvd', '555-123-4567', 'westside@petshop.com'), +('East End Shop', '321 East Road', '555-987-6543', 'eastend@petshop.com'), +('South Mall Location', '654 South Plaza', '555-246-8135', 'southmall@petshop.com'); INSERT INTO employee (firstName, lastName, email, phone, role, isActive) VALUES ('John', 'Doe', 'john@petshop.com', '111-222-3333', 'Manager', TRUE), -('Sara', 'Smith', 'sara@petshop.com', '444-555-6666', 'Staff', TRUE); +('Sara', 'Smith', 'sara@petshop.com', '444-555-6666', 'Staff', TRUE), +('Michael', 'Johnson', 'michael@petshop.com', '222-333-4444', 'Groomer', TRUE), +('Lisa', 'Williams', 'lisa@petshop.com', '333-444-5555', 'Staff', TRUE), +('David', 'Brown', 'david@petshop.com', '555-666-7777', 'Veterinarian', TRUE), +('Emma', 'Davis', 'emma@petshop.com', '666-777-8888', 'Manager', FALSE); INSERT INTO employeeStore (employeeId, storeId) VALUES (1, 1), (2, 1), -(2, 2); +(2, 2), +(3, 2), +(4, 3), +(5, 1), +(5, 4), +(6, 5); INSERT INTO customer (firstName, lastName, email, phone) VALUES ('Alex', 'Brown', 'alex@gmail.com', '777-888-9999'), -('Emily', 'Clark', 'emily@gmail.com', '666-555-4444'); +('Emily', 'Clark', 'emily@gmail.com', '666-555-4444'), +('James', 'Wilson', 'james@gmail.com', '888-999-0000'), +('Olivia', 'Martinez', 'olivia@gmail.com', '999-000-1111'), +('William', 'Anderson', 'william@gmail.com', '000-111-2222'), +('Sophia', 'Taylor', 'sophia@gmail.com', '111-222-3333'); INSERT INTO pet (petName, petSpecies, petBreed, petAge, petStatus, petPrice) VALUES ('Buddy', 'Dog', 'Labrador', 2, 'Available', 500.00), -('Milo', 'Cat', 'Persian', 1, 'Available', 300.00); +('Milo', 'Cat', 'Persian', 1, 'Available', 300.00), +('Charlie', 'Dog', 'Golden Retriever', 3, 'Available', 550.00), +('Luna', 'Cat', 'Siamese', 2, 'Adopted', 350.00), +('Max', 'Dog', 'Beagle', 1, 'Available', 450.00), +('Bella', 'Cat', 'Maine Coon', 4, 'Available', 400.00); INSERT INTO adoption (petId, customerId, adoptionDate, adoptionStatus) VALUES -(1, 1, '2026-01-15', 'Completed'); +(1, 1, '2026-01-15', 'Completed'), +(4, 3, '2026-01-20', 'Completed'), +(2, 2, '2026-01-25', 'Pending'), +(5, 4, '2026-02-01', 'Completed'), +(6, 5, '2026-02-02', 'Pending'); INSERT INTO supplier (supCompany, supContactFirstName, supContactLastName, supEmail, supPhone) VALUES -('PetFood Inc', 'Robert', 'King', 'contact@petfood.com', '888-111-2222'); +('PetFood Inc', 'Robert', 'King', 'contact@petfood.com', '888-111-2222'), +('Toy World', 'Jennifer', 'Lee', 'sales@toyworld.com', '888-222-3333'), +('Pet Supplies Co', 'Kevin', 'White', 'info@petsupplies.com', '888-333-4444'), +('Animal Care Products', 'Nancy', 'Green', 'orders@animalcare.com', '888-444-5555'), +('Premium Pet Goods', 'Tom', 'Black', 'support@premiumpet.com', '888-555-6666'); INSERT INTO category (categoryName, categoryType) VALUES ('Dog Food', 'Product'), -('Cat Toys', 'Product'); +('Cat Toys', 'Product'), +('Bird Supplies', 'Product'), +('Aquarium', 'Product'), +('Small Animals', 'Product'); -INSERT INTO product (prodName, prodSku, prodPrice, categoryId, prodDesc) +INSERT INTO product (prodName, prodPrice, categoryId, prodDesc) VALUES -('Premium Dog Food', 'DF001', 50.00, 1, 'High quality dog food'), -('Cat Toy Ball', 'CT001', 10.00, 2, 'Colorful toy for cats'); +('Premium Dog Food', 50.00, 1, 'High quality dog food'), +('Cat Toy Ball', 10.00, 2, 'Colorful toy for cats'), +('Bird Cage Large', 120.00, 3, 'Spacious bird cage'), +('Fish Tank 20 Gallon', 80.00, 4, 'Complete aquarium kit'), +('Hamster Wheel', 15.00, 5, 'Exercise wheel for small pets'), +('Organic Dog Treats', 25.00, 1, 'Natural dog treats'); INSERT INTO productSupplier (supId, prodId) VALUES (1, 1), -(1, 2); +(1, 2), +(2, 2), +(3, 3), +(3, 4), +(4, 5), +(5, 6), +(1, 6); INSERT INTO inventory (prodId, quantity) VALUES (1, 100), -(2, 200); +(2, 200), +(3, 50), +(4, 30), +(5, 150), +(6, 75); INSERT INTO service (serviceName, serviceDesc, serviceDuration, servicePrice) VALUES -('Pet Grooming', 'Full grooming service', 60, 40.00); +('Pet Grooming', 'Full grooming service', 60, 40.00), +('Nail Trimming', 'Quick nail trim', 15, 10.00), +('Bath and Brush', 'Bathing and brushing service', 45, 30.00), +('Veterinary Checkup', 'Complete health examination', 30, 75.00), +('Teeth Cleaning', 'Professional dental cleaning', 90, 100.00); INSERT INTO appointment (serviceId, customerId, appointmentDate, appointmentTime, appointmentStatus) VALUES -(1, 2, '2026-02-01', '10:30:00', 'Booked'); +(1, 2, '2026-02-01', '10:30:00', 'Booked'), +(2, 1, '2026-02-03', '14:00:00', 'Booked'), +(3, 3, '2026-02-05', '09:00:00', 'Completed'), +(4, 4, '2026-02-07', '11:30:00', 'Booked'), +(5, 5, '2026-02-10', '15:00:00', 'Cancelled'); INSERT INTO appointmentPet (appointmentId, petId) VALUES -(1, 2); +(1, 2), +(2, 1), +(3, 3), +(4, 5), +(5, 6); INSERT INTO sale (saleDate, totalAmount, paymentMethod, employeeId, storeId) VALUES -(NOW(), 60.00, 'Card', 2, 1); +(NOW(), 60.00, 'Card', 2, 1), +('2026-01-28 10:30:00', 50.00, 'Cash', 1, 1), +('2026-01-29 14:15:00', 120.00, 'Card', 4, 3), +('2026-01-30 16:45:00', 80.00, 'Card', 2, 2), +('2026-02-01 11:20:00', 150.00, 'Cash', 5, 4); INSERT INTO saleItem (saleId, prodId, quantity, unitPrice) VALUES -(1, 2, 2, 10.00); +(1, 2, 2, 10.00), +(2, 1, 1, 50.00), +(3, 3, 1, 120.00), +(4, 4, 1, 80.00), +(5, 6, 6, 25.00), +(2, 2, 3, 10.00); INSERT INTO activityLog (employeeId, activity) VALUES (1, 'Created new sale'), -(2, 'Booked appointment'); +(2, 'Booked appointment'), +(3, 'Completed grooming service'), +(4, 'Processed inventory order'), +(5, 'Conducted health checkup'), +(1, 'Updated customer information'); \ No newline at end of file diff --git a/src/main/java/org/example/petshopdesktop/DTOs/ProductDTO.java b/src/main/java/org/example/petshopdesktop/DTOs/ProductDTO.java index 865af1de..3ea081df 100644 --- a/src/main/java/org/example/petshopdesktop/DTOs/ProductDTO.java +++ b/src/main/java/org/example/petshopdesktop/DTOs/ProductDTO.java @@ -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() diff --git a/src/main/java/org/example/petshopdesktop/Validator.java b/src/main/java/org/example/petshopdesktop/Validator.java new file mode 100644 index 00000000..29182e20 --- /dev/null +++ b/src/main/java/org/example/petshopdesktop/Validator.java @@ -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; + } +} diff --git a/src/main/java/org/example/petshopdesktop/controllers/ProductController.java b/src/main/java/org/example/petshopdesktop/controllers/ProductController.java index d8811cc0..4dc1587e 100644 --- a/src/main/java/org/example/petshopdesktop/controllers/ProductController.java +++ b/src/main/java/org/example/petshopdesktop/controllers/ProductController.java @@ -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 colProductPrice; - @FXML - private TableColumn colProductSKU; - @FXML private TableView tvProducts; @@ -68,19 +73,31 @@ public class ProductController { //set up table columns colProductId.setCellValueFactory(new PropertyValueFactory("prodId")); colProductName.setCellValueFactory(new PropertyValueFactory("prodName")); - colProductSKU.setCellValueFactory(new PropertyValueFactory("prodSku")); colProductPrice.setCellValueFactory(new PropertyValueFactory("prodPrice")); colProductCategory.setCellValueFactory(new PropertyValueFactory("categoryName")); colProductDesc.setCellValueFactory(new PropertyValueFactory("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 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(""); } } diff --git a/src/main/java/org/example/petshopdesktop/controllers/SupplierController.java b/src/main/java/org/example/petshopdesktop/controllers/SupplierController.java index c64eff6c..080cc751 100644 --- a/src/main/java/org/example/petshopdesktop/controllers/SupplierController.java +++ b/src/main/java/org/example/petshopdesktop/controllers/SupplierController.java @@ -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(""); } -} +} \ No newline at end of file diff --git a/src/main/java/org/example/petshopdesktop/controllers/dialogcontrollers/ProductDialogController.java b/src/main/java/org/example/petshopdesktop/controllers/dialogcontrollers/ProductDialogController.java new file mode 100644 index 00000000..5cc58d87 --- /dev/null +++ b/src/main/java/org/example/petshopdesktop/controllers/dialogcontrollers/ProductDialogController.java @@ -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 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() { + @Override + public void handle(MouseEvent mouseEvent) { + buttonSaveClicked(mouseEvent); + } + }); + + btnCancel.setOnMouseClicked(new EventHandler() { + @Override + public void handle(MouseEvent mouseEvent) { + closeStage(mouseEvent); + } + }); + + //Set up combobox for selecting category + try { + //set up combobox + ObservableList 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); + } + } + +} diff --git a/src/main/java/org/example/petshopdesktop/controllers/dialogcontrollers/SupplierDialogController.java b/src/main/java/org/example/petshopdesktop/controllers/dialogcontrollers/SupplierDialogController.java index fe6e06c2..d901d3d5 100644 --- a/src/main/java/org/example/petshopdesktop/controllers/dialogcontrollers/SupplierDialogController.java +++ b/src/main/java/org/example/petshopdesktop/controllers/dialogcontrollers/SupplierDialogController.java @@ -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 diff --git a/src/main/java/org/example/petshopdesktop/database/CategoryDB.java b/src/main/java/org/example/petshopdesktop/database/CategoryDB.java new file mode 100644 index 00000000..f9a2a434 --- /dev/null +++ b/src/main/java/org/example/petshopdesktop/database/CategoryDB.java @@ -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 getCategories() throws SQLException{ + //Connect to the database + ObservableList 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; + } +} diff --git a/src/main/java/org/example/petshopdesktop/database/ProductDB.java b/src/main/java/org/example/petshopdesktop/database/ProductDB.java index 5eaf1e89..b5fbeb07 100644 --- a/src/main/java/org/example/petshopdesktop/database/ProductDB.java +++ b/src/main/java/org/example/petshopdesktop/database/ProductDB.java @@ -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 getFilteredProductDTOs(String filter) throws SQLException { + //Connect to the database + ObservableList 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; + } } diff --git a/src/main/java/org/example/petshopdesktop/database/SupplierDB.java b/src/main/java/org/example/petshopdesktop/database/SupplierDB.java index cc186081..325b6dd4 100644 --- a/src/main/java/org/example/petshopdesktop/database/SupplierDB.java +++ b/src/main/java/org/example/petshopdesktop/database/SupplierDB.java @@ -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 getFilteredSuppliers(String filter) throws SQLException { + //Connect to the database + ObservableList 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; + } } diff --git a/src/main/java/org/example/petshopdesktop/models/Category.java b/src/main/java/org/example/petshopdesktop/models/Category.java new file mode 100644 index 00000000..1f28182b --- /dev/null +++ b/src/main/java/org/example/petshopdesktop/models/Category.java @@ -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(); + } +} diff --git a/src/main/java/org/example/petshopdesktop/models/Product.java b/src/main/java/org/example/petshopdesktop/models/Product.java index 1a7333b3..0738068a 100644 --- a/src/main/java/org/example/petshopdesktop/models/Product.java +++ b/src/main/java/org/example/petshopdesktop/models/Product.java @@ -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(); } diff --git a/src/main/resources/org/example/petshopdesktop/dialogviews/product-dialog-view.fxml b/src/main/resources/org/example/petshopdesktop/dialogviews/product-dialog-view.fxml new file mode 100644 index 00000000..2972f5ed --- /dev/null +++ b/src/main/resources/org/example/petshopdesktop/dialogviews/product-dialog-view.fxml @@ -0,0 +1,149 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/main/resources/org/example/petshopdesktop/modelviews/product-view.fxml b/src/main/resources/org/example/petshopdesktop/modelviews/product-view.fxml index 68f15d78..2473d057 100644 --- a/src/main/resources/org/example/petshopdesktop/modelviews/product-view.fxml +++ b/src/main/resources/org/example/petshopdesktop/modelviews/product-view.fxml @@ -68,11 +68,10 @@ - - - - - + + + +