Fix null pointers and unsafe parsing bugs

This commit is contained in:
2026-03-08 10:05:09 -06:00
parent aa011205a0
commit 59de8ae1aa
21 changed files with 328 additions and 80 deletions

View File

@@ -44,6 +44,28 @@ public class ApiClient {
return handleResponse(response, responseClass);
}
public String getRawResponse(String path) throws Exception {
HttpRequest.Builder builder = HttpRequest.newBuilder()
.uri(URI.create(baseUrl + path))
.GET()
.timeout(Duration.ofSeconds(30));
addAuthHeader(builder);
HttpRequest request = builder.build();
HttpResponse<String> response = httpClient.send(request, HttpResponse.BodyHandlers.ofString());
if (response.statusCode() == 200 || response.statusCode() == 201) {
return response.body();
} else if (response.statusCode() == 401) {
throw new RuntimeException("Authentication failed. Please log in again.");
} else if (response.statusCode() == 403) {
throw new RuntimeException("Access restricted. You don't have permission to perform this action.");
} else {
throw new RuntimeException(parseErrorMessage(response));
}
}
public <T> T post(String path, Object requestBody, Class<T> responseClass) throws Exception {
String jsonBody = objectMapper.writeValueAsString(requestBody);
@@ -155,6 +177,7 @@ public class ApiClient {
}
}
} catch (Exception e) {
System.err.println("Error parsing error message: " + e.getMessage());
}
return "Request failed with status " + response.statusCode();
}

View File

@@ -5,7 +5,10 @@ import org.example.petshopdesktop.api.ApiClient;
import org.example.petshopdesktop.api.dto.adoption.AdoptionRequest;
import org.example.petshopdesktop.api.dto.adoption.AdoptionResponse;
import org.example.petshopdesktop.api.dto.common.BulkDeleteRequest;
import org.example.petshopdesktop.api.dto.common.PageResponse;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
import java.util.List;
public class AdoptionApi {
@@ -23,10 +26,17 @@ public class AdoptionApi {
public List<AdoptionResponse> listAdoptions(String query) throws Exception {
String path = "/api/v1/adoptions?page=0&size=1000";
if (query != null && !query.isEmpty()) {
path += "&q=" + query;
path += "&q=" + URLEncoder.encode(query, StandardCharsets.UTF_8);
}
String response = apiClient.get(path, String.class);
return apiClient.getObjectMapper().readValue(response, new TypeReference<List<AdoptionResponse>>() {});
String response = apiClient.getRawResponse(path);
PageResponse<AdoptionResponse> pageResponse = apiClient.getObjectMapper().readValue(
response,
new TypeReference<PageResponse<AdoptionResponse>>() {}
);
if (pageResponse == null) {
throw new IllegalStateException("Null response from adoptions endpoint");
}
return pageResponse.getContent();
}
public AdoptionResponse createAdoption(AdoptionRequest request) throws Exception {

View File

@@ -5,7 +5,10 @@ import org.example.petshopdesktop.api.ApiClient;
import org.example.petshopdesktop.api.dto.appointment.AppointmentRequest;
import org.example.petshopdesktop.api.dto.appointment.AppointmentResponse;
import org.example.petshopdesktop.api.dto.common.BulkDeleteRequest;
import org.example.petshopdesktop.api.dto.common.PageResponse;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
import java.util.List;
public class AppointmentApi {
@@ -23,10 +26,17 @@ public class AppointmentApi {
public List<AppointmentResponse> listAppointments(String query) throws Exception {
String path = "/api/v1/appointments?page=0&size=1000";
if (query != null && !query.isEmpty()) {
path += "&q=" + query;
path += "&q=" + URLEncoder.encode(query, StandardCharsets.UTF_8);
}
String response = apiClient.get(path, String.class);
return apiClient.getObjectMapper().readValue(response, new TypeReference<List<AppointmentResponse>>() {});
String response = apiClient.getRawResponse(path);
PageResponse<AppointmentResponse> pageResponse = apiClient.getObjectMapper().readValue(
response,
new TypeReference<PageResponse<AppointmentResponse>>() {}
);
if (pageResponse == null) {
throw new IllegalStateException("Null response from appointments endpoint");
}
return pageResponse.getContent();
}
public AppointmentResponse createAppointment(AppointmentRequest request) throws Exception {

View File

@@ -19,37 +19,58 @@ public class DropdownApi {
}
public List<DropdownOption> getCategories() throws Exception {
String response = apiClient.get("/api/v1/dropdowns/categories", String.class);
String response = apiClient.getRawResponse("/api/v1/dropdowns/categories");
if (response == null || response.isEmpty()) {
throw new IllegalStateException("Empty response from categories endpoint");
}
return apiClient.getObjectMapper().readValue(response, new TypeReference<List<DropdownOption>>() {});
}
public List<DropdownOption> getProducts() throws Exception {
String response = apiClient.get("/api/v1/dropdowns/products", String.class);
String response = apiClient.getRawResponse("/api/v1/dropdowns/products");
if (response == null || response.isEmpty()) {
throw new IllegalStateException("Empty response from products endpoint");
}
return apiClient.getObjectMapper().readValue(response, new TypeReference<List<DropdownOption>>() {});
}
public List<DropdownOption> getSuppliers() throws Exception {
String response = apiClient.get("/api/v1/dropdowns/suppliers", String.class);
String response = apiClient.getRawResponse("/api/v1/dropdowns/suppliers");
if (response == null || response.isEmpty()) {
throw new IllegalStateException("Empty response from suppliers endpoint");
}
return apiClient.getObjectMapper().readValue(response, new TypeReference<List<DropdownOption>>() {});
}
public List<DropdownOption> getServices() throws Exception {
String response = apiClient.get("/api/v1/dropdowns/services", String.class);
String response = apiClient.getRawResponse("/api/v1/dropdowns/services");
if (response == null || response.isEmpty()) {
throw new IllegalStateException("Empty response from services endpoint");
}
return apiClient.getObjectMapper().readValue(response, new TypeReference<List<DropdownOption>>() {});
}
public List<DropdownOption> getCustomers() throws Exception {
String response = apiClient.get("/api/v1/dropdowns/customers", String.class);
String response = apiClient.getRawResponse("/api/v1/dropdowns/customers");
if (response == null || response.isEmpty()) {
throw new IllegalStateException("Empty response from customers endpoint");
}
return apiClient.getObjectMapper().readValue(response, new TypeReference<List<DropdownOption>>() {});
}
public List<DropdownOption> getPets() throws Exception {
String response = apiClient.get("/api/v1/dropdowns/pets", String.class);
String response = apiClient.getRawResponse("/api/v1/dropdowns/pets");
if (response == null || response.isEmpty()) {
throw new IllegalStateException("Empty response from pets endpoint");
}
return apiClient.getObjectMapper().readValue(response, new TypeReference<List<DropdownOption>>() {});
}
public List<DropdownOption> getStores() throws Exception {
String response = apiClient.get("/api/v1/dropdowns/stores", String.class);
String response = apiClient.getRawResponse("/api/v1/dropdowns/stores");
if (response == null || response.isEmpty()) {
throw new IllegalStateException("Empty response from stores endpoint");
}
return apiClient.getObjectMapper().readValue(response, new TypeReference<List<DropdownOption>>() {});
}
}

View File

@@ -2,9 +2,12 @@ package org.example.petshopdesktop.api.endpoints;
import com.fasterxml.jackson.core.type.TypeReference;
import org.example.petshopdesktop.api.ApiClient;
import org.example.petshopdesktop.api.dto.common.PageResponse;
import org.example.petshopdesktop.api.dto.inventory.InventoryRequest;
import org.example.petshopdesktop.api.dto.inventory.InventoryResponse;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
import java.util.List;
public class InventoryApi {
@@ -22,10 +25,17 @@ public class InventoryApi {
public List<InventoryResponse> listInventory(String query) throws Exception {
String path = "/api/v1/inventory?page=0&size=1000";
if (query != null && !query.isEmpty()) {
path += "&q=" + query;
path += "&q=" + URLEncoder.encode(query, StandardCharsets.UTF_8);
}
String response = apiClient.get(path, String.class);
return apiClient.getObjectMapper().readValue(response, new TypeReference<List<InventoryResponse>>() {});
String response = apiClient.getRawResponse(path);
PageResponse<InventoryResponse> pageResponse = apiClient.getObjectMapper().readValue(
response,
new TypeReference<PageResponse<InventoryResponse>>() {}
);
if (pageResponse == null) {
throw new IllegalStateException("Null response from inventory endpoint");
}
return pageResponse.getContent();
}
public InventoryResponse createInventory(InventoryRequest request) throws Exception {

View File

@@ -3,9 +3,12 @@ package org.example.petshopdesktop.api.endpoints;
import com.fasterxml.jackson.core.type.TypeReference;
import org.example.petshopdesktop.api.ApiClient;
import org.example.petshopdesktop.api.dto.common.BulkDeleteRequest;
import org.example.petshopdesktop.api.dto.common.PageResponse;
import org.example.petshopdesktop.api.dto.pet.PetRequest;
import org.example.petshopdesktop.api.dto.pet.PetResponse;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
import java.util.List;
public class PetApi {
@@ -23,10 +26,17 @@ public class PetApi {
public List<PetResponse> listPets(String query) throws Exception {
String path = "/api/v1/pets?page=0&size=1000";
if (query != null && !query.isEmpty()) {
path += "&q=" + query;
path += "&q=" + URLEncoder.encode(query, StandardCharsets.UTF_8);
}
String response = apiClient.get(path, String.class);
return apiClient.getObjectMapper().readValue(response, new TypeReference<List<PetResponse>>() {});
String response = apiClient.getRawResponse(path);
PageResponse<PetResponse> pageResponse = apiClient.getObjectMapper().readValue(
response,
new TypeReference<PageResponse<PetResponse>>() {}
);
if (pageResponse == null) {
throw new IllegalStateException("Null response from pets endpoint");
}
return pageResponse.getContent();
}
public PetResponse createPet(PetRequest request) throws Exception {

View File

@@ -3,9 +3,12 @@ package org.example.petshopdesktop.api.endpoints;
import com.fasterxml.jackson.core.type.TypeReference;
import org.example.petshopdesktop.api.ApiClient;
import org.example.petshopdesktop.api.dto.common.BulkDeleteRequest;
import org.example.petshopdesktop.api.dto.common.PageResponse;
import org.example.petshopdesktop.api.dto.product.ProductRequest;
import org.example.petshopdesktop.api.dto.product.ProductResponse;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
import java.util.List;
public class ProductApi {
@@ -23,10 +26,17 @@ public class ProductApi {
public List<ProductResponse> listProducts(String query) throws Exception {
String path = "/api/v1/products?page=0&size=1000";
if (query != null && !query.isEmpty()) {
path += "&q=" + query;
path += "&q=" + URLEncoder.encode(query, StandardCharsets.UTF_8);
}
String response = apiClient.get(path, String.class);
return apiClient.getObjectMapper().readValue(response, new TypeReference<List<ProductResponse>>() {});
String response = apiClient.getRawResponse(path);
PageResponse<ProductResponse> pageResponse = apiClient.getObjectMapper().readValue(
response,
new TypeReference<PageResponse<ProductResponse>>() {}
);
if (pageResponse == null) {
throw new IllegalStateException("Null response from products endpoint");
}
return pageResponse.getContent();
}
public ProductResponse createProduct(ProductRequest request) throws Exception {

View File

@@ -3,9 +3,12 @@ package org.example.petshopdesktop.api.endpoints;
import com.fasterxml.jackson.core.type.TypeReference;
import org.example.petshopdesktop.api.ApiClient;
import org.example.petshopdesktop.api.dto.common.BulkDeleteRequest;
import org.example.petshopdesktop.api.dto.common.PageResponse;
import org.example.petshopdesktop.api.dto.productsupplier.ProductSupplierRequest;
import org.example.petshopdesktop.api.dto.productsupplier.ProductSupplierResponse;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
import java.util.List;
public class ProductSupplierApi {
@@ -23,10 +26,17 @@ public class ProductSupplierApi {
public List<ProductSupplierResponse> listProductSuppliers(String query) throws Exception {
String path = "/api/v1/product-suppliers?page=0&size=1000";
if (query != null && !query.isEmpty()) {
path += "&q=" + query;
path += "&q=" + URLEncoder.encode(query, StandardCharsets.UTF_8);
}
String response = apiClient.get(path, String.class);
return apiClient.getObjectMapper().readValue(response, new TypeReference<List<ProductSupplierResponse>>() {});
String response = apiClient.getRawResponse(path);
PageResponse<ProductSupplierResponse> pageResponse = apiClient.getObjectMapper().readValue(
response,
new TypeReference<PageResponse<ProductSupplierResponse>>() {}
);
if (pageResponse == null) {
throw new IllegalStateException("Null response from product-suppliers endpoint");
}
return pageResponse.getContent();
}
public ProductSupplierResponse createProductSupplier(ProductSupplierRequest request) throws Exception {

View File

@@ -2,8 +2,11 @@ package org.example.petshopdesktop.api.endpoints;
import com.fasterxml.jackson.core.type.TypeReference;
import org.example.petshopdesktop.api.ApiClient;
import org.example.petshopdesktop.api.dto.common.PageResponse;
import org.example.petshopdesktop.api.dto.purchaseorder.PurchaseOrderResponse;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
import java.util.List;
public class PurchaseOrderApi {
@@ -21,9 +24,16 @@ public class PurchaseOrderApi {
public List<PurchaseOrderResponse> listPurchaseOrders(String query) throws Exception {
String path = "/api/v1/purchase-orders?page=0&size=1000";
if (query != null && !query.isEmpty()) {
path += "&q=" + query;
path += "&q=" + URLEncoder.encode(query, StandardCharsets.UTF_8);
}
String response = apiClient.get(path, String.class);
return apiClient.getObjectMapper().readValue(response, new TypeReference<List<PurchaseOrderResponse>>() {});
String response = apiClient.getRawResponse(path);
PageResponse<PurchaseOrderResponse> pageResponse = apiClient.getObjectMapper().readValue(
response,
new TypeReference<PageResponse<PurchaseOrderResponse>>() {}
);
if (pageResponse == null) {
throw new IllegalStateException("Null response from purchase-orders endpoint");
}
return pageResponse.getContent();
}
}

View File

@@ -2,9 +2,12 @@ package org.example.petshopdesktop.api.endpoints;
import com.fasterxml.jackson.core.type.TypeReference;
import org.example.petshopdesktop.api.ApiClient;
import org.example.petshopdesktop.api.dto.common.PageResponse;
import org.example.petshopdesktop.api.dto.sale.SaleRequest;
import org.example.petshopdesktop.api.dto.sale.SaleResponse;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
import java.util.List;
public class SaleApi {
@@ -22,10 +25,17 @@ public class SaleApi {
public List<SaleResponse> listSales(int page, int size, String query) throws Exception {
String path = "/api/v1/sales?page=" + page + "&size=" + size;
if (query != null && !query.isEmpty()) {
path += "&q=" + query;
path += "&q=" + URLEncoder.encode(query, StandardCharsets.UTF_8);
}
String response = apiClient.get(path, String.class);
return apiClient.getObjectMapper().readValue(response, new TypeReference<List<SaleResponse>>() {});
String response = apiClient.getRawResponse(path);
PageResponse<SaleResponse> pageResponse = apiClient.getObjectMapper().readValue(
response,
new TypeReference<PageResponse<SaleResponse>>() {}
);
if (pageResponse == null) {
throw new IllegalStateException("Null response from sales endpoint");
}
return pageResponse.getContent();
}
public SaleResponse getSale(Long id) throws Exception {

View File

@@ -3,9 +3,12 @@ package org.example.petshopdesktop.api.endpoints;
import com.fasterxml.jackson.core.type.TypeReference;
import org.example.petshopdesktop.api.ApiClient;
import org.example.petshopdesktop.api.dto.common.BulkDeleteRequest;
import org.example.petshopdesktop.api.dto.common.PageResponse;
import org.example.petshopdesktop.api.dto.service.ServiceRequest;
import org.example.petshopdesktop.api.dto.service.ServiceResponse;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
import java.util.List;
public class ServiceApi {
@@ -23,10 +26,17 @@ public class ServiceApi {
public List<ServiceResponse> listServices(String query) throws Exception {
String path = "/api/v1/services?page=0&size=1000";
if (query != null && !query.isEmpty()) {
path += "&q=" + query;
path += "&q=" + URLEncoder.encode(query, StandardCharsets.UTF_8);
}
String response = apiClient.get(path, String.class);
return apiClient.getObjectMapper().readValue(response, new TypeReference<List<ServiceResponse>>() {});
String response = apiClient.getRawResponse(path);
PageResponse<ServiceResponse> pageResponse = apiClient.getObjectMapper().readValue(
response,
new TypeReference<PageResponse<ServiceResponse>>() {}
);
if (pageResponse == null) {
throw new IllegalStateException("Null response from services endpoint");
}
return pageResponse.getContent();
}
public ServiceResponse createService(ServiceRequest request) throws Exception {

View File

@@ -3,9 +3,12 @@ package org.example.petshopdesktop.api.endpoints;
import com.fasterxml.jackson.core.type.TypeReference;
import org.example.petshopdesktop.api.ApiClient;
import org.example.petshopdesktop.api.dto.common.BulkDeleteRequest;
import org.example.petshopdesktop.api.dto.common.PageResponse;
import org.example.petshopdesktop.api.dto.supplier.SupplierRequest;
import org.example.petshopdesktop.api.dto.supplier.SupplierResponse;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
import java.util.List;
public class SupplierApi {
@@ -23,10 +26,17 @@ public class SupplierApi {
public List<SupplierResponse> listSuppliers(String query) throws Exception {
String path = "/api/v1/suppliers?page=0&size=1000";
if (query != null && !query.isEmpty()) {
path += "&q=" + query;
path += "&q=" + URLEncoder.encode(query, StandardCharsets.UTF_8);
}
String response = apiClient.get(path, String.class);
return apiClient.getObjectMapper().readValue(response, new TypeReference<List<SupplierResponse>>() {});
String response = apiClient.getRawResponse(path);
PageResponse<SupplierResponse> pageResponse = apiClient.getObjectMapper().readValue(
response,
new TypeReference<PageResponse<SupplierResponse>>() {}
);
if (pageResponse == null) {
throw new IllegalStateException("Null response from suppliers endpoint");
}
return pageResponse.getContent();
}
public SupplierResponse createSupplier(SupplierRequest request) throws Exception {

View File

@@ -2,9 +2,12 @@ package org.example.petshopdesktop.api.endpoints;
import com.fasterxml.jackson.core.type.TypeReference;
import org.example.petshopdesktop.api.ApiClient;
import org.example.petshopdesktop.api.dto.common.PageResponse;
import org.example.petshopdesktop.api.dto.user.UserRequest;
import org.example.petshopdesktop.api.dto.user.UserResponse;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
import java.util.List;
public class UserApi {
@@ -22,10 +25,17 @@ public class UserApi {
public List<UserResponse> listUsers(String query) throws Exception {
String path = "/api/v1/users?page=0&size=1000";
if (query != null && !query.isEmpty()) {
path += "&q=" + query;
path += "&q=" + URLEncoder.encode(query, StandardCharsets.UTF_8);
}
String response = apiClient.get(path, String.class);
return apiClient.getObjectMapper().readValue(response, new TypeReference<List<UserResponse>>() {});
String response = apiClient.getRawResponse(path);
PageResponse<UserResponse> pageResponse = apiClient.getObjectMapper().readValue(
response,
new TypeReference<PageResponse<UserResponse>>() {}
);
if (pageResponse == null) {
throw new IllegalStateException("Null response from users endpoint");
}
return pageResponse.getContent();
}
public UserResponse createUser(UserRequest request) throws Exception {

View File

@@ -54,17 +54,27 @@ public class LoginController {
LoginRequest loginRequest = new LoginRequest(username, password);
LoginResponse loginResponse = apiClient.post("/api/v1/auth/login", loginRequest, LoginResponse.class);
if (loginResponse == null) {
throw new IllegalStateException("Login response is null");
}
String token = loginResponse.getToken();
String roleStr = loginResponse.getRole();
if (token == null || roleStr == null) {
throw new IllegalStateException("Token or role is null");
}
Role role = Role.valueOf(roleStr.toUpperCase());
UserSession.getInstance().login(null, username, role, token);
UserInfoResponse userInfo = apiClient.get("/api/v1/auth/me", UserInfoResponse.class);
if (userInfo == null) {
throw new IllegalStateException("User info is null");
}
UserSession.getInstance().login(userInfo.getId(), username, role, token);
List<DropdownOption> stores = DropdownApi.getInstance().getStores();
if (!stores.isEmpty()) {
if (stores != null && !stores.isEmpty()) {
UserSession.getInstance().setStoreId(stores.get(0).getId());
}

View File

@@ -67,8 +67,10 @@ public class AdoptionDialogController {
try {
List<DropdownOption> pets = DropdownApi.getInstance().getPets();
Platform.runLater(() -> {
ObservableList<DropdownOption> petsObs = FXCollections.observableArrayList(pets);
cbPet.setItems(petsObs);
if (pets != null) {
ObservableList<DropdownOption> petsObs = FXCollections.observableArrayList(pets);
cbPet.setItems(petsObs);
}
});
} catch (Exception e) {
Platform.runLater(() -> {
@@ -85,8 +87,10 @@ public class AdoptionDialogController {
try {
List<DropdownOption> customers = DropdownApi.getInstance().getCustomers();
Platform.runLater(() -> {
ObservableList<DropdownOption> customersObs = FXCollections.observableArrayList(customers);
cbCustomer.setItems(customersObs);
if (customers != null) {
ObservableList<DropdownOption> customersObs = FXCollections.observableArrayList(customers);
cbCustomer.setItems(customersObs);
}
});
} catch (Exception e) {
Platform.runLater(() -> {
@@ -144,7 +148,11 @@ public class AdoptionDialogController {
if (mode.equals("Add")) {
AdoptionApi.getInstance().createAdoption(request);
} else {
Long adoptionId = Long.parseLong(lblAdoptionId.getText().split(": ")[1]);
String[] parts = lblAdoptionId.getText().split(": ");
if (parts.length < 2) {
throw new IllegalStateException("Invalid adoption ID format");
}
Long adoptionId = Long.parseLong(parts[1]);
AdoptionApi.getInstance().updateAdoption(adoptionId, request);
}
@@ -197,7 +205,14 @@ public class AdoptionDialogController {
}
if (adoption.getAdoptionDate() != null && !adoption.getAdoptionDate().isEmpty()) {
dpAdoptionDate.setValue(LocalDate.parse(adoption.getAdoptionDate()));
try {
dpAdoptionDate.setValue(LocalDate.parse(adoption.getAdoptionDate()));
} catch (Exception e) {
ActivityLogger.getInstance().logException(
"AdoptionDialogController.displayAdoptionDetails",
e,
"Parsing adoption date");
}
}
for (String status : cbAdoptionStatus.getItems()) {

View File

@@ -80,9 +80,15 @@ public class AppointmentDialogController {
List<DropdownOption> pets = DropdownApi.getInstance().getPets();
Platform.runLater(() -> {
cbService.setItems(FXCollections.observableArrayList(services));
cbCustomer.setItems(FXCollections.observableArrayList(customers));
cbPet.setItems(FXCollections.observableArrayList(pets));
if (services != null) {
cbService.setItems(FXCollections.observableArrayList(services));
}
if (customers != null) {
cbCustomer.setItems(FXCollections.observableArrayList(customers));
}
if (pets != null) {
cbPet.setItems(FXCollections.observableArrayList(pets));
}
});
} catch (Exception e) {
Platform.runLater(() -> {
@@ -163,15 +169,29 @@ public class AppointmentDialogController {
selectedAppointment = appt;
lblAppointmentId.setText("ID: " + appt.getAppointmentId());
dpAppointmentDate.setValue(
java.time.LocalDate.parse(appt.getAppointmentDate())
);
try {
dpAppointmentDate.setValue(
java.time.LocalDate.parse(appt.getAppointmentDate())
);
} catch (Exception e) {
ActivityLogger.getInstance().logException(
"AppointmentDialogController.displayAppointmentDetails",
e,
"Parsing appointment date");
}
cbAppointmentStatus.setValue(appt.getAppointmentStatus());
LocalTime time = LocalTime.parse(appt.getAppointmentTime());
cbHour.setValue(time.getHour());
cbMinute.setValue(time.getMinute());
try {
LocalTime time = LocalTime.parse(appt.getAppointmentTime());
cbHour.setValue(time.getHour());
cbMinute.setValue(time.getMinute());
} catch (Exception e) {
ActivityLogger.getInstance().logException(
"AppointmentDialogController.displayAppointmentDetails",
e,
"Parsing appointment time");
}
cbService.getItems().forEach(s -> {
if (s.getId() == appt.getServiceId()) cbService.setValue(s);

View File

@@ -70,17 +70,19 @@ public class InventoryDialogController {
//Load product list from API into combobox
try {
List<ProductResponse> productResponses = ProductApi.getInstance().listProducts(null);
ObservableList<Product> products = FXCollections.observableArrayList();
for (ProductResponse pr : productResponses) {
products.add(new Product(
pr.getId().intValue(),
pr.getProductName(),
pr.getPrice().doubleValue(),
0,
pr.getDescription()
));
if (productResponses != null) {
ObservableList<Product> products = FXCollections.observableArrayList();
for (ProductResponse pr : productResponses) {
products.add(new Product(
pr.getId().intValue(),
pr.getProductName(),
pr.getPrice().doubleValue(),
0,
pr.getDescription()
));
}
cbProduct.setItems(products);
}
cbProduct.setItems(products);
} catch (Exception e) {
ActivityLogger.getInstance().logException(
"InventoryDialogController.initialize",
@@ -126,12 +128,22 @@ public class InventoryDialogController {
InventoryRequest request = new InventoryRequest();
Product selectedProduct = cbProduct.getSelectionModel().getSelectedItem();
request.setProductId((long) selectedProduct.getProdId());
request.setStockQuantity(Integer.parseInt(txtQuantity.getText()));
int quantity;
try {
quantity = Integer.parseInt(txtQuantity.getText());
} catch (NumberFormatException e) {
throw new IllegalArgumentException("Invalid quantity format");
}
request.setStockQuantity(quantity);
if (mode.equals("Add")) {
InventoryApi.getInstance().createInventory(request);
} else {
Long inventoryId = Long.parseLong(lblInventoryId.getText().split(": ")[1]);
String[] parts = lblInventoryId.getText().split(": ");
if (parts.length < 2) {
throw new IllegalStateException("Invalid inventory ID format");
}
Long inventoryId = Long.parseLong(parts[1]);
InventoryApi.getInstance().updateInventory(inventoryId, request);
}

View File

@@ -107,7 +107,11 @@ public class PetDialogController {
if(mode.equals("Add")) {
PetApi.getInstance().createPet(request);
} else {
Long petId = Long.parseLong(lblPetId.getText().split(": ")[1]);
String[] parts = lblPetId.getText().split(": ");
if (parts.length < 2) {
throw new IllegalStateException("Invalid pet ID format");
}
Long petId = Long.parseLong(parts[1]);
PetApi.getInstance().updatePet(petId, request);
}
@@ -142,9 +146,18 @@ public class PetDialogController {
request.setSpecies(txtPetSpecies.getText());
request.setBreed(txtPetBreed.getText());
request.setPetStatus(cbPetStatus.getValue());
request.setPrice(new BigDecimal(txtPetPrice.getText()));
try {
request.setPrice(new BigDecimal(txtPetPrice.getText()));
} catch (NumberFormatException e) {
throw new IllegalArgumentException("Invalid price format");
}
int age = Integer.parseInt(txtPetAge.getText());
int age;
try {
age = Integer.parseInt(txtPetAge.getText());
} catch (NumberFormatException e) {
throw new IllegalArgumentException("Invalid age format");
}
LocalDate dateOfBirth = LocalDate.now().minusYears(age);
request.setDateOfBirth(dateOfBirth);

View File

@@ -70,14 +70,16 @@ public class ProductDialogController {
//Set up combobox for selecting category
try {
List<DropdownOption> categories = DropdownApi.getInstance().getCategories();
ObservableList<DropdownOption> categoriesObs = FXCollections.observableArrayList(categories);
cbProdCategory.setItems(categoriesObs);
if (categories != null) {
ObservableList<DropdownOption> categoriesObs = FXCollections.observableArrayList(categories);
cbProdCategory.setItems(categoriesObs);
}
} catch (Exception e) {
ActivityLogger.getInstance().logException(
"ProductDialogController.initialize",
e,
"Loading categories for combo box");
throw new RuntimeException(e);
System.out.println("Error loading categories: " + e.getMessage());
}
}
@@ -110,14 +112,24 @@ public class ProductDialogController {
try {
ProductRequest request = new ProductRequest();
request.setProductName(txtProdName.getText());
request.setPrice(new BigDecimal(txtProdPrice.getText()));
BigDecimal price;
try {
price = new BigDecimal(txtProdPrice.getText());
} catch (NumberFormatException e) {
throw new IllegalArgumentException("Invalid price format");
}
request.setPrice(price);
request.setCategoryId(cbProdCategory.getSelectionModel().getSelectedItem().getId());
request.setDescription(txtProdDesc.getText());
if (mode.equals("Add")) {
ProductApi.getInstance().createProduct(request);
} else {
Long productId = Long.parseLong(lblProdId.getText().split(": ")[1]);
String[] parts = lblProdId.getText().split(": ");
if (parts.length < 2) {
throw new IllegalStateException("Invalid product ID format");
}
Long productId = Long.parseLong(parts[1]);
ProductApi.getInstance().updateProduct(productId, request);
}

View File

@@ -119,8 +119,12 @@ public class ProductSupplierDialogController {
var products = DropdownApi.getInstance().getProducts();
Platform.runLater(() -> {
cbSupplier.setItems(FXCollections.observableArrayList(suppliers));
cbProduct.setItems(FXCollections.observableArrayList(products));
if (suppliers != null) {
cbSupplier.setItems(FXCollections.observableArrayList(suppliers));
}
if (products != null) {
cbProduct.setItems(FXCollections.observableArrayList(products));
}
});
} catch (Exception e) {
Platform.runLater(() -> {
@@ -204,7 +208,11 @@ public class ProductSupplierDialogController {
ProductSupplierRequest request = new ProductSupplierRequest();
request.setSupplierId(cbSupplier.getSelectionModel().getSelectedItem().getId());
request.setProductId(cbProduct.getSelectionModel().getSelectedItem().getId());
request.setSupplierPrice(new BigDecimal(txtCost.getText()));
try {
request.setSupplierPrice(new BigDecimal(txtCost.getText()));
} catch (NumberFormatException e) {
throw new IllegalArgumentException("Invalid cost format");
}
return request;
}

View File

@@ -99,7 +99,11 @@ public class SupplierDialogController {
if (mode.equals("Add")) {
SupplierApi.getInstance().createSupplier(request);
} else {
Long supplierId = Long.parseLong(lblSupId.getText().split(": ")[1]);
String[] parts = lblSupId.getText().split(": ");
if (parts.length < 2) {
throw new IllegalStateException("Invalid supplier ID format");
}
Long supplierId = Long.parseLong(parts[1]);
SupplierApi.getInstance().updateSupplier(supplierId, request);
}