From 13e8c01a2809c17900fce4a3d8387424e34387f2 Mon Sep 17 00:00:00 2001 From: Harkamal Randhawa Date: Tue, 24 Feb 2026 20:26:50 -0700 Subject: [PATCH] Merge conflict resolution and updates --- Petstoredata.sql | 107 ++++++++++++-- README.md | 48 +++++++ pom.xml | 5 +- .../example/petshopdesktop/DTOs/SaleDTO.java | 93 ++++++++++++ .../org/example/petshopdesktop/Launcher.java | 2 - .../example/petshopdesktop/Validator.class | Bin 0 -> 2511 bytes .../org/example/petshopdesktop/Validator.java | 23 ++- .../example/petshopdesktop/auth/Role.class | Bin 0 -> 995 bytes .../org/example/petshopdesktop/auth/Role.java | 7 - .../petshopdesktop/auth/UserSession.java | 14 -- .../controllers/LoginController.java | 9 -- .../controllers/MainLayoutController.java | 45 +++--- .../controllers/SaleController.java | 132 ++++++++++++++++-- .../petshopdesktop/database/AdoptionDB.java | 4 +- .../database/ProductSupplierDB.java | 12 +- .../petshopdesktop/database/SaleDB.java | 113 +++++++++++++++ .../petshopdesktop/database/UserDB.java | 7 - .../dialogviews/adoption-dialog-view.fxml | 2 +- .../dialogviews/appointment-dialog-view.fxml | 2 +- .../dialogviews/inventory-dialog-view.fxml | 2 +- .../dialogviews/pet-dialog-view.fxml | 2 +- .../dialogviews/product-dialog-view.fxml | 2 +- .../product-supplier-dialog-view.fxml | 2 +- .../dialogviews/service-dialog-view.fxml | 2 +- .../dialogviews/supplier-dialog-view.fxml | 2 +- .../example/petshopdesktop/login-view.fxml | 2 +- .../petshopdesktop/main-layout-view.fxml | 119 +++++++++------- .../modelviews/adoption-view.fxml | 2 +- .../modelviews/appointment-view.fxml | 2 +- .../modelviews/inventory-view.fxml | 2 +- .../petshopdesktop/modelviews/pet-view.fxml | 2 +- .../modelviews/product-supplier-view.fxml | 2 +- .../modelviews/product-view.fxml | 2 +- .../modelviews/purchase-order-view.fxml | 2 +- .../modelviews/purchaseorder-view.fxml | 82 ----------- .../petshopdesktop/modelviews/sale-view.fxml | 2 +- .../modelviews/service-view.fxml | 2 +- .../modelviews/supplier-view.fxml | 2 +- 38 files changed, 594 insertions(+), 266 deletions(-) create mode 100644 README.md create mode 100644 src/main/java/org/example/petshopdesktop/DTOs/SaleDTO.java create mode 100644 src/main/java/org/example/petshopdesktop/Validator.class create mode 100644 src/main/java/org/example/petshopdesktop/auth/Role.class create mode 100644 src/main/java/org/example/petshopdesktop/database/SaleDB.java delete mode 100644 src/main/resources/org/example/petshopdesktop/modelviews/purchaseorder-view.fxml diff --git a/Petstoredata.sql b/Petstoredata.sql index 1b968e23..4d50c46a 100644 --- a/Petstoredata.sql +++ b/Petstoredata.sql @@ -146,6 +146,14 @@ CREATE TABLE saleItem ( FOREIGN KEY (prodId) REFERENCES product(prodId) ); +CREATE TABLE purchaseOrder ( + purchaseOrderId INT AUTO_INCREMENT PRIMARY KEY, + supId INT NOT NULL, + orderDate DATE NOT NULL, + status VARCHAR(50) NOT NULL, + FOREIGN KEY (supId) REFERENCES supplier(supId) +); + CREATE TABLE activityLog ( logId INT AUTO_INCREMENT PRIMARY KEY, employeeId INT NOT NULL, @@ -281,20 +289,97 @@ VALUES INSERT INTO sale (saleDate, totalAmount, paymentMethod, employeeId, storeId) VALUES -(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); +-- January Sales +('2026-01-05 09:15:00', 125.00, 'Card', 1, 1), -- Sale 1: Dog food + treats +('2026-01-08 11:30:00', 200.00, 'Card', 2, 1), -- Sale 2: Bird cage + fish tank +('2026-01-12 14:20:00', 60.00, 'Cash', 3, 2), -- Sale 3: Cat toys + hamster wheel +('2026-01-15 10:45:00', 150.00, 'Debit', 1, 1), -- Sale 4: Dog food (bulk purchase) +('2026-01-18 16:30:00', 80.00, 'Card', 4, 3), -- Sale 5: Fish tank +('2026-01-22 13:15:00', 95.00, 'Cash', 2, 2), -- Sale 6: Mixed items +('2026-01-25 15:40:00', 240.00, 'Card', 5, 4), -- Sale 7: Two bird cages +('2026-01-28 10:30:00', 80.00, 'Cash', 1, 1), -- Sale 8: Dog food + cat toys +-- February Sales +('2026-02-01 09:00:00', 175.00, 'Card', 3, 3), -- Sale 9: Dog food + treats (bulk) +('2026-02-03 11:20:00', 120.00, 'Card', 2, 1), -- Sale 10: Bird cage +('2026-02-05 14:50:00', 45.00, 'Cash', 4, 2), -- Sale 11: Hamster wheel + cat toys +('2026-02-08 16:15:00', 160.00, 'Debit', 1, 1), -- Sale 12: Fish tank + accessories +('2026-02-10 10:25:00', 100.00, 'Card', 5, 4), -- Sale 13: Dog treats (bulk) +('2026-02-12 13:45:00', 50.00, 'Cash', 2, 2), -- Sale 14: Dog food +('2026-02-15 15:30:00', 85.00, 'Card', 3, 3), -- Sale 15: Mixed pet supplies +('2026-02-18 11:10:00', 200.00, 'Card', 1, 1), -- Sale 16: Bird cage + hamster wheel +('2026-02-20 14:35:00', 155.00, 'Debit', 4, 3), -- Sale 17: Fish tank + cat toys +('2026-02-22 16:50:00', 75.00, 'Cash', 2, 1), -- Sale 18: Dog treats + toys +('2026-02-24 10:15:00', 140.00, 'Card', 5, 4), -- Sale 19: Dog food + treats +(NOW(), 95.00, 'Card', 1, 1); -- Sale 20: Recent sale (current timestamp) INSERT INTO saleItem (saleId, prodId, quantity, unitPrice) VALUES -(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); +-- Sale 1 items (Dog food + treats) +(1, 1, 2, 50.00), -- 2x Premium Dog Food +(1, 6, 1, 25.00), -- 1x Organic Dog Treats +-- Sale 2 items (Bird cage + fish tank) +(2, 3, 1, 120.00), -- 1x Bird Cage Large +(2, 4, 1, 80.00), -- 1x Fish Tank 20 Gallon +-- Sale 3 items (Cat toys + hamster wheel) +(3, 2, 3, 10.00), -- 3x Cat Toy Ball +(3, 5, 2, 15.00), -- 2x Hamster Wheel +-- Sale 4 items (Dog food bulk) +(4, 1, 3, 50.00), -- 3x Premium Dog Food +-- Sale 5 items (Fish tank) +(5, 4, 1, 80.00), -- 1x Fish Tank 20 Gallon +-- Sale 6 items (Mixed) +(6, 2, 4, 10.00), -- 4x Cat Toy Ball +(6, 5, 1, 15.00), -- 1x Hamster Wheel +(6, 6, 1, 25.00), -- 1x Organic Dog Treats +(6, 1, 1, 50.00), -- 1x Premium Dog Food (partial - discount applied) +-- Sale 7 items (Two bird cages) +(7, 3, 2, 120.00), -- 2x Bird Cage Large +-- Sale 8 items (Dog food + cat toys) +(8, 1, 1, 50.00), -- 1x Premium Dog Food +(8, 2, 3, 10.00), -- 3x Cat Toy Ball +-- Sale 9 items (Dog food + treats bulk) +(9, 1, 3, 50.00), -- 3x Premium Dog Food +(9, 6, 1, 25.00), -- 1x Organic Dog Treats +-- Sale 10 items (Bird cage) +(10, 3, 1, 120.00), -- 1x Bird Cage Large +-- Sale 11 items (Hamster wheel + cat toys) +(11, 5, 1, 15.00), -- 1x Hamster Wheel +(11, 2, 3, 10.00), -- 3x Cat Toy Ball +-- Sale 12 items (Fish tank + accessories) +(12, 4, 2, 80.00), -- 2x Fish Tank 20 Gallon +-- Sale 13 items (Dog treats bulk) +(13, 6, 4, 25.00), -- 4x Organic Dog Treats +-- Sale 14 items (Dog food) +(14, 1, 1, 50.00), -- 1x Premium Dog Food +-- Sale 15 items (Mixed supplies) +(15, 2, 2, 10.00), -- 2x Cat Toy Ball +(15, 5, 1, 15.00), -- 1x Hamster Wheel +(15, 6, 2, 25.00), -- 2x Organic Dog Treats +-- Sale 16 items (Bird cage + hamster wheel) +(16, 3, 1, 120.00), -- 1x Bird Cage Large +(16, 4, 1, 80.00), -- 1x Fish Tank 20 Gallon +-- Sale 17 items (Fish tank + cat toys) +(17, 4, 1, 80.00), -- 1x Fish Tank 20 Gallon +(17, 1, 1, 50.00), -- 1x Premium Dog Food +(17, 6, 1, 25.00), -- 1x Organic Dog Treats +-- Sale 18 items (Dog treats + toys) +(18, 6, 2, 25.00), -- 2x Organic Dog Treats +(18, 2, 2, 10.00), -- 2x Cat Toy Ball +(18, 5, 1, 15.00), -- 1x Hamster Wheel +-- Sale 19 items (Dog food + treats) +(19, 1, 2, 50.00), -- 2x Premium Dog Food +(19, 6, 2, 25.00), -- 2x Organic Dog Treats (discount applied) +-- Sale 20 items (Recent sale) +(20, 2, 5, 10.00), -- 5x Cat Toy Ball +(20, 5, 3, 15.00); -- 3x Hamster Wheel + +INSERT INTO purchaseOrder (supId, orderDate, status) +VALUES +(1, '2025-01-15', 'Delivered'), +(2, '2025-01-20', 'Pending'), +(3, '2025-02-01', 'Delivered'), +(4, '2025-02-10', 'In Transit'), +(1, '2025-02-15', 'Pending'); INSERT INTO activityLog (employeeId, activity) VALUES diff --git a/README.md b/README.md new file mode 100644 index 00000000..b525f4b2 --- /dev/null +++ b/README.md @@ -0,0 +1,48 @@ +# Pet Shop Desktop (JavaFX) + +Desktop pet shop management app built with JavaFX and MySQL. + +Made by **Group 2**, Shiv, Nikitha, Alex, Harkamal. + +## Requirements + +- IntelliJ IDEA (Community or Ultimate) +- Java 17+ +- Maven (handled through IntelliJ) +- Docker and Docker Compose (for the local MySQL container) + +## Database setup (IntelliJ) + +1. Open the project in IntelliJ. +2. Open **View → Tool Windows → Services**. +3. Add a Docker connection if needed, then open the **Docker** section in Services. +4. Start the Compose stack from `docker-compose.yml` (Compose Up, or Start). +5. Confirm the `mysql` service is running. + +The container uses `mysql:8.4`, creates the `Petstoredb` database, and imports `Petstoredata.sql`. + +## App configuration + +An example connection file is provided at `connectionpetstore.properties.example`. Copy it to `connectionpetstore.properties` and edit the values to match the local database setup. + +## Run the app (IntelliJ, Maven) + +1. Open **View → Tool Windows → Maven**. +2. Click **Reload All Maven Projects** if the dependencies have not loaded yet. +3. In the Maven tool window, expand **Plugins → javafx**. +4. Double click **javafx:run**. + +Optional, run a clean first: +- In the Maven tool window, expand **Lifecycle** and run **clean**. + +## Default accounts + +On first run, the app creates a `users` table (if missing) and seeds two accounts: + +- Admin: `admin` / `admin123` +- Staff: `staff` / `staff123` + +## Notes + +- `connectionpetstore.properties` is gitignored so credentials are not committed. +- If the app cannot connect to MySQL, confirm the Compose stack is running and MySQL is available. diff --git a/pom.xml b/pom.xml index 6da4edce..3c683c9e 100644 --- a/pom.xml +++ b/pom.xml @@ -10,7 +10,7 @@ PetShopDesktop UTF-8 - 25.0.2 + 17.0.10 5.12.1 @@ -53,8 +53,7 @@ maven-compiler-plugin 3.13.0 - 23 - 23 + 17 diff --git a/src/main/java/org/example/petshopdesktop/DTOs/SaleDTO.java b/src/main/java/org/example/petshopdesktop/DTOs/SaleDTO.java new file mode 100644 index 00000000..a20bf5fd --- /dev/null +++ b/src/main/java/org/example/petshopdesktop/DTOs/SaleDTO.java @@ -0,0 +1,93 @@ +package org.example.petshopdesktop.DTOs; + +import javafx.beans.property.*; + +public class SaleDTO { + + private IntegerProperty saleId; + private StringProperty saleDate; + private StringProperty employeeName; + private StringProperty productName; + private IntegerProperty quantity; + private DoubleProperty unitPrice; + private DoubleProperty total; + private StringProperty paymentMethod; + + public SaleDTO(int saleId, String saleDate, String employeeName, String productName, + int quantity, double unitPrice, double total, String paymentMethod) { + this.saleId = new SimpleIntegerProperty(saleId); + this.saleDate = new SimpleStringProperty(saleDate); + this.employeeName = new SimpleStringProperty(employeeName); + this.productName = new SimpleStringProperty(productName); + this.quantity = new SimpleIntegerProperty(quantity); + this.unitPrice = new SimpleDoubleProperty(unitPrice); + this.total = new SimpleDoubleProperty(total); + this.paymentMethod = new SimpleStringProperty(paymentMethod); + } + + // Getters + public int getSaleId() { + return saleId.get(); + } + + public String getSaleDate() { + return saleDate.get(); + } + + public String getEmployeeName() { + return employeeName.get(); + } + + public String getProductName() { + return productName.get(); + } + + public int getQuantity() { + return quantity.get(); + } + + public double getUnitPrice() { + return unitPrice.get(); + } + + public double getTotal() { + return total.get(); + } + + public String getPaymentMethod() { + return paymentMethod.get(); + } + + // Properties + public IntegerProperty saleIdProperty() { + return saleId; + } + + public StringProperty saleDateProperty() { + return saleDate; + } + + public StringProperty employeeNameProperty() { + return employeeName; + } + + public StringProperty productNameProperty() { + return productName; + } + + public IntegerProperty quantityProperty() { + return quantity; + } + + public DoubleProperty unitPriceProperty() { + return unitPrice; + } + + public DoubleProperty totalProperty() { + return total; + } + + public StringProperty paymentMethodProperty() { + return paymentMethod; + } +} diff --git a/src/main/java/org/example/petshopdesktop/Launcher.java b/src/main/java/org/example/petshopdesktop/Launcher.java index 8b91cd9c..70456482 100644 --- a/src/main/java/org/example/petshopdesktop/Launcher.java +++ b/src/main/java/org/example/petshopdesktop/Launcher.java @@ -1,5 +1,3 @@ -//Initial commmit - package org.example.petshopdesktop; import javafx.application.Application; diff --git a/src/main/java/org/example/petshopdesktop/Validator.class b/src/main/java/org/example/petshopdesktop/Validator.class new file mode 100644 index 0000000000000000000000000000000000000000..b5653a2dca2e18266db187dfd0144479ca7ca7f1 GIT binary patch literal 2511 zcma)8-B%Mw9KAzAHY5=+B7z^dDq6lm{H{Q2RgfBmh(eJnehgtsR>E$&yWrQMr>Cd? zL#^%UQ_u0$zStff`q+p5P1^R(ZX`s~p0bD8ot@v@-<|urGn+sE+V~y7$0#JwfQW%; z3XO;fv_6z;GFy`NQug}7LsjqvVjo$y<)0Ub^z_cg5f?y$SJFT#g&k{*e^YSgg{(!XW-MLv1Hw0%$DT+c)`dk8eL{Y~%oR|&LX zw}JK)_MoGN&X}{hP*MWPvUEN5uD82RqTaDIIMu*DfrC{V`PG#L<&Hbf~r(~W7%uYvdV@VDBNh{vOrOu2t40f|4Lv8dPUlc zCFONbIL`8Fxz4`Z;^&%)Gf&E@PWYWI@!?4_vei`;h*4Q8O8dYR zEmtiLnu$231h<7SS5`gWTu|nctE8`7)2GI!3PaCaG!E)D|NjJ8lZE! z{yUThMObbe!a1I4`Y+B?kY56}!|Wa4UGU!6_bbFNd=MC6tB1k!uL&PPADcS#n*NaR z-jOyY`~EG9prd7 zBMxI9j_^7fWIuq&TeLHKt>zR@9^btF{IJb&Ol-J)8zV^!VS z_yMh@G)~=e)a@$kb&a3dDMsW;?>a4WqpDjQ35b8u?IJQ2-L4Q!m%cr1=u}+grOj2|;3_q$HePx#-5|ROl#U;c~-FS{-*DhO2{Ihf< zLNppa`$rk?t5cTD4{MX&-uv!3_q==W&tG4E0C;%)Y|KV{X>TJ#x%%^fF=#3VyJywtJg*3jsXKR3|g^S zYrNgF88+Tc$EPEMtcDo_v&fN}wio!EAzv~Z=gx&=d5+()j#}ru9aePYaZkgXfqC3# zNZ%&x`B9guUpQXGkKQvpFO8vhJ!deej0Nnl@A{p}cm+Wa^A`*}z#>DU>iTZD%`i7k zHA3#2%_LNvE?!6?CG4_+6|9N|#2N++X33ng1yt-WNZAce>Gqk1>+{2?+v5FWr{z)P z<$qL|({-33WxE~U38Ov{$tAN%6Rftq(fwYGHAZxyIvwkFg+aH2sNd#wS13%0#o7`h z*?C3{$_i?ywojBHG<&jE5@nbpSZxGb{zj colCustomerName; + private TableColumn colCustomerName; @FXML - private TableColumn colSaleDate; + private TableColumn colSaleDate; @FXML - private TableColumn colSaleId; + private TableColumn colSaleId; @FXML - private TableColumn colSalePaymentType; + private TableColumn colSalePaymentType; @FXML - private TableColumn colSaleQuantity; + private TableColumn colSaleQuantity; @FXML - private TableColumn colSaleTotal; + private TableColumn colSaleTotal; @FXML - private TableColumn colSaleUnitPrice; + private TableColumn colSaleUnitPrice; @FXML - private TableColumn colServiceProduct; + private TableColumn colServiceProduct; @FXML - private TableView tvSales; + private TableView tvSales; @FXML private TextField txtSearch; - @FXML - void btnRefresh(ActionEvent event) { + private ObservableList salesData; + /** + * Initialize the controller - set up table columns and load data + */ + @FXML + public void initialize() { + // Set up table columns + colSaleId.setCellValueFactory(new PropertyValueFactory<>("saleId")); + colSaleDate.setCellValueFactory(new PropertyValueFactory<>("saleDate")); + colCustomerName.setCellValueFactory(new PropertyValueFactory<>("employeeName")); + colServiceProduct.setCellValueFactory(new PropertyValueFactory<>("productName")); + colSaleQuantity.setCellValueFactory(new PropertyValueFactory<>("quantity")); + colSaleUnitPrice.setCellValueFactory(new PropertyValueFactory<>("unitPrice")); + colSaleTotal.setCellValueFactory(new PropertyValueFactory<>("total")); + colSalePaymentType.setCellValueFactory(new PropertyValueFactory<>("paymentMethod")); + + // Format currency columns + colSaleUnitPrice.setCellFactory(tc -> new TableCell() { + @Override + protected void updateItem(Double price, boolean empty) { + super.updateItem(price, empty); + if (empty || price == null) { + setText(null); + } else { + setText(String.format("$%.2f", price)); + } + } + }); + + colSaleTotal.setCellFactory(tc -> new TableCell() { + @Override + protected void updateItem(Double total, boolean empty) { + super.updateItem(total, empty); + if (empty || total == null) { + setText(null); + } else { + setText(String.format("$%.2f", total)); + } + } + }); + + // Load initial data + loadSales(); + + // Add search functionality + txtSearch.textProperty().addListener((observable, oldValue, newValue) -> { + if (newValue == null || newValue.trim().isEmpty()) { + loadSales(); + } else { + searchSales(newValue.trim()); + } + }); } + /** + * Load all sales from database + */ + private void loadSales() { + try { + salesData = SaleDB.getSales(); + tvSales.setItems(salesData); + } catch (SQLException e) { + e.printStackTrace(); + showError("Failed to load sales data", e.getMessage()); + } + } + + /** + * Search sales based on filter text + * @param filter search term + */ + private void searchSales(String filter) { + try { + ObservableList filteredSales = SaleDB.getFilteredSales(filter); + tvSales.setItems(filteredSales); + } catch (SQLException e) { + e.printStackTrace(); + showError("Failed to search sales", e.getMessage()); + } + } + + /** + * Refresh button handler - reload all sales data + * @param event button click event + */ + @FXML + void btnRefresh(ActionEvent event) { + txtSearch.clear(); + loadSales(); + } + + /** + * Show error alert + * @param title alert title + * @param message error message + */ + private void showError(String title, String message) { + Alert alert = new Alert(Alert.AlertType.ERROR); + alert.setTitle(title); + alert.setHeaderText(null); + alert.setContentText(message); + alert.showAndWait(); + } } diff --git a/src/main/java/org/example/petshopdesktop/database/AdoptionDB.java b/src/main/java/org/example/petshopdesktop/database/AdoptionDB.java index 87c087ef..6c436479 100644 --- a/src/main/java/org/example/petshopdesktop/database/AdoptionDB.java +++ b/src/main/java/org/example/petshopdesktop/database/AdoptionDB.java @@ -115,10 +115,10 @@ public class AdoptionDB { Connection conn = ConnectionDB.getConnection(); Statement stmt = conn.createStatement(); - ResultSet rs = stmt.executeQuery("SELECT customerId, firstName, lastName FROM customer"); + ResultSet rs = stmt.executeQuery("SELECT customerId, firstName, lastName, email, phone FROM customer"); while (rs.next()) { - customers.add(new Customer(rs.getInt(1), rs.getString(2), rs.getString(3))); + customers.add(new Customer(rs.getInt(1), rs.getString(2), rs.getString(3), rs.getString(4), rs.getString(5))); } conn.close(); diff --git a/src/main/java/org/example/petshopdesktop/database/ProductSupplierDB.java b/src/main/java/org/example/petshopdesktop/database/ProductSupplierDB.java index cc651bd0..c3298699 100644 --- a/src/main/java/org/example/petshopdesktop/database/ProductSupplierDB.java +++ b/src/main/java/org/example/petshopdesktop/database/ProductSupplierDB.java @@ -23,7 +23,7 @@ public class ProductSupplierDB { //Execute Query Statement stmt = conn.createStatement(); String sql = "SELECT ps.supId, ps.prodId, s.supCompany, p.prodName, ps.cost " + - "FROM productsupplier ps " + + "FROM productSupplier ps " + "LEFT JOIN product p " + "ON p.prodId = ps.prodId " + "LEFT JOIN supplier s " + @@ -62,7 +62,7 @@ public class ProductSupplierDB { String sql = "SELECT ps.supId, ps.prodId, s.supCompany, p.prodName, ps.cost " + "FROM product p " + - "LEFT JOIN productsupplier ps " + + "LEFT JOIN productSupplier ps " + "ON p.prodId = ps.prodId " + "LEFT JOIN supplier s " + "ON s.supId = ps.supId " + @@ -108,7 +108,7 @@ public class ProductSupplierDB { int numRows = 0; Connection conn = ConnectionDB.getConnection(); - String sql = "INSERT INTO productsupplier (prodId, supId, cost) " + + String sql = "INSERT INTO productSupplier (prodId, supId, cost) " + "VALUES (?, ?, ?)"; //These are the values from productSupplier to put into query above @@ -141,7 +141,7 @@ public class ProductSupplierDB { try{ //Delete old data first - String sql = "DELETE FROM productsupplier WHERE supId = ? AND prodId = ?"; + String sql = "DELETE FROM productSupplier WHERE supId = ? AND prodId = ?"; PreparedStatement stmt = conn.prepareStatement(sql); stmt.setInt(1, oldSupId); stmt.setInt(2, oldProdId); @@ -149,7 +149,7 @@ public class ProductSupplierDB { //Then change the data by inserting a new relation with given keys (only if delete worked) if(numRows > 0){ - sql = "INSERT INTO productsupplier (prodId, supId, cost) " + + sql = "INSERT INTO productSupplier (prodId, supId, cost) " + "VALUES (?, ?, ?)"; stmt = conn.prepareStatement(sql); stmt.setInt(1, productSupplier.getProdId()); @@ -184,7 +184,7 @@ public class ProductSupplierDB { int numRows = 0; Connection conn = ConnectionDB.getConnection(); - String sql = "DELETE FROM productsupplier WHERE supId = ? AND prodId = ?"; + String sql = "DELETE FROM productSupplier WHERE supId = ? AND prodId = ?"; PreparedStatement stmt = conn.prepareStatement(sql); stmt.setInt(1, supId); stmt.setInt(2, prodId); diff --git a/src/main/java/org/example/petshopdesktop/database/SaleDB.java b/src/main/java/org/example/petshopdesktop/database/SaleDB.java new file mode 100644 index 00000000..43bc798d --- /dev/null +++ b/src/main/java/org/example/petshopdesktop/database/SaleDB.java @@ -0,0 +1,113 @@ +package org.example.petshopdesktop.database; + +import javafx.collections.FXCollections; +import javafx.collections.ObservableList; +import org.example.petshopdesktop.DTOs.SaleDTO; + +import java.sql.*; + +public class SaleDB { + + /** + * Get all sale items with details + * @return ObservableList of SaleDTOs + * @throws SQLException if database operation fails + */ + public static ObservableList getSales() throws SQLException { + ObservableList sales = FXCollections.observableArrayList(); + Connection conn = ConnectionDB.getConnection(); + + String sql = """ + SELECT + s.saleId, + DATE_FORMAT(s.saleDate, '%Y-%m-%d %H:%i') as saleDate, + CONCAT(e.firstName, ' ', e.lastName) as employeeName, + p.prodName, + si.quantity, + si.unitPrice, + (si.quantity * si.unitPrice) as lineTotal, + s.paymentMethod + FROM sale s + JOIN saleItem si ON s.saleId = si.saleId + JOIN product p ON si.prodId = p.prodId + JOIN employee e ON s.employeeId = e.employeeId + ORDER BY s.saleDate DESC, s.saleId, si.saleItemId + """; + + Statement stmt = conn.createStatement(); + ResultSet rs = stmt.executeQuery(sql); + + while (rs.next()) { + sales.add(new SaleDTO( + rs.getInt("saleId"), + rs.getString("saleDate"), + rs.getString("employeeName"), + rs.getString("prodName"), + rs.getInt("quantity"), + rs.getDouble("unitPrice"), + rs.getDouble("lineTotal"), + rs.getString("paymentMethod") + )); + } + + conn.close(); + return sales; + } + + /** + * Get filtered sale items + * @param filter search term + * @return ObservableList of SaleDTOs matching the filter + * @throws SQLException if database operation fails + */ + public static ObservableList getFilteredSales(String filter) throws SQLException { + ObservableList sales = FXCollections.observableArrayList(); + Connection conn = ConnectionDB.getConnection(); + + String sql = """ + SELECT + s.saleId, + DATE_FORMAT(s.saleDate, '%Y-%m-%d %H:%i') as saleDate, + CONCAT(e.firstName, ' ', e.lastName) as employeeName, + p.prodName, + si.quantity, + si.unitPrice, + (si.quantity * si.unitPrice) as lineTotal, + s.paymentMethod + FROM sale s + JOIN saleItem si ON s.saleId = si.saleId + JOIN product p ON si.prodId = p.prodId + JOIN employee e ON s.employeeId = e.employeeId + WHERE s.saleId LIKE ? + OR p.prodName LIKE ? + OR CONCAT(e.firstName, ' ', e.lastName) LIKE ? + OR s.paymentMethod LIKE ? + ORDER BY s.saleDate DESC, s.saleId, si.saleItemId + """; + + PreparedStatement pstmt = conn.prepareStatement(sql); + String searchPattern = "%" + filter + "%"; + pstmt.setString(1, searchPattern); + pstmt.setString(2, searchPattern); + pstmt.setString(3, searchPattern); + pstmt.setString(4, searchPattern); + + ResultSet rs = pstmt.executeQuery(); + + while (rs.next()) { + sales.add(new SaleDTO( + rs.getInt("saleId"), + rs.getString("saleDate"), + rs.getString("employeeName"), + rs.getString("prodName"), + rs.getInt("quantity"), + rs.getDouble("unitPrice"), + rs.getDouble("lineTotal"), + rs.getString("paymentMethod") + )); + } + + conn.close(); + return sales; + } +} diff --git a/src/main/java/org/example/petshopdesktop/database/UserDB.java b/src/main/java/org/example/petshopdesktop/database/UserDB.java index 3b5f78b4..88efe556 100644 --- a/src/main/java/org/example/petshopdesktop/database/UserDB.java +++ b/src/main/java/org/example/petshopdesktop/database/UserDB.java @@ -5,10 +5,6 @@ import org.example.petshopdesktop.models.User; import java.sql.*; -/* -Petshop Desktop -Purpose: User authentication and role lookup against the users table. -*/ public class UserDB { /** @@ -34,8 +30,6 @@ public class UserDB { int userId = rs.getInt("user_id"); String uname = rs.getString("username"); - // Role values are stored in the database as strings and normalised to match the enum. - // Table constraints limit role values, Role.valueOf is expected to be safe under normal operation. Role role = Role.valueOf(rs.getString("role").toUpperCase()); return new User(userId, uname, role); @@ -59,7 +53,6 @@ public class UserDB { ) """; - // Default accounts support initial development and testing, credentials should be rotated or removed for deployment. String seedAdmin = """ INSERT IGNORE INTO users (username, password_hash, role) VALUES ('admin', SHA2('admin123', 256), 'ADMIN') diff --git a/src/main/resources/org/example/petshopdesktop/dialogviews/adoption-dialog-view.fxml b/src/main/resources/org/example/petshopdesktop/dialogviews/adoption-dialog-view.fxml index ef02cdf0..c3a14b62 100644 --- a/src/main/resources/org/example/petshopdesktop/dialogviews/adoption-dialog-view.fxml +++ b/src/main/resources/org/example/petshopdesktop/dialogviews/adoption-dialog-view.fxml @@ -13,7 +13,7 @@ - + diff --git a/src/main/resources/org/example/petshopdesktop/dialogviews/appointment-dialog-view.fxml b/src/main/resources/org/example/petshopdesktop/dialogviews/appointment-dialog-view.fxml index b12bc777..99cf0833 100644 --- a/src/main/resources/org/example/petshopdesktop/dialogviews/appointment-dialog-view.fxml +++ b/src/main/resources/org/example/petshopdesktop/dialogviews/appointment-dialog-view.fxml @@ -17,7 +17,7 @@ - + diff --git a/src/main/resources/org/example/petshopdesktop/dialogviews/pet-dialog-view.fxml b/src/main/resources/org/example/petshopdesktop/dialogviews/pet-dialog-view.fxml index 0784811b..d4c97ddb 100644 --- a/src/main/resources/org/example/petshopdesktop/dialogviews/pet-dialog-view.fxml +++ b/src/main/resources/org/example/petshopdesktop/dialogviews/pet-dialog-view.fxml @@ -13,7 +13,7 @@ - + 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 index 2972f5ed..2164ec66 100644 --- a/src/main/resources/org/example/petshopdesktop/dialogviews/product-dialog-view.fxml +++ b/src/main/resources/org/example/petshopdesktop/dialogviews/product-dialog-view.fxml @@ -13,7 +13,7 @@ - + diff --git a/src/main/resources/org/example/petshopdesktop/dialogviews/product-supplier-dialog-view.fxml b/src/main/resources/org/example/petshopdesktop/dialogviews/product-supplier-dialog-view.fxml index 0ef57a60..ec29e4b6 100644 --- a/src/main/resources/org/example/petshopdesktop/dialogviews/product-supplier-dialog-view.fxml +++ b/src/main/resources/org/example/petshopdesktop/dialogviews/product-supplier-dialog-view.fxml @@ -13,7 +13,7 @@ - + diff --git a/src/main/resources/org/example/petshopdesktop/dialogviews/service-dialog-view.fxml b/src/main/resources/org/example/petshopdesktop/dialogviews/service-dialog-view.fxml index 327ce2d0..6cf098fd 100644 --- a/src/main/resources/org/example/petshopdesktop/dialogviews/service-dialog-view.fxml +++ b/src/main/resources/org/example/petshopdesktop/dialogviews/service-dialog-view.fxml @@ -13,7 +13,7 @@ - + diff --git a/src/main/resources/org/example/petshopdesktop/dialogviews/supplier-dialog-view.fxml b/src/main/resources/org/example/petshopdesktop/dialogviews/supplier-dialog-view.fxml index e26557c8..968d1021 100644 --- a/src/main/resources/org/example/petshopdesktop/dialogviews/supplier-dialog-view.fxml +++ b/src/main/resources/org/example/petshopdesktop/dialogviews/supplier-dialog-view.fxml @@ -12,7 +12,7 @@ - + diff --git a/src/main/resources/org/example/petshopdesktop/login-view.fxml b/src/main/resources/org/example/petshopdesktop/login-view.fxml index 65199c95..ad6e0bca 100644 --- a/src/main/resources/org/example/petshopdesktop/login-view.fxml +++ b/src/main/resources/org/example/petshopdesktop/login-view.fxml @@ -10,7 +10,7 @@ diff --git a/src/main/resources/org/example/petshopdesktop/main-layout-view.fxml b/src/main/resources/org/example/petshopdesktop/main-layout-view.fxml index a1471b98..fdf5c267 100644 --- a/src/main/resources/org/example/petshopdesktop/main-layout-view.fxml +++ b/src/main/resources/org/example/petshopdesktop/main-layout-view.fxml @@ -5,131 +5,146 @@ + - + - + - + - diff --git a/src/main/resources/org/example/petshopdesktop/modelviews/adoption-view.fxml b/src/main/resources/org/example/petshopdesktop/modelviews/adoption-view.fxml index c1ec6564..9443ef14 100644 --- a/src/main/resources/org/example/petshopdesktop/modelviews/adoption-view.fxml +++ b/src/main/resources/org/example/petshopdesktop/modelviews/adoption-view.fxml @@ -11,7 +11,7 @@ - + diff --git a/src/main/resources/org/example/petshopdesktop/modelviews/appointment-view.fxml b/src/main/resources/org/example/petshopdesktop/modelviews/appointment-view.fxml index 4bfd3029..f698c5c1 100644 --- a/src/main/resources/org/example/petshopdesktop/modelviews/appointment-view.fxml +++ b/src/main/resources/org/example/petshopdesktop/modelviews/appointment-view.fxml @@ -11,7 +11,7 @@ - + diff --git a/src/main/resources/org/example/petshopdesktop/modelviews/inventory-view.fxml b/src/main/resources/org/example/petshopdesktop/modelviews/inventory-view.fxml index dea27d1b..18e9ad5a 100644 --- a/src/main/resources/org/example/petshopdesktop/modelviews/inventory-view.fxml +++ b/src/main/resources/org/example/petshopdesktop/modelviews/inventory-view.fxml @@ -11,7 +11,7 @@ - + diff --git a/src/main/resources/org/example/petshopdesktop/modelviews/pet-view.fxml b/src/main/resources/org/example/petshopdesktop/modelviews/pet-view.fxml index a9ab6772..43c3c323 100644 --- a/src/main/resources/org/example/petshopdesktop/modelviews/pet-view.fxml +++ b/src/main/resources/org/example/petshopdesktop/modelviews/pet-view.fxml @@ -11,7 +11,7 @@ - + diff --git a/src/main/resources/org/example/petshopdesktop/modelviews/product-supplier-view.fxml b/src/main/resources/org/example/petshopdesktop/modelviews/product-supplier-view.fxml index 6ef50d13..19817faa 100644 --- a/src/main/resources/org/example/petshopdesktop/modelviews/product-supplier-view.fxml +++ b/src/main/resources/org/example/petshopdesktop/modelviews/product-supplier-view.fxml @@ -11,7 +11,7 @@ - + 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 2473d057..d9b9a37c 100644 --- a/src/main/resources/org/example/petshopdesktop/modelviews/product-view.fxml +++ b/src/main/resources/org/example/petshopdesktop/modelviews/product-view.fxml @@ -11,7 +11,7 @@ - + diff --git a/src/main/resources/org/example/petshopdesktop/modelviews/purchase-order-view.fxml b/src/main/resources/org/example/petshopdesktop/modelviews/purchase-order-view.fxml index e4c3a488..74a00e6d 100644 --- a/src/main/resources/org/example/petshopdesktop/modelviews/purchase-order-view.fxml +++ b/src/main/resources/org/example/petshopdesktop/modelviews/purchase-order-view.fxml @@ -7,7 +7,7 @@ diff --git a/src/main/resources/org/example/petshopdesktop/modelviews/purchaseorder-view.fxml b/src/main/resources/org/example/petshopdesktop/modelviews/purchaseorder-view.fxml deleted file mode 100644 index fdac860e..00000000 --- a/src/main/resources/org/example/petshopdesktop/modelviews/purchaseorder-view.fxml +++ /dev/null @@ -1,82 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/src/main/resources/org/example/petshopdesktop/modelviews/sale-view.fxml b/src/main/resources/org/example/petshopdesktop/modelviews/sale-view.fxml index 26b24418..8ed34120 100644 --- a/src/main/resources/org/example/petshopdesktop/modelviews/sale-view.fxml +++ b/src/main/resources/org/example/petshopdesktop/modelviews/sale-view.fxml @@ -11,7 +11,7 @@ - + diff --git a/src/main/resources/org/example/petshopdesktop/modelviews/service-view.fxml b/src/main/resources/org/example/petshopdesktop/modelviews/service-view.fxml index 2adac139..5353b0e6 100644 --- a/src/main/resources/org/example/petshopdesktop/modelviews/service-view.fxml +++ b/src/main/resources/org/example/petshopdesktop/modelviews/service-view.fxml @@ -11,7 +11,7 @@ - + diff --git a/src/main/resources/org/example/petshopdesktop/modelviews/supplier-view.fxml b/src/main/resources/org/example/petshopdesktop/modelviews/supplier-view.fxml index 423ae2bf..9c6d75cc 100644 --- a/src/main/resources/org/example/petshopdesktop/modelviews/supplier-view.fxml +++ b/src/main/resources/org/example/petshopdesktop/modelviews/supplier-view.fxml @@ -11,7 +11,7 @@ - +