Add pet product filters

This commit is contained in:
2026-03-29 22:54:25 -06:00
parent c48e3b8a95
commit e572d9f3cf
15 changed files with 166 additions and 61 deletions

View File

@@ -25,8 +25,9 @@ public class CategoryController {
@GetMapping
public ResponseEntity<Page<CategoryResponse>> getAllCategories(
@RequestParam(required = false) String q,
@RequestParam(required = false) String type,
Pageable pageable) {
return ResponseEntity.ok(categoryService.getAllCategories(q, pageable));
return ResponseEntity.ok(categoryService.getAllCategories(q, type, pageable));
}
@GetMapping("/{id}")

View File

@@ -25,8 +25,10 @@ public class PetController {
@GetMapping
public ResponseEntity<Page<PetResponse>> getAllPets(
@RequestParam(required = false) String q,
@RequestParam(required = false) String species,
@RequestParam(required = false) String status,
Pageable pageable) {
return ResponseEntity.ok(petService.getAllPets(q, pageable));
return ResponseEntity.ok(petService.getAllPets(q, species, status, pageable));
}
@GetMapping("/{id}")

View File

@@ -25,8 +25,9 @@ public class ProductController {
@GetMapping
public ResponseEntity<Page<ProductResponse>> getAllProducts(
@RequestParam(required = false) String q,
@RequestParam(required = false) Long categoryId,
Pageable pageable) {
return ResponseEntity.ok(productService.getAllProducts(q, pageable));
return ResponseEntity.ok(productService.getAllProducts(q, categoryId, pageable));
}
@GetMapping("/{id}")

View File

@@ -16,7 +16,7 @@ public interface CategoryRepository extends JpaRepository<Category, Long> {
Optional<Category> findByCategoryName(String categoryName);
@Query("SELECT c FROM Category c WHERE " +
"LOWER(c.categoryName) LIKE LOWER(CONCAT('%', :q, '%')) OR " +
"LOWER(c.categoryType) LIKE LOWER(CONCAT('%', :q, '%'))")
Page<Category> searchCategories(@Param("q") String query, Pageable pageable);
"(:q IS NULL OR LOWER(c.categoryName) LIKE LOWER(CONCAT('%', :q, '%')) OR LOWER(c.categoryType) LIKE LOWER(CONCAT('%', :q, '%'))) AND " +
"(:type IS NULL OR LOWER(c.categoryType) = LOWER(:type))")
Page<Category> searchCategories(@Param("q") String query, @Param("type") String type, Pageable pageable);
}

View File

@@ -12,8 +12,8 @@ import org.springframework.stereotype.Repository;
public interface PetRepository extends JpaRepository<Pet, Long> {
@Query("SELECT p FROM Pet p WHERE " +
"LOWER(p.petName) LIKE LOWER(CONCAT('%', :q, '%')) OR " +
"LOWER(p.petSpecies) LIKE LOWER(CONCAT('%', :q, '%')) OR " +
"LOWER(p.petBreed) LIKE LOWER(CONCAT('%', :q, '%'))")
Page<Pet> searchPets(@Param("q") String query, Pageable pageable);
"(:q IS NULL OR LOWER(p.petName) LIKE LOWER(CONCAT('%', :q, '%')) OR LOWER(p.petSpecies) LIKE LOWER(CONCAT('%', :q, '%')) OR LOWER(p.petBreed) LIKE LOWER(CONCAT('%', :q, '%'))) AND " +
"(:species IS NULL OR LOWER(p.petSpecies) = LOWER(:species)) AND " +
"(:status IS NULL OR LOWER(p.petStatus) = LOWER(:status))")
Page<Pet> searchPets(@Param("q") String query, @Param("species") String species, @Param("status") String status, Pageable pageable);
}

View File

@@ -12,7 +12,7 @@ import org.springframework.stereotype.Repository;
public interface ProductRepository extends JpaRepository<Product, Long> {
@Query("SELECT p FROM Product p WHERE " +
"LOWER(p.prodName) LIKE LOWER(CONCAT('%', :q, '%')) OR " +
"LOWER(p.prodDesc) LIKE LOWER(CONCAT('%', :q, '%'))")
Page<Product> searchProducts(@Param("q") String query, Pageable pageable);
"(:q IS NULL OR LOWER(p.prodName) LIKE LOWER(CONCAT('%', :q, '%')) OR LOWER(COALESCE(p.prodDesc, '')) LIKE LOWER(CONCAT('%', :q, '%'))) AND " +
"(:categoryId IS NULL OR p.category.categoryId = :categoryId)")
Page<Product> searchProducts(@Param("q") String query, @Param("categoryId") Long categoryId, Pageable pageable);
}

