WIP: Update morefiles #152
@@ -9,6 +9,8 @@ public class PetRequest {
|
||||
private Integer petAge;
|
||||
private String petStatus;
|
||||
private BigDecimal petPrice;
|
||||
private Long customerId;
|
||||
private Long storeId;
|
||||
|
||||
public PetRequest() {
|
||||
}
|
||||
@@ -60,4 +62,20 @@ public class PetRequest {
|
||||
public void setPetPrice(BigDecimal petPrice) {
|
||||
this.petPrice = petPrice;
|
||||
}
|
||||
|
||||
public Long getCustomerId() {
|
||||
return customerId;
|
||||
}
|
||||
|
||||
public void setCustomerId(Long customerId) {
|
||||
this.customerId = customerId;
|
||||
}
|
||||
|
||||
public Long getStoreId() {
|
||||
return storeId;
|
||||
}
|
||||
|
||||
public void setStoreId(Long storeId) {
|
||||
this.storeId = storeId;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -14,6 +14,10 @@ public class PetResponse {
|
||||
private String imageUrl;
|
||||
private LocalDateTime createdAt;
|
||||
private LocalDateTime updatedAt;
|
||||
private Long customerId;
|
||||
private String customerName;
|
||||
private Long storeId;
|
||||
private String storeName;
|
||||
|
||||
public PetResponse() {
|
||||
}
|
||||
@@ -97,4 +101,36 @@ public class PetResponse {
|
||||
public void setUpdatedAt(LocalDateTime updatedAt) {
|
||||
this.updatedAt = updatedAt;
|
||||
}
|
||||
|
||||
public Long getCustomerId() {
|
||||
return customerId;
|
||||
}
|
||||
|
||||
public void setCustomerId(Long customerId) {
|
||||
this.customerId = customerId;
|
||||
}
|
||||
|
||||
public String getCustomerName() {
|
||||
return customerName;
|
||||
}
|
||||
|
||||
public void setCustomerName(String customerName) {
|
||||
this.customerName = customerName;
|
||||
}
|
||||
|
||||
public Long getStoreId() {
|
||||
return storeId;
|
||||
}
|
||||
|
||||
public void setStoreId(Long storeId) {
|
||||
this.storeId = storeId;
|
||||
}
|
||||
|
||||
public String getStoreName() {
|
||||
return storeName;
|
||||
}
|
||||
|
||||
public void setStoreName(String storeName) {
|
||||
this.storeName = storeName;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -24,7 +24,7 @@ public class PetApi {
|
||||
return INSTANCE;
|
||||
}
|
||||
|
||||
public List<PetResponse> listPets(String query, String species, String status) throws Exception {
|
||||
public List<PetResponse> listPets(String query, String species, String status, Long storeId) throws Exception {
|
||||
String path = "/api/v1/pets?page=0&size=1000";
|
||||
if (query != null && !query.isEmpty()) {
|
||||
path += "&q=" + URLEncoder.encode(query, StandardCharsets.UTF_8);
|
||||
@@ -35,6 +35,9 @@ public class PetApi {
|
||||
if (status != null && !status.isEmpty()) {
|
||||
path += "&status=" + URLEncoder.encode(status, StandardCharsets.UTF_8);
|
||||
}
|
||||
if (storeId != null) {
|
||||
path += "&storeId=" + storeId;
|
||||
}
|
||||
String response = apiClient.getRawResponse(path);
|
||||
PageResponse<PetResponse> pageResponse = apiClient.getObjectMapper().readValue(
|
||||
response,
|
||||
@@ -46,8 +49,12 @@ public class PetApi {
|
||||
return pageResponse.getContent();
|
||||
}
|
||||
|
||||
public List<PetResponse> listPets(String query, String species, String status) throws Exception {
|
||||
return listPets(query, species, status, null);
|
||||
}
|
||||
|
||||
public List<PetResponse> listPets(String query) throws Exception {
|
||||
return listPets(query, null, null);
|
||||
return listPets(query, null, null, null);
|
||||
}
|
||||
|
||||
public PetResponse createPet(PetRequest request) throws Exception {
|
||||
|
||||
@@ -63,6 +63,12 @@ public class PetController {
|
||||
@FXML
|
||||
private TableColumn<Pet, String> colPetStatus;
|
||||
|
||||
@FXML
|
||||
private TableColumn<Pet, String> colCustomerName;
|
||||
|
||||
@FXML
|
||||
private TableColumn<Pet, String> colStoreName;
|
||||
|
||||
@FXML
|
||||
private TableView<Pet> tvPets;
|
||||
|
||||
@@ -156,11 +162,13 @@ public class PetController {
|
||||
colPetAge.setCellValueFactory(new PropertyValueFactory<Pet,Integer>("petAge"));
|
||||
colPetStatus.setCellValueFactory(new PropertyValueFactory<Pet,String>("petStatus"));
|
||||
colPetPrice.setCellValueFactory(new PropertyValueFactory<Pet,Double>("petPrice"));
|
||||
colCustomerName.setCellValueFactory(new PropertyValueFactory<Pet,String>("customerName"));
|
||||
colStoreName.setCellValueFactory(new PropertyValueFactory<Pet,String>("storeName"));
|
||||
configureImageColumn(colPetImage);
|
||||
|
||||
loadSpeciesFilter();
|
||||
|
||||
cbStatusFilter.setItems(FXCollections.observableArrayList("All Statuses", "Available", "Adopted", "Pending"));
|
||||
cbStatusFilter.setItems(FXCollections.observableArrayList("All Statuses", "Available", "Adopted", "Owned", "Pending"));
|
||||
cbStatusFilter.getSelectionModel().selectFirst();
|
||||
|
||||
displayPets();
|
||||
@@ -316,7 +324,7 @@ public class PetController {
|
||||
}
|
||||
|
||||
private Pet mapToPet(PetResponse response) {
|
||||
return new Pet(
|
||||
Pet pet = new Pet(
|
||||
response.getPetId().intValue(),
|
||||
response.getPetName(),
|
||||
response.getPetSpecies(),
|
||||
@@ -326,6 +334,11 @@ public class PetController {
|
||||
response.getPetPrice().doubleValue(),
|
||||
response.getImageUrl()
|
||||
);
|
||||
pet.setCustomerName(response.getCustomerName());
|
||||
pet.setStoreName(response.getStoreName());
|
||||
pet.setCustomerId(response.getCustomerId() != null ? response.getCustomerId() : 0L);
|
||||
pet.setStoreId(response.getStoreId() != null ? response.getStoreId() : 0L);
|
||||
return pet;
|
||||
}
|
||||
|
||||
private void configureImageColumn(TableColumn<Pet, String> column) {
|
||||
|
||||
@@ -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;
|
||||
@@ -10,8 +11,10 @@ import javafx.scene.image.ImageView;
|
||||
import javafx.scene.input.MouseEvent;
|
||||
import javafx.stage.Stage;
|
||||
import org.example.petshopdesktop.Validator;
|
||||
import org.example.petshopdesktop.api.dto.common.DropdownOption;
|
||||
import org.example.petshopdesktop.api.dto.pet.PetRequest;
|
||||
import org.example.petshopdesktop.api.dto.pet.PetResponse;
|
||||
import org.example.petshopdesktop.api.endpoints.DropdownApi;
|
||||
import org.example.petshopdesktop.api.endpoints.PetApi;
|
||||
import org.example.petshopdesktop.models.Pet;
|
||||
import org.example.petshopdesktop.util.ActivityLogger;
|
||||
@@ -20,6 +23,7 @@ import org.example.petshopdesktop.util.FilePickerSupport;
|
||||
|
||||
import java.io.File;
|
||||
import java.math.BigDecimal;
|
||||
import java.util.List;
|
||||
|
||||
public class PetDialogController {
|
||||
|
||||
@@ -38,6 +42,12 @@ public class PetDialogController {
|
||||
@FXML
|
||||
private ComboBox<String> cbPetStatus;
|
||||
|
||||
@FXML
|
||||
private ComboBox<DropdownOption> cbCustomer;
|
||||
|
||||
@FXML
|
||||
private ComboBox<DropdownOption> cbStore;
|
||||
|
||||
@FXML
|
||||
private Label lblMode;
|
||||
|
||||
@@ -70,16 +80,54 @@ public class PetDialogController {
|
||||
private String currentImageUrl;
|
||||
private boolean removeImageRequested;
|
||||
|
||||
private Long pendingCustomerId = null;
|
||||
private Long pendingStoreId = null;
|
||||
|
||||
private ObservableList<String> statusList = FXCollections.observableArrayList(
|
||||
"Available", "Adopted"
|
||||
"Available", "Adopted", "Owned"
|
||||
);
|
||||
|
||||
@FXML
|
||||
void initialize() {
|
||||
|
||||
cbPetStatus.setItems(statusList); //set status combobox
|
||||
cbPetStatus.setItems(statusList);
|
||||
|
||||
cbCustomer.setCellFactory(param -> new ListCell<>() {
|
||||
@Override protected void updateItem(DropdownOption o, boolean empty) {
|
||||
super.updateItem(o, empty);
|
||||
setText(empty || o == null ? null : o.getLabel());
|
||||
}
|
||||
});
|
||||
cbCustomer.setButtonCell(new ListCell<>() {
|
||||
@Override protected void updateItem(DropdownOption o, boolean empty) {
|
||||
super.updateItem(o, empty);
|
||||
setText(empty || o == null ? null : o.getLabel());
|
||||
}
|
||||
});
|
||||
|
||||
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());
|
||||
}
|
||||
});
|
||||
|
||||
cbCustomer.setVisible(false);
|
||||
cbStore.setVisible(false);
|
||||
|
||||
cbPetStatus.valueProperty().addListener((obs, oldVal, newVal) -> {
|
||||
boolean isOwned = "Owned".equalsIgnoreCase(newVal);
|
||||
boolean isAvailable = "Available".equalsIgnoreCase(newVal) || "Unadopted".equalsIgnoreCase(newVal);
|
||||
cbCustomer.setVisible(isOwned);
|
||||
cbStore.setVisible(isAvailable);
|
||||
});
|
||||
|
||||
//Set up mouse handlers for buttons
|
||||
btnSave.setOnMouseClicked(new EventHandler<MouseEvent>() {
|
||||
@Override
|
||||
public void handle(MouseEvent mouseEvent) {
|
||||
@@ -97,6 +145,9 @@ public class PetDialogController {
|
||||
btnChangeImage.setOnMouseClicked(mouseEvent -> handleChangeImage());
|
||||
btnRemoveImage.setOnMouseClicked(mouseEvent -> handleRemoveImage());
|
||||
refreshImagePreview();
|
||||
|
||||
loadCustomers();
|
||||
loadStores();
|
||||
}
|
||||
|
||||
private void buttonSaveClicked(MouseEvent mouseEvent) {
|
||||
@@ -111,6 +162,10 @@ public class PetDialogController {
|
||||
if (cbPetStatus.getSelectionModel().getSelectedItem() == null){
|
||||
errorMsg += "Status is required";
|
||||
}
|
||||
String selectedStatus = cbPetStatus.getValue();
|
||||
if ("Owned".equalsIgnoreCase(selectedStatus) && cbCustomer.getValue() == null) {
|
||||
errorMsg += "Customer is required for Owned status\n";
|
||||
}
|
||||
|
||||
//Check validation (length size)
|
||||
errorMsg += Validator.isLessThanVarChars(txtPetName.getText(), "Pet Name", 50);
|
||||
@@ -184,9 +239,81 @@ public class PetDialogController {
|
||||
}
|
||||
request.setPetAge(age);
|
||||
|
||||
String status = cbPetStatus.getValue();
|
||||
if ("Owned".equalsIgnoreCase(status) && cbCustomer.getValue() != null) {
|
||||
request.setCustomerId(cbCustomer.getValue().getId());
|
||||
}
|
||||
if (("Available".equalsIgnoreCase(status) || "Unadopted".equalsIgnoreCase(status)) && cbStore.getValue() != null) {
|
||||
request.setStoreId(cbStore.getValue().getId());
|
||||
}
|
||||
|
||||
return request;
|
||||
}
|
||||
|
||||
private void loadCustomers() {
|
||||
new Thread(() -> {
|
||||
try {
|
||||
List<DropdownOption> customers = DropdownApi.getInstance().getCustomers();
|
||||
Platform.runLater(() -> {
|
||||
cbCustomer.setItems(FXCollections.observableArrayList(customers));
|
||||
applySelectedCustomer();
|
||||
});
|
||||
} catch (Exception e) {
|
||||
Platform.runLater(() -> {
|
||||
ActivityLogger.getInstance().logException(
|
||||
"PetDialogController.loadCustomers", e, "Loading customers");
|
||||
cbCustomer.setDisable(true);
|
||||
cbCustomer.setPromptText("Unable to load customers");
|
||||
});
|
||||
}
|
||||
}).start();
|
||||
}
|
||||
|
||||
private void loadStores() {
|
||||
new Thread(() -> {
|
||||
try {
|
||||
List<DropdownOption> stores = DropdownApi.getInstance().getStores();
|
||||
Platform.runLater(() -> {
|
||||
cbStore.setItems(FXCollections.observableArrayList(stores));
|
||||
applySelectedStore();
|
||||
});
|
||||
} catch (Exception e) {
|
||||
Platform.runLater(() -> {
|
||||
ActivityLogger.getInstance().logException(
|
||||
"PetDialogController.loadStores", e, "Loading stores");
|
||||
cbStore.setDisable(true);
|
||||
cbStore.setPromptText("Unable to load stores");
|
||||
});
|
||||
}
|
||||
}).start();
|
||||
}
|
||||
|
||||
private void applySelectedCustomer() {
|
||||
if (pendingCustomerId == null) return;
|
||||
DropdownOption selected = findOptionById(cbCustomer.getItems(), pendingCustomerId);
|
||||
if (selected != null) {
|
||||
cbCustomer.setValue(selected);
|
||||
pendingCustomerId = null;
|
||||
}
|
||||
}
|
||||
|
||||
private void applySelectedStore() {
|
||||
if (pendingStoreId == null) return;
|
||||
DropdownOption selected = findOptionById(cbStore.getItems(), pendingStoreId);
|
||||
if (selected != null) {
|
||||
cbStore.setValue(selected);
|
||||
pendingStoreId = null;
|
||||
}
|
||||
}
|
||||
|
||||
private DropdownOption findOptionById(List<DropdownOption> options, Long id) {
|
||||
if (id == null || options == null) return null;
|
||||
for (DropdownOption option : options) {
|
||||
if (option.getId() != null && option.getId().equals(id)) return option;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private void closeStage(MouseEvent mouseEvent) {
|
||||
Node node = (Node) mouseEvent.getSource();
|
||||
Stage stage = (Stage) node.getScene().getWindow();
|
||||
@@ -206,14 +333,14 @@ public class PetDialogController {
|
||||
removeImageRequested = false;
|
||||
refreshImagePreview();
|
||||
|
||||
//get the right combobox selection
|
||||
pendingCustomerId = pet.getCustomerId() > 0 ? pet.getCustomerId() : null;
|
||||
pendingStoreId = pet.getStoreId() > 0 ? pet.getStoreId() : null;
|
||||
|
||||
for (String status : cbPetStatus.getItems()) {
|
||||
if(status.equals(pet.getPetStatus())){
|
||||
cbPetStatus.getSelectionModel().select(status);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -13,6 +13,10 @@ public class Pet {
|
||||
private SimpleStringProperty petStatus;
|
||||
private SimpleDoubleProperty petPrice;
|
||||
private SimpleStringProperty imageUrl;
|
||||
private SimpleStringProperty customerName = new SimpleStringProperty("");
|
||||
private SimpleStringProperty storeName = new SimpleStringProperty("");
|
||||
private long customerId = 0L;
|
||||
private long storeId = 0L;
|
||||
|
||||
public Pet(int petId, String petName, String petSpecies, String petBreed, int petAge, String petStatus, double petPrice, String imageUrl) {
|
||||
this.petId = new SimpleIntegerProperty(petId);
|
||||
@@ -120,4 +124,44 @@ public class Pet {
|
||||
public SimpleStringProperty imageUrlProperty() {
|
||||
return imageUrl;
|
||||
}
|
||||
|
||||
public String getCustomerName() {
|
||||
return customerName.get();
|
||||
}
|
||||
|
||||
public void setCustomerName(String customerName) {
|
||||
this.customerName.set(customerName != null ? customerName : "");
|
||||
}
|
||||
|
||||
public SimpleStringProperty customerNameProperty() {
|
||||
return customerName;
|
||||
}
|
||||
|
||||
public String getStoreName() {
|
||||
return storeName.get();
|
||||
}
|
||||
|
||||
public void setStoreName(String storeName) {
|
||||
this.storeName.set(storeName != null ? storeName : "");
|
||||
}
|
||||
|
||||
public SimpleStringProperty storeNameProperty() {
|
||||
return storeName;
|
||||
}
|
||||
|
||||
public long getCustomerId() {
|
||||
return customerId;
|
||||
}
|
||||
|
||||
public void setCustomerId(long customerId) {
|
||||
this.customerId = customerId;
|
||||
}
|
||||
|
||||
public long getStoreId() {
|
||||
return storeId;
|
||||
}
|
||||
|
||||
public void setStoreId(long storeId) {
|
||||
this.storeId = storeId;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -13,7 +13,7 @@
|
||||
<?import javafx.scene.layout.VBox?>
|
||||
<?import javafx.scene.text.Font?>
|
||||
|
||||
<VBox minHeight="-Infinity" minWidth="-Infinity" prefHeight="560.0" prefWidth="790.0" spacing="20.0" style="-fx-font-size: 14px;" xmlns="http://javafx.com/javafx/17" xmlns:fx="http://javafx.com/fxml/1" fx:controller="org.example.petshopdesktop.controllers.dialogcontrollers.PetDialogController">
|
||||
<VBox minHeight="-Infinity" minWidth="-Infinity" prefHeight="660.0" prefWidth="790.0" spacing="20.0" style="-fx-font-size: 14px;" xmlns="http://javafx.com/javafx/17" xmlns:fx="http://javafx.com/fxml/1" fx:controller="org.example.petshopdesktop.controllers.dialogcontrollers.PetDialogController">
|
||||
<children>
|
||||
<HBox alignment="CENTER_LEFT" prefHeight="79.0" prefWidth="727.0" spacing="20.0" style="-fx-background-color: #2C3E50; -fx-background-radius: 14;">
|
||||
<children>
|
||||
@@ -153,6 +153,34 @@
|
||||
</TextField>
|
||||
</children>
|
||||
</VBox>
|
||||
<VBox prefHeight="200.0" prefWidth="100.0" spacing="8.0" GridPane.rowIndex="3">
|
||||
<children>
|
||||
<Label text="Customer:" textFill="#2c3e50">
|
||||
<font>
|
||||
<Font name="System Bold" size="16.0" />
|
||||
</font>
|
||||
</Label>
|
||||
<ComboBox fx:id="cbCustomer" prefHeight="29.0" prefWidth="336.0" promptText="Select Customer" style="-fx-border-color: #E8EBED; -fx-border-width: 2; -fx-border-radius: 10; -fx-background-radius: 10; -fx-background-color: white;">
|
||||
<padding>
|
||||
<Insets bottom="3.0" left="10.0" right="10.0" top="3.0" />
|
||||
</padding>
|
||||
</ComboBox>
|
||||
</children>
|
||||
</VBox>
|
||||
<VBox prefHeight="200.0" prefWidth="100.0" spacing="8.0" GridPane.columnIndex="1" GridPane.rowIndex="3">
|
||||
<children>
|
||||
<Label text="Store:" textFill="#2c3e50">
|
||||
<font>
|
||||
<Font name="System Bold" size="16.0" />
|
||||
</font>
|
||||
</Label>
|
||||
<ComboBox fx:id="cbStore" prefHeight="29.0" prefWidth="336.0" promptText="Select Store" style="-fx-border-color: #E8EBED; -fx-border-width: 2; -fx-border-radius: 10; -fx-background-radius: 10; -fx-background-color: white;">
|
||||
<padding>
|
||||
<Insets bottom="3.0" left="10.0" right="10.0" top="3.0" />
|
||||
</padding>
|
||||
</ComboBox>
|
||||
</children>
|
||||
</VBox>
|
||||
</children>
|
||||
<VBox.margin>
|
||||
<Insets bottom="15.0" left="15.0" right="15.0" top="15.0" />
|
||||
|
||||
@@ -79,6 +79,8 @@
|
||||
<TableColumn fx:id="colPetAge" prefWidth="60.0" text="Age" />
|
||||
<TableColumn fx:id="colPetStatus" prefWidth="110.0" text="Status" />
|
||||
<TableColumn fx:id="colPetPrice" prefWidth="80.0" text="Price" />
|
||||
<TableColumn fx:id="colCustomerName" prefWidth="130.0" text="Owner" />
|
||||
<TableColumn fx:id="colStoreName" prefWidth="130.0" text="Store" />
|
||||
</columns>
|
||||
</TableView>
|
||||
</children>
|
||||
|
||||
Reference in New Issue
Block a user