mirror of
https://git.imnavajas.es/jjimenez/erp-imprimelibros.git
synced 2026-01-13 08:58:48 +00:00
262 lines
6.9 KiB
Java
262 lines
6.9 KiB
Java
package com.imprimelibros.erp.users;
|
|
|
|
import jakarta.persistence.*;
|
|
import jakarta.validation.constraints.Email;
|
|
import jakarta.validation.constraints.NotBlank;
|
|
|
|
import java.util.Set;
|
|
|
|
import org.hibernate.annotations.Formula;
|
|
|
|
import java.time.LocalDateTime;
|
|
import java.util.Collections;
|
|
import java.util.HashSet;
|
|
import java.util.List;
|
|
import java.util.Optional;
|
|
import java.util.stream.Collectors;
|
|
|
|
import org.hibernate.annotations.SQLRestriction;
|
|
|
|
import com.fasterxml.jackson.annotation.JsonIgnore;
|
|
import com.fasterxml.jackson.annotation.JsonProperty;
|
|
|
|
@Entity
|
|
@Table(name = "users", uniqueConstraints = {
|
|
@UniqueConstraint(name = "uk_users_username", columnNames = "username")
|
|
})
|
|
@SQLRestriction("deleted = false")
|
|
public class User {
|
|
|
|
@Id
|
|
@GeneratedValue(strategy = GenerationType.IDENTITY)
|
|
@Column(name = "id")
|
|
private Long id;
|
|
|
|
@Column(name = "fullname")
|
|
@NotBlank(message = "{validation.required}")
|
|
private String fullName;
|
|
|
|
@Column(name = "username", nullable = false, length = 190)
|
|
@Email(message = "{validation.email}")
|
|
@NotBlank(message = "{validation.required}")
|
|
private String userName;
|
|
|
|
@Column(name = "password")
|
|
@NotBlank(message = "{validation.required}")
|
|
private String password;
|
|
|
|
@Column(name = "enabled")
|
|
private boolean enabled;
|
|
|
|
@Column(name = "deleted", nullable = false)
|
|
private boolean deleted = false;
|
|
|
|
@Column(name = "deleted_at")
|
|
private LocalDateTime deletedAt;
|
|
|
|
@Column(name = "deleted_by")
|
|
private Long deletedBy;
|
|
|
|
@OneToMany(mappedBy = "user", fetch = FetchType.LAZY, cascade = { CascadeType.PERSIST, CascadeType.MERGE,
|
|
CascadeType.REMOVE }, orphanRemoval = true)
|
|
@SQLRestriction("deleted = false")
|
|
@JsonIgnore
|
|
private Set<UserRole> rolesLink = new HashSet<>();
|
|
|
|
// SUPERADMIN=3, ADMIN=2, USER=1 (ajusta a tus nombres reales)
|
|
@Formula("""
|
|
(
|
|
select coalesce(max(
|
|
case r.name
|
|
when 'SUPERADMIN' then 3
|
|
when 'ADMIN' then 2
|
|
else 1
|
|
end
|
|
), 0)
|
|
from users_roles ur
|
|
join roles r on r.id = ur.role_id
|
|
where ur.user_id = id
|
|
)
|
|
""")
|
|
private Integer roleRank;
|
|
|
|
@Formula("""
|
|
(select group_concat(lower(r.name) order by r.name separator ', ')
|
|
from users_roles ur join roles r on r.id = ur.role_id
|
|
where ur.user_id = id)
|
|
""")
|
|
private String rolesConcat;
|
|
|
|
/* Constructors */
|
|
public User() {
|
|
}
|
|
|
|
public User(String fullName, String userName, String password, boolean enabled) {
|
|
this.fullName = fullName;
|
|
this.userName = userName;
|
|
this.password = password;
|
|
this.enabled = enabled;
|
|
}
|
|
|
|
public User(String fullName, String userName, String password, boolean enabled,
|
|
Set<UserRole> roles) {
|
|
this.fullName = fullName;
|
|
this.userName = userName;
|
|
this.password = password;
|
|
this.enabled = enabled;
|
|
this.rolesLink = roles;
|
|
}
|
|
|
|
/* Getters and Setters */
|
|
|
|
public Long getId() {
|
|
return id;
|
|
}
|
|
|
|
public void setId(Long id) {
|
|
this.id = id;
|
|
}
|
|
|
|
public String getFullName() {
|
|
return fullName;
|
|
}
|
|
|
|
public void setFullName(String fullName) {
|
|
this.fullName = fullName;
|
|
}
|
|
|
|
public String getUserName() {
|
|
return userName;
|
|
}
|
|
|
|
public void setUserName(String userName) {
|
|
this.userName = userName;
|
|
}
|
|
|
|
public String getPassword() {
|
|
return password;
|
|
}
|
|
|
|
public void setPassword(String password) {
|
|
this.password = password;
|
|
}
|
|
|
|
public boolean isEnabled() {
|
|
return enabled;
|
|
}
|
|
|
|
public void setEnabled(boolean enabled) {
|
|
this.enabled = enabled;
|
|
}
|
|
|
|
@Transient
|
|
public Set<Role> getRoles() {
|
|
return rolesLink.stream()
|
|
.filter(ur -> !ur.isDeleted())
|
|
.map(UserRole::getRole)
|
|
.collect(Collectors.toSet());
|
|
}
|
|
|
|
@JsonProperty("roles")
|
|
public List<String> getRoleNames() {
|
|
return this.getRoles().stream()
|
|
.map(Role::getName)
|
|
.filter(java.util.Objects::nonNull)
|
|
.map(String::trim)
|
|
.toList();
|
|
}
|
|
|
|
public void setRoles(Set<Role> desired) {
|
|
if (desired == null)
|
|
desired = Collections.emptySet();
|
|
|
|
// 1) ids deseados
|
|
Set<Long> desiredIds = desired.stream()
|
|
.map(Role::getId)
|
|
.collect(Collectors.toSet());
|
|
|
|
// 2) Soft-delete de vínculos activos que ya no se desean
|
|
this.rolesLink.stream()
|
|
.filter(ur -> !ur.isDeleted() && !desiredIds.contains(ur.getRole().getId()))
|
|
.forEach(UserRole::softDelete);
|
|
|
|
// 3) Para cada rol deseado: si hay vínculo borrado => reactivar; si no existe
|
|
// => crear
|
|
for (Role role : desired) {
|
|
// ya activo
|
|
boolean activeExists = this.rolesLink.stream()
|
|
.anyMatch(ur -> !ur.isDeleted() && ur.getRole().getId().equals(role.getId()));
|
|
if (activeExists)
|
|
continue;
|
|
|
|
// existe borrado => reactivar
|
|
Optional<UserRole> deletedLink = this.rolesLink.stream()
|
|
.filter(ur -> ur.isDeleted() && ur.getRole().getId().equals(role.getId()))
|
|
.findFirst();
|
|
|
|
if (deletedLink.isPresent()) {
|
|
UserRole ur = deletedLink.get();
|
|
ur.setDeleted(false);
|
|
ur.setDeletedAt(null);
|
|
} else {
|
|
// crear nuevo vínculo
|
|
UserRole ur = new UserRole(this, role);
|
|
this.rolesLink.add(ur);
|
|
// si tienes la colección inversa en Role:
|
|
role.getUsersLink().add(ur);
|
|
}
|
|
}
|
|
}
|
|
|
|
public Integer getRoleRank() {
|
|
return roleRank;
|
|
}
|
|
|
|
public String getRolesConcat() {
|
|
return rolesConcat;
|
|
}
|
|
|
|
public boolean isDeleted() {
|
|
return deleted;
|
|
}
|
|
|
|
public void setDeleted(boolean deleted) {
|
|
this.deleted = deleted;
|
|
}
|
|
|
|
public LocalDateTime getDeletedAt() {
|
|
return deletedAt;
|
|
}
|
|
|
|
public void setDeletedAt(LocalDateTime deletedAt) {
|
|
this.deletedAt = deletedAt;
|
|
}
|
|
|
|
public Long getDeletedBy() {
|
|
return deletedBy;
|
|
}
|
|
|
|
public void setDeletedBy(Long deletedBy) {
|
|
this.deletedBy = deletedBy;
|
|
}
|
|
|
|
public Set<UserRole> getRolesLink() {
|
|
return rolesLink;
|
|
}
|
|
|
|
public void setRolesLink(Set<UserRole> rolesLink) {
|
|
this.rolesLink = rolesLink;
|
|
}
|
|
|
|
@Override
|
|
public String toString() {
|
|
return "User{" +
|
|
"id=" + id +
|
|
", fullName='" + fullName + '\'' +
|
|
", userName='" + userName + '\'' +
|
|
", enabled=" + enabled +
|
|
'}';
|
|
}
|
|
|
|
}
|