View File

@@ -20,14 +20,9 @@ public class CategoryService {
this.categoryRepository = categoryRepository;
}
public Page<CategoryResponse> getAllCategories(String query, Pageable pageable) {
Page<Category> categories;
if (query != null && !query.trim().isEmpty()) {
categories = categoryRepository.searchCategories(query, pageable);
} else {
categories = categoryRepository.findAll(pageable);
}
return categories.map(this::mapToResponse);
public Page<CategoryResponse> getAllCategories(String query, String type, Pageable pageable) {
return categoryRepository.searchCategories(normalizeFilter(query), normalizeFilter(type), pageable)
.map(this::mapToResponse);
}
public CategoryResponse getCategoryById(Long id) {
@@ -80,4 +75,12 @@ public class CategoryService {
category.getUpdatedAt()
);
}
private String normalizeFilter(String value) {
if (value == null) {
return null;
}
String trimmed = value.trim();
return trimmed.isEmpty() ? null : trimmed;
}
}

View File

@@ -33,14 +33,9 @@ public class PetService {
this.catalogImageStorageService = catalogImageStorageService;
}
public Page<PetResponse> getAllPets(String query, Pageable pageable) {
Page<Pet> pets;
if (query != null && !query.trim().isEmpty()) {
pets = petRepository.searchPets(query, pageable);
} else {
pets = petRepository.findAll(pageable);
}
return pets.map(this::mapToResponse);
public Page<PetResponse> getAllPets(String query, String species, String status, Pageable pageable) {
return petRepository.searchPets(normalizeFilter(query), normalizeFilter(species), normalizeFilter(status), pageable)
.map(this::mapToResponse);
}
public PetResponse getPetById(Long id) {
@@ -182,6 +177,14 @@ public class PetService {
return status == null ? "" : status.trim();
}
private String normalizeFilter(String value) {
if (value == null) {
return null;
}
String trimmed = value.trim();
return trimmed.isEmpty() ? null : trimmed;
}
private PetResponse mapToResponse(Pet pet) {
return new PetResponse(
pet.getPetId(),

View File

@@ -32,14 +32,9 @@ public class ProductService {
this.catalogImageStorageService = catalogImageStorageService;
}
public Page<ProductResponse> getAllProducts(String query, Pageable pageable) {
Page<Product> products;
if (query != null && !query.trim().isEmpty()) {
products = productRepository.searchProducts(query, pageable);
} else {
products = productRepository.findAll(pageable);
}
return products.map(this::mapToResponse);
public Page<ProductResponse> getAllProducts(String query, Long categoryId, Pageable pageable) {
return productRepository.searchProducts(normalizeFilter(query), categoryId, pageable)
.map(this::mapToResponse);
}
public ProductResponse getProductById(Long id) {
@@ -168,4 +163,12 @@ public class ProductService {
public record ImagePayload(Resource resource, MediaType mediaType) {
}
private String normalizeFilter(String value) {
if (value == null) {
return null;
}
String trimmed = value.trim();
return trimmed.isEmpty() ? null : trimmed;
}
}