diff --git a/src/main/java/de/avatic/lcc/controller/calculation/PremiseController.java b/src/main/java/de/avatic/lcc/controller/calculation/PremiseController.java index d0f750a..41da931 100644 --- a/src/main/java/de/avatic/lcc/controller/calculation/PremiseController.java +++ b/src/main/java/de/avatic/lcc/controller/calculation/PremiseController.java @@ -20,12 +20,15 @@ import de.avatic.lcc.service.calculation.ChangeSupplierService; import de.avatic.lcc.service.calculation.PremiseCreationService; import de.avatic.lcc.service.calculation.PremiseSearchStringAnalyzerService; import de.avatic.lcc.util.exception.badrequest.InvalidArgumentException; +import de.avatic.lcc.util.exception.base.BadRequestException; import jakarta.validation.Valid; import jakarta.validation.constraints.Min; import org.springframework.http.ResponseEntity; import org.springframework.validation.annotation.Validated; import org.springframework.web.bind.annotation.*; +import java.net.URLDecoder; +import java.nio.charset.StandardCharsets; import java.util.Collections; import java.util.HashMap; import java.util.List; @@ -71,8 +74,17 @@ public class PremiseController { } @GetMapping({"/search", "/search/"}) - public ResponseEntity findMaterialsAndSuppliers(@RequestParam String search) { - return ResponseEntity.ok(premiseSearchStringAnalyzerService.findMaterialAndSuppliers(search)); + public ResponseEntity findMaterialsAndSuppliers(@RequestHeader String search) { + try { + // Decode the header value + String decodedValue = URLDecoder.decode(search, StandardCharsets.UTF_8); + return ResponseEntity.ok(premiseSearchStringAnalyzerService.findMaterialAndSuppliers(decodedValue)); + } catch (Exception e) { + throw new BadRequestException("Bad string encoding", "Unable to decode request", e); + } + + + } @PostMapping({"/create", "/create/"}) diff --git a/src/main/java/de/avatic/lcc/controller/configuration/NodeController.java b/src/main/java/de/avatic/lcc/controller/configuration/NodeController.java index e35fcc7..443e61c 100644 --- a/src/main/java/de/avatic/lcc/controller/configuration/NodeController.java +++ b/src/main/java/de/avatic/lcc/controller/configuration/NodeController.java @@ -46,8 +46,8 @@ public class NodeController { .body(nodes.toList()); } - @GetMapping("/search") - public ResponseEntity> searchNodes(@RequestParam(required = false) String filter, @RequestParam(defaultValue = "1") @Min(1) int limit, @RequestParam(name = "node_type", required = false) NodeType nodeType, @RequestParam(name = "include_user_node", defaultValue = "false") boolean includeUserNode) { + @GetMapping({"/search", "/search/"}) + public ResponseEntity> searchNodes(@RequestParam(required = false) String filter, @RequestParam(defaultValue = "10") @Min(1) int limit, @RequestParam(name = "node_type", required = false) NodeType nodeType, @RequestParam(name = "include_user_node", defaultValue = "false") boolean includeUserNode) { return ResponseEntity.ok(nodeService.searchNode(filter, limit, nodeType, includeUserNode)); } diff --git a/src/main/java/de/avatic/lcc/dto/calculation/create/CreatePremiseDTO.java b/src/main/java/de/avatic/lcc/dto/calculation/create/CreatePremiseDTO.java index c4293cc..94079f9 100644 --- a/src/main/java/de/avatic/lcc/dto/calculation/create/CreatePremiseDTO.java +++ b/src/main/java/de/avatic/lcc/dto/calculation/create/CreatePremiseDTO.java @@ -18,6 +18,7 @@ public class CreatePremiseDTO { @JsonProperty("supplier") private List<@Min(1) Integer> supplierIds; + @Valid @JsonProperty("user_supplier") private List<@Min(1) Integer> userSupplierIds; diff --git a/src/main/java/de/avatic/lcc/repositories/MaterialRepository.java b/src/main/java/de/avatic/lcc/repositories/MaterialRepository.java index 883cfd5..23b8388 100644 --- a/src/main/java/de/avatic/lcc/repositories/MaterialRepository.java +++ b/src/main/java/de/avatic/lcc/repositories/MaterialRepository.java @@ -69,10 +69,14 @@ public class MaterialRepository { return Collections.emptyList(); } - String placeholders = String.join(",", Collections.nCopies(partNumbers.size(), "?")); - String query = "SELECT * FROM material WHERE part_number IN (" + placeholders + ")"; + List params = new ArrayList<>(); + params.addAll(partNumbers); + params.addAll(partNumbers); - return jdbcTemplate.query(query, new MaterialMapper(), partNumbers.toArray()); + String placeholders = String.join(",", Collections.nCopies(partNumbers.size(), "?")); + String query = "SELECT * FROM material WHERE part_number IN (" + placeholders + ") OR normalized_part_number IN (" + placeholders + ")"; + + return jdbcTemplate.query(query, new MaterialMapper(), params.toArray()); } @Transactional diff --git a/src/main/java/de/avatic/lcc/repositories/NodeRepository.java b/src/main/java/de/avatic/lcc/repositories/NodeRepository.java index 609e751..18a441a 100644 --- a/src/main/java/de/avatic/lcc/repositories/NodeRepository.java +++ b/src/main/java/de/avatic/lcc/repositories/NodeRepository.java @@ -171,25 +171,51 @@ public class NodeRepository { } public List searchNode(String filter, int limit, NodeType nodeType, boolean excludeDeprecated) { - StringBuilder queryBuilder = new StringBuilder().append("SELECT * FROM node WHERE (name LIKE ? OR address LIKE ?)"); + StringBuilder queryBuilder = new StringBuilder().append("SELECT * FROM node"); + List parameters = new ArrayList<>(); - if (nodeType != null) { - if (nodeType.equals(NodeType.SOURCE)) - queryBuilder.append(" AND is_source = true"); - if (nodeType.equals(NodeType.DESTINATION)) - queryBuilder.append(" AND is_destination = true"); - if (nodeType.equals(NodeType.INTERMEDIATE)) - queryBuilder.append(" AND is_intermediate = true"); + boolean hasWhereClause = false; + + // Add filter conditions only if filter is not null + if (filter != null && !filter.trim().isEmpty()) { + queryBuilder.append(" WHERE (name LIKE ? OR address LIKE ?)"); + parameters.add("%" + filter + "%"); + parameters.add("%" + filter + "%"); + hasWhereClause = true; } + // Add node type conditions + if (nodeType != null) { + if (!hasWhereClause) { + queryBuilder.append(" WHERE "); + hasWhereClause = true; + } else { + queryBuilder.append(" AND "); + } + + if (nodeType.equals(NodeType.SOURCE)) { + queryBuilder.append("is_source = true"); + } else if (nodeType.equals(NodeType.DESTINATION)) { + queryBuilder.append("is_destination = true"); + } else if (nodeType.equals(NodeType.INTERMEDIATE)) { + queryBuilder.append("is_intermediate = true"); + } + } + + // Add deprecated filter if (excludeDeprecated) { - queryBuilder.append(" AND is_deprecated = false"); + if (!hasWhereClause) { + queryBuilder.append(" WHERE "); + } else { + queryBuilder.append(" AND "); + } + queryBuilder.append("is_deprecated = false"); } queryBuilder.append(" LIMIT ?"); + parameters.add(limit); - - return jdbcTemplate.query(queryBuilder.toString(), new NodeMapper(), "%" + filter + "%", "%" + filter + "%", limit); + return jdbcTemplate.query(queryBuilder.toString(), new NodeMapper(), parameters.toArray()); } public List listAllNodes(boolean onlySources) { diff --git a/src/main/java/de/avatic/lcc/repositories/users/UserNodeRepository.java b/src/main/java/de/avatic/lcc/repositories/users/UserNodeRepository.java index 7dcc4da..d466606 100644 --- a/src/main/java/de/avatic/lcc/repositories/users/UserNodeRepository.java +++ b/src/main/java/de/avatic/lcc/repositories/users/UserNodeRepository.java @@ -11,10 +11,7 @@ import org.springframework.transaction.annotation.Transactional; import java.sql.ResultSet; import java.sql.SQLException; -import java.util.Collection; -import java.util.Collections; -import java.util.List; -import java.util.Optional; +import java.util.*; @Repository public class UserNodeRepository { @@ -29,15 +26,26 @@ public class UserNodeRepository { public Collection searchNode(String filter, int limit, int userId, boolean excludeDeprecated) { - StringBuilder queryBuilder = new StringBuilder().append("SELECT * FROM sys_user_node WHERE user_id = ? AND (name LIKE ? OR address LIKE ?)"); + StringBuilder queryBuilder = new StringBuilder().append("SELECT * FROM sys_user_node WHERE user_id = ?"); + + List params = new ArrayList<>(); + params.add(userId); + + // Add filter conditions only if filter is not null + if (filter != null) { + queryBuilder.append(" AND (name LIKE ? OR address LIKE ?)"); + params.add('%' + filter + '%'); + params.add('%' + filter + '%'); + } if (excludeDeprecated) { queryBuilder.append(" AND is_deprecated = FALSE"); } - queryBuilder.append("LIMIT ?"); + queryBuilder.append(" LIMIT ?"); + params.add(limit); - return jdbcTemplate.query(queryBuilder.toString(), new NodeMapper(), userId, '%' + filter + '%', '%' + filter + '%', limit); + return jdbcTemplate.query(queryBuilder.toString(), new NodeMapper(), params.toArray()); } public void add(Integer userId, Node node) {