diff --git a/backend/src/main/java/com/petshop/backend/controller/AppointmentController.java b/backend/src/main/java/com/petshop/backend/controller/AppointmentController.java index 5e64afd9..0dc828a1 100644 --- a/backend/src/main/java/com/petshop/backend/controller/AppointmentController.java +++ b/backend/src/main/java/com/petshop/backend/controller/AppointmentController.java @@ -50,7 +50,7 @@ public class AppointmentController { .orElse(null); Long effectiveCustomerId = customerId; - if (role != null && role.equals("CUSTOMER")) { + if ("CUSTOMER".equals(role)) { User user = AuthenticationHelper.getAuthenticatedUser(userRepository); effectiveCustomerId = user.getId(); } @@ -88,7 +88,7 @@ public class AppointmentController { .map(authority -> authority.getAuthority().replace("ROLE_", "")) .orElse(null); - if (role != null && role.equals("CUSTOMER")) { + if ("CUSTOMER".equals(role)) { User user = AuthenticationHelper.getAuthenticatedUser(userRepository); if (!request.getCustomerId().equals(user.getId())) { throw new org.springframework.security.access.AccessDeniedException("You can only create appointments for yourself"); diff --git a/backend/src/main/java/com/petshop/backend/controller/DropdownController.java b/backend/src/main/java/com/petshop/backend/controller/DropdownController.java index 3b0a2009..acf77b52 100644 --- a/backend/src/main/java/com/petshop/backend/controller/DropdownController.java +++ b/backend/src/main/java/com/petshop/backend/controller/DropdownController.java @@ -52,7 +52,7 @@ public class DropdownController { @PreAuthorize("hasAnyRole('STAFF', 'ADMIN')") public ResponseEntity> getAdoptionPets() { return ResponseEntity.ok( - petRepository.findAllByPetStatusIgnoreCaseOrderByPetNameAsc("Available").stream() + petRepository.findAdoptablePetsOrderByPetNameAsc().stream() .map(p -> new DropdownOption(p.getPetId(), p.getPetName())) .collect(Collectors.toList()) ); diff --git a/backend/src/main/java/com/petshop/backend/exception/GlobalExceptionHandler.java b/backend/src/main/java/com/petshop/backend/exception/GlobalExceptionHandler.java index 81163287..1f9434a5 100644 --- a/backend/src/main/java/com/petshop/backend/exception/GlobalExceptionHandler.java +++ b/backend/src/main/java/com/petshop/backend/exception/GlobalExceptionHandler.java @@ -5,6 +5,7 @@ import jakarta.servlet.http.HttpServletRequest; import org.springframework.dao.DataIntegrityViolationException; import org.springframework.data.core.PropertyReferenceException; import org.springframework.http.HttpStatus; +import org.springframework.http.MediaType; import org.springframework.http.ResponseEntity; import org.springframework.validation.FieldError; import org.springframework.web.HttpRequestMethodNotSupportedException; @@ -118,7 +119,9 @@ public class GlobalExceptionHandler { request.getRequestURI(), LocalDateTime.now() ); - return ResponseEntity.status(status).body(error); + return ResponseEntity.status(status) + .contentType(MediaType.APPLICATION_JSON) + .body(error); } private String buildDetails(Exception ex) { diff --git a/backend/src/main/java/com/petshop/backend/repository/PetRepository.java b/backend/src/main/java/com/petshop/backend/repository/PetRepository.java index 73f05460..970050e1 100644 --- a/backend/src/main/java/com/petshop/backend/repository/PetRepository.java +++ b/backend/src/main/java/com/petshop/backend/repository/PetRepository.java @@ -15,6 +15,14 @@ import java.util.Optional; public interface PetRepository extends JpaRepository { List findAllByPetStatusIgnoreCaseOrderByPetNameAsc(String petStatus); + @Query("SELECT p FROM Pet p " + + "WHERE LOWER(p.petStatus) = 'available' " + + "AND NOT EXISTS (" + + " SELECT 1 FROM Adoption a " + + " WHERE a.pet = p AND LOWER(a.adoptionStatus) = 'completed'" + + ") " + + "ORDER BY p.petName ASC") + List findAdoptablePetsOrderByPetNameAsc(); List findAllByOwner_IdOrderByPetNameAsc(Long ownerId); Optional findByIdAndOwner_Id(Long id, Long ownerId); diff --git a/backend/src/main/java/com/petshop/backend/service/AdoptionService.java b/backend/src/main/java/com/petshop/backend/service/AdoptionService.java index ab528b79..0e3c7a95 100644 --- a/backend/src/main/java/com/petshop/backend/service/AdoptionService.java +++ b/backend/src/main/java/com/petshop/backend/service/AdoptionService.java @@ -80,7 +80,7 @@ public class AdoptionService { .orElseThrow(() -> new ResourceNotFoundException("Store not found with id: " + request.getSourceStoreId())) : null; String adoptionStatus = normalizeAdoptionStatus(request.getAdoptionStatus()); - validatePetAvailability(pet, null); + validatePetAvailability(pet, null, null); Adoption adoption = new Adoption(); adoption.setPet(pet); @@ -111,7 +111,8 @@ public class AdoptionService { .orElseThrow(() -> new ResourceNotFoundException("Store not found with id: " + request.getSourceStoreId())) : null; String adoptionStatus = normalizeAdoptionStatus(request.getAdoptionStatus()); - validatePetAvailability(pet, adoption.getAdoptionId()); + Long currentPetId = adoption.getPet() != null ? adoption.getPet().getPetId() : null; + validatePetAvailability(pet, adoption.getAdoptionId(), currentPetId); adoption.setPet(pet); adoption.setCustomer(customer); @@ -201,7 +202,8 @@ public class AdoptionService { throw new IllegalArgumentException("Adoption status must be Pending, Completed, or Cancelled"); } - private void validatePetAvailability(Pet pet, Long adoptionId) { + private void validatePetAvailability(Pet pet, Long adoptionId, Long currentPetId) { + boolean samePetAsCurrentAdoption = currentPetId != null && currentPetId.equals(pet.getPetId()); boolean adoptedElsewhere = adoptionId == null ? adoptionRepository.existsByPet_IdAndAdoptionStatusIgnoreCase(pet.getPetId(), ADOPTION_STATUS_COMPLETED) : adoptionRepository.existsByPet_IdAndAdoptionStatusIgnoreCaseAndAdoptionIdNot(pet.getPetId(), ADOPTION_STATUS_COMPLETED, adoptionId); @@ -209,7 +211,7 @@ public class AdoptionService { throw new IllegalArgumentException("Selected pet has already been adopted"); } - if (!PET_STATUS_AVAILABLE.equalsIgnoreCase(pet.getPetStatus()) && adoptionId == null) { + if (!samePetAsCurrentAdoption && !PET_STATUS_AVAILABLE.equalsIgnoreCase(pet.getPetStatus())) { throw new IllegalArgumentException("Selected pet is not available for adoption"); } } diff --git a/backend/src/main/java/com/petshop/backend/service/PetService.java b/backend/src/main/java/com/petshop/backend/service/PetService.java index bbd39085..e35deb7d 100644 --- a/backend/src/main/java/com/petshop/backend/service/PetService.java +++ b/backend/src/main/java/com/petshop/backend/service/PetService.java @@ -247,7 +247,13 @@ public class PetService { if (principal instanceof AppPrincipal appPrincipal) { return new CurrentViewer(appPrincipal.getUserId(), appPrincipal.getRole()); } - return null; + String username = authentication.getName(); + if (username == null || username.isBlank() || "anonymousUser".equalsIgnoreCase(username)) { + return null; + } + return userRepository.findByUsername(username) + .map(user -> new CurrentViewer(user.getId(), user.getRole())) + .orElse(null); } private Pet findPet(Long id) { diff --git a/backend/src/main/java/com/petshop/backend/service/SaleService.java b/backend/src/main/java/com/petshop/backend/service/SaleService.java index 7c17dbf3..a5224675 100644 --- a/backend/src/main/java/com/petshop/backend/service/SaleService.java +++ b/backend/src/main/java/com/petshop/backend/service/SaleService.java @@ -245,9 +245,6 @@ public class SaleService { } String normalized = paymentMethod.trim(); - if (normalized.equalsIgnoreCase("Debit")) { - return "Card"; - } if (normalized.equalsIgnoreCase("Cash")) { return "Cash"; } diff --git a/desktop/src/main/java/org/example/petshopdesktop/controllers/AdoptionController.java b/desktop/src/main/java/org/example/petshopdesktop/controllers/AdoptionController.java index 4de4d212..7b5b6a5f 100644 --- a/desktop/src/main/java/org/example/petshopdesktop/controllers/AdoptionController.java +++ b/desktop/src/main/java/org/example/petshopdesktop/controllers/AdoptionController.java @@ -83,8 +83,9 @@ public class AdoptionController { tvAdoptions.getSelectionModel().selectedItemProperty().addListener( (observable, oldValue, newValue) -> { - btnEdit.setDisable(false); - btnDelete.setDisable(false); + boolean hasSelection = newValue != null; + btnEdit.setDisable(!hasSelection); + btnDelete.setDisable(!hasSelection); }); txtSearch.textProperty().addListener((observable, oldValue, newValue) -> { diff --git a/desktop/src/main/java/org/example/petshopdesktop/controllers/AppointmentController.java b/desktop/src/main/java/org/example/petshopdesktop/controllers/AppointmentController.java index 039e4b4f..ecc44bc6 100644 --- a/desktop/src/main/java/org/example/petshopdesktop/controllers/AppointmentController.java +++ b/desktop/src/main/java/org/example/petshopdesktop/controllers/AppointmentController.java @@ -47,7 +47,8 @@ public class AppointmentController { @FXML public void initialize(){ - + btnEdit.setDisable(true); + btnDelete.setDisable(true); tvAppointments.getSelectionModel().setSelectionMode(javafx.scene.control.SelectionMode.MULTIPLE); colAppointmentId.setCellValueFactory(new PropertyValueFactory<>("appointmentId")); @@ -66,6 +67,12 @@ public class AppointmentController { txtSearch.textProperty().addListener((obs, o, n) -> applyFilter(n)); } + tvAppointments.getSelectionModel().selectedItemProperty().addListener((obs, oldValue, newValue) -> { + boolean hasSelection = newValue != null; + btnEdit.setDisable(!hasSelection); + btnDelete.setDisable(!hasSelection); + }); + tvAppointments.setOnKeyPressed(event -> { if (event.getCode() == javafx.scene.input.KeyCode.DELETE) { if (tvAppointments.getSelectionModel().getSelectedItem() != null) { diff --git a/desktop/src/main/java/org/example/petshopdesktop/controllers/ChatController.java b/desktop/src/main/java/org/example/petshopdesktop/controllers/ChatController.java index f9dc4940..7ac193a5 100644 --- a/desktop/src/main/java/org/example/petshopdesktop/controllers/ChatController.java +++ b/desktop/src/main/java/org/example/petshopdesktop/controllers/ChatController.java @@ -123,29 +123,20 @@ public class ChatController { @FXML void btnSendClicked() { - try { - if (selectedConversation == null) { - lblChatStatus.setText("Select a conversation"); - return; - } - - String content = txtMessage.getText() == null ? "" : txtMessage.getText().trim(); - if (content.isEmpty()) { - return; - } - - txtMessage.clear(); - boolean sent = realtimeClient.sendMessage(selectedConversation.getId(), content); - if (!sent) { - sendMessageFallback(selectedConversation.getId(), content); - } - } catch (Exception e) { - ActivityLogger.getInstance().logException( - "ChatController.btnSendClicked", - e, - "Sending chat message"); - lblChatStatus.setText("Chat send failed"); + if (selectedConversation == null) { + lblChatStatus.setText("Select a conversation"); + return; } + + String content = txtMessage.getText() == null ? "" : txtMessage.getText().trim(); + if (content.isEmpty()) { + return; + } + + txtMessage.clear(); + btnSend.setDisable(true); + lblChatStatus.setText("Sending message..."); + sendMessage(selectedConversation.getId(), content); } private void loadCustomers() { @@ -211,19 +202,29 @@ public class ChatController { }).start(); } - private void sendMessageFallback(Long conversationId, String content) { + private void sendMessage(Long conversationId, String content) { new Thread(() -> { try { MessageResponse response = ChatApi.getInstance().sendMessage(conversationId, new MessageRequest(content)); Platform.runLater(() -> { - lblChatStatus.setText("Chat fallback active"); - appendMessageIfSelected(response); + btnSend.setDisable(false); + if (!realtimeClient.isConnected()) { + appendMessageIfSelected(response); + } + if (selectedConversation != null && selectedConversation.getId().equals(conversationId)) { + lblChatStatus.setText("Message sent"); + } }); } catch (Exception e) { - Platform.runLater(() -> ActivityLogger.getInstance().logException( - "ChatController.sendMessageFallback", - e, - "Sending chat message for conversation " + conversationId)); + Platform.runLater(() -> { + txtMessage.setText(content); + btnSend.setDisable(false); + lblChatStatus.setText("Chat send failed"); + ActivityLogger.getInstance().logException( + "ChatController.sendMessage", + e, + "Sending chat message for conversation " + conversationId); + }); } }).start(); } diff --git a/desktop/src/main/java/org/example/petshopdesktop/controllers/InventoryController.java b/desktop/src/main/java/org/example/petshopdesktop/controllers/InventoryController.java index 06b2afa9..1153fe04 100644 --- a/desktop/src/main/java/org/example/petshopdesktop/controllers/InventoryController.java +++ b/desktop/src/main/java/org/example/petshopdesktop/controllers/InventoryController.java @@ -73,8 +73,9 @@ public class InventoryController { tvInventory.getSelectionModel().selectedItemProperty().addListener( (observable, oldValue, newValue) -> { - btnEdit.setDisable(false); - btnDelete.setDisable(false); + boolean hasSelection = newValue != null; + btnEdit.setDisable(!hasSelection); + btnDelete.setDisable(!hasSelection); }); txtSearch.textProperty().addListener((observable, oldValue, newValue) -> { diff --git a/desktop/src/main/java/org/example/petshopdesktop/controllers/PetController.java b/desktop/src/main/java/org/example/petshopdesktop/controllers/PetController.java index 005eab1b..e12c13c8 100644 --- a/desktop/src/main/java/org/example/petshopdesktop/controllers/PetController.java +++ b/desktop/src/main/java/org/example/petshopdesktop/controllers/PetController.java @@ -175,8 +175,9 @@ public class PetController { tvPets.getSelectionModel().selectedItemProperty().addListener( (observable, oldValue, newValue) -> { - btnEdit.setDisable(false); - btnDelete.setDisable(false); + boolean hasSelection = newValue != null; + btnEdit.setDisable(!hasSelection); + btnDelete.setDisable(!hasSelection); }); txtSearch.textProperty().addListener((observable, oldValue, newValue) -> { diff --git a/desktop/src/main/java/org/example/petshopdesktop/controllers/ProductController.java b/desktop/src/main/java/org/example/petshopdesktop/controllers/ProductController.java index 84cfb8ce..61702f3b 100644 --- a/desktop/src/main/java/org/example/petshopdesktop/controllers/ProductController.java +++ b/desktop/src/main/java/org/example/petshopdesktop/controllers/ProductController.java @@ -99,8 +99,9 @@ public class ProductController { //EventListener to Enable buttons when a row is selected tvProducts.getSelectionModel().selectedItemProperty().addListener( (observable, oldValue, newValue) -> { - btnEdit.setDisable(false); - btnDelete.setDisable(false); + boolean hasSelection = newValue != null; + btnEdit.setDisable(!hasSelection); + btnDelete.setDisable(!hasSelection); } ); diff --git a/desktop/src/main/java/org/example/petshopdesktop/controllers/ProductSupplierController.java b/desktop/src/main/java/org/example/petshopdesktop/controllers/ProductSupplierController.java index 63bba3ae..1e9b9a95 100644 --- a/desktop/src/main/java/org/example/petshopdesktop/controllers/ProductSupplierController.java +++ b/desktop/src/main/java/org/example/petshopdesktop/controllers/ProductSupplierController.java @@ -80,8 +80,9 @@ public class ProductSupplierController { //EventListener to Enable buttons when a row is selected tvProductSuppliers.getSelectionModel().selectedItemProperty().addListener( (observable, oldValue, newValue) -> { - btnEdit.setDisable(false); - btnDelete.setDisable(false); + boolean hasSelection = newValue != null; + btnEdit.setDisable(!hasSelection); + btnDelete.setDisable(!hasSelection); } ); diff --git a/desktop/src/main/java/org/example/petshopdesktop/controllers/ServiceController.java b/desktop/src/main/java/org/example/petshopdesktop/controllers/ServiceController.java index d0a3049e..8500677a 100644 --- a/desktop/src/main/java/org/example/petshopdesktop/controllers/ServiceController.java +++ b/desktop/src/main/java/org/example/petshopdesktop/controllers/ServiceController.java @@ -57,8 +57,9 @@ public class ServiceController { tvServices.getSelectionModel().selectedItemProperty().addListener( (observable, oldValue, newValue) -> { - btnEdit.setDisable(false); - btnDelete.setDisable(false); + boolean hasSelection = newValue != null; + btnEdit.setDisable(!hasSelection); + btnDelete.setDisable(!hasSelection); } ); @@ -230,4 +231,4 @@ public class ServiceController { response.getServicePrice().doubleValue() ); } -} \ No newline at end of file +} diff --git a/desktop/src/main/java/org/example/petshopdesktop/controllers/SupplierController.java b/desktop/src/main/java/org/example/petshopdesktop/controllers/SupplierController.java index 4df26941..28248657 100644 --- a/desktop/src/main/java/org/example/petshopdesktop/controllers/SupplierController.java +++ b/desktop/src/main/java/org/example/petshopdesktop/controllers/SupplierController.java @@ -82,8 +82,9 @@ public class SupplierController { //EventListener to Enable buttons when a row is selected tvSuppliers.getSelectionModel().selectedItemProperty().addListener( (observable, oldValue, newValue) -> { - btnEdit.setDisable(false); - btnDelete.setDisable(false); + boolean hasSelection = newValue != null; + btnEdit.setDisable(!hasSelection); + btnDelete.setDisable(!hasSelection); } ); @@ -285,19 +286,21 @@ public class SupplierController { } private Supplier mapToSupplier(SupplierResponse response) { - String contactPerson = response.getSupContactFirstName() + " " + response.getSupContactLastName() != null ? response.getSupContactFirstName() + " " + response.getSupContactLastName() : ""; + String firstName = response.getSupContactFirstName() != null ? response.getSupContactFirstName().trim() : ""; + String lastName = response.getSupContactLastName() != null ? response.getSupContactLastName().trim() : ""; + String contactPerson = (firstName + " " + lastName).trim(); String[] nameParts = contactPerson.split(" ", 2); - String firstName = nameParts.length > 0 ? nameParts[0] : ""; - String lastName = nameParts.length > 1 ? nameParts[1] : ""; + String mappedFirstName = nameParts.length > 0 ? nameParts[0] : ""; + String mappedLastName = nameParts.length > 1 ? nameParts[1] : ""; return new Supplier( response.getSupId().intValue(), response.getSupCompany(), - firstName, - lastName, + mappedFirstName, + mappedLastName, response.getSupEmail(), response.getSupPhone() ); } -} \ No newline at end of file +} diff --git a/desktop/src/main/java/org/example/petshopdesktop/controllers/dialogcontrollers/AdoptionDialogController.java b/desktop/src/main/java/org/example/petshopdesktop/controllers/dialogcontrollers/AdoptionDialogController.java index 0240c128..534d9feb 100644 --- a/desktop/src/main/java/org/example/petshopdesktop/controllers/dialogcontrollers/AdoptionDialogController.java +++ b/desktop/src/main/java/org/example/petshopdesktop/controllers/dialogcontrollers/AdoptionDialogController.java @@ -74,6 +74,7 @@ public class AdoptionDialogController { Platform.runLater(() -> { if (pets != null) { ObservableList petsObs = FXCollections.observableArrayList(pets); + ensureSelectedPetOption(petsObs); cbPet.setItems(petsObs); applySelectedPet(); } @@ -318,4 +319,17 @@ public class AdoptionDialogController { } return null; } + + private void ensureSelectedPetOption(ObservableList options) { + if (selectedAdoption == null || selectedAdoption.getPetId() <= 0 || options == null) { + return; + } + DropdownOption existing = findOptionById(options, (long) selectedAdoption.getPetId()); + if (existing == null) { + DropdownOption option = new DropdownOption(); + option.setId((long) selectedAdoption.getPetId()); + option.setLabel(selectedAdoption.getPetName()); + options.add(0, option); + } + } } diff --git a/desktop/src/main/java/org/example/petshopdesktop/controllers/dialogcontrollers/PetDialogController.java b/desktop/src/main/java/org/example/petshopdesktop/controllers/dialogcontrollers/PetDialogController.java index afd2f549..5e4835e2 100644 --- a/desktop/src/main/java/org/example/petshopdesktop/controllers/dialogcontrollers/PetDialogController.java +++ b/desktop/src/main/java/org/example/petshopdesktop/controllers/dialogcontrollers/PetDialogController.java @@ -9,6 +9,7 @@ import javafx.scene.Node; import javafx.scene.control.*; import javafx.scene.image.ImageView; import javafx.scene.input.MouseEvent; +import javafx.scene.layout.VBox; import javafx.stage.Stage; import org.example.petshopdesktop.Validator; import org.example.petshopdesktop.api.dto.common.DropdownOption; @@ -48,6 +49,12 @@ public class PetDialogController { @FXML private ComboBox cbStore; + @FXML + private VBox vbCustomerField; + + @FXML + private VBox vbStoreField; + @FXML private Label lblMode; @@ -84,7 +91,7 @@ public class PetDialogController { private Long pendingStoreId = null; private ObservableList statusList = FXCollections.observableArrayList( - "Available", "Adopted", "Owned" + "Available", "Adopted", "Owned", "Pending" ); @FXML @@ -118,14 +125,11 @@ public class PetDialogController { } }); - cbCustomer.setVisible(false); - cbStore.setVisible(false); + setFieldVisibility(vbCustomerField, false); + setFieldVisibility(vbStoreField, 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); + updateStatusFieldVisibility(newVal); }); btnSave.setOnMouseClicked(new EventHandler() { @@ -166,6 +170,9 @@ public class PetDialogController { if ("Owned".equalsIgnoreCase(selectedStatus) && cbCustomer.getValue() == null) { errorMsg += "Customer is required for Owned status\n"; } + if (requiresStore(selectedStatus) && cbStore.getValue() == null) { + errorMsg += "Store is required for " + selectedStatus + " status\n"; + } //Check validation (length size) errorMsg += Validator.isLessThanVarChars(txtPetName.getText(), "Pet Name", 50); @@ -243,7 +250,7 @@ public class PetDialogController { if ("Owned".equalsIgnoreCase(status) && cbCustomer.getValue() != null) { request.setCustomerId(cbCustomer.getValue().getId()); } - if (("Available".equalsIgnoreCase(status) || "Unadopted".equalsIgnoreCase(status)) && cbStore.getValue() != null) { + if (requiresStore(status) && cbStore.getValue() != null) { request.setStoreId(cbStore.getValue().getId()); } @@ -339,8 +346,10 @@ public class PetDialogController { for (String status : cbPetStatus.getItems()) { if(status.equals(pet.getPetStatus())){ cbPetStatus.getSelectionModel().select(status); + break; } } + updateStatusFieldVisibility(cbPetStatus.getValue()); } } @@ -358,6 +367,7 @@ public class PetDialogController { lblPetId.setVisible(true); refreshImagePreview(); } + updateStatusFieldVisibility(cbPetStatus.getValue()); } private void handleChangeImage() { @@ -421,4 +431,25 @@ public class PetDialogController { btnRemoveImage.setDisable(true); } + private void updateStatusFieldVisibility(String status) { + boolean owned = "Owned".equalsIgnoreCase(status); + boolean storeBased = requiresStore(status); + setFieldVisibility(vbCustomerField, owned); + setFieldVisibility(vbStoreField, storeBased); + } + + private boolean requiresStore(String status) { + return "Available".equalsIgnoreCase(status) + || "Pending".equalsIgnoreCase(status) + || "Unadopted".equalsIgnoreCase(status); + } + + private void setFieldVisibility(VBox field, boolean visible) { + if (field == null) { + return; + } + field.setVisible(visible); + field.setManaged(visible); + } + } diff --git a/desktop/src/main/java/org/example/petshopdesktop/controllers/dialogcontrollers/ProductSupplierDialogController.java b/desktop/src/main/java/org/example/petshopdesktop/controllers/dialogcontrollers/ProductSupplierDialogController.java index 2348b43b..acff3799 100644 --- a/desktop/src/main/java/org/example/petshopdesktop/controllers/dialogcontrollers/ProductSupplierDialogController.java +++ b/desktop/src/main/java/org/example/petshopdesktop/controllers/dialogcontrollers/ProductSupplierDialogController.java @@ -19,6 +19,7 @@ import org.example.petshopdesktop.api.endpoints.ProductSupplierApi; import org.example.petshopdesktop.util.ActivityLogger; import java.math.BigDecimal; +import java.util.List; public class ProductSupplierDialogController { @@ -46,6 +47,8 @@ public class ProductSupplierDialogController { private String mode = null; private int selectedSupId = -1; private int selectedProdId = -1; + private Long pendingSupplierId = null; + private Long pendingProductId = null; /** * add event listeners to buttons and set up combobox @@ -120,9 +123,11 @@ public class ProductSupplierDialogController { Platform.runLater(() -> { if (suppliers != null) { cbSupplier.setItems(FXCollections.observableArrayList(suppliers)); + applyPendingSupplierSelection(); } if (products != null) { cbProduct.setItems(FXCollections.observableArrayList(products)); + applyPendingProductSelection(); } }); } catch (Exception e) { @@ -220,21 +225,14 @@ public class ProductSupplierDialogController { * @param productSupplier */ public void displayProductSupplierDetails(ProductSupplierDTO productSupplier){ - if(productSupplier != null){ - txtCost.setText(productSupplier.getCost() + ""); - } - - for (DropdownOption product : cbProduct.getItems()) { - if(product.getId() == productSupplier.getProdId()){ - cbProduct.getSelectionModel().select(product); - } - } - - for (DropdownOption supplier : cbSupplier.getItems()) { - if (supplier.getId() == productSupplier.getSupId()) { - cbSupplier.getSelectionModel().select(supplier); - } + if (productSupplier == null) { + return; } + txtCost.setText(productSupplier.getCost() + ""); + pendingProductId = (long) productSupplier.getProdId(); + pendingSupplierId = (long) productSupplier.getSupId(); + applyPendingProductSelection(); + applyPendingSupplierSelection(); } /** @@ -253,7 +251,7 @@ public class ProductSupplierDialogController { */ public void setMode(String mode) { this.mode = mode; - lblMode.setText(mode + " Product"); + lblMode.setText(mode + " Product-Supplier"); lblProductSupplierId.setVisible(false); } @@ -267,4 +265,38 @@ public class ProductSupplierDialogController { this.selectedProdId = prodId; } + private void applyPendingProductSelection() { + if (pendingProductId == null) { + return; + } + DropdownOption product = findOptionById(cbProduct.getItems(), pendingProductId); + if (product != null) { + cbProduct.getSelectionModel().select(product); + pendingProductId = null; + } + } + + private void applyPendingSupplierSelection() { + if (pendingSupplierId == null) { + return; + } + DropdownOption supplier = findOptionById(cbSupplier.getItems(), pendingSupplierId); + if (supplier != null) { + cbSupplier.getSelectionModel().select(supplier); + pendingSupplierId = null; + } + } + + private DropdownOption findOptionById(List options, Long id) { + if (options == null || id == null) { + return null; + } + for (DropdownOption option : options) { + if (option.getId() != null && option.getId().equals(id)) { + return option; + } + } + return null; + } + } diff --git a/desktop/src/main/java/org/example/petshopdesktop/controllers/dialogcontrollers/RefundDialogController.java b/desktop/src/main/java/org/example/petshopdesktop/controllers/dialogcontrollers/RefundDialogController.java index bc262e30..65b2590a 100644 --- a/desktop/src/main/java/org/example/petshopdesktop/controllers/dialogcontrollers/RefundDialogController.java +++ b/desktop/src/main/java/org/example/petshopdesktop/controllers/dialogcontrollers/RefundDialogController.java @@ -99,7 +99,7 @@ public class RefundDialogController { @FXML public void initialize() { setupTables(); - cbPaymentMethod.setItems(FXCollections.observableArrayList("Cash", "Card", "Debit")); + cbPaymentMethod.setItems(FXCollections.observableArrayList("Cash", "Card")); cbPaymentMethod.getSelectionModel().selectFirst(); updateRefundTotal(); } diff --git a/desktop/src/main/resources/org/example/petshopdesktop/dialogviews/pet-dialog-view.fxml b/desktop/src/main/resources/org/example/petshopdesktop/dialogviews/pet-dialog-view.fxml index f25e113f..9130513a 100644 --- a/desktop/src/main/resources/org/example/petshopdesktop/dialogviews/pet-dialog-view.fxml +++ b/desktop/src/main/resources/org/example/petshopdesktop/dialogviews/pet-dialog-view.fxml @@ -153,7 +153,7 @@ - + - +