commit 9ffa82d38a7615de10f410a246100c0f858329bf
Author: Jakub Smid <jaksmid@seznam.cz>
Date:   Sat Mar 26 09:52:05 2022 +0100

    Added catalog filter
    re #9164

diff --git a/backend/src/main/java/cz/zcu/kiv/backendapi/catalog/CatalogController.java b/backend/src/main/java/cz/zcu/kiv/backendapi/catalog/CatalogController.java
index e2fee67..69c813c 100644
--- a/backend/src/main/java/cz/zcu/kiv/backendapi/catalog/CatalogController.java
+++ b/backend/src/main/java/cz/zcu/kiv/backendapi/catalog/CatalogController.java
@@ -27,13 +27,16 @@ public class CatalogController {
     }
 
     /**
-     * Returns catalog
+     * Returns catalog entries satisfying given filter
      *
-     * @return catalog
+     * @param name    name - optional
+     * @param country country - optional
+     * @param type    type - optional
+     * @return list of catalog entries satisfying given filter
      */
     @GetMapping("")
-    public ResponseEntity<List<CatalogDto>> getAllUsers() {
-        return new ResponseEntity<>(catalogService.getCatalog(), HttpStatus.OK);
+    public ResponseEntity<List<CatalogDto>> getCatalog(@RequestParam(defaultValue = "") String name, @RequestParam(defaultValue = "") String country, @RequestParam(defaultValue = "") String type) {
+        return new ResponseEntity<>(catalogService.getCatalog(name, country, type), HttpStatus.OK);
     }
 
     /**
diff --git a/backend/src/main/java/cz/zcu/kiv/backendapi/catalog/CatalogDto.java b/backend/src/main/java/cz/zcu/kiv/backendapi/catalog/CatalogDto.java
index 6ae5cba..564b716 100644
--- a/backend/src/main/java/cz/zcu/kiv/backendapi/catalog/CatalogDto.java
+++ b/backend/src/main/java/cz/zcu/kiv/backendapi/catalog/CatalogDto.java
@@ -1,6 +1,9 @@
 package cz.zcu.kiv.backendapi.catalog;
 
+import com.fasterxml.jackson.annotation.JsonProperty;
+import lombok.AllArgsConstructor;
 import lombok.Data;
+import lombok.NoArgsConstructor;
 
 import java.util.Collections;
 import java.util.Set;
@@ -10,10 +13,13 @@ import java.util.UUID;
  * Class representing catalog DTO
  */
 @Data
+@AllArgsConstructor
+@NoArgsConstructor
 public class CatalogDto {
     /**
      * Id
      */
+    @JsonProperty(access = JsonProperty.Access.READ_ONLY)
     private UUID id;
 
     /**
diff --git a/backend/src/main/java/cz/zcu/kiv/backendapi/catalog/CatalogEntity.java b/backend/src/main/java/cz/zcu/kiv/backendapi/catalog/CatalogEntity.java
index af609bd..a60e2ca 100644
--- a/backend/src/main/java/cz/zcu/kiv/backendapi/catalog/CatalogEntity.java
+++ b/backend/src/main/java/cz/zcu/kiv/backendapi/catalog/CatalogEntity.java
@@ -62,28 +62,28 @@ public class CatalogEntity {
      */
     @OneToMany(mappedBy = "catalog", cascade = CascadeType.ALL)
     @LazyCollection(LazyCollectionOption.FALSE)
-    private Set<BibliographyEntity> bibliography;
+    private Set<BibliographyEntity> bibliography = Collections.emptySet();
 
     /**
      * Countries
      */
     @OneToMany(mappedBy = "catalog", cascade = CascadeType.ALL)
     @LazyCollection(LazyCollectionOption.FALSE)
-    private Set<CountryEntity> countries;
+    private Set<CountryEntity> countries = Collections.emptySet();
 
     /**
      * Written forms
      */
     @OneToMany(mappedBy = "catalog", cascade = CascadeType.ALL)
     @LazyCollection(LazyCollectionOption.FALSE)
-    private Set<WrittenFormEntity> writtenForms;
+    private Set<WrittenFormEntity> writtenForms = Collections.emptySet();
 
     /**
      * Alternative names
      */
     @OneToMany(mappedBy = "catalog", cascade = CascadeType.ALL)
     @LazyCollection(LazyCollectionOption.FALSE)
-    private Set<AlternativeNameEntity> alternativeNames;
+    private Set<AlternativeNameEntity> alternativeNames = Collections.emptySet();
 
     /**
      * Set of user roles - many-to-many relationship
diff --git a/backend/src/main/java/cz/zcu/kiv/backendapi/catalog/CatalogRepository.java b/backend/src/main/java/cz/zcu/kiv/backendapi/catalog/CatalogRepository.java
index 5d88524..f0b4ac2 100644
--- a/backend/src/main/java/cz/zcu/kiv/backendapi/catalog/CatalogRepository.java
+++ b/backend/src/main/java/cz/zcu/kiv/backendapi/catalog/CatalogRepository.java
@@ -5,7 +5,6 @@ import org.springframework.data.jpa.repository.Query;
 import org.springframework.stereotype.Repository;
 import org.springframework.transaction.annotation.Transactional;
 
-import java.util.List;
 import java.util.Set;
 import java.util.UUID;
 
@@ -17,14 +16,18 @@ import java.util.UUID;
 public interface CatalogRepository extends JpaRepository<CatalogEntity, UUID> {
 
     /**
-     * Selects all catalog entries with given name or where given name appears in alternative names
-     * @param name name
-     * @return list of catalog entries with given name / alternative name
+     * Returns all catalog entries containing specific values
+     *
+     * @param name    name - optional
+     * @param country country - optional
+     * @param type    type - optional
+     * @return set of catalog entries satisfying filter conditions
      */
-    @Query("SELECT DISTINCT c FROM CatalogEntity c LEFT JOIN AlternativeNameEntity a ON c = a.catalog WHERE (?1 = c.name OR ?1 = a.name)")
-    List<CatalogEntity> getCatalogEntitiesByName(String name);
-
-//    @Query("SELECT DISTINCT c FROM CatalogEntity c LEFT JOIN AlternativeNameEntity a ON c = a.catalog WHERE (?1 IS NULL OR ?1 = c.name OR ?1 = a.name)" +
-//            "LEFT JOIN TypeEntity e on c = e.catalog WHERE (?2 IS NULL OR e.)")
-//    Set<CatalogEntity> filterCatalog(String name, String type, String country);
+    @Query("SELECT DISTINCT e FROM CatalogEntity e LEFT JOIN AlternativeNameEntity a ON e = a.catalog " +
+            "LEFT JOIN CountryEntity c ON e = c.catalog " +
+            "INNER JOIN e.types t " +
+            "WHERE (?1 = '' OR e.name LIKE ?1 OR a.name LIKE ?1) " +
+            "AND (?2 = '' OR c.name LIKE ?2) " +
+            "AND (?3 = '' OR t.type LIKE ?3)")
+    Set<CatalogEntity> filterCatalog(String name, String country, String type);
 }
diff --git a/backend/src/main/java/cz/zcu/kiv/backendapi/catalog/CatalogServiceImpl.java b/backend/src/main/java/cz/zcu/kiv/backendapi/catalog/CatalogServiceImpl.java
index ff5de87..d999041 100644
--- a/backend/src/main/java/cz/zcu/kiv/backendapi/catalog/CatalogServiceImpl.java
+++ b/backend/src/main/java/cz/zcu/kiv/backendapi/catalog/CatalogServiceImpl.java
@@ -3,16 +3,18 @@ package cz.zcu.kiv.backendapi.catalog;
 import cz.zcu.kiv.backendapi.alternativename.AlternativeNameEntity;
 import cz.zcu.kiv.backendapi.bibliography.BibliographyEntity;
 import cz.zcu.kiv.backendapi.country.CountryEntity;
+import cz.zcu.kiv.backendapi.exception.ApiRequestException;
 import cz.zcu.kiv.backendapi.type.TypeEntity;
 import cz.zcu.kiv.backendapi.type.ITypeService;
 import cz.zcu.kiv.backendapi.writtenform.WrittenFormEntity;
 import lombok.RequiredArgsConstructor;
 import lombok.extern.slf4j.Slf4j;
-import org.springframework.security.core.userdetails.UsernameNotFoundException;
+import org.springframework.http.HttpStatus;
 import org.springframework.stereotype.Service;
 import org.springframework.transaction.annotation.Transactional;
 
 import java.util.List;
+import java.util.Set;
 import java.util.UUID;
 import java.util.stream.Collectors;
 
@@ -56,10 +58,10 @@ public class CatalogServiceImpl implements ICatalogService {
     public void updateCatalogEntry(UUID id, CatalogDto catalogDto) {
         CatalogEntity catalogEntity = catalogRepository.findById(id).orElseThrow(() -> {
             log.error(CATALOG_ENTRY_NOT_FOUND);
-            throw new UsernameNotFoundException(CATALOG_ENTRY_NOT_FOUND);
+            throw new ApiRequestException(CATALOG_ENTRY_NOT_FOUND, HttpStatus.NOT_FOUND);
         });
         convertDtoToEntity(catalogDto, catalogEntity);
-        catalogRepository.save(catalogEntity);
+        saveCatalogEntity(catalogEntity);
         log.info("Catalog entry updated");
     }
 
@@ -67,16 +69,16 @@ public class CatalogServiceImpl implements ICatalogService {
     public void deleteCatalogEntry(UUID id) {
         CatalogEntity catalogEntity = catalogRepository.findById(id).orElseThrow(() -> {
             log.error(CATALOG_ENTRY_NOT_FOUND);
-            throw new UsernameNotFoundException(CATALOG_ENTRY_NOT_FOUND);
+            throw new ApiRequestException(CATALOG_ENTRY_NOT_FOUND, HttpStatus.NOT_FOUND);
         });
         catalogRepository.delete(catalogEntity);
         log.info("Catalog entry deleted");
     }
 
     @Override
-    public List<CatalogDto> getCatalog() {
+    public List<CatalogDto> getCatalog(String name, String country, String type) {
         log.info("Retrieving catalog");
-        List<CatalogEntity> entities = catalogRepository.findAll();
+        Set<CatalogEntity> entities = catalogRepository.filterCatalog(name, country, type);
         return entities.stream().map(this::convertEntityToDto).collect(Collectors.toList());
     }
 
diff --git a/backend/src/main/java/cz/zcu/kiv/backendapi/catalog/ICatalogService.java b/backend/src/main/java/cz/zcu/kiv/backendapi/catalog/ICatalogService.java
index c479467..66da0f0 100644
--- a/backend/src/main/java/cz/zcu/kiv/backendapi/catalog/ICatalogService.java
+++ b/backend/src/main/java/cz/zcu/kiv/backendapi/catalog/ICatalogService.java
@@ -37,10 +37,13 @@ public interface ICatalogService {
     void deleteCatalogEntry(UUID id);
 
     /**
-     * Returns whole catalog
+     * Returns catalog entries satisfying given filter
      *
-     * @return catalog (as list of catalog entries)
+     * @param name    name - optional
+     * @param country country - optional
+     * @param type    type - optional
+     * @return list of catalog entries satisfying given filter
      */
-    List<CatalogDto> getCatalog();
+    List<CatalogDto> getCatalog(String name, String country, String type);
 
 }
