implementados filtros y delete. falta los textos del delete

This commit is contained in:
2025-09-28 09:41:15 +02:00
parent 847249d2de
commit 50599cf33e
5 changed files with 163 additions and 41 deletions

View File

@ -7,7 +7,10 @@ import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import org.springframework.context.MessageSource;
import org.springframework.dao.DataIntegrityViolationException;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.validation.BindingResult;
@ -28,6 +31,7 @@ import com.imprimelibros.erp.config.Sanitizer;
import com.imprimelibros.erp.datatables.DataTable;
import java.util.Map;
import java.util.Optional;
import java.util.Set;
import java.util.stream.Collectors;
import java.util.List;
@ -75,7 +79,8 @@ public class UserController {
// Si 'role' es relación, sácalo de aquí:
List<String> searchable = List.of("fullName", "userName", "enabled", "rolesConcat"); // <- busca por roles de
// verdad
List<String> orderable = List.of("fullName", "userName", "enabled", "roleRank"); // <- permite ordenar por estas columnas
List<String> orderable = List.of("fullName", "userName", "enabled", "roleRank"); // <- permite ordenar por estas
// columnas
Specification<User> base = (root, query, cb) -> cb.conjunction();
long total = repo.count();
@ -83,7 +88,7 @@ public class UserController {
return DataTable
.of(repo, User.class, dt, searchable) // 'searchable' en DataTable.java
// edita columnas "reales":
.orderable(orderable)
.orderable(orderable)
.edit("enabled", (User u) -> {
if (u.isEnabled()) {
return "<span class=\"badge bg-success\" >"
@ -105,10 +110,30 @@ public class UserController {
" <a href=\"javascript:void(0);\" data-id=\"" + user.getId()
+ "\" class=\"link-success btn-edit-user fs-15\"><i class=\"ri-edit-2-line\"></i></a>\n" +
" <a href=\"javascript:void(0);\" data-id=\"" + user.getId()
+ "\" class=\"link-danger fs-15\"><i class=\"user-delete ri-delete-bin-line\"></i></a>\n" +
+ "\" class=\"link-danger btn-delete-user fs-15\"><i class=\"user-delete ri-delete-bin-line\"></i></a>\n" +
" </div>";
})
.where(base)
// Filtros custom:
.filter((builder, req) -> {
// f_enabled: 'true' | 'false' | ''
String fEnabled = Optional.ofNullable(req.raw.get("f_enabled")).orElse("").trim();
if (!fEnabled.isEmpty()) {
boolean enabledVal = Boolean.parseBoolean(fEnabled);
builder.add((root, q, cb) -> cb.equal(root.get("enabled"), enabledVal));
}
// f_role: 'USER' | 'ADMIN' | 'SUPERADMIN' | ''
String fRole = Optional.ofNullable(req.raw.get("f_role")).orElse("").trim();
if (!fRole.isEmpty()) {
builder.add((root, q, cb) -> {
// join a roles; marca la query como distinct para evitar duplicados
var r = root.join("roles", jakarta.persistence.criteria.JoinType.LEFT);
q.distinct(true);
return cb.equal(r.get("name"), fRole);
});
}
})
.toJson(total);
}
@ -255,33 +280,28 @@ public class UserController {
}
@DeleteMapping("/{id}")
@ResponseBody
public void delete(@PathVariable Long id, HttpServletResponse response, Authentication authentication) {
var uOpt = repo.findById(id);
if (uOpt.isEmpty()) {
response.setStatus(404);
return;
}
var u = uOpt.get();
String currentUserName = authentication.getName();
if (u.getUserName().equalsIgnoreCase(currentUserName)) {
response.setStatus(403); // no puede borrarse a sí mismo
return;
}
try {
repo.delete(u);
} catch (Exception ex) {
response.setStatus(500);
}
// Si llegamos aquí, la eliminación fue exitosa
/*
* response.setStatus(204);
* response.getWriter().flush();
* response.getWriter().close();
*/
return;
public ResponseEntity<?> delete(@PathVariable Long id, Authentication authentication, Locale locale) {
return repo.findById(id).map(u -> {
if (authentication != null && u.getUserName().equalsIgnoreCase(authentication.getName())) {
return ResponseEntity.status(HttpStatus.FORBIDDEN)
.body(Map.of("message", messageSource.getMessage("usuarios.error.delete-self", null, locale)));
}
try {
repo.delete(u);
return ResponseEntity.status(HttpStatus.OK).body(
Map.of("message", messageSource.getMessage("usuarios.exito.eliminado", null, locale))
);
} catch (DataIntegrityViolationException dive) {
// Restricción FK / dependencias
return ResponseEntity.status(HttpStatus.CONFLICT)
.body(Map.of("message", messageSource.getMessage("usuarios.error.delete-relational-data", null, locale)));
} catch (Exception ex) {
return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR)
.body(Map.of("message", messageSource.getMessage("usuarios.error.delete-internal-error", null, locale)));
}
}).orElseGet(() -> ResponseEntity.status(HttpStatus.NOT_FOUND)
.body(Map.of("message", messageSource.getMessage("usuarios.error.delete-not-found", null, locale))));
}
}