BACKEND: Enhance search and query functionalities in repositories and controllers. Refactor string decoding in PremiseController, add support for multiple part number filters in MaterialRepository, and improve query flexibility in NodeRepository and UserNodeRepository. Adjust NodeController and DTO validations.

This commit is contained in:
Jan 2025-08-12 15:20:11 +02:00
parent dd56a539ef
commit 7280a1208f
6 changed files with 76 additions and 25 deletions

View file

@ -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<PremiseSearchResultDTO> findMaterialsAndSuppliers(@RequestParam String search) {
return ResponseEntity.ok(premiseSearchStringAnalyzerService.findMaterialAndSuppliers(search));
public ResponseEntity<PremiseSearchResultDTO> 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/"})

View file

@ -46,8 +46,8 @@ public class NodeController {
.body(nodes.toList());
}
@GetMapping("/search")
public ResponseEntity<List<NodeDTO>> 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<List<NodeDTO>> 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));
}

View file

@ -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;

View file

@ -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<Object> 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

View file

@ -171,25 +171,51 @@ public class NodeRepository {
}
public List<Node> 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<Object> 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<Node> listAllNodes(boolean onlySources) {

View file

@ -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<Node> 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<Object> 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 ?");
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) {