fixes to desktop part 1
This commit is contained in:
@@ -22,6 +22,7 @@ public class AppointmentDTO {
|
||||
private SimpleStringProperty appointmentTime;
|
||||
private SimpleStringProperty appointmentStatus;
|
||||
private SimpleStringProperty storeName;
|
||||
private Long storeId;
|
||||
|
||||
public AppointmentDTO(int appointmentId,
|
||||
int customerId, String customerName,
|
||||
@@ -32,7 +33,8 @@ public class AppointmentDTO {
|
||||
String appointmentDate,
|
||||
String appointmentTime,
|
||||
String appointmentStatus,
|
||||
String storeName) {
|
||||
String storeName,
|
||||
Long storeId) {
|
||||
|
||||
this.appointmentId = new SimpleIntegerProperty(appointmentId);
|
||||
this.customerId = new SimpleIntegerProperty(customerId);
|
||||
@@ -47,6 +49,7 @@ public class AppointmentDTO {
|
||||
this.appointmentTime = new SimpleStringProperty(appointmentTime);
|
||||
this.appointmentStatus = new SimpleStringProperty(appointmentStatus);
|
||||
this.storeName = new SimpleStringProperty(storeName != null ? storeName : "");
|
||||
this.storeId = storeId;
|
||||
}
|
||||
|
||||
public int getAppointmentId() { return appointmentId.get(); }
|
||||
@@ -66,4 +69,6 @@ public class AppointmentDTO {
|
||||
public String getAppointmentTime() { return appointmentTime.get(); }
|
||||
public String getAppointmentStatus() { return appointmentStatus.get(); }
|
||||
public String getStoreName() { return storeName.get(); }
|
||||
|
||||
public Long getStoreId() { return storeId; }
|
||||
}
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
package org.example.petshopdesktop.api.dto.adoption;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.time.LocalDate;
|
||||
|
||||
public class AdoptionRequest {
|
||||
@@ -9,7 +10,7 @@ public class AdoptionRequest {
|
||||
private Long sourceStoreId;
|
||||
private LocalDate adoptionDate;
|
||||
private String adoptionStatus;
|
||||
private String paymentMethod;
|
||||
private BigDecimal adoptionFee;
|
||||
|
||||
public AdoptionRequest() {
|
||||
}
|
||||
@@ -62,11 +63,11 @@ public class AdoptionRequest {
|
||||
this.adoptionStatus = adoptionStatus;
|
||||
}
|
||||
|
||||
public String getPaymentMethod() {
|
||||
return paymentMethod;
|
||||
public BigDecimal getAdoptionFee() {
|
||||
return adoptionFee;
|
||||
}
|
||||
|
||||
public void setPaymentMethod(String paymentMethod) {
|
||||
this.paymentMethod = paymentMethod;
|
||||
public void setAdoptionFee(BigDecimal adoptionFee) {
|
||||
this.adoptionFee = adoptionFee;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -13,6 +13,7 @@ public class AdoptionResponse {
|
||||
private LocalDate adoptionDate;
|
||||
private java.math.BigDecimal adoptionFee;
|
||||
private String adoptionStatus;
|
||||
private Long sourceStoreId;
|
||||
private String sourceStoreName;
|
||||
|
||||
public AdoptionResponse() {
|
||||
@@ -98,6 +99,14 @@ public class AdoptionResponse {
|
||||
this.adoptionStatus = adoptionStatus;
|
||||
}
|
||||
|
||||
public Long getSourceStoreId() {
|
||||
return sourceStoreId;
|
||||
}
|
||||
|
||||
public void setSourceStoreId(Long sourceStoreId) {
|
||||
this.sourceStoreId = sourceStoreId;
|
||||
}
|
||||
|
||||
public String getSourceStoreName() {
|
||||
return sourceStoreName;
|
||||
}
|
||||
|
||||
@@ -8,6 +8,7 @@ public class UserRequest {
|
||||
private String phone;
|
||||
private String role;
|
||||
private Boolean active;
|
||||
private Integer loyaltyPoints;
|
||||
|
||||
public UserRequest() {
|
||||
}
|
||||
@@ -67,4 +68,12 @@ public class UserRequest {
|
||||
public void setActive(Boolean active) {
|
||||
this.active = active;
|
||||
}
|
||||
|
||||
public Integer getLoyaltyPoints() {
|
||||
return loyaltyPoints;
|
||||
}
|
||||
|
||||
public void setLoyaltyPoints(Integer loyaltyPoints) {
|
||||
this.loyaltyPoints = loyaltyPoints;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -23,7 +23,7 @@ public class AppointmentApi {
|
||||
return INSTANCE;
|
||||
}
|
||||
|
||||
public List<AppointmentResponse> listAppointments(String query, Long storeId) throws Exception {
|
||||
public List<AppointmentResponse> listAppointments(String query, Long storeId, Long employeeId) throws Exception {
|
||||
String path = "/api/v1/appointments?page=0&size=1000";
|
||||
if (query != null && !query.isEmpty()) {
|
||||
path += "&q=" + URLEncoder.encode(query, StandardCharsets.UTF_8);
|
||||
@@ -31,6 +31,9 @@ public class AppointmentApi {
|
||||
if (storeId != null) {
|
||||
path += "&storeId=" + storeId;
|
||||
}
|
||||
if (employeeId != null) {
|
||||
path += "&employeeId=" + employeeId;
|
||||
}
|
||||
String response = apiClient.getRawResponse(path);
|
||||
PageResponse<AppointmentResponse> pageResponse = apiClient.getObjectMapper().readValue(
|
||||
response,
|
||||
|
||||
@@ -57,6 +57,10 @@ public class PetApi {
|
||||
return listPets(query, null, null, null);
|
||||
}
|
||||
|
||||
public PetResponse getPetById(Long id) throws Exception {
|
||||
return apiClient.get("/api/v1/pets/" + id, PetResponse.class);
|
||||
}
|
||||
|
||||
public PetResponse createPet(PetRequest request) throws Exception {
|
||||
return apiClient.post("/api/v1/pets", request, PetResponse.class);
|
||||
}
|
||||
|
||||
@@ -284,7 +284,8 @@ public class AdoptionController {
|
||||
response.getAdoptionDate() != null ? response.getAdoptionDate().toString() : "",
|
||||
response.getAdoptionFee() != null ? response.getAdoptionFee().doubleValue() : 0.0,
|
||||
response.getAdoptionStatus(),
|
||||
response.getSourceStoreName()
|
||||
response.getSourceStoreName(),
|
||||
response.getSourceStoreId()
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -43,6 +43,7 @@ public class AppointmentController {
|
||||
@FXML private Button btnEdit;
|
||||
@FXML private Button btnDelete;
|
||||
@FXML private Button btnRefresh;
|
||||
@FXML private javafx.scene.control.ToggleButton btnMyAppointments;
|
||||
|
||||
@FXML private Label lblStatus;
|
||||
|
||||
@@ -71,6 +72,11 @@ public class AppointmentController {
|
||||
TableViewSupport.bindSortedItems(tvAppointments, filtered);
|
||||
TableViewSupport.installDoubleClickAction(tvAppointments, selected -> openDialog(selected, "Edit"));
|
||||
|
||||
if (UserSession.getInstance().isStaff()) {
|
||||
btnMyAppointments.setVisible(true);
|
||||
btnMyAppointments.setManaged(true);
|
||||
}
|
||||
|
||||
if (txtSearch != null) {
|
||||
txtSearch.textProperty().addListener((obs, o, n) -> applyFilter(n));
|
||||
}
|
||||
@@ -92,11 +98,17 @@ public class AppointmentController {
|
||||
loadAppointments();
|
||||
}
|
||||
|
||||
@FXML
|
||||
void btnMyAppointmentsToggled(javafx.event.ActionEvent event) {
|
||||
loadAppointments();
|
||||
}
|
||||
|
||||
private void loadAppointments(){
|
||||
new Thread(() -> {
|
||||
try{
|
||||
Long storeId = UserSession.getInstance().isAdmin() ? null : UserSession.getInstance().getStoreId();
|
||||
List<AppointmentResponse> responses = AppointmentApi.getInstance().listAppointments(null, storeId);
|
||||
Long employeeId = btnMyAppointments.isSelected() ? UserSession.getInstance().getEmployeeId() : null;
|
||||
List<AppointmentResponse> responses = AppointmentApi.getInstance().listAppointments(null, storeId, employeeId);
|
||||
List<AppointmentDTO> appointmentDTOs = responses.stream()
|
||||
.map(this::mapToAppointmentDTO)
|
||||
.sorted(Comparator.comparing((AppointmentDTO a) -> a.getAppointmentDate() + "T" + a.getAppointmentTime()).reversed())
|
||||
@@ -122,7 +134,8 @@ public class AppointmentController {
|
||||
new Thread(() -> {
|
||||
try {
|
||||
Long storeId = UserSession.getInstance().isAdmin() ? null : UserSession.getInstance().getStoreId();
|
||||
List<AppointmentResponse> responses = AppointmentApi.getInstance().listAppointments(query, storeId);
|
||||
Long employeeId = btnMyAppointments.isSelected() ? UserSession.getInstance().getEmployeeId() : null;
|
||||
List<AppointmentResponse> responses = AppointmentApi.getInstance().listAppointments(query, storeId, employeeId);
|
||||
List<AppointmentDTO> appointmentDTOs = responses.stream()
|
||||
.map(this::mapToAppointmentDTO)
|
||||
.sorted(Comparator.comparing((AppointmentDTO a) -> a.getAppointmentDate() + "T" + a.getAppointmentTime()).reversed())
|
||||
@@ -269,7 +282,8 @@ public class AppointmentController {
|
||||
response.getAppointmentDate() != null ? response.getAppointmentDate().toString() : "",
|
||||
response.getAppointmentTime() != null ? response.getAppointmentTime().toString() : "",
|
||||
normalizeAppointmentStatus(response.getAppointmentStatus()),
|
||||
response.getStoreName()
|
||||
response.getStoreName(),
|
||||
response.getStoreId()
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@@ -108,15 +108,15 @@ public class CustomerAccountsController {
|
||||
}
|
||||
|
||||
try {
|
||||
FXMLLoader loader = new FXMLLoader(getClass().getResource("/org/example/petshopdesktop/dialogviews/staff-edit-dialog-view.fxml"));
|
||||
FXMLLoader loader = new FXMLLoader(getClass().getResource("/org/example/petshopdesktop/dialogviews/customer-edit-dialog-view.fxml"));
|
||||
Stage dialog = new Stage();
|
||||
dialog.initOwner(tvCustomers.getScene().getWindow());
|
||||
dialog.initModality(Modality.APPLICATION_MODAL);
|
||||
dialog.setTitle("Edit Customer Account");
|
||||
dialog.setScene(new Scene(loader.load()));
|
||||
dialog.setResizable(false);
|
||||
var controller = (org.example.petshopdesktop.controllers.dialogcontrollers.StaffEditDialogController) loader.getController();
|
||||
controller.setUser(selected);
|
||||
var controller = (org.example.petshopdesktop.controllers.dialogcontrollers.CustomerEditDialogController) loader.getController();
|
||||
controller.setCustomer(selected);
|
||||
dialog.showAndWait();
|
||||
refresh();
|
||||
} catch (Exception e) {
|
||||
|
||||
@@ -12,8 +12,8 @@ import javafx.scene.control.*;
|
||||
import javafx.scene.layout.VBox;
|
||||
import javafx.stage.Modality;
|
||||
import javafx.stage.Stage;
|
||||
import org.example.petshopdesktop.api.dto.user.UserResponse;
|
||||
import org.example.petshopdesktop.api.endpoints.UserApi;
|
||||
import org.example.petshopdesktop.api.dto.employee.EmployeeResponse;
|
||||
import org.example.petshopdesktop.api.endpoints.EmployeeApi;
|
||||
import org.example.petshopdesktop.auth.UserSession;
|
||||
import org.example.petshopdesktop.util.ActivityLogger;
|
||||
import org.example.petshopdesktop.util.TableViewSupport;
|
||||
@@ -24,53 +24,24 @@ import java.util.stream.Collectors;
|
||||
|
||||
public class StaffAccountsController {
|
||||
|
||||
@FXML
|
||||
private VBox staffSection;
|
||||
@FXML private VBox staffSection;
|
||||
@FXML private TableView<EmployeeResponse> tvStaff;
|
||||
@FXML private TableColumn<EmployeeResponse, String> colUsername;
|
||||
@FXML private TableColumn<EmployeeResponse, String> colName;
|
||||
@FXML private TableColumn<EmployeeResponse, String> colEmail;
|
||||
@FXML private TableColumn<EmployeeResponse, String> colPhone;
|
||||
@FXML private TableColumn<EmployeeResponse, String> colRole;
|
||||
@FXML private TableColumn<EmployeeResponse, String> colStatus;
|
||||
@FXML private TableColumn<EmployeeResponse, Object> colCreated;
|
||||
@FXML private TextField txtSearch;
|
||||
@FXML private Button btnRefresh;
|
||||
@FXML private Button btnCreateAccount;
|
||||
@FXML private Button btnEditAccount;
|
||||
@FXML private Label lblError;
|
||||
@FXML private Label lblStatus;
|
||||
|
||||
@FXML
|
||||
private TableView<UserResponse> tvStaff;
|
||||
|
||||
@FXML
|
||||
private TableColumn<UserResponse, String> colUsername;
|
||||
|
||||
@FXML
|
||||
private TableColumn<UserResponse, String> colName;
|
||||
|
||||
@FXML
|
||||
private TableColumn<UserResponse, String> colEmail;
|
||||
|
||||
@FXML
|
||||
private TableColumn<UserResponse, String> colPhone;
|
||||
|
||||
@FXML
|
||||
private TableColumn<UserResponse, String> colRole;
|
||||
|
||||
@FXML
|
||||
private TableColumn<UserResponse, String> colStatus;
|
||||
|
||||
@FXML
|
||||
private TableColumn<UserResponse, Object> colCreated;
|
||||
|
||||
@FXML
|
||||
private TextField txtSearch;
|
||||
|
||||
@FXML
|
||||
private Button btnRefresh;
|
||||
|
||||
@FXML
|
||||
private Button btnCreateAccount;
|
||||
|
||||
@FXML
|
||||
private Button btnEditAccount;
|
||||
|
||||
@FXML
|
||||
private Label lblError;
|
||||
|
||||
@FXML
|
||||
private Label lblStatus;
|
||||
|
||||
private final ObservableList<UserResponse> staffAccounts = FXCollections.observableArrayList();
|
||||
private FilteredList<UserResponse> filteredStaff;
|
||||
private final ObservableList<EmployeeResponse> staffAccounts = FXCollections.observableArrayList();
|
||||
private FilteredList<EmployeeResponse> filteredStaff;
|
||||
|
||||
@FXML
|
||||
public void initialize() {
|
||||
@@ -78,8 +49,13 @@ public class StaffAccountsController {
|
||||
colName.setCellValueFactory(data -> new javafx.beans.property.SimpleStringProperty(data.getValue().getFullName()));
|
||||
colEmail.setCellValueFactory(data -> new javafx.beans.property.SimpleStringProperty(data.getValue().getEmail()));
|
||||
colPhone.setCellValueFactory(data -> new javafx.beans.property.SimpleStringProperty(data.getValue().getPhone()));
|
||||
colRole.setCellValueFactory(data -> new javafx.beans.property.SimpleStringProperty(data.getValue().getRole()));
|
||||
colStatus.setCellValueFactory(data -> new javafx.beans.property.SimpleStringProperty(data.getValue().getActive() != null && data.getValue().getActive() ? "Active" : "Inactive"));
|
||||
colRole.setCellValueFactory(data -> {
|
||||
String role = data.getValue().getRole() != null ? data.getValue().getRole() : "";
|
||||
String staffRole = data.getValue().getStaffRole() != null ? " (" + data.getValue().getStaffRole() + ")" : "";
|
||||
return new javafx.beans.property.SimpleStringProperty(role + staffRole);
|
||||
});
|
||||
colStatus.setCellValueFactory(data -> new javafx.beans.property.SimpleStringProperty(
|
||||
Boolean.TRUE.equals(data.getValue().getActive()) ? "Active" : "Inactive"));
|
||||
colCreated.setCellValueFactory(data -> new javafx.beans.property.SimpleObjectProperty<>(data.getValue().getCreatedAt()));
|
||||
|
||||
filteredStaff = new FilteredList<>(staffAccounts, a -> true);
|
||||
@@ -128,7 +104,7 @@ public class StaffAccountsController {
|
||||
openEditDialog(tvStaff.getSelectionModel().getSelectedItem());
|
||||
}
|
||||
|
||||
private void openEditDialog(UserResponse selected) {
|
||||
private void openEditDialog(EmployeeResponse selected) {
|
||||
if (selected == null) {
|
||||
lblError.setText("Select a user account to edit.");
|
||||
return;
|
||||
@@ -152,12 +128,12 @@ public class StaffAccountsController {
|
||||
dialog.setScene(new Scene(loader.load()));
|
||||
dialog.setResizable(false);
|
||||
var controller = (org.example.petshopdesktop.controllers.dialogcontrollers.StaffEditDialogController) loader.getController();
|
||||
controller.setUser(selected);
|
||||
controller.setEmployee(selected);
|
||||
dialog.showAndWait();
|
||||
refresh();
|
||||
} catch (Exception e) {
|
||||
ActivityLogger.getInstance().logException("StaffAccountsController.openEditDialog", e, "Opening user edit dialog");
|
||||
lblError.setText("Could not open user account editor.");
|
||||
ActivityLogger.getInstance().logException("StaffAccountsController.openEditDialog", e, "Opening employee edit dialog");
|
||||
lblError.setText("Could not open employee account editor.");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -167,11 +143,10 @@ public class StaffAccountsController {
|
||||
|
||||
new Thread(() -> {
|
||||
try {
|
||||
Comparator<UserResponse> byCreated = Comparator.comparing(
|
||||
UserResponse::getCreatedAt, Comparator.nullsLast(Comparator.reverseOrder()));
|
||||
Comparator<EmployeeResponse> byCreated = Comparator.comparing(
|
||||
EmployeeResponse::getCreatedAt, Comparator.nullsLast(Comparator.reverseOrder()));
|
||||
|
||||
List<UserResponse> staff = UserApi.getInstance().listUsers(null).stream()
|
||||
.filter(u -> !"CUSTOMER".equalsIgnoreCase(u.getRole()))
|
||||
List<EmployeeResponse> staff = EmployeeApi.getInstance().listEmployees(null).stream()
|
||||
.sorted(byCreated)
|
||||
.collect(Collectors.toList());
|
||||
|
||||
@@ -180,7 +155,7 @@ public class StaffAccountsController {
|
||||
tvStaff.setDisable(false);
|
||||
});
|
||||
} catch (Exception e) {
|
||||
ActivityLogger.getInstance().logException("StaffAccountsController.refresh", e, "Loading staff accounts");
|
||||
ActivityLogger.getInstance().logException("StaffAccountsController.refresh", e, "Loading employee accounts");
|
||||
Platform.runLater(() -> {
|
||||
lblError.setText("Could not load staff accounts.");
|
||||
tvStaff.setDisable(false);
|
||||
@@ -201,6 +176,7 @@ public class StaffAccountsController {
|
||||
|| safe(a.getEmail()).contains(q)
|
||||
|| safe(a.getPhone()).contains(q)
|
||||
|| safe(a.getRole()).contains(q)
|
||||
|| safe(a.getStaffRole()).contains(q)
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@@ -8,164 +8,92 @@ import javafx.fxml.FXML;
|
||||
import javafx.scene.Node;
|
||||
import javafx.scene.control.Alert;
|
||||
import javafx.scene.control.Button;
|
||||
import javafx.scene.control.ChoiceDialog;
|
||||
import javafx.scene.control.ComboBox;
|
||||
import javafx.scene.control.DatePicker;
|
||||
import javafx.scene.control.Label;
|
||||
import javafx.scene.control.ListCell;
|
||||
import javafx.scene.control.TextField;
|
||||
import javafx.scene.input.MouseEvent;
|
||||
import javafx.scene.layout.VBox;
|
||||
import javafx.stage.Stage;
|
||||
import org.example.petshopdesktop.api.dto.adoption.AdoptionRequest;
|
||||
import org.example.petshopdesktop.api.dto.common.DropdownOption;
|
||||
import org.example.petshopdesktop.api.endpoints.AdoptionApi;
|
||||
import org.example.petshopdesktop.api.endpoints.DropdownApi;
|
||||
import org.example.petshopdesktop.api.endpoints.PetApi;
|
||||
import org.example.petshopdesktop.auth.UserSession;
|
||||
import org.example.petshopdesktop.models.Adoption;
|
||||
import org.example.petshopdesktop.util.ActivityLogger;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.time.LocalDate;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
|
||||
public class AdoptionDialogController {
|
||||
|
||||
@FXML
|
||||
private Button btnCancel;
|
||||
|
||||
@FXML
|
||||
private Button btnSave;
|
||||
|
||||
@FXML
|
||||
private ComboBox<String> cbAdoptionStatus;
|
||||
|
||||
@FXML
|
||||
private ComboBox<DropdownOption> cbCustomer;
|
||||
|
||||
@FXML
|
||||
private ComboBox<DropdownOption> cbEmployee;
|
||||
|
||||
@FXML
|
||||
private ComboBox<DropdownOption> cbPet;
|
||||
|
||||
@FXML
|
||||
private DatePicker dpAdoptionDate;
|
||||
|
||||
@FXML
|
||||
private Label lblAdoptionId;
|
||||
|
||||
@FXML
|
||||
private Label lblMode;
|
||||
@FXML private Button btnCancel;
|
||||
@FXML private Button btnSave;
|
||||
@FXML private ComboBox<String> cbAdoptionStatus;
|
||||
@FXML private ComboBox<DropdownOption> cbCustomer;
|
||||
@FXML private ComboBox<DropdownOption> cbEmployee;
|
||||
@FXML private ComboBox<DropdownOption> cbPet;
|
||||
@FXML private ComboBox<DropdownOption> cbStore;
|
||||
@FXML private VBox vbStore;
|
||||
@FXML private DatePicker dpAdoptionDate;
|
||||
@FXML private TextField txtAdoptionFee;
|
||||
@FXML private Label lblAdoptionId;
|
||||
@FXML private Label lblMode;
|
||||
|
||||
private String mode = null;
|
||||
private Adoption selectedAdoption = null;
|
||||
private String selectedPaymentMethod = null;
|
||||
private boolean suppressPaymentDialog = false;
|
||||
private boolean suppressStatusListener = false;
|
||||
private Long pendingStoreId = null;
|
||||
|
||||
private ObservableList<String> statusList = FXCollections.observableArrayList(
|
||||
private final ObservableList<String> statusList = FXCollections.observableArrayList(
|
||||
"Pending", "Completed", "Missed", "Cancelled"
|
||||
);
|
||||
|
||||
@FXML
|
||||
void initialize() {
|
||||
|
||||
cbAdoptionStatus.setItems(statusList);
|
||||
cbAdoptionStatus.valueProperty().addListener((obs, oldVal, newVal) -> {
|
||||
if ("Completed".equals(newVal) && !"Completed".equals(oldVal) && !suppressPaymentDialog) {
|
||||
ChoiceDialog<String> dialog = new ChoiceDialog<>("Cash", "Cash", "Credit Card", "Debit Card", "E-Transfer");
|
||||
dialog.setTitle("Payment Method");
|
||||
dialog.setHeaderText("Confirm payment received");
|
||||
dialog.setContentText("Select payment method:");
|
||||
dialog.showAndWait().ifPresentOrElse(
|
||||
method -> selectedPaymentMethod = method,
|
||||
() -> {
|
||||
selectedPaymentMethod = null;
|
||||
cbAdoptionStatus.setValue(oldVal);
|
||||
}
|
||||
);
|
||||
} else if (!"Completed".equals(newVal)) {
|
||||
selectedPaymentMethod = null;
|
||||
if (!suppressStatusListener && newVal != null) {
|
||||
applyStatusFieldRules(newVal);
|
||||
}
|
||||
});
|
||||
|
||||
cbEmployee.setPromptText("Select an employee");
|
||||
txtAdoptionFee.setDisable(true);
|
||||
|
||||
new Thread(() -> {
|
||||
try {
|
||||
List<DropdownOption> pets = DropdownApi.getInstance().getAdoptionPets();
|
||||
Platform.runLater(() -> {
|
||||
if (pets != null) {
|
||||
ObservableList<DropdownOption> petsObs = FXCollections.observableArrayList(pets);
|
||||
ensureSelectedPetOption(petsObs);
|
||||
cbPet.setItems(petsObs);
|
||||
applySelectedPet();
|
||||
}
|
||||
});
|
||||
} catch (Exception e) {
|
||||
Platform.runLater(() -> {
|
||||
ActivityLogger.getInstance().logException(
|
||||
"AdoptionDialogController.initialize",
|
||||
e,
|
||||
"Loading pets for combo box");
|
||||
System.out.println("Error loading pets: " + e.getMessage());
|
||||
});
|
||||
}
|
||||
}).start();
|
||||
|
||||
new Thread(() -> {
|
||||
try {
|
||||
List<DropdownOption> employees = DropdownApi.getInstance().getEmployees();
|
||||
Platform.runLater(() -> {
|
||||
ObservableList<DropdownOption> employeesObs = FXCollections.observableArrayList(employees);
|
||||
ensureSelectedEmployeeOption(employeesObs);
|
||||
cbEmployee.setItems(employeesObs);
|
||||
applySelectedEmployee();
|
||||
});
|
||||
} catch (Exception e) {
|
||||
Platform.runLater(() -> {
|
||||
ActivityLogger.getInstance().logException(
|
||||
"AdoptionDialogController.initialize",
|
||||
e,
|
||||
"Loading employees for combo box");
|
||||
cbEmployee.setDisable(true);
|
||||
cbEmployee.setPromptText("Unable to load employees");
|
||||
});
|
||||
}
|
||||
}).start();
|
||||
|
||||
cbEmployee.setCellFactory(param -> new ListCell<>() {
|
||||
LocalDate today = LocalDate.now();
|
||||
dpAdoptionDate.setDayCellFactory(picker -> new javafx.scene.control.DateCell() {
|
||||
@Override
|
||||
protected void updateItem(DropdownOption option, boolean empty) {
|
||||
super.updateItem(option, empty);
|
||||
setText(empty || option == null ? null : option.getLabel());
|
||||
}
|
||||
});
|
||||
cbEmployee.setButtonCell(new ListCell<>() {
|
||||
@Override
|
||||
protected void updateItem(DropdownOption option, boolean empty) {
|
||||
super.updateItem(option, empty);
|
||||
setText(empty || option == null ? null : option.getLabel());
|
||||
public void updateItem(LocalDate item, boolean empty) {
|
||||
super.updateItem(item, empty);
|
||||
setDisable(empty || item.isBefore(today));
|
||||
}
|
||||
});
|
||||
|
||||
new Thread(() -> {
|
||||
try {
|
||||
List<DropdownOption> customers = DropdownApi.getInstance().getCustomers();
|
||||
Platform.runLater(() -> {
|
||||
if (customers != null) {
|
||||
ObservableList<DropdownOption> customersObs = FXCollections.observableArrayList(customers);
|
||||
cbCustomer.setItems(customersObs);
|
||||
applySelectedCustomer();
|
||||
}
|
||||
});
|
||||
} catch (Exception e) {
|
||||
Platform.runLater(() -> {
|
||||
ActivityLogger.getInstance().logException(
|
||||
"AdoptionDialogController.initialize",
|
||||
e,
|
||||
"Loading customers for combo box");
|
||||
System.out.println("Error loading customers: " + e.getMessage());
|
||||
});
|
||||
setupDropdownCellFactory(cbEmployee);
|
||||
setupDropdownCellFactory(cbPet);
|
||||
setupDropdownCellFactory(cbCustomer);
|
||||
setupDropdownCellFactory(cbStore);
|
||||
|
||||
cbPet.valueProperty().addListener((obs, oldVal, newVal) -> {
|
||||
if (newVal != null) {
|
||||
loadPetPrice(newVal.getId());
|
||||
} else {
|
||||
txtAdoptionFee.setText("0");
|
||||
}
|
||||
}).start();
|
||||
});
|
||||
|
||||
if (UserSession.getInstance().isAdmin()) {
|
||||
vbStore.setVisible(true);
|
||||
vbStore.setManaged(true);
|
||||
}
|
||||
|
||||
loadDropdownsAsync();
|
||||
|
||||
btnSave.setOnMouseClicked(new EventHandler<MouseEvent>() {
|
||||
@Override
|
||||
@@ -182,32 +110,146 @@ public class AdoptionDialogController {
|
||||
});
|
||||
}
|
||||
|
||||
private void setupDropdownCellFactory(ComboBox<DropdownOption> cb) {
|
||||
cb.setCellFactory(param -> new ListCell<>() {
|
||||
@Override protected void updateItem(DropdownOption o, boolean empty) {
|
||||
super.updateItem(o, empty);
|
||||
setText(empty || o == null ? null : o.getLabel());
|
||||
}
|
||||
});
|
||||
cb.setButtonCell(new ListCell<>() {
|
||||
@Override protected void updateItem(DropdownOption o, boolean empty) {
|
||||
super.updateItem(o, empty);
|
||||
setText(empty || o == null ? null : o.getLabel());
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private void loadDropdownsAsync() {
|
||||
new Thread(() -> {
|
||||
try {
|
||||
List<DropdownOption> pets = DropdownApi.getInstance().getAdoptionPets();
|
||||
Platform.runLater(() -> {
|
||||
if (pets != null) {
|
||||
ObservableList<DropdownOption> petsObs = FXCollections.observableArrayList(pets);
|
||||
ensureSelectedPetOption(petsObs);
|
||||
cbPet.setItems(petsObs);
|
||||
applySelectedPet();
|
||||
}
|
||||
});
|
||||
} catch (Exception e) {
|
||||
Platform.runLater(() -> ActivityLogger.getInstance().logException(
|
||||
"AdoptionDialogController.loadDropdownsAsync", e, "Loading pets"));
|
||||
}
|
||||
}).start();
|
||||
|
||||
new Thread(() -> {
|
||||
try {
|
||||
List<DropdownOption> employees = DropdownApi.getInstance().getEmployees();
|
||||
Platform.runLater(() -> {
|
||||
ObservableList<DropdownOption> employeesObs = FXCollections.observableArrayList(employees);
|
||||
ensureSelectedEmployeeOption(employeesObs);
|
||||
cbEmployee.setItems(employeesObs);
|
||||
applySelectedEmployee();
|
||||
});
|
||||
} catch (Exception e) {
|
||||
Platform.runLater(() -> {
|
||||
ActivityLogger.getInstance().logException(
|
||||
"AdoptionDialogController.loadDropdownsAsync", e, "Loading employees");
|
||||
cbEmployee.setDisable(true);
|
||||
cbEmployee.setPromptText("Unable to load employees");
|
||||
});
|
||||
}
|
||||
}).start();
|
||||
|
||||
new Thread(() -> {
|
||||
try {
|
||||
List<DropdownOption> customers = DropdownApi.getInstance().getCustomers();
|
||||
Platform.runLater(() -> {
|
||||
if (customers != null) {
|
||||
ObservableList<DropdownOption> customersObs = FXCollections.observableArrayList(customers);
|
||||
cbCustomer.setItems(customersObs);
|
||||
applySelectedCustomer();
|
||||
}
|
||||
});
|
||||
} catch (Exception e) {
|
||||
Platform.runLater(() -> ActivityLogger.getInstance().logException(
|
||||
"AdoptionDialogController.loadDropdownsAsync", e, "Loading customers"));
|
||||
}
|
||||
}).start();
|
||||
|
||||
if (UserSession.getInstance().isAdmin()) {
|
||||
new Thread(() -> {
|
||||
try {
|
||||
List<DropdownOption> stores = DropdownApi.getInstance().getStores();
|
||||
Platform.runLater(() -> {
|
||||
if (stores != null) {
|
||||
cbStore.setItems(FXCollections.observableArrayList(stores));
|
||||
if (pendingStoreId != null) {
|
||||
for (DropdownOption store : cbStore.getItems()) {
|
||||
if (pendingStoreId.equals(store.getId())) {
|
||||
cbStore.setValue(store);
|
||||
break;
|
||||
}
|
||||
}
|
||||
pendingStoreId = null;
|
||||
}
|
||||
}
|
||||
});
|
||||
} catch (Exception e) {
|
||||
Platform.runLater(() -> ActivityLogger.getInstance().logException(
|
||||
"AdoptionDialogController.loadDropdownsAsync", e, "Loading stores"));
|
||||
}
|
||||
}).start();
|
||||
}
|
||||
}
|
||||
|
||||
private void applyStatusFieldRules(String status) {
|
||||
if ("Cancelled".equalsIgnoreCase(status) || "Completed".equalsIgnoreCase(status) || "Missed".equalsIgnoreCase(status)) {
|
||||
cbEmployee.setDisable(true);
|
||||
dpAdoptionDate.setDisable(true);
|
||||
cbStore.setDisable(true);
|
||||
} else {
|
||||
cbEmployee.setDisable(false);
|
||||
dpAdoptionDate.setDisable(false);
|
||||
if (UserSession.getInstance().isAdmin()) cbStore.setDisable(false);
|
||||
}
|
||||
}
|
||||
|
||||
private void buttonSaveClicked(MouseEvent mouseEvent) {
|
||||
String errorMsg = "";
|
||||
|
||||
if (cbPet.getSelectionModel().getSelectedItem() == null) {
|
||||
errorMsg += "Pet is required.\n";
|
||||
}
|
||||
if (cbPet.getSelectionModel().getSelectedItem() == null) errorMsg += "Pet is required.\n";
|
||||
if (cbCustomer.getSelectionModel().getSelectedItem() == null) errorMsg += "Customer is required.\n";
|
||||
if (cbEmployee.getSelectionModel().getSelectedItem() == null) errorMsg += "Employee is required.\n";
|
||||
if (dpAdoptionDate.getValue() == null) errorMsg += "Adoption Date is required.\n";
|
||||
if (cbAdoptionStatus.getSelectionModel().getSelectedItem() == null) errorMsg += "Status is required.\n";
|
||||
|
||||
if (cbCustomer.getSelectionModel().getSelectedItem() == null) {
|
||||
errorMsg += "Customer is required.\n";
|
||||
}
|
||||
|
||||
if (cbEmployee.getSelectionModel().getSelectedItem() == null) {
|
||||
errorMsg += "Employee is required.\n";
|
||||
}
|
||||
|
||||
if (dpAdoptionDate.getValue() == null) {
|
||||
errorMsg += "Adoption Date is required.\n";
|
||||
}
|
||||
|
||||
if (cbAdoptionStatus.getSelectionModel().getSelectedItem() == null) {
|
||||
errorMsg += "Status is required.\n";
|
||||
BigDecimal adoptionFee = BigDecimal.ZERO;
|
||||
String feeText = txtAdoptionFee.getText() == null ? "" : txtAdoptionFee.getText().trim();
|
||||
if (!feeText.isEmpty()) {
|
||||
try {
|
||||
adoptionFee = new BigDecimal(feeText);
|
||||
} catch (NumberFormatException e) {
|
||||
adoptionFee = BigDecimal.ZERO;
|
||||
}
|
||||
}
|
||||
|
||||
if (errorMsg.isEmpty()) {
|
||||
try {
|
||||
Long storeId = UserSession.getInstance().getStoreId();
|
||||
Long storeId;
|
||||
if (UserSession.getInstance().isAdmin()) {
|
||||
if (cbStore.getSelectionModel().getSelectedItem() == null) {
|
||||
Alert alert = new Alert(Alert.AlertType.ERROR);
|
||||
alert.setHeaderText("Input Error");
|
||||
alert.setContentText("Store is required.");
|
||||
alert.showAndWait();
|
||||
return;
|
||||
}
|
||||
storeId = cbStore.getSelectionModel().getSelectedItem().getId();
|
||||
} else {
|
||||
storeId = UserSession.getInstance().getStoreId();
|
||||
}
|
||||
if (storeId == null || storeId <= 0) {
|
||||
throw new IllegalStateException("Store is not set for this account");
|
||||
}
|
||||
@@ -219,15 +261,13 @@ public class AdoptionDialogController {
|
||||
request.setSourceStoreId(storeId);
|
||||
request.setAdoptionDate(dpAdoptionDate.getValue());
|
||||
request.setAdoptionStatus(cbAdoptionStatus.getValue());
|
||||
request.setPaymentMethod(selectedPaymentMethod);
|
||||
request.setAdoptionFee(adoptionFee);
|
||||
|
||||
if (mode.equals("Add")) {
|
||||
AdoptionApi.getInstance().createAdoption(request);
|
||||
} else {
|
||||
String[] parts = lblAdoptionId.getText().split(": ");
|
||||
if (parts.length < 2) {
|
||||
throw new IllegalStateException("Invalid adoption ID format");
|
||||
}
|
||||
if (parts.length < 2) throw new IllegalStateException("Invalid adoption ID format");
|
||||
Long adoptionId = Long.parseLong(parts[1]);
|
||||
AdoptionApi.getInstance().updateAdoption(adoptionId, request);
|
||||
}
|
||||
@@ -239,9 +279,7 @@ public class AdoptionDialogController {
|
||||
closeStage(mouseEvent);
|
||||
} catch (Exception e) {
|
||||
ActivityLogger.getInstance().logException(
|
||||
"AdoptionDialogController.buttonSaveClicked",
|
||||
e,
|
||||
mode + " adoption");
|
||||
"AdoptionDialogController.buttonSaveClicked", e, mode + " adoption");
|
||||
Alert alert = new Alert(Alert.AlertType.ERROR);
|
||||
alert.setHeaderText("Database Operation Error");
|
||||
alert.setContentText(e.getMessage());
|
||||
@@ -262,36 +300,37 @@ public class AdoptionDialogController {
|
||||
}
|
||||
|
||||
public void displayAdoptionDetails(Adoption adoption) {
|
||||
if (adoption != null) {
|
||||
selectedAdoption = adoption;
|
||||
lblAdoptionId.setText("ID: " + adoption.getAdoptionId());
|
||||
ensureSelectedEmployeeOption(cbEmployee.getItems());
|
||||
applySelectedPet();
|
||||
applySelectedCustomer();
|
||||
applySelectedEmployee();
|
||||
if (adoption == null) return;
|
||||
selectedAdoption = adoption;
|
||||
lblAdoptionId.setText("ID: " + adoption.getAdoptionId());
|
||||
pendingStoreId = adoption.getStoreId();
|
||||
ensureSelectedEmployeeOption(cbEmployee.getItems());
|
||||
applySelectedPet();
|
||||
applySelectedCustomer();
|
||||
applySelectedEmployee();
|
||||
|
||||
if (adoption.getAdoptionDate() != null && !adoption.getAdoptionDate().isEmpty()) {
|
||||
try {
|
||||
dpAdoptionDate.setValue(LocalDate.parse(adoption.getAdoptionDate()));
|
||||
} catch (Exception e) {
|
||||
ActivityLogger.getInstance().logException(
|
||||
"AdoptionDialogController.displayAdoptionDetails",
|
||||
e,
|
||||
"Parsing adoption date");
|
||||
}
|
||||
if (adoption.getAdoptionDate() != null && !adoption.getAdoptionDate().isEmpty()) {
|
||||
try {
|
||||
dpAdoptionDate.setValue(LocalDate.parse(adoption.getAdoptionDate()));
|
||||
} catch (Exception e) {
|
||||
ActivityLogger.getInstance().logException(
|
||||
"AdoptionDialogController.displayAdoptionDetails", e, "Parsing adoption date");
|
||||
}
|
||||
|
||||
suppressPaymentDialog = true;
|
||||
cbAdoptionStatus.setItems(statusList);
|
||||
for (String status : cbAdoptionStatus.getItems()) {
|
||||
if (status.equals(adoption.getAdoptionStatus())) {
|
||||
cbAdoptionStatus.getSelectionModel().select(status);
|
||||
break;
|
||||
}
|
||||
}
|
||||
suppressPaymentDialog = false;
|
||||
applyEditModeLock();
|
||||
}
|
||||
|
||||
txtAdoptionFee.setText(adoption.getAdoptionFee() > 0
|
||||
? String.format("%.2f", adoption.getAdoptionFee()) : "0.00");
|
||||
|
||||
suppressStatusListener = true;
|
||||
cbAdoptionStatus.setItems(statusList);
|
||||
for (String status : cbAdoptionStatus.getItems()) {
|
||||
if (status.equals(adoption.getAdoptionStatus())) {
|
||||
cbAdoptionStatus.getSelectionModel().select(status);
|
||||
break;
|
||||
}
|
||||
}
|
||||
suppressStatusListener = false;
|
||||
applyEditModeLock();
|
||||
}
|
||||
|
||||
private void applyEditModeLock() {
|
||||
@@ -304,6 +343,7 @@ public class AdoptionDialogController {
|
||||
dpAdoptionDate.setDisable(true);
|
||||
cbAdoptionStatus.setDisable(true);
|
||||
cbAdoptionStatus.setItems(FXCollections.observableArrayList("Cancelled"));
|
||||
cbStore.setDisable(true);
|
||||
btnSave.setDisable(true);
|
||||
return;
|
||||
}
|
||||
@@ -311,23 +351,33 @@ public class AdoptionDialogController {
|
||||
LocalDate adoptionDate = dpAdoptionDate.getValue();
|
||||
boolean isPast = adoptionDate != null && adoptionDate.isBefore(LocalDate.now());
|
||||
|
||||
cbPet.setDisable(true);
|
||||
cbCustomer.setDisable(true);
|
||||
dpAdoptionDate.setDisable(false);
|
||||
cbEmployee.setDisable(false);
|
||||
cbAdoptionStatus.setDisable(false);
|
||||
|
||||
suppressPaymentDialog = true;
|
||||
if (isPast) {
|
||||
cbAdoptionStatus.setItems(FXCollections.observableArrayList("Completed", "Missed"));
|
||||
cbPet.setDisable(true);
|
||||
cbCustomer.setDisable(true);
|
||||
cbEmployee.setDisable(true);
|
||||
dpAdoptionDate.setDisable(true);
|
||||
cbStore.setDisable(true);
|
||||
cbAdoptionStatus.setDisable(false);
|
||||
suppressStatusListener = true;
|
||||
cbAdoptionStatus.setItems(FXCollections.observableArrayList("Completed", "Missed"));
|
||||
if (!cbAdoptionStatus.getItems().contains(cbAdoptionStatus.getValue())) {
|
||||
cbAdoptionStatus.getSelectionModel().selectFirst();
|
||||
}
|
||||
suppressStatusListener = false;
|
||||
} else {
|
||||
cbPet.setDisable(true);
|
||||
cbCustomer.setDisable(true);
|
||||
dpAdoptionDate.setDisable(false);
|
||||
cbEmployee.setDisable(false);
|
||||
cbAdoptionStatus.setDisable(false);
|
||||
if (UserSession.getInstance().isAdmin()) cbStore.setDisable(false);
|
||||
suppressStatusListener = true;
|
||||
cbAdoptionStatus.setItems(FXCollections.observableArrayList("Pending", "Cancelled"));
|
||||
if (!cbAdoptionStatus.getItems().contains(cbAdoptionStatus.getValue())) {
|
||||
cbAdoptionStatus.getSelectionModel().selectFirst();
|
||||
}
|
||||
suppressStatusListener = false;
|
||||
}
|
||||
if (!cbAdoptionStatus.getItems().contains(cbAdoptionStatus.getValue())) {
|
||||
cbAdoptionStatus.getSelectionModel().selectFirst();
|
||||
}
|
||||
suppressPaymentDialog = false;
|
||||
}
|
||||
|
||||
public void setMode(String mode) {
|
||||
@@ -335,60 +385,64 @@ public class AdoptionDialogController {
|
||||
lblMode.setText(mode + " Adoption");
|
||||
lblAdoptionId.setVisible(mode.equals("Edit"));
|
||||
if (mode.equals("Add")) {
|
||||
suppressPaymentDialog = true;
|
||||
suppressStatusListener = true;
|
||||
cbAdoptionStatus.setItems(FXCollections.observableArrayList("Pending"));
|
||||
cbAdoptionStatus.setValue("Pending");
|
||||
cbAdoptionStatus.setDisable(true);
|
||||
suppressPaymentDialog = false;
|
||||
suppressStatusListener = false;
|
||||
txtAdoptionFee.setText("");
|
||||
}
|
||||
}
|
||||
|
||||
private void applySelectedPet() {
|
||||
if (selectedAdoption == null || selectedAdoption.getPetId() <= 0) {
|
||||
return;
|
||||
}
|
||||
if (selectedAdoption == null || selectedAdoption.getPetId() <= 0) return;
|
||||
DropdownOption selected = findOptionById(cbPet.getItems(), (long) selectedAdoption.getPetId());
|
||||
if (selected != null && !Objects.equals(cbPet.getValue(), selected)) {
|
||||
cbPet.setValue(selected);
|
||||
}
|
||||
if (selected != null && !Objects.equals(cbPet.getValue(), selected)) cbPet.setValue(selected);
|
||||
}
|
||||
|
||||
private void applySelectedCustomer() {
|
||||
if (selectedAdoption == null || selectedAdoption.getCustomerId() <= 0) {
|
||||
return;
|
||||
}
|
||||
if (selectedAdoption == null || selectedAdoption.getCustomerId() <= 0) return;
|
||||
DropdownOption selected = findOptionById(cbCustomer.getItems(), (long) selectedAdoption.getCustomerId());
|
||||
if (selected != null && !Objects.equals(cbCustomer.getValue(), selected)) {
|
||||
cbCustomer.setValue(selected);
|
||||
}
|
||||
if (selected != null && !Objects.equals(cbCustomer.getValue(), selected)) cbCustomer.setValue(selected);
|
||||
}
|
||||
|
||||
private void applySelectedEmployee() {
|
||||
if (selectedAdoption == null || selectedAdoption.getEmployeeId() <= 0) {
|
||||
return;
|
||||
}
|
||||
if (selectedAdoption == null || selectedAdoption.getEmployeeId() <= 0) return;
|
||||
DropdownOption selected = findOptionById(cbEmployee.getItems(), (long) selectedAdoption.getEmployeeId());
|
||||
if (selected != null && !Objects.equals(cbEmployee.getValue(), selected)) {
|
||||
cbEmployee.setValue(selected);
|
||||
}
|
||||
if (selected != null && !Objects.equals(cbEmployee.getValue(), selected)) cbEmployee.setValue(selected);
|
||||
}
|
||||
|
||||
private DropdownOption findOptionById(List<DropdownOption> options, Long id) {
|
||||
if (id == null || options == null) {
|
||||
return null;
|
||||
}
|
||||
if (id == null || options == null) return null;
|
||||
for (DropdownOption option : options) {
|
||||
if (option.getId() != null && option.getId().equals(id)) {
|
||||
return option;
|
||||
}
|
||||
if (option.getId() != null && option.getId().equals(id)) return option;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private void loadPetPrice(Long petId) {
|
||||
new Thread(() -> {
|
||||
try {
|
||||
var pet = PetApi.getInstance().getPetById(petId);
|
||||
Platform.runLater(() -> {
|
||||
if (pet != null && pet.getPetPrice() != null) {
|
||||
txtAdoptionFee.setText(String.format("%.2f", pet.getPetPrice()));
|
||||
} else {
|
||||
txtAdoptionFee.setText("0.00");
|
||||
}
|
||||
});
|
||||
} catch (Exception e) {
|
||||
Platform.runLater(() -> {
|
||||
txtAdoptionFee.setText("0.00");
|
||||
ActivityLogger.getInstance().logException(
|
||||
"AdoptionDialogController.loadPetPrice", e, "Loading pet price");
|
||||
});
|
||||
}
|
||||
}).start();
|
||||
}
|
||||
|
||||
private void ensureSelectedEmployeeOption(ObservableList<DropdownOption> options) {
|
||||
if (selectedAdoption == null || selectedAdoption.getEmployeeId() <= 0 || options == null) {
|
||||
return;
|
||||
}
|
||||
if (selectedAdoption == null || selectedAdoption.getEmployeeId() <= 0 || options == null) return;
|
||||
DropdownOption existing = findOptionById(options, (long) selectedAdoption.getEmployeeId());
|
||||
if (existing == null) {
|
||||
DropdownOption option = new DropdownOption();
|
||||
@@ -399,9 +453,7 @@ public class AdoptionDialogController {
|
||||
}
|
||||
|
||||
private void ensureSelectedPetOption(ObservableList<DropdownOption> options) {
|
||||
if (selectedAdoption == null || selectedAdoption.getPetId() <= 0 || options == null) {
|
||||
return;
|
||||
}
|
||||
if (selectedAdoption == null || selectedAdoption.getPetId() <= 0 || options == null) return;
|
||||
DropdownOption existing = findOptionById(options, (long) selectedAdoption.getPetId());
|
||||
if (existing == null) {
|
||||
DropdownOption option = new DropdownOption();
|
||||
|
||||
@@ -7,6 +7,7 @@ import javafx.fxml.FXML;
|
||||
import javafx.scene.Node;
|
||||
import javafx.scene.control.*;
|
||||
import javafx.scene.input.MouseEvent;
|
||||
import javafx.scene.layout.VBox;
|
||||
import javafx.stage.Stage;
|
||||
import javafx.scene.control.ListCell;
|
||||
|
||||
@@ -18,7 +19,6 @@ import org.example.petshopdesktop.api.endpoints.DropdownApi;
|
||||
import org.example.petshopdesktop.auth.UserSession;
|
||||
import org.example.petshopdesktop.util.ActivityLogger;
|
||||
|
||||
import java.time.DayOfWeek;
|
||||
import java.time.LocalTime;
|
||||
import java.time.LocalDate;
|
||||
import java.util.List;
|
||||
@@ -33,6 +33,8 @@ public class AppointmentDialogController {
|
||||
@FXML private ComboBox<DropdownOption> cbCustomer;
|
||||
@FXML private ComboBox<DropdownOption> cbPet;
|
||||
@FXML private ComboBox<DropdownOption> cbEmployee;
|
||||
@FXML private ComboBox<DropdownOption> cbStore;
|
||||
@FXML private VBox vbStore;
|
||||
|
||||
@FXML private ComboBox<Integer> cbHour;
|
||||
@FXML private ComboBox<Integer> cbMinute;
|
||||
@@ -46,6 +48,7 @@ public class AppointmentDialogController {
|
||||
private String mode = null;
|
||||
private AppointmentDTO selectedAppointment = null;
|
||||
private Long pendingPetSelectionId = null;
|
||||
private Long pendingStoreId = null;
|
||||
private boolean isOriginallyCancel = false;
|
||||
private boolean isOriginallyCompletedOrMissed = false;
|
||||
|
||||
@@ -63,18 +66,39 @@ public class AppointmentDialogController {
|
||||
@FXML
|
||||
public void initialize() {
|
||||
cbAppointmentStatus.setItems(FXCollections.observableArrayList("Booked", "Completed", "Missed", "Cancelled"));
|
||||
cbAppointmentStatus.valueProperty().addListener((obs, oldVal, newVal) -> {
|
||||
if (newVal == null) return;
|
||||
boolean lockAll = "Cancelled".equalsIgnoreCase(newVal)
|
||||
|| "Completed".equalsIgnoreCase(newVal)
|
||||
|| "Missed".equalsIgnoreCase(newVal);
|
||||
if (lockAll) {
|
||||
cbEmployee.setDisable(true);
|
||||
cbHour.setDisable(true);
|
||||
cbMinute.setDisable(true);
|
||||
dpAppointmentDate.setDisable(true);
|
||||
cbStore.setDisable(true);
|
||||
} else {
|
||||
if (!isOriginallyCancel && !isOriginallyCompletedOrMissed) {
|
||||
cbEmployee.setDisable(false);
|
||||
cbHour.setDisable(false);
|
||||
cbMinute.setDisable(false);
|
||||
dpAppointmentDate.setDisable(false);
|
||||
if (UserSession.getInstance().isAdmin()) cbStore.setDisable(false);
|
||||
}
|
||||
}
|
||||
});
|
||||
cbPet.setDisable(true);
|
||||
cbEmployee.setPromptText("Select an employee");
|
||||
cbPet.setPromptText("Select a customer first");
|
||||
cbCustomer.setPromptText("Select a customer");
|
||||
cbService.setPromptText("Select a service");
|
||||
LocalDate minDate = minAppointmentDate();
|
||||
dpAppointmentDate.setValue(minDate);
|
||||
LocalDate today = LocalDate.now();
|
||||
dpAppointmentDate.setValue(today);
|
||||
dpAppointmentDate.setDayCellFactory(picker -> new javafx.scene.control.DateCell() {
|
||||
@Override
|
||||
public void updateItem(LocalDate item, boolean empty) {
|
||||
super.updateItem(item, empty);
|
||||
setDisable(empty || item.isBefore(minDate));
|
||||
setDisable(empty || item.isBefore(today));
|
||||
}
|
||||
});
|
||||
cbAppointmentStatus.setValue("Booked");
|
||||
@@ -179,7 +203,7 @@ public class AppointmentDialogController {
|
||||
Long customerId = newValue != null ? newValue.getId() : null;
|
||||
cbPet.setValue(null);
|
||||
cbPet.setItems(FXCollections.observableArrayList());
|
||||
cbPet.setDisable(customerId == null);
|
||||
cbPet.setDisable(customerId == null || isOriginallyCancel || isOriginallyCompletedOrMissed);
|
||||
if (customerId != null) {
|
||||
cbPet.setPromptText("Loading customer pets...");
|
||||
loadCustomerPets(customerId);
|
||||
@@ -189,12 +213,36 @@ public class AppointmentDialogController {
|
||||
}
|
||||
});
|
||||
|
||||
cbStore.setCellFactory(param -> new ListCell<>() {
|
||||
@Override
|
||||
protected void updateItem(DropdownOption option, boolean empty) {
|
||||
super.updateItem(option, empty);
|
||||
setText(empty || option == null ? null : option.getLabel());
|
||||
}
|
||||
});
|
||||
cbStore.setButtonCell(new ListCell<>() {
|
||||
@Override
|
||||
protected void updateItem(DropdownOption option, boolean empty) {
|
||||
super.updateItem(option, empty);
|
||||
setText(empty || option == null ? null : option.getLabel());
|
||||
}
|
||||
});
|
||||
|
||||
if (UserSession.getInstance().isAdmin()) {
|
||||
vbStore.setVisible(true);
|
||||
vbStore.setManaged(true);
|
||||
}
|
||||
|
||||
btnSave.setOnMouseClicked(this::buttonSaveClicked);
|
||||
btnCancel.setOnMouseClicked(this::closeStage);
|
||||
|
||||
loadServices();
|
||||
loadAppointmentCustomers();
|
||||
loadEmployees();
|
||||
if (UserSession.getInstance().isAdmin()) {
|
||||
loadStores();
|
||||
} else {
|
||||
loadEmployees();
|
||||
}
|
||||
}
|
||||
|
||||
public void displayAppointmentDetails(AppointmentDTO appt) {
|
||||
@@ -202,6 +250,7 @@ public class AppointmentDialogController {
|
||||
selectedAppointment = appt;
|
||||
lblAppointmentId.setText("ID: " + appt.getAppointmentId());
|
||||
pendingPetSelectionId = appt.getPetId() > 0 ? (long) appt.getPetId() : null;
|
||||
pendingStoreId = appt.getStoreId();
|
||||
|
||||
try {
|
||||
dpAppointmentDate.setValue(
|
||||
@@ -248,6 +297,7 @@ public class AppointmentDialogController {
|
||||
dpAppointmentDate.setDisable(true);
|
||||
cbAppointmentStatus.setDisable(true);
|
||||
cbAppointmentStatus.setItems(FXCollections.observableArrayList("Cancelled"));
|
||||
cbStore.setDisable(true);
|
||||
btnSave.setDisable(true);
|
||||
} else if (isOriginallyCompletedOrMissed) {
|
||||
cbService.setDisable(true);
|
||||
@@ -257,6 +307,7 @@ public class AppointmentDialogController {
|
||||
cbHour.setDisable(true);
|
||||
cbMinute.setDisable(true);
|
||||
dpAppointmentDate.setDisable(true);
|
||||
cbStore.setDisable(true);
|
||||
cbAppointmentStatus.setDisable(false);
|
||||
cbAppointmentStatus.setItems(FXCollections.observableArrayList("Completed", "Missed"));
|
||||
} else {
|
||||
@@ -288,7 +339,16 @@ public class AppointmentDialogController {
|
||||
}
|
||||
|
||||
LocalTime appointmentTime = LocalTime.of(cbHour.getValue(), cbMinute.getValue());
|
||||
Long storeId = UserSession.getInstance().getStoreId();
|
||||
Long storeId;
|
||||
if (UserSession.getInstance().isAdmin()) {
|
||||
if (cbStore.getSelectionModel().getSelectedItem() == null) {
|
||||
showError("Store is required.");
|
||||
return;
|
||||
}
|
||||
storeId = cbStore.getSelectionModel().getSelectedItem().getId();
|
||||
} else {
|
||||
storeId = UserSession.getInstance().getStoreId();
|
||||
}
|
||||
if (storeId == null || storeId <= 0) {
|
||||
showError("Store is not set for this account");
|
||||
return;
|
||||
@@ -408,7 +468,7 @@ public class AppointmentDialogController {
|
||||
}
|
||||
}
|
||||
cbPet.setItems(petOptions);
|
||||
cbPet.setDisable(petOptions.isEmpty());
|
||||
cbPet.setDisable(petOptions.isEmpty() || isOriginallyCancel || isOriginallyCompletedOrMissed);
|
||||
cbPet.setPromptText(petOptions.isEmpty() ? "No pets for selected customer" : "Select a pet");
|
||||
if (pendingPetSelectionId != null) {
|
||||
for (DropdownOption pet : cbPet.getItems()) {
|
||||
@@ -462,7 +522,7 @@ public class AppointmentDialogController {
|
||||
Platform.runLater(() -> {
|
||||
cbCustomer.setItems(FXCollections.observableArrayList(customers));
|
||||
boolean hasCustomers = customers != null && !customers.isEmpty();
|
||||
cbCustomer.setDisable(!hasCustomers);
|
||||
cbCustomer.setDisable(!hasCustomers || isOriginallyCancel || isOriginallyCompletedOrMissed);
|
||||
cbPet.setDisable(true);
|
||||
cbPet.setItems(FXCollections.observableArrayList());
|
||||
cbCustomer.setPromptText(hasCustomers ? "Select a customer" : "No customers with pets yet");
|
||||
@@ -484,17 +544,61 @@ public class AppointmentDialogController {
|
||||
}).start();
|
||||
}
|
||||
|
||||
private LocalDate minAppointmentDate() {
|
||||
LocalDate date = LocalDate.now();
|
||||
int businessDaysAdded = 0;
|
||||
while (businessDaysAdded < 2) {
|
||||
date = date.plusDays(1);
|
||||
DayOfWeek dow = date.getDayOfWeek();
|
||||
if (dow != DayOfWeek.SATURDAY && dow != DayOfWeek.SUNDAY) {
|
||||
businessDaysAdded++;
|
||||
|
||||
private void loadStores() {
|
||||
new Thread(() -> {
|
||||
try {
|
||||
List<DropdownOption> stores = DropdownApi.getInstance().getStores();
|
||||
Platform.runLater(() -> {
|
||||
if (stores != null) {
|
||||
cbStore.setItems(FXCollections.observableArrayList(stores));
|
||||
cbStore.valueProperty().addListener((obs, oldVal, newVal) -> {
|
||||
Long sid = newVal != null ? newVal.getId() : null;
|
||||
cbEmployee.setValue(null);
|
||||
cbEmployee.setItems(FXCollections.observableArrayList());
|
||||
if (sid != null) {
|
||||
loadEmployeesForStore(sid);
|
||||
}
|
||||
});
|
||||
if (pendingStoreId != null) {
|
||||
for (DropdownOption store : cbStore.getItems()) {
|
||||
if (pendingStoreId.equals(store.getId())) {
|
||||
cbStore.setValue(store);
|
||||
break;
|
||||
}
|
||||
}
|
||||
pendingStoreId = null;
|
||||
}
|
||||
}
|
||||
});
|
||||
} catch (Exception e) {
|
||||
Platform.runLater(() -> ActivityLogger.getInstance().logException(
|
||||
"AppointmentDialogController.loadStores",
|
||||
e,
|
||||
"Loading stores for appointment dialog"));
|
||||
}
|
||||
}
|
||||
return date;
|
||||
}).start();
|
||||
}
|
||||
|
||||
private void loadEmployeesForStore(Long storeId) {
|
||||
new Thread(() -> {
|
||||
try {
|
||||
List<DropdownOption> employees = DropdownApi.getInstance().getStoreEmployees(storeId);
|
||||
Platform.runLater(() -> {
|
||||
cbEmployee.setItems(FXCollections.observableArrayList(employees));
|
||||
applySelectedEmployee();
|
||||
});
|
||||
} catch (Exception e) {
|
||||
Platform.runLater(() -> {
|
||||
ActivityLogger.getInstance().logException(
|
||||
"AppointmentDialogController.loadEmployeesForStore",
|
||||
e,
|
||||
"Loading employees for store");
|
||||
cbEmployee.setDisable(true);
|
||||
cbEmployee.setPromptText("Unable to load employees");
|
||||
});
|
||||
}
|
||||
}).start();
|
||||
}
|
||||
|
||||
private void loadEmployees() {
|
||||
|
||||
@@ -0,0 +1,175 @@
|
||||
package org.example.petshopdesktop.controllers.dialogcontrollers;
|
||||
|
||||
import javafx.application.Platform;
|
||||
import javafx.collections.FXCollections;
|
||||
import javafx.event.ActionEvent;
|
||||
import javafx.fxml.FXML;
|
||||
import javafx.scene.control.Button;
|
||||
import javafx.scene.control.ComboBox;
|
||||
import javafx.scene.control.Label;
|
||||
import javafx.scene.control.PasswordField;
|
||||
import javafx.scene.control.TextField;
|
||||
import javafx.stage.Stage;
|
||||
import org.example.petshopdesktop.Validator;
|
||||
import org.example.petshopdesktop.api.dto.user.UserRequest;
|
||||
import org.example.petshopdesktop.api.dto.user.UserResponse;
|
||||
import org.example.petshopdesktop.api.endpoints.CustomerApi;
|
||||
import org.example.petshopdesktop.auth.UserSession;
|
||||
import org.example.petshopdesktop.util.ActivityLogger;
|
||||
import org.example.petshopdesktop.util.TextFieldFormatSupport;
|
||||
|
||||
public class CustomerEditDialogController {
|
||||
|
||||
@FXML private TextField txtFirstName;
|
||||
@FXML private TextField txtLastName;
|
||||
@FXML private TextField txtEmail;
|
||||
@FXML private TextField txtPhone;
|
||||
@FXML private TextField txtUsername;
|
||||
@FXML private PasswordField txtPassword;
|
||||
@FXML private PasswordField txtPasswordConfirm;
|
||||
@FXML private ComboBox<String> cbActive;
|
||||
@FXML private TextField txtLoyaltyPoints;
|
||||
@FXML private Label lblError;
|
||||
@FXML private Button btnSave;
|
||||
|
||||
private UserResponse customer;
|
||||
|
||||
@FXML
|
||||
void initialize() {
|
||||
TextFieldFormatSupport.applyPhoneNumberFormat(txtPhone);
|
||||
cbActive.setItems(FXCollections.observableArrayList("Active", "Inactive"));
|
||||
|
||||
boolean isAdmin = UserSession.getInstance().isAdmin();
|
||||
txtLoyaltyPoints.setDisable(!isAdmin);
|
||||
}
|
||||
|
||||
public void setCustomer(UserResponse user) {
|
||||
this.customer = user;
|
||||
String fullName = user.getFullName() == null ? "" : user.getFullName();
|
||||
String[] names = splitFullName(fullName);
|
||||
txtFirstName.setText(names[0]);
|
||||
txtLastName.setText(names[1]);
|
||||
txtEmail.setText(user.getEmail());
|
||||
txtPhone.setText(user.getPhone());
|
||||
txtUsername.setText(user.getUsername());
|
||||
cbActive.setValue(Boolean.TRUE.equals(user.getActive()) ? "Active" : "Inactive");
|
||||
int pts = user.getLoyaltyPoints() != null ? user.getLoyaltyPoints() : 0;
|
||||
txtLoyaltyPoints.setText(String.valueOf(pts));
|
||||
}
|
||||
|
||||
private String[] splitFullName(String fullName) {
|
||||
if (fullName == null || fullName.trim().isEmpty()) return new String[]{"", ""};
|
||||
String[] parts = fullName.trim().split("\\s+", 2);
|
||||
return new String[]{parts.length > 0 ? parts[0] : "", parts.length > 1 ? parts[1] : ""};
|
||||
}
|
||||
|
||||
@FXML
|
||||
void btnSaveClicked(ActionEvent event) {
|
||||
lblError.setText("");
|
||||
if (customer == null) {
|
||||
lblError.setText("No customer selected.");
|
||||
return;
|
||||
}
|
||||
|
||||
String firstName = value(txtFirstName);
|
||||
String lastName = value(txtLastName);
|
||||
String email = value(txtEmail);
|
||||
String phone = value(txtPhone);
|
||||
String username = value(txtUsername);
|
||||
String password = txtPassword.getText() == null ? "" : txtPassword.getText().trim();
|
||||
String confirm = txtPasswordConfirm.getText() == null ? "" : txtPasswordConfirm.getText().trim();
|
||||
String loyaltyPointsText = value(txtLoyaltyPoints);
|
||||
|
||||
if (firstName.isBlank() || lastName.isBlank()) {
|
||||
lblError.setText("First name and last name are required.");
|
||||
return;
|
||||
}
|
||||
if (email.isBlank()) {
|
||||
lblError.setText("Email is required.");
|
||||
return;
|
||||
}
|
||||
if (phone.isBlank()) {
|
||||
lblError.setText("Phone is required.");
|
||||
return;
|
||||
}
|
||||
String phoneError = Validator.isValidPhoneNumber(phone, "Phone");
|
||||
if (!phoneError.isEmpty()) {
|
||||
lblError.setText(phoneError.trim());
|
||||
return;
|
||||
}
|
||||
if (username.isBlank()) {
|
||||
lblError.setText("Username is required.");
|
||||
return;
|
||||
}
|
||||
if (!password.isEmpty() && password.length() < 6) {
|
||||
lblError.setText("Password must be at least 6 characters.");
|
||||
return;
|
||||
}
|
||||
if (!password.equals(confirm)) {
|
||||
lblError.setText("Passwords do not match.");
|
||||
return;
|
||||
}
|
||||
|
||||
Integer loyaltyPoints = null;
|
||||
if (UserSession.getInstance().isAdmin()) {
|
||||
if (loyaltyPointsText.isBlank()) {
|
||||
lblError.setText("Loyalty points is required.");
|
||||
return;
|
||||
}
|
||||
try {
|
||||
loyaltyPoints = Integer.parseInt(loyaltyPointsText);
|
||||
if (loyaltyPoints < 0) {
|
||||
lblError.setText("Loyalty points cannot be negative.");
|
||||
return;
|
||||
}
|
||||
} catch (NumberFormatException e) {
|
||||
lblError.setText("Loyalty points must be a valid integer.");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
btnSave.setDisable(true);
|
||||
|
||||
boolean active = "Active".equals(cbActive.getValue());
|
||||
Integer finalLoyaltyPoints = loyaltyPoints;
|
||||
|
||||
new Thread(() -> {
|
||||
try {
|
||||
UserRequest request = new UserRequest();
|
||||
request.setUsername(username);
|
||||
request.setPassword(password.isEmpty() ? null : password);
|
||||
request.setFullName(firstName + " " + lastName);
|
||||
request.setEmail(email);
|
||||
request.setPhone(phone);
|
||||
request.setRole(customer.getRole());
|
||||
request.setActive(active);
|
||||
if (finalLoyaltyPoints != null) request.setLoyaltyPoints(finalLoyaltyPoints);
|
||||
|
||||
CustomerApi.getInstance().updateCustomer(customer.getId(), request);
|
||||
|
||||
Platform.runLater(this::close);
|
||||
} catch (Exception e) {
|
||||
ActivityLogger.getInstance().logException("CustomerEditDialogController.btnSaveClicked", e, "Updating customer");
|
||||
String msg = e.getMessage() == null ? "Could not update customer." : e.getMessage();
|
||||
Platform.runLater(() -> {
|
||||
lblError.setText(msg);
|
||||
btnSave.setDisable(false);
|
||||
});
|
||||
}
|
||||
}).start();
|
||||
}
|
||||
|
||||
@FXML
|
||||
void btnCancelClicked(ActionEvent event) {
|
||||
close();
|
||||
}
|
||||
|
||||
private void close() {
|
||||
Stage stage = (Stage) btnSave.getScene().getWindow();
|
||||
stage.close();
|
||||
}
|
||||
|
||||
private static String value(TextField tf) {
|
||||
return tf.getText() == null ? "" : tf.getText().trim();
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,6 @@
|
||||
package org.example.petshopdesktop.controllers.dialogcontrollers;
|
||||
|
||||
import javafx.application.Platform;
|
||||
import javafx.collections.FXCollections;
|
||||
import javafx.collections.ObservableList;
|
||||
import javafx.event.EventHandler;
|
||||
@@ -9,66 +10,65 @@ import javafx.scene.control.Alert;
|
||||
import javafx.scene.control.Button;
|
||||
import javafx.scene.control.ComboBox;
|
||||
import javafx.scene.control.Label;
|
||||
import javafx.scene.control.ListCell;
|
||||
import javafx.scene.control.TextField;
|
||||
import javafx.scene.input.MouseEvent;
|
||||
import javafx.scene.layout.VBox;
|
||||
import javafx.stage.Stage;
|
||||
import javafx.util.StringConverter;
|
||||
import org.example.petshopdesktop.models.Inventory;
|
||||
import org.example.petshopdesktop.Validator;
|
||||
import org.example.petshopdesktop.api.dto.common.DropdownOption;
|
||||
import org.example.petshopdesktop.api.dto.inventory.InventoryRequest;
|
||||
import org.example.petshopdesktop.api.dto.inventory.InventoryResponse;
|
||||
import org.example.petshopdesktop.api.dto.product.ProductResponse;
|
||||
import org.example.petshopdesktop.api.endpoints.DropdownApi;
|
||||
import org.example.petshopdesktop.api.endpoints.InventoryApi;
|
||||
import org.example.petshopdesktop.api.endpoints.ProductApi;
|
||||
import org.example.petshopdesktop.auth.UserSession;
|
||||
import org.example.petshopdesktop.models.Product;
|
||||
import org.example.petshopdesktop.util.ActivityLogger;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
public class InventoryDialogController {
|
||||
|
||||
//FXML elements
|
||||
@FXML
|
||||
private Button btnCancel;
|
||||
@FXML private Button btnCancel;
|
||||
@FXML private Button btnSave;
|
||||
@FXML private ComboBox<Product> cbProduct;
|
||||
@FXML private ComboBox<DropdownOption> cbStore;
|
||||
@FXML private VBox vbStoreField;
|
||||
@FXML private Label lblInventoryId;
|
||||
@FXML private Label lblMode;
|
||||
@FXML private TextField txtQuantity;
|
||||
|
||||
@FXML
|
||||
private Button btnSave;
|
||||
|
||||
@FXML
|
||||
private ComboBox<Product> cbProduct;
|
||||
|
||||
@FXML
|
||||
private Label lblInventoryId;
|
||||
|
||||
@FXML
|
||||
private Label lblMode;
|
||||
|
||||
@FXML
|
||||
private TextField txtQuantity;
|
||||
|
||||
//Determines if the mode is add or edit
|
||||
private String mode = null;
|
||||
private Long pendingStoreId = null;
|
||||
|
||||
//Loads upon .FXML boot
|
||||
@FXML
|
||||
void initialize() {
|
||||
cbProduct.setConverter(new StringConverter<Product>() {
|
||||
|
||||
//Displays product in combobox (prodID + name)
|
||||
@Override
|
||||
public String toString(Product product) {
|
||||
return product == null ? "" : product.getProdId() + ": " + product.getProdName();
|
||||
}
|
||||
|
||||
//Not needed
|
||||
@Override
|
||||
public Product fromString(String string) { return null; }
|
||||
});
|
||||
|
||||
//Load product list from API into combobox
|
||||
cbStore.setCellFactory(param -> new ListCell<>() {
|
||||
@Override protected void updateItem(DropdownOption o, boolean empty) {
|
||||
super.updateItem(o, empty);
|
||||
setText(empty || o == null ? null : o.getLabel());
|
||||
}
|
||||
});
|
||||
cbStore.setButtonCell(new ListCell<>() {
|
||||
@Override protected void updateItem(DropdownOption o, boolean empty) {
|
||||
super.updateItem(o, empty);
|
||||
setText(empty || o == null ? null : o.getLabel());
|
||||
}
|
||||
});
|
||||
|
||||
try {
|
||||
List<ProductResponse> productResponses = ProductApi.getInstance().listProducts(null);
|
||||
if (productResponses != null) {
|
||||
@@ -89,10 +89,16 @@ public class InventoryDialogController {
|
||||
"InventoryDialogController.initialize",
|
||||
e,
|
||||
"Loading products for combo box");
|
||||
System.out.println("Error loading products: " + e.getMessage());
|
||||
}
|
||||
|
||||
//Save button handler
|
||||
boolean isAdmin = UserSession.getInstance().isAdmin();
|
||||
if (isAdmin) {
|
||||
loadStores();
|
||||
} else {
|
||||
vbStoreField.setManaged(false);
|
||||
vbStoreField.setVisible(false);
|
||||
}
|
||||
|
||||
btnSave.setOnMouseClicked(new EventHandler<MouseEvent>() {
|
||||
@Override
|
||||
public void handle(MouseEvent mouseEvent) {
|
||||
@@ -100,7 +106,6 @@ public class InventoryDialogController {
|
||||
}
|
||||
});
|
||||
|
||||
//Cancel button handler
|
||||
btnCancel.setOnMouseClicked(new EventHandler<MouseEvent>() {
|
||||
@Override
|
||||
public void handle(MouseEvent mouseEvent) {
|
||||
@@ -109,29 +114,66 @@ public class InventoryDialogController {
|
||||
});
|
||||
}
|
||||
|
||||
//Handles save button click event
|
||||
private void loadStores() {
|
||||
new Thread(() -> {
|
||||
try {
|
||||
List<DropdownOption> stores = DropdownApi.getInstance().getStores();
|
||||
Platform.runLater(() -> {
|
||||
cbStore.setItems(FXCollections.observableArrayList(stores));
|
||||
applyPendingStore();
|
||||
});
|
||||
} catch (Exception e) {
|
||||
ActivityLogger.getInstance().logException("InventoryDialogController.loadStores", e, "Loading stores");
|
||||
Platform.runLater(() -> {
|
||||
cbStore.setDisable(true);
|
||||
cbStore.setPromptText("Unable to load stores");
|
||||
});
|
||||
}
|
||||
}).start();
|
||||
}
|
||||
|
||||
private void applyPendingStore() {
|
||||
if (pendingStoreId == null) return;
|
||||
for (DropdownOption opt : cbStore.getItems()) {
|
||||
if (opt.getId() != null && opt.getId().equals(pendingStoreId)) {
|
||||
cbStore.setValue(opt);
|
||||
pendingStoreId = null;
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void buttonSaveClicked(MouseEvent mouseEvent) {
|
||||
int numRow = 0;
|
||||
String errorMsg = "";
|
||||
|
||||
if (cbProduct.getSelectionModel().getSelectedItem() == null) {
|
||||
errorMsg += "Product is required.\n";
|
||||
}
|
||||
|
||||
//Validate inputs
|
||||
errorMsg += Validator.isPresent(txtQuantity.getText(), "Quantity");
|
||||
errorMsg += Validator.isLessThanVarChars(txtQuantity.getText(), "Quantity", 11);
|
||||
errorMsg += Validator.isPositiveInteger(txtQuantity.getText(), "Quantity");
|
||||
|
||||
//Operation only occurs if there are no errors
|
||||
boolean isAdmin = UserSession.getInstance().isAdmin();
|
||||
Long storeId;
|
||||
if (isAdmin) {
|
||||
if (cbStore.getValue() == null) {
|
||||
errorMsg += "Store is required.\n";
|
||||
storeId = null;
|
||||
} else {
|
||||
storeId = cbStore.getValue().getId();
|
||||
}
|
||||
} else {
|
||||
storeId = UserSession.getInstance().getStoreId();
|
||||
if (storeId == null || storeId <= 0) {
|
||||
errorMsg += "Store is not set for this account.\n";
|
||||
}
|
||||
}
|
||||
|
||||
if (errorMsg.isEmpty()) {
|
||||
try {
|
||||
InventoryRequest request = new InventoryRequest();
|
||||
Product selectedProduct = cbProduct.getSelectionModel().getSelectedItem();
|
||||
Long storeId = UserSession.getInstance().getStoreId();
|
||||
if (storeId == null || storeId <= 0) {
|
||||
throw new IllegalStateException("Store is not set for this account");
|
||||
}
|
||||
request.setProdId((long) selectedProduct.getProdId());
|
||||
int quantity;
|
||||
try {
|
||||
@@ -168,10 +210,7 @@ public class InventoryDialogController {
|
||||
alert.setContentText(e.getMessage());
|
||||
alert.showAndWait();
|
||||
}
|
||||
}
|
||||
|
||||
//Displays validation errors
|
||||
else {
|
||||
} else {
|
||||
Alert alert = new Alert(Alert.AlertType.ERROR);
|
||||
alert.setHeaderText("Input Error");
|
||||
alert.setContentText(errorMsg);
|
||||
@@ -179,22 +218,16 @@ public class InventoryDialogController {
|
||||
}
|
||||
}
|
||||
|
||||
//Close dialog view
|
||||
private void closeStage(MouseEvent mouseEvent) {
|
||||
Node node = (Node) mouseEvent.getSource();
|
||||
Stage stage = (Stage) node.getScene().getWindow();
|
||||
stage.close();
|
||||
}
|
||||
|
||||
//Editing
|
||||
//Displays fields with existing inventory data
|
||||
public void displayInventoryDetails(Inventory inventory) {
|
||||
if (inventory != null) {
|
||||
|
||||
//Displays inventory ID
|
||||
lblInventoryId.setText("ID: " + inventory.getInventoryId());
|
||||
|
||||
//Selecting matching product in combobox
|
||||
for (Product product : cbProduct.getItems()) {
|
||||
if (product.getProdId() == inventory.getProdId()) {
|
||||
cbProduct.getSelectionModel().select(product);
|
||||
@@ -203,10 +236,15 @@ public class InventoryDialogController {
|
||||
}
|
||||
|
||||
txtQuantity.setText(String.valueOf(inventory.getQuantity()));
|
||||
|
||||
boolean isAdmin = UserSession.getInstance().isAdmin();
|
||||
if (isAdmin && inventory.getStoreId() > 0) {
|
||||
pendingStoreId = (long) inventory.getStoreId();
|
||||
applyPendingStore();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//Sets dialog view to add/edit. Updates UI labels
|
||||
public void setMode(String mode) {
|
||||
this.mode = mode;
|
||||
lblMode.setText(mode + " Inventory");
|
||||
|
||||
@@ -1,84 +1,132 @@
|
||||
package org.example.petshopdesktop.controllers.dialogcontrollers;
|
||||
|
||||
import javafx.application.Platform;
|
||||
import javafx.collections.FXCollections;
|
||||
import javafx.event.ActionEvent;
|
||||
import javafx.fxml.FXML;
|
||||
import javafx.scene.control.Button;
|
||||
import javafx.scene.control.ComboBox;
|
||||
import javafx.scene.control.Label;
|
||||
import javafx.scene.control.ListCell;
|
||||
import javafx.scene.control.PasswordField;
|
||||
import javafx.scene.control.TextField;
|
||||
import javafx.stage.Stage;
|
||||
import org.example.petshopdesktop.Validator;
|
||||
import org.example.petshopdesktop.api.dto.user.UserRequest;
|
||||
import org.example.petshopdesktop.api.dto.user.UserResponse;
|
||||
import org.example.petshopdesktop.api.endpoints.UserApi;
|
||||
import org.example.petshopdesktop.api.endpoints.CustomerApi;
|
||||
import org.example.petshopdesktop.auth.UserSession;
|
||||
import org.example.petshopdesktop.api.dto.common.DropdownOption;
|
||||
import org.example.petshopdesktop.api.dto.employee.EmployeeRequest;
|
||||
import org.example.petshopdesktop.api.dto.employee.EmployeeResponse;
|
||||
import org.example.petshopdesktop.api.endpoints.DropdownApi;
|
||||
import org.example.petshopdesktop.api.endpoints.EmployeeApi;
|
||||
import org.example.petshopdesktop.util.ActivityLogger;
|
||||
import org.example.petshopdesktop.util.TextFieldFormatSupport;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class StaffEditDialogController {
|
||||
|
||||
@FXML
|
||||
private TextField txtFirstName;
|
||||
@FXML private TextField txtFirstName;
|
||||
@FXML private TextField txtLastName;
|
||||
@FXML private TextField txtEmail;
|
||||
@FXML private TextField txtPhone;
|
||||
@FXML private TextField txtUsername;
|
||||
@FXML private PasswordField txtPassword;
|
||||
@FXML private PasswordField txtPasswordConfirm;
|
||||
@FXML private ComboBox<String> cbRole;
|
||||
@FXML private ComboBox<String> cbStaffRole;
|
||||
@FXML private ComboBox<String> cbActive;
|
||||
@FXML private ComboBox<DropdownOption> cbStore;
|
||||
@FXML private Label lblError;
|
||||
@FXML private Button btnSave;
|
||||
|
||||
@FXML
|
||||
private TextField txtLastName;
|
||||
|
||||
@FXML
|
||||
private TextField txtEmail;
|
||||
|
||||
@FXML
|
||||
private TextField txtPhone;
|
||||
|
||||
@FXML
|
||||
private TextField txtUsername;
|
||||
|
||||
@FXML
|
||||
private PasswordField txtPassword;
|
||||
|
||||
@FXML
|
||||
private PasswordField txtPasswordConfirm;
|
||||
|
||||
@FXML
|
||||
private Label lblError;
|
||||
|
||||
@FXML
|
||||
private Button btnSave;
|
||||
|
||||
private UserResponse user;
|
||||
private EmployeeResponse employee;
|
||||
private Long pendingStoreId = null;
|
||||
|
||||
@FXML
|
||||
void initialize() {
|
||||
TextFieldFormatSupport.applyPhoneNumberFormat(txtPhone);
|
||||
|
||||
cbRole.setItems(FXCollections.observableArrayList("STAFF", "ADMIN"));
|
||||
cbStaffRole.setItems(FXCollections.observableArrayList(
|
||||
"STORE_MANAGER", "SALES_ASSOCIATE", "GROOMER", "VETERINARIAN"));
|
||||
cbActive.setItems(FXCollections.observableArrayList("Active", "Inactive"));
|
||||
|
||||
cbStore.setCellFactory(param -> new ListCell<>() {
|
||||
@Override protected void updateItem(DropdownOption o, boolean empty) {
|
||||
super.updateItem(o, empty);
|
||||
setText(empty || o == null ? null : o.getLabel());
|
||||
}
|
||||
});
|
||||
cbStore.setButtonCell(new ListCell<>() {
|
||||
@Override protected void updateItem(DropdownOption o, boolean empty) {
|
||||
super.updateItem(o, empty);
|
||||
setText(empty || o == null ? null : o.getLabel());
|
||||
}
|
||||
});
|
||||
|
||||
loadStores();
|
||||
}
|
||||
|
||||
public void setUser(UserResponse user) {
|
||||
this.user = user;
|
||||
String fullName = user.getFullName() == null ? "" : user.getFullName();
|
||||
private void loadStores() {
|
||||
new Thread(() -> {
|
||||
try {
|
||||
List<DropdownOption> stores = DropdownApi.getInstance().getStores();
|
||||
Platform.runLater(() -> {
|
||||
cbStore.setItems(FXCollections.observableArrayList(stores));
|
||||
applyPendingStore();
|
||||
});
|
||||
} catch (Exception e) {
|
||||
ActivityLogger.getInstance().logException("StaffEditDialogController.loadStores", e, "Loading stores");
|
||||
Platform.runLater(() -> {
|
||||
cbStore.setDisable(true);
|
||||
cbStore.setPromptText("Unable to load stores");
|
||||
});
|
||||
}
|
||||
}).start();
|
||||
}
|
||||
|
||||
private void applyPendingStore() {
|
||||
if (pendingStoreId == null) return;
|
||||
for (DropdownOption opt : cbStore.getItems()) {
|
||||
if (opt.getId() != null && opt.getId().equals(pendingStoreId)) {
|
||||
cbStore.setValue(opt);
|
||||
pendingStoreId = null;
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void setEmployee(EmployeeResponse emp) {
|
||||
this.employee = emp;
|
||||
String fullName = emp.getFullName() != null ? emp.getFullName() : "";
|
||||
if (fullName.isEmpty() && emp.getFirstName() != null) {
|
||||
fullName = emp.getFirstName() + (emp.getLastName() != null ? " " + emp.getLastName() : "");
|
||||
}
|
||||
String[] names = splitFullName(fullName);
|
||||
txtFirstName.setText(names[0]);
|
||||
txtLastName.setText(names[1]);
|
||||
txtEmail.setText(user.getEmail());
|
||||
txtPhone.setText(user.getPhone());
|
||||
txtUsername.setText(user.getUsername());
|
||||
txtEmail.setText(emp.getEmail());
|
||||
txtPhone.setText(emp.getPhone());
|
||||
txtUsername.setText(emp.getUsername());
|
||||
|
||||
if (emp.getRole() != null) cbRole.setValue(emp.getRole());
|
||||
if (emp.getStaffRole() != null) cbStaffRole.setValue(emp.getStaffRole());
|
||||
cbActive.setValue(Boolean.TRUE.equals(emp.getActive()) ? "Active" : "Inactive");
|
||||
|
||||
pendingStoreId = emp.getPrimaryStoreId();
|
||||
applyPendingStore();
|
||||
}
|
||||
|
||||
private String[] splitFullName(String fullName) {
|
||||
if (fullName == null || fullName.trim().isEmpty()) {
|
||||
return new String[]{"", ""};
|
||||
}
|
||||
if (fullName == null || fullName.trim().isEmpty()) return new String[]{"", ""};
|
||||
String[] parts = fullName.trim().split("\\s+", 2);
|
||||
String firstName = parts.length > 0 ? parts[0] : "";
|
||||
String lastName = parts.length > 1 ? parts[1] : "";
|
||||
return new String[]{firstName, lastName};
|
||||
return new String[]{parts.length > 0 ? parts[0] : "", parts.length > 1 ? parts[1] : ""};
|
||||
}
|
||||
|
||||
@FXML
|
||||
void btnSaveClicked(ActionEvent event) {
|
||||
lblError.setText("");
|
||||
if (user == null) {
|
||||
lblError.setText("No user selected.");
|
||||
if (employee == null) {
|
||||
lblError.setText("No employee selected.");
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -119,31 +167,47 @@ public class StaffEditDialogController {
|
||||
lblError.setText("Passwords do not match.");
|
||||
return;
|
||||
}
|
||||
if (cbRole.getValue() == null) {
|
||||
lblError.setText("Role is required.");
|
||||
return;
|
||||
}
|
||||
if (cbStaffRole.getValue() == null) {
|
||||
lblError.setText("Staff role is required.");
|
||||
return;
|
||||
}
|
||||
if (cbStore.getValue() == null) {
|
||||
lblError.setText("Primary store is required.");
|
||||
return;
|
||||
}
|
||||
|
||||
btnSave.setDisable(true);
|
||||
|
||||
String role = cbRole.getValue();
|
||||
String staffRole = cbStaffRole.getValue();
|
||||
boolean active = "Active".equals(cbActive.getValue());
|
||||
Long storeId = cbStore.getValue().getId();
|
||||
|
||||
new Thread(() -> {
|
||||
try {
|
||||
UserRequest request = new UserRequest();
|
||||
EmployeeRequest request = new EmployeeRequest();
|
||||
request.setUsername(username);
|
||||
request.setPassword(password.isEmpty() ? null : password);
|
||||
request.setFirstName(firstName);
|
||||
request.setLastName(lastName);
|
||||
request.setFullName(firstName + " " + lastName);
|
||||
request.setEmail(email);
|
||||
request.setPhone(phone);
|
||||
request.setRole(user.getRole());
|
||||
request.setActive(user.getActive());
|
||||
request.setRole(role);
|
||||
request.setStaffRole(staffRole);
|
||||
request.setActive(active);
|
||||
request.setPrimaryStoreId(storeId);
|
||||
|
||||
UserSession session = UserSession.getInstance();
|
||||
if (session.isAdmin()) {
|
||||
UserApi.getInstance().updateUser(user.getId(), request);
|
||||
} else {
|
||||
CustomerApi.getInstance().updateCustomer(user.getId(), request);
|
||||
}
|
||||
EmployeeApi.getInstance().updateEmployee(employee.getId(), request);
|
||||
|
||||
Platform.runLater(this::close);
|
||||
} catch (Exception e) {
|
||||
ActivityLogger.getInstance().logException("StaffEditDialogController.btnSaveClicked", e, "Updating user");
|
||||
String msg = e.getMessage() == null ? "Could not update user." : e.getMessage();
|
||||
ActivityLogger.getInstance().logException("StaffEditDialogController.btnSaveClicked", e, "Updating employee");
|
||||
String msg = e.getMessage() == null ? "Could not update employee." : e.getMessage();
|
||||
Platform.runLater(() -> {
|
||||
lblError.setText(msg);
|
||||
btnSave.setDisable(false);
|
||||
|
||||
@@ -1,54 +1,86 @@
|
||||
package org.example.petshopdesktop.controllers.dialogcontrollers;
|
||||
|
||||
import javafx.application.Platform;
|
||||
import javafx.collections.FXCollections;
|
||||
import javafx.event.ActionEvent;
|
||||
import javafx.fxml.FXML;
|
||||
import javafx.scene.control.Alert;
|
||||
import javafx.scene.control.Button;
|
||||
import javafx.scene.control.ComboBox;
|
||||
import javafx.scene.control.Label;
|
||||
import javafx.scene.control.ListCell;
|
||||
import javafx.scene.control.PasswordField;
|
||||
import javafx.scene.control.TextField;
|
||||
import javafx.stage.Stage;
|
||||
import org.example.petshopdesktop.api.dto.user.UserRequest;
|
||||
import org.example.petshopdesktop.api.endpoints.UserApi;
|
||||
import org.example.petshopdesktop.api.endpoints.CustomerApi;
|
||||
import org.example.petshopdesktop.auth.UserSession;
|
||||
import org.example.petshopdesktop.Validator;
|
||||
import org.example.petshopdesktop.api.dto.common.DropdownOption;
|
||||
import org.example.petshopdesktop.api.dto.employee.EmployeeRequest;
|
||||
import org.example.petshopdesktop.api.endpoints.DropdownApi;
|
||||
import org.example.petshopdesktop.api.endpoints.EmployeeApi;
|
||||
import org.example.petshopdesktop.util.ActivityLogger;
|
||||
import org.example.petshopdesktop.util.TextFieldFormatSupport;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class StaffRegisterDialogController {
|
||||
|
||||
@FXML
|
||||
private TextField txtFirstName;
|
||||
|
||||
@FXML
|
||||
private TextField txtLastName;
|
||||
|
||||
@FXML
|
||||
private TextField txtEmail;
|
||||
|
||||
@FXML
|
||||
private TextField txtPhone;
|
||||
|
||||
@FXML
|
||||
private TextField txtUsername;
|
||||
|
||||
@FXML
|
||||
private PasswordField txtPassword;
|
||||
|
||||
@FXML
|
||||
private PasswordField txtPasswordConfirm;
|
||||
|
||||
@FXML
|
||||
private Label lblError;
|
||||
|
||||
@FXML
|
||||
private Button btnCreate;
|
||||
@FXML private TextField txtFirstName;
|
||||
@FXML private TextField txtLastName;
|
||||
@FXML private TextField txtEmail;
|
||||
@FXML private TextField txtPhone;
|
||||
@FXML private TextField txtUsername;
|
||||
@FXML private PasswordField txtPassword;
|
||||
@FXML private PasswordField txtPasswordConfirm;
|
||||
@FXML private ComboBox<String> cbRole;
|
||||
@FXML private ComboBox<String> cbStaffRole;
|
||||
@FXML private ComboBox<String> cbActive;
|
||||
@FXML private ComboBox<DropdownOption> cbStore;
|
||||
@FXML private Label lblError;
|
||||
@FXML private Button btnCreate;
|
||||
|
||||
@FXML
|
||||
void initialize() {
|
||||
TextFieldFormatSupport.applyPhoneNumberFormat(txtPhone);
|
||||
|
||||
cbRole.setItems(FXCollections.observableArrayList("STAFF", "ADMIN"));
|
||||
cbRole.getSelectionModel().select("STAFF");
|
||||
|
||||
cbStaffRole.setItems(FXCollections.observableArrayList(
|
||||
"STORE_MANAGER", "SALES_ASSOCIATE", "GROOMER", "VETERINARIAN"));
|
||||
cbStaffRole.getSelectionModel().selectFirst();
|
||||
|
||||
cbActive.setItems(FXCollections.observableArrayList("Active", "Inactive"));
|
||||
cbActive.getSelectionModel().select("Active");
|
||||
|
||||
cbStore.setCellFactory(param -> new ListCell<>() {
|
||||
@Override protected void updateItem(DropdownOption o, boolean empty) {
|
||||
super.updateItem(o, empty);
|
||||
setText(empty || o == null ? null : o.getLabel());
|
||||
}
|
||||
});
|
||||
cbStore.setButtonCell(new ListCell<>() {
|
||||
@Override protected void updateItem(DropdownOption o, boolean empty) {
|
||||
super.updateItem(o, empty);
|
||||
setText(empty || o == null ? null : o.getLabel());
|
||||
}
|
||||
});
|
||||
|
||||
loadStores();
|
||||
}
|
||||
|
||||
private void loadStores() {
|
||||
new Thread(() -> {
|
||||
try {
|
||||
List<DropdownOption> stores = DropdownApi.getInstance().getStores();
|
||||
Platform.runLater(() -> cbStore.setItems(FXCollections.observableArrayList(stores)));
|
||||
} catch (Exception e) {
|
||||
ActivityLogger.getInstance().logException("StaffRegisterDialogController.loadStores", e, "Loading stores");
|
||||
Platform.runLater(() -> {
|
||||
cbStore.setDisable(true);
|
||||
cbStore.setPromptText("Unable to load stores");
|
||||
});
|
||||
}
|
||||
}).start();
|
||||
}
|
||||
|
||||
@FXML
|
||||
@@ -96,38 +128,53 @@ public class StaffRegisterDialogController {
|
||||
lblError.setText("Passwords do not match.");
|
||||
return;
|
||||
}
|
||||
if (cbRole.getValue() == null) {
|
||||
lblError.setText("Role is required.");
|
||||
return;
|
||||
}
|
||||
if (cbStaffRole.getValue() == null) {
|
||||
lblError.setText("Staff role is required.");
|
||||
return;
|
||||
}
|
||||
if (cbStore.getValue() == null) {
|
||||
lblError.setText("Primary store is required.");
|
||||
return;
|
||||
}
|
||||
|
||||
btnCreate.setDisable(true);
|
||||
|
||||
String role = cbRole.getValue();
|
||||
String staffRole = cbStaffRole.getValue();
|
||||
boolean active = "Active".equals(cbActive.getValue());
|
||||
Long storeId = cbStore.getValue().getId();
|
||||
|
||||
new Thread(() -> {
|
||||
try {
|
||||
UserSession session = UserSession.getInstance();
|
||||
UserRequest request = new UserRequest();
|
||||
EmployeeRequest request = new EmployeeRequest();
|
||||
request.setUsername(username);
|
||||
request.setPassword(password);
|
||||
request.setFirstName(firstName);
|
||||
request.setLastName(lastName);
|
||||
request.setFullName(firstName + " " + lastName);
|
||||
request.setEmail(email);
|
||||
request.setPhone(phone);
|
||||
request.setActive(true);
|
||||
request.setRole(role);
|
||||
request.setStaffRole(staffRole);
|
||||
request.setActive(active);
|
||||
request.setPrimaryStoreId(storeId);
|
||||
|
||||
if (session.isAdmin()) {
|
||||
request.setRole("STAFF");
|
||||
UserApi.getInstance().createUser(request);
|
||||
} else {
|
||||
request.setRole("CUSTOMER");
|
||||
CustomerApi.getInstance().createCustomer(request);
|
||||
}
|
||||
EmployeeApi.getInstance().createEmployee(request);
|
||||
|
||||
Platform.runLater(() -> {
|
||||
Alert alert = new Alert(Alert.AlertType.INFORMATION);
|
||||
alert.setTitle("Account Created");
|
||||
alert.setHeaderText(null);
|
||||
alert.setContentText("Account created successfully.");
|
||||
alert.setContentText("Staff account created successfully.");
|
||||
alert.showAndWait();
|
||||
close();
|
||||
});
|
||||
} catch (Exception e) {
|
||||
ActivityLogger.getInstance().logException("StaffRegisterDialogController.btnCreateClicked", e, "Creating account");
|
||||
ActivityLogger.getInstance().logException("StaffRegisterDialogController.btnCreateClicked", e, "Creating staff account");
|
||||
String msg = e.getMessage() == null ? "Could not create account." : e.getMessage();
|
||||
Platform.runLater(() -> {
|
||||
if (msg.toLowerCase().contains("duplicate") || msg.toLowerCase().contains("unique")) {
|
||||
|
||||
@@ -16,8 +16,9 @@ public class Adoption {
|
||||
private SimpleDoubleProperty adoptionFee;
|
||||
private SimpleStringProperty adoptionStatus;
|
||||
private SimpleStringProperty storeName;
|
||||
private Long storeId;
|
||||
|
||||
public Adoption(int adoptionId, int petId, int customerId, int employeeId, String petName, String customerName, String employeeName, String adoptionDate, double adoptionFee, String adoptionStatus, String storeName) {
|
||||
public Adoption(int adoptionId, int petId, int customerId, int employeeId, String petName, String customerName, String employeeName, String adoptionDate, double adoptionFee, String adoptionStatus, String storeName, Long storeId) {
|
||||
this.adoptionId = new SimpleIntegerProperty(adoptionId);
|
||||
this.petId = new SimpleIntegerProperty(petId);
|
||||
this.customerId = new SimpleIntegerProperty(customerId);
|
||||
@@ -29,6 +30,7 @@ public class Adoption {
|
||||
this.adoptionFee = new SimpleDoubleProperty(adoptionFee);
|
||||
this.adoptionStatus = new SimpleStringProperty(adoptionStatus);
|
||||
this.storeName = new SimpleStringProperty(storeName != null ? storeName : "");
|
||||
this.storeId = storeId;
|
||||
}
|
||||
|
||||
public int getAdoptionId() { return adoptionId.get(); }
|
||||
@@ -96,4 +98,8 @@ public class Adoption {
|
||||
public void setStoreName(String storeName) { this.storeName.set(storeName); }
|
||||
|
||||
public SimpleStringProperty storeNameProperty() { return storeName; }
|
||||
|
||||
public Long getStoreId() { return storeId; }
|
||||
|
||||
public void setStoreId(Long storeId) { this.storeId = storeId; }
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user