fixed pet busniss logic desktop
This commit is contained in:
@@ -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,14 +334,15 @@ public class PetDialogController {
|
||||
stage.close();
|
||||
}
|
||||
|
||||
public void displayPetDetails(Pet pet){
|
||||
if (pet!=null){
|
||||
public void displayPetDetails(Pet pet) {
|
||||
if (pet == null) return;
|
||||
|
||||
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() + "");
|
||||
txtPetAge.setText(String.valueOf(pet.getPetAge()));
|
||||
txtPetPrice.setText(String.valueOf(pet.getPetPrice()));
|
||||
currentImageUrl = pet.getImageUrl();
|
||||
selectedImageFile = null;
|
||||
removeImageRequested = false;
|
||||
@@ -395,46 +352,56 @@ public class PetDialogController {
|
||||
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())){
|
||||
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);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user