Migrate Product controllers to REST API
This commit is contained in:
@@ -1,5 +1,6 @@
|
|||||||
package org.example.petshopdesktop.controllers;
|
package org.example.petshopdesktop.controllers;
|
||||||
|
|
||||||
|
import javafx.application.Platform;
|
||||||
import javafx.collections.FXCollections;
|
import javafx.collections.FXCollections;
|
||||||
import javafx.collections.ObservableList;
|
import javafx.collections.ObservableList;
|
||||||
import javafx.event.ActionEvent;
|
import javafx.event.ActionEvent;
|
||||||
@@ -11,18 +12,16 @@ import javafx.scene.control.cell.PropertyValueFactory;
|
|||||||
import javafx.stage.Modality;
|
import javafx.stage.Modality;
|
||||||
import javafx.stage.Stage;
|
import javafx.stage.Stage;
|
||||||
import org.example.petshopdesktop.DTOs.ProductDTO;
|
import org.example.petshopdesktop.DTOs.ProductDTO;
|
||||||
|
import org.example.petshopdesktop.api.dto.product.ProductResponse;
|
||||||
|
import org.example.petshopdesktop.api.endpoints.ProductApi;
|
||||||
import org.example.petshopdesktop.controllers.dialogcontrollers.ProductDialogController;
|
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 org.example.petshopdesktop.util.ActivityLogger;
|
import org.example.petshopdesktop.util.ActivityLogger;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.sql.SQLException;
|
import java.util.ArrayList;
|
||||||
import java.sql.SQLIntegrityConstraintViolationException;
|
import java.util.List;
|
||||||
import java.util.Optional;
|
import java.util.Optional;
|
||||||
|
import java.util.stream.Collectors
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The controller for any operations in the products view
|
* The controller for any operations in the products view
|
||||||
@@ -110,22 +109,27 @@ public class ProductController {
|
|||||||
* Display the productDTO to table view
|
* Display the productDTO to table view
|
||||||
*/
|
*/
|
||||||
private void displayProduct(){
|
private void displayProduct(){
|
||||||
//Erase old content
|
new Thread(() -> {
|
||||||
data.clear();
|
try {
|
||||||
|
List<ProductResponse> products = ProductApi.getInstance().listProducts(null);
|
||||||
|
List<ProductDTO> productDTOs = products.stream()
|
||||||
|
.map(this::mapToProductDTO)
|
||||||
|
.collect(Collectors.toList());
|
||||||
|
|
||||||
//get Products from database
|
Platform.runLater(() -> {
|
||||||
try{
|
data.setAll(productDTOs);
|
||||||
data = ProductDB.getProductDTO();
|
tvProducts.setItems(data);
|
||||||
} catch (SQLException e) {
|
});
|
||||||
|
} catch (Exception e) {
|
||||||
|
Platform.runLater(() -> {
|
||||||
System.out.println("Error while fetching table data: " + e.getMessage());
|
System.out.println("Error while fetching table data: " + e.getMessage());
|
||||||
ActivityLogger.getInstance().logException(
|
ActivityLogger.getInstance().logException(
|
||||||
"ProductController.displayProduct",
|
"ProductController.displayProduct",
|
||||||
e,
|
e,
|
||||||
"Fetching product data for table display");
|
"Fetching product data for table display");
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
}).start();
|
||||||
//put data in the table
|
|
||||||
tvProducts.setItems(data);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -160,48 +164,24 @@ public class ProductController {
|
|||||||
|
|
||||||
//if confirmed, start deletion
|
//if confirmed, start deletion
|
||||||
if (result.isPresent() && result.get() == ButtonType.OK) {
|
if (result.isPresent() && result.get() == ButtonType.OK) {
|
||||||
int successCount = 0;
|
List<Long> ids = selectedProducts.stream()
|
||||||
int failCount = 0;
|
.map(p -> (long) p.getProdId())
|
||||||
StringBuilder errors = new StringBuilder();
|
.collect(Collectors.toList());
|
||||||
|
|
||||||
for (ProductDTO product : selectedProducts) {
|
try {
|
||||||
try{
|
ProductApi.getInstance().deleteProducts(ids);
|
||||||
int numRows = ProductDB.deleteProduct(product.getProdId());
|
|
||||||
if (numRows > 0) {
|
|
||||||
successCount++;
|
|
||||||
} else {
|
|
||||||
failCount++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
catch (SQLIntegrityConstraintViolationException e){
|
|
||||||
ActivityLogger.getInstance().logException(
|
|
||||||
"ProductController.btnDeleteClicked",
|
|
||||||
e,
|
|
||||||
String.format("Attempting to delete product ID %d - foreign key constraint", product.getProdId()));
|
|
||||||
failCount++;
|
|
||||||
errors.append("Product '").append(product.getProdName()).append("' is referenced in another table\n");
|
|
||||||
}
|
|
||||||
catch (SQLException e) {
|
|
||||||
ActivityLogger.getInstance().logException(
|
|
||||||
"ProductController.btnDeleteClicked",
|
|
||||||
e,
|
|
||||||
String.format("Attempting to delete product ID %d", product.getProdId()));
|
|
||||||
failCount++;
|
|
||||||
errors.append("Failed to delete '").append(product.getProdName()).append("'\n");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//show results
|
|
||||||
if (failCount > 0) {
|
|
||||||
Alert alert = new Alert(Alert.AlertType.WARNING);
|
|
||||||
alert.setHeaderText("Delete Operation Completed with Errors");
|
|
||||||
alert.setContentText(String.format("Deleted: %d\nFailed: %d\n\n%s",
|
|
||||||
successCount, failCount, errors.toString()));
|
|
||||||
alert.showAndWait();
|
|
||||||
} else if (successCount > 0) {
|
|
||||||
Alert alert = new Alert(Alert.AlertType.INFORMATION);
|
Alert alert = new Alert(Alert.AlertType.INFORMATION);
|
||||||
alert.setHeaderText("Database Operation Confirmed");
|
alert.setHeaderText("Database Operation Confirmed");
|
||||||
alert.setContentText("Successfully deleted " + successCount + " product(s)");
|
alert.setContentText("Successfully deleted " + ids.size() + " product(s)");
|
||||||
|
alert.showAndWait();
|
||||||
|
} catch (Exception e) {
|
||||||
|
ActivityLogger.getInstance().logException(
|
||||||
|
"ProductController.btnDeleteClicked",
|
||||||
|
e,
|
||||||
|
"Deleting products");
|
||||||
|
Alert alert = new Alert(Alert.AlertType.ERROR);
|
||||||
|
alert.setHeaderText("Delete Operation Failed");
|
||||||
|
alert.setContentText(e.getMessage());
|
||||||
alert.showAndWait();
|
alert.showAndWait();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -233,22 +213,30 @@ public class ProductController {
|
|||||||
* @param filter word to filter table
|
* @param filter word to filter table
|
||||||
*/
|
*/
|
||||||
private void displayFilteredProduct(String filter){
|
private void displayFilteredProduct(String filter){
|
||||||
data.clear();
|
|
||||||
try{
|
|
||||||
if (txtSearch.getText() == null || txtSearch.getText().isEmpty()){
|
if (txtSearch.getText() == null || txtSearch.getText().isEmpty()){
|
||||||
displayProduct(); //If search bar is empty just display everything
|
displayProduct();
|
||||||
}
|
} else {
|
||||||
else{
|
new Thread(() -> {
|
||||||
//Filter the using the keyword
|
try {
|
||||||
data = ProductDB.getFilteredProductDTOs(filter);
|
List<ProductResponse> products = ProductApi.getInstance().listProducts(filter);
|
||||||
|
List<ProductDTO> productDTOs = products.stream()
|
||||||
|
.map(this::mapToProductDTO)
|
||||||
|
.collect(Collectors.toList());
|
||||||
|
|
||||||
|
Platform.runLater(() -> {
|
||||||
|
data.setAll(productDTOs);
|
||||||
tvProducts.setItems(data);
|
tvProducts.setItems(data);
|
||||||
}
|
});
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
|
Platform.runLater(() -> {
|
||||||
System.out.println("Error while fetching table data: " + e.getMessage());
|
System.out.println("Error while fetching table data: " + e.getMessage());
|
||||||
ActivityLogger.getInstance().logException(
|
ActivityLogger.getInstance().logException(
|
||||||
"ProductController.displayFilteredProduct",
|
"ProductController.displayFilteredProduct",
|
||||||
e,
|
e,
|
||||||
String.format("Filtering products with keyword: %s", filter));
|
String.format("Filtering products with keyword: %s", filter));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}).start();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -297,4 +285,14 @@ public class ProductController {
|
|||||||
txtSearch.setText("");
|
txtSearch.setText("");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private ProductDTO mapToProductDTO(ProductResponse response) {
|
||||||
|
ProductDTO dto = new ProductDTO();
|
||||||
|
dto.setProdId(response.getId().intValue());
|
||||||
|
dto.setProdName(response.getProductName());
|
||||||
|
dto.setProdPrice(response.getPrice().doubleValue());
|
||||||
|
dto.setCategoryName(response.getCategoryName());
|
||||||
|
dto.setProdDesc(response.getDescription());
|
||||||
|
return dto;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -10,15 +10,14 @@ import javafx.scene.input.MouseEvent;
|
|||||||
import javafx.stage.Stage;
|
import javafx.stage.Stage;
|
||||||
import org.example.petshopdesktop.DTOs.ProductDTO;
|
import org.example.petshopdesktop.DTOs.ProductDTO;
|
||||||
import org.example.petshopdesktop.Validator;
|
import org.example.petshopdesktop.Validator;
|
||||||
import org.example.petshopdesktop.database.CategoryDB;
|
import org.example.petshopdesktop.api.dto.common.DropdownOption;
|
||||||
import org.example.petshopdesktop.database.ProductDB;
|
import org.example.petshopdesktop.api.dto.product.ProductRequest;
|
||||||
import org.example.petshopdesktop.models.Category;
|
import org.example.petshopdesktop.api.endpoints.DropdownApi;
|
||||||
import org.example.petshopdesktop.models.Product;
|
import org.example.petshopdesktop.api.endpoints.ProductApi;
|
||||||
import org.example.petshopdesktop.models.Supplier;
|
|
||||||
import org.example.petshopdesktop.util.ActivityLogger;
|
import org.example.petshopdesktop.util.ActivityLogger;
|
||||||
|
|
||||||
import java.sql.SQLException;
|
import java.math.BigDecimal;
|
||||||
import java.util.ArrayList;
|
import java.util.List
|
||||||
|
|
||||||
public class ProductDialogController {
|
public class ProductDialogController {
|
||||||
|
|
||||||
@@ -29,7 +28,7 @@ public class ProductDialogController {
|
|||||||
private Button btnSave;
|
private Button btnSave;
|
||||||
|
|
||||||
@FXML
|
@FXML
|
||||||
private ComboBox<Category> cbProdCategory;
|
private ComboBox<DropdownOption> cbProdCategory;
|
||||||
|
|
||||||
@FXML
|
@FXML
|
||||||
private Label lblMode;
|
private Label lblMode;
|
||||||
@@ -70,11 +69,10 @@ public class ProductDialogController {
|
|||||||
|
|
||||||
//Set up combobox for selecting category
|
//Set up combobox for selecting category
|
||||||
try {
|
try {
|
||||||
//set up combobox
|
List<DropdownOption> categories = DropdownApi.getInstance().getCategories();
|
||||||
ObservableList<Category> categories = FXCollections.observableArrayList(); //empty list
|
ObservableList<DropdownOption> categoriesObs = FXCollections.observableArrayList(categories);
|
||||||
categories = CategoryDB.getCategories();
|
cbProdCategory.setItems(categoriesObs);
|
||||||
cbProdCategory.setItems(categories);
|
} catch (Exception e) {
|
||||||
} catch (SQLException e) {
|
|
||||||
ActivityLogger.getInstance().logException(
|
ActivityLogger.getInstance().logException(
|
||||||
"ProductDialogController.initialize",
|
"ProductDialogController.initialize",
|
||||||
e,
|
e,
|
||||||
@@ -108,45 +106,35 @@ public class ProductDialogController {
|
|||||||
//Check Validation (format)
|
//Check Validation (format)
|
||||||
errorMsg += Validator.isNonNegativeDouble(txtProdPrice.getText(), "Product Price");
|
errorMsg += Validator.isNonNegativeDouble(txtProdPrice.getText(), "Product Price");
|
||||||
|
|
||||||
if (errorMsg.isEmpty()) { //no validation errors detected
|
if (errorMsg.isEmpty()) {
|
||||||
Product product = collectProduct(); //get product info
|
try {
|
||||||
if (mode.equals("Add")){ //add mode
|
ProductRequest request = new ProductRequest();
|
||||||
try{
|
request.setProductName(txtProdName.getText());
|
||||||
numRow = ProductDB.insertProduct(product);
|
request.setPrice(new BigDecimal(txtProdPrice.getText()));
|
||||||
} catch (SQLException e) {
|
request.setCategoryId(cbProdCategory.getSelectionModel().getSelectedItem().getId());
|
||||||
ActivityLogger.getInstance().logException(
|
request.setDescription(txtProdDesc.getText());
|
||||||
"ProductDialogController.buttonSaveClicked",
|
|
||||||
e,
|
if (mode.equals("Add")) {
|
||||||
"Inserting new product record");
|
ProductApi.getInstance().createProduct(request);
|
||||||
throw new RuntimeException(e);
|
} else {
|
||||||
}
|
Long productId = Long.parseLong(lblProdId.getText().split(": ")[1]);
|
||||||
}
|
ProductApi.getInstance().updateProduct(productId, request);
|
||||||
else { //edit
|
|
||||||
try{
|
|
||||||
numRow = ProductDB.updateProduct(product.getProdId(),product);
|
|
||||||
} catch (SQLException e) {
|
|
||||||
ActivityLogger.getInstance().logException(
|
|
||||||
"ProductDialogController.buttonSaveClicked",
|
|
||||||
e,
|
|
||||||
"Updating product with ID: " + product.getProdId());
|
|
||||||
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();
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
//tell the user operation was successful
|
|
||||||
Alert alert = new Alert(Alert.AlertType.INFORMATION);
|
Alert alert = new Alert(Alert.AlertType.INFORMATION);
|
||||||
alert.setHeaderText("Saved");
|
alert.setHeaderText("Saved");
|
||||||
alert.setContentText(mode + " succeeded");
|
alert.setContentText(mode + " succeeded");
|
||||||
alert.showAndWait();
|
alert.showAndWait();
|
||||||
closeStage(mouseEvent);
|
closeStage(mouseEvent);
|
||||||
|
} catch (Exception e) {
|
||||||
|
ActivityLogger.getInstance().logException(
|
||||||
|
"ProductDialogController.buttonSaveClicked",
|
||||||
|
e,
|
||||||
|
mode + " product");
|
||||||
|
Alert alert = new Alert(Alert.AlertType.ERROR);
|
||||||
|
alert.setHeaderText("Database Operation Error");
|
||||||
|
alert.setContentText(e.getMessage());
|
||||||
|
alert.showAndWait();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else{ //Display validation errors
|
else{ //Display validation errors
|
||||||
@@ -190,10 +178,10 @@ public class ProductDialogController {
|
|||||||
txtProdDesc.setText(product.getProdDesc());
|
txtProdDesc.setText(product.getProdDesc());
|
||||||
txtProdPrice.setText(product.getProdPrice() + "");
|
txtProdPrice.setText(product.getProdPrice() + "");
|
||||||
|
|
||||||
//get the right combobox selection
|
for (DropdownOption category : cbProdCategory.getItems()) {
|
||||||
for (Category category : cbProdCategory.getItems()) {
|
if(category.getLabel().equals(product.getCategoryName())){
|
||||||
if(category.getCategoryId() == product.getCategoryId()){
|
|
||||||
cbProdCategory.getSelectionModel().select(category);
|
cbProdCategory.getSelectionModel().select(category);
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user