fixed pet busniss logic desktop

This commit is contained in:
Alex
2026-04-13 21:10:35 -06:00
parent 044e9ba7b2
commit 3ef6604884

View File

@@ -31,62 +31,30 @@ import java.util.Optional;
public class PetDialogController {
@FXML
private Button btnCancel;
private static final String STATUS_AVAILABLE = "Available";
private static final String STATUS_ADOPTED = "Adopted";
private static final String STATUS_OWNED = "Owned";
private static final String STATUS_PENDING = "Pending";
@FXML
private Button btnSave;
@FXML
private Button btnChangeImage;
@FXML
private Button btnRemoveImage;
@FXML
private ComboBox<String> cbPetStatus;
@FXML
private ComboBox<DropdownOption> cbCustomer;
@FXML
private ComboBox<DropdownOption> cbStore;
@FXML
private VBox vbCustomerField;
@FXML
private VBox vbStoreField;
@FXML
private VBox vbPriceField;
@FXML
private Label lblMode;
@FXML
private Label lblPetId;
@FXML
private Label lblImageStatus;
@FXML
private ImageView imgPetPreview;
@FXML
private TextField txtPetAge;
@FXML
private TextField txtPetBreed;
@FXML
private TextField txtPetName;
@FXML
private TextField txtPetPrice;
@FXML
private ComboBox<String> cbPetSpecies;
@FXML private Button btnCancel;
@FXML private Button btnSave;
@FXML private Button btnChangeImage;
@FXML private Button btnRemoveImage;
@FXML private ComboBox<String> cbPetStatus;
@FXML private ComboBox<DropdownOption> cbCustomer;
@FXML private ComboBox<DropdownOption> cbStore;
@FXML private VBox vbCustomerField;
@FXML private VBox vbStoreField;
@FXML private VBox vbPriceField;
@FXML private Label lblMode;
@FXML private Label lblPetId;
@FXML private Label lblImageStatus;
@FXML private ImageView imgPetPreview;
@FXML private TextField txtPetAge;
@FXML private TextField txtPetBreed;
@FXML private TextField txtPetName;
@FXML private TextField txtPetPrice;
@FXML private ComboBox<String> cbPetSpecies;
private String mode = null;
private File selectedImageFile;
@@ -96,14 +64,14 @@ public class PetDialogController {
private Long pendingCustomerId = null;
private Long pendingStoreId = null;
private Long originalCustomerId = null;
private boolean isOriginallyOwnedOrAdopted = false;
private ObservableList<String> statusList = FXCollections.observableArrayList(
"Available", "Adopted", "Owned", "Pending"
private final ObservableList<String> statusList = FXCollections.observableArrayList(
STATUS_AVAILABLE, STATUS_ADOPTED, STATUS_OWNED, STATUS_PENDING
);
@FXML
void initialize() {
cbPetStatus.setItems(statusList);
cbCustomer.setCellFactory(param -> new ListCell<>() {
@@ -132,12 +100,14 @@ public class PetDialogController {
}
});
updateStatusFieldVisibility(null);
applyStatusRules(STATUS_AVAILABLE, false);
loadSpecies();
loadCustomers();
loadStores();
cbPetStatus.valueProperty().addListener((obs, oldVal, newVal) -> {
updateStatusFieldVisibility(newVal);
if (newVal != null) applyStatusRules(newVal, true);
});
btnSave.setOnMouseClicked(new EventHandler<MouseEvent>() {
@@ -157,48 +127,57 @@ public class PetDialogController {
btnChangeImage.setOnMouseClicked(mouseEvent -> handleChangeImage());
btnRemoveImage.setOnMouseClicked(mouseEvent -> handleRemoveImage());
refreshImagePreview();
}
loadCustomers();
loadStores();
private void applyStatusRules(String status, boolean clearInvalidSelections) {
if (STATUS_AVAILABLE.equalsIgnoreCase(status)) {
vbCustomerField.setDisable(true);
vbStoreField.setDisable(false);
if (clearInvalidSelections) cbCustomer.setValue(null);
return;
}
if (STATUS_OWNED.equalsIgnoreCase(status)) {
vbCustomerField.setDisable(false);
vbStoreField.setDisable(true);
if (clearInvalidSelections) cbStore.setValue(null);
return;
}
vbCustomerField.setDisable(false);
vbStoreField.setDisable(false);
}
private void buttonSaveClicked(MouseEvent mouseEvent) {
String errorMsg = "";
//Check validation (input required)
errorMsg += Validator.isPresent(txtPetName.getText(), "Pet Name");
errorMsg += Validator.isPresent(txtPetAge.getText(), "Age");
errorMsg += Validator.isPresent(txtPetBreed.getText(), "Breed");
String speciesValue = cbPetSpecies.getValue() != null ? cbPetSpecies.getValue().trim() : "";
if (speciesValue.isEmpty()) errorMsg += "Species is required\n";
String selectedStatus = cbPetStatus.getValue();
if (cbPetStatus.getSelectionModel().getSelectedItem() == null) errorMsg += "Status is required\n";
errorMsg += Validator.isPresent(txtPetPrice.getText(), "Price");
if (cbPetStatus.getSelectionModel().getSelectedItem() == null){
errorMsg += "Status is required";
String selectedStatus = cbPetStatus.getValue();
if (STATUS_AVAILABLE.equalsIgnoreCase(selectedStatus) && cbStore.getValue() == null) {
errorMsg += "Store is required for Available status\n";
}
boolean needsCustomer = "Owned".equalsIgnoreCase(selectedStatus)
|| "Adopted".equalsIgnoreCase(selectedStatus)
|| "Pending".equalsIgnoreCase(selectedStatus);
boolean needsStore = requiresStore(selectedStatus);
if (needsCustomer && cbCustomer.getValue() == null && UserSession.getInstance().isAdmin()) {
errorMsg += "Customer is required for " + selectedStatus + " status\n";
if (STATUS_OWNED.equalsIgnoreCase(selectedStatus) && cbCustomer.getValue() == null) {
errorMsg += "Customer is required for Owned status\n";
}
if (needsStore && cbStore.getValue() == null) {
errorMsg += "Store is required for " + selectedStatus + " status\n";
if (STATUS_ADOPTED.equalsIgnoreCase(selectedStatus)) {
if (cbCustomer.getValue() == null) errorMsg += "Customer is required for Adopted status\n";
if (cbStore.getValue() == null) errorMsg += "Store is required for Adopted status\n";
}
//Check validation (length size)
errorMsg += Validator.isLessThanVarChars(txtPetName.getText(), "Pet Name", 50);
errorMsg += Validator.isLessThanVarChars(speciesValue, "Species", 50);
errorMsg += Validator.isLessThanVarChars(txtPetBreed.getText(), "Breed", 50);
errorMsg += Validator.isLessThanVarChars(txtPetPrice.getText(), "Price", 12);
errorMsg += Validator.isLessThanVarChars(txtPetAge.getText(), "Age", 11);
//Check validation (format)
errorMsg += Validator.isNonNegativeDouble(txtPetPrice.getText(), "Price");
errorMsg += Validator.isPositiveInteger(txtPetAge.getText(), "Age");
if(errorMsg.isEmpty()){
if (errorMsg.isEmpty()) {
if ("Edit".equals(mode) && UserSession.getInstance().isAdmin()) {
Long newCustomerId = cbCustomer.getValue() != null ? cbCustomer.getValue().getId() : null;
if (!Objects.equals(originalCustomerId, newCustomerId)) {
@@ -206,44 +185,34 @@ public class PetDialogController {
confirm.setHeaderText("Confirm Owner Change");
confirm.setContentText("Are you sure you want to reassign this pet to a different owner?");
Optional<ButtonType> result = confirm.showAndWait();
if (result.isEmpty() || result.get() != ButtonType.OK) {
return;
}
if (result.isEmpty() || result.get() != ButtonType.OK) return;
}
}
PetRequest request = buildPetRequest();
try {
if(mode.equals("Add")) {
if (mode.equals("Add")) {
PetResponse response = PetApi.getInstance().createPet(request);
applyImageChanges(response.getPetId());
} else {
String[] parts = lblPetId.getText().split(": ");
if (parts.length < 2) {
throw new IllegalStateException("Invalid pet ID format");
}
if (parts.length < 2) throw new IllegalStateException("Invalid pet ID format");
Long petId = Long.parseLong(parts[1]);
PetApi.getInstance().updatePet(petId, request);
applyImageChanges(petId);
}
//tell the user operation was successful
Alert alert = new Alert(Alert.AlertType.INFORMATION);
alert.setHeaderText("Saved");
alert.setContentText(mode + " succeeded");
alert.showAndWait();
closeStage(mouseEvent);
} catch (Exception e) {
ActivityLogger.getInstance().logException(
"PetDialogController.buttonSaveClicked",
e,
mode + " pet record");
ActivityLogger.getInstance().logException("PetDialogController.buttonSaveClicked", e, mode + " pet record");
Alert alert = new Alert(Alert.AlertType.ERROR);
alert.setHeaderText("Operation Error");
alert.setContentText(mode + " failed: " + e.getMessage());
alert.showAndWait();
}
}
else{
} else {
Alert alert = new Alert(Alert.AlertType.ERROR);
alert.setHeaderText("Input Error");
alert.setContentText(errorMsg);
@@ -257,6 +226,7 @@ public class PetDialogController {
request.setPetSpecies(cbPetSpecies.getValue() != null ? cbPetSpecies.getValue().trim() : "");
request.setPetBreed(txtPetBreed.getText());
request.setPetStatus(cbPetStatus.getValue());
if (txtPetPrice.getText() != null && !txtPetPrice.getText().isBlank()) {
try {
request.setPetPrice(new BigDecimal(txtPetPrice.getText()));
@@ -265,24 +235,14 @@ public class PetDialogController {
}
}
int age;
try {
age = Integer.parseInt(txtPetAge.getText());
request.setPetAge(Integer.parseInt(txtPetAge.getText()));
} catch (NumberFormatException e) {
throw new IllegalArgumentException("Invalid age format");
}
request.setPetAge(age);
String status = cbPetStatus.getValue();
boolean customerApplicable = "Owned".equalsIgnoreCase(status)
|| "Adopted".equalsIgnoreCase(status)
|| "Pending".equalsIgnoreCase(status);
if (customerApplicable && cbCustomer.getValue() != null) {
request.setCustomerId(cbCustomer.getValue().getId());
}
if (requiresStore(status) && cbStore.getValue() != null) {
request.setStoreId(cbStore.getValue().getId());
}
if (cbCustomer.getValue() != null) request.setCustomerId(cbCustomer.getValue().getId());
if (cbStore.getValue() != null) request.setStoreId(cbStore.getValue().getId());
return request;
}
@@ -297,9 +257,7 @@ public class PetDialogController {
Platform.runLater(() -> {
String current = cbPetSpecies.getValue();
cbPetSpecies.setItems(FXCollections.observableArrayList(species));
if (current != null && !current.isBlank()) {
cbPetSpecies.setValue(current);
}
if (current != null && !current.isBlank()) cbPetSpecies.setValue(current);
});
} catch (Exception e) {
Platform.runLater(() -> ActivityLogger.getInstance().logException(
@@ -318,8 +276,7 @@ public class PetDialogController {
});
} catch (Exception e) {
Platform.runLater(() -> {
ActivityLogger.getInstance().logException(
"PetDialogController.loadCustomers", e, "Loading customers");
ActivityLogger.getInstance().logException("PetDialogController.loadCustomers", e, "Loading customers");
cbCustomer.setDisable(true);
cbCustomer.setPromptText("Unable to load customers");
});
@@ -337,8 +294,7 @@ public class PetDialogController {
});
} catch (Exception e) {
Platform.runLater(() -> {
ActivityLogger.getInstance().logException(
"PetDialogController.loadStores", e, "Loading stores");
ActivityLogger.getInstance().logException("PetDialogController.loadStores", e, "Loading stores");
cbStore.setDisable(true);
cbStore.setPromptText("Unable to load stores");
});
@@ -378,63 +334,74 @@ public class PetDialogController {
stage.close();
}
public void displayPetDetails(Pet pet){
if (pet!=null){
lblPetId.setText("ID: " + pet.getPetId());
txtPetName.setText(pet.getPetName());
cbPetSpecies.setValue(pet.getPetSpecies());
txtPetBreed.setText(pet.getPetBreed());
txtPetAge.setText(pet.getPetAge() + "");
txtPetPrice.setText(pet.getPetPrice() + "");
currentImageUrl = pet.getImageUrl();
selectedImageFile = null;
removeImageRequested = false;
refreshImagePreview();
public void displayPetDetails(Pet pet) {
if (pet == null) return;
pendingCustomerId = pet.getCustomerId() > 0 ? pet.getCustomerId() : null;
originalCustomerId = pendingCustomerId;
pendingStoreId = pet.getStoreId() > 0 ? pet.getStoreId() : null;
lblPetId.setText("ID: " + pet.getPetId());
txtPetName.setText(pet.getPetName());
cbPetSpecies.setValue(pet.getPetSpecies());
txtPetBreed.setText(pet.getPetBreed());
txtPetAge.setText(String.valueOf(pet.getPetAge()));
txtPetPrice.setText(String.valueOf(pet.getPetPrice()));
currentImageUrl = pet.getImageUrl();
selectedImageFile = null;
removeImageRequested = false;
refreshImagePreview();
for (String status : cbPetStatus.getItems()) {
if(status.equals(pet.getPetStatus())){
cbPetStatus.getSelectionModel().select(status);
break;
}
pendingCustomerId = pet.getCustomerId() > 0 ? pet.getCustomerId() : null;
originalCustomerId = pendingCustomerId;
pendingStoreId = pet.getStoreId() > 0 ? pet.getStoreId() : null;
isOriginallyOwnedOrAdopted = STATUS_OWNED.equalsIgnoreCase(pet.getPetStatus())
|| STATUS_ADOPTED.equalsIgnoreCase(pet.getPetStatus());
for (String status : cbPetStatus.getItems()) {
if (status.equals(pet.getPetStatus())) {
cbPetStatus.getSelectionModel().select(status);
break;
}
updateStatusFieldVisibility(cbPetStatus.getValue());
applyStatusLock();
}
applyStatusRules(cbPetStatus.getValue(), false);
applyEditModeLock();
}
private void applyStatusLock() {
String status = cbPetStatus.getValue();
boolean isRestricted = "Adopted".equalsIgnoreCase(status) || "Owned".equalsIgnoreCase(status);
private void applyEditModeLock() {
cbPetSpecies.setDisable(true);
txtPetBreed.setDisable(true);
boolean isStaff = !UserSession.getInstance().isAdmin();
cbPetStatus.setDisable(isRestricted && isStaff);
if (isStaff && isOriginallyOwnedOrAdopted) {
cbPetStatus.setDisable(true);
vbCustomerField.setDisable(true);
vbStoreField.setDisable(true);
}
}
public void setMode(String mode) {
this.mode = mode;
lblMode.setText(mode + " Pet");
if(mode.equals("Add")) {
if (mode.equals("Add")) {
lblPetId.setVisible(false);
currentImageUrl = null;
selectedImageFile = null;
removeImageRequested = false;
cbPetSpecies.setDisable(false);
txtPetBreed.setDisable(false);
cbPetStatus.setDisable(false);
cbPetStatus.getSelectionModel().select(STATUS_AVAILABLE);
applyStatusRules(STATUS_AVAILABLE, false);
refreshImagePreview();
}
else if(mode.equals("Edit")) {
} else if (mode.equals("Edit")) {
lblPetId.setVisible(true);
refreshImagePreview();
}
updateStatusFieldVisibility(cbPetStatus.getValue());
}
private void handleChangeImage() {
File file = FilePickerSupport.pickImageFile(btnSave.getScene().getWindow());
if (file == null) {
return;
}
if (file == null) return;
selectedImageFile = file;
removeImageRequested = false;
lblImageStatus.setText("Selected: " + file.getName());
@@ -471,9 +438,7 @@ public class PetDialogController {
}
private void refreshImagePreview() {
if (imgPetPreview == null || lblImageStatus == null || btnRemoveImage == null) {
return;
}
if (imgPetPreview == null || lblImageStatus == null || btnRemoveImage == null) return;
imgPetPreview.setImage(null);
if (selectedImageFile != null) {
lblImageStatus.setText("Selected: " + selectedImageFile.getName());
@@ -490,29 +455,4 @@ public class PetDialogController {
lblImageStatus.setText("No image selected");
btnRemoveImage.setDisable(true);
}
private void updateStatusFieldVisibility(String status) {
if (status == null) {
vbPriceField.setDisable(false);
vbCustomerField.setDisable(true);
vbStoreField.setDisable(false);
return;
}
boolean isAdmin = UserSession.getInstance().isAdmin();
boolean customerApplicable = "Owned".equalsIgnoreCase(status)
|| "Adopted".equalsIgnoreCase(status)
|| "Pending".equalsIgnoreCase(status);
boolean isOwned = "Owned".equalsIgnoreCase(status);
vbPriceField.setDisable(false);
vbCustomerField.setDisable(!customerApplicable || !isAdmin);
vbStoreField.setDisable(isOwned);
}
private boolean requiresStore(String status) {
return "Available".equalsIgnoreCase(status)
|| "Pending".equalsIgnoreCase(status)
|| "Adopted".equalsIgnoreCase(status);
}
}