restrict adoption pets

This commit is contained in:
2026-04-08 08:11:20 -06:00
parent 55b61d3908
commit 4845aeb479
4 changed files with 29 additions and 5 deletions

View File

@@ -52,7 +52,7 @@ public class DropdownController {
@PreAuthorize("hasAnyRole('STAFF', 'ADMIN')") @PreAuthorize("hasAnyRole('STAFF', 'ADMIN')")
public ResponseEntity<List<DropdownOption>> getAdoptionPets() { public ResponseEntity<List<DropdownOption>> getAdoptionPets() {
return ResponseEntity.ok( return ResponseEntity.ok(
petRepository.findAllByPetStatusIgnoreCaseOrderByPetNameAsc("Available").stream() petRepository.findAdoptablePetsOrderByPetNameAsc().stream()
.map(p -> new DropdownOption(p.getPetId(), p.getPetName())) .map(p -> new DropdownOption(p.getPetId(), p.getPetName()))
.collect(Collectors.toList()) .collect(Collectors.toList())
); );

View File

@@ -15,6 +15,14 @@ import java.util.Optional;
public interface PetRepository extends JpaRepository<Pet, Long> { public interface PetRepository extends JpaRepository<Pet, Long> {
List<Pet> findAllByPetStatusIgnoreCaseOrderByPetNameAsc(String petStatus); List<Pet> 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<Pet> findAdoptablePetsOrderByPetNameAsc();
List<Pet> findAllByOwner_IdOrderByPetNameAsc(Long ownerId); List<Pet> findAllByOwner_IdOrderByPetNameAsc(Long ownerId);
Optional<Pet> findByIdAndOwner_Id(Long id, Long ownerId); Optional<Pet> findByIdAndOwner_Id(Long id, Long ownerId);

View File

@@ -80,7 +80,7 @@ public class AdoptionService {
.orElseThrow(() -> new ResourceNotFoundException("Store not found with id: " + request.getSourceStoreId())) .orElseThrow(() -> new ResourceNotFoundException("Store not found with id: " + request.getSourceStoreId()))
: null; : null;
String adoptionStatus = normalizeAdoptionStatus(request.getAdoptionStatus()); String adoptionStatus = normalizeAdoptionStatus(request.getAdoptionStatus());
validatePetAvailability(pet, null); validatePetAvailability(pet, null, null);
Adoption adoption = new Adoption(); Adoption adoption = new Adoption();
adoption.setPet(pet); adoption.setPet(pet);
@@ -111,7 +111,8 @@ public class AdoptionService {
.orElseThrow(() -> new ResourceNotFoundException("Store not found with id: " + request.getSourceStoreId())) .orElseThrow(() -> new ResourceNotFoundException("Store not found with id: " + request.getSourceStoreId()))
: null; : null;
String adoptionStatus = normalizeAdoptionStatus(request.getAdoptionStatus()); 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.setPet(pet);
adoption.setCustomer(customer); adoption.setCustomer(customer);
@@ -201,7 +202,8 @@ public class AdoptionService {
throw new IllegalArgumentException("Adoption status must be Pending, Completed, or Cancelled"); 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 boolean adoptedElsewhere = adoptionId == null
? adoptionRepository.existsByPet_IdAndAdoptionStatusIgnoreCase(pet.getPetId(), ADOPTION_STATUS_COMPLETED) ? adoptionRepository.existsByPet_IdAndAdoptionStatusIgnoreCase(pet.getPetId(), ADOPTION_STATUS_COMPLETED)
: adoptionRepository.existsByPet_IdAndAdoptionStatusIgnoreCaseAndAdoptionIdNot(pet.getPetId(), ADOPTION_STATUS_COMPLETED, adoptionId); : 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"); 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"); throw new IllegalArgumentException("Selected pet is not available for adoption");
} }
} }

View File

@@ -74,6 +74,7 @@ public class AdoptionDialogController {
Platform.runLater(() -> { Platform.runLater(() -> {
if (pets != null) { if (pets != null) {
ObservableList<DropdownOption> petsObs = FXCollections.observableArrayList(pets); ObservableList<DropdownOption> petsObs = FXCollections.observableArrayList(pets);
ensureSelectedPetOption(petsObs);
cbPet.setItems(petsObs); cbPet.setItems(petsObs);
applySelectedPet(); applySelectedPet();
} }
@@ -318,4 +319,17 @@ public class AdoptionDialogController {
} }
return null; return null;
} }
private void ensureSelectedPetOption(ObservableList<DropdownOption> 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);
}
}
} }