Files
Lizandro GuarnizoandClaude Sonnet 5 6942c04d27 fix(usuarios): un usuario con tipo inesperado desaparecía de todas las listas
El administrador no aparecía en /app/users.

La lista de usuarios del sistema filtraba con una lista blanca
(tipo_usuario 'sistema', '' o NULL) y la pantalla de usuarios 'gas' es la
complementaria. Un usuario con cualquier otro valor —o con uno viejo de
antes de que existiera el campo— no salía en NINGUNA de las dos: quedaba
invisible en todo el panel aunque pudiera entrar y fuera administrador.

Ahora se excluye 'gas' en vez de exigir 'sistema', así todo usuario cae en
exactamente una de las dos listas.

Además la búsqueda usaba LIKE, que en Postgres distingue mayúsculas:
buscar "lizandro" no encontraba a "Lizandro", así que el atajo obvio para
comprobarlo tampoco funcionaba. Pasa a ILIKE y también busca por email,
que es lo que la mayoría escribe.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-08-15 20:13:03 -05:00

241 lines
7.8 KiB
Go
Executable File

package models
import (
"errors"
"fmt"
"time"
"github.com/sujit-baniya/fiber-boilerplate/app"
"gorm.io/gorm"
)
type Users struct {
ID uint `gorm:"primarykey"`
CreatedAt time.Time
UpdatedAt time.Time
DeletedAt gorm.DeletedAt `gorm:"index"`
Name string `json:"name" gorm:"name"`
Email string `json:"email" gorm:"email"`
Password string `json:"password,omitempty" gorm:"password"`
EmailVerified bool `json:"email_verified" gorm:"email_verified"`
IsAdmin bool `json:"is_admin" gorm:"is_admin"`
RoleID uint `json:"role_id" gorm:"role_id"`
Role Roles `gorm:"foreignKey:RoleID"` // Establecer relación con Roles
NombreUsuario string `json:"nombre_usuario" gorm:"nombre_usuario"`
Documento string `json:"documento" gorm:"documento"`
Estado *bool `json:"estado" gorm:"estado"`
TipoUsuario string `json:"tipo" gorm:"tipo_usuario"`
CogidoUsuarioGas string `json:"cogido_usuario_gas" gorm:"cogido_usuario_gas"`
NumeroMedidor string `json:"numero_medidor" gorm:"numero_medidor"`
TelefonoFijo string `json:"telefono_fijo" gorm:"telefono_fijo"`
Celular string `json:"celular" gorm:"celular"`
TelegramChatID string `json:"telegram_chat_id" gorm:"column:telegram_chat_id"`
AceptoInfo bool `json:"acepto_info" gorm:"acepto_info"`
}
// TableName overrides the table name used by Modules to `modules`
func (Users) TableName() string {
return "users"
}
// AllModules recupera todos los módulos con búsqueda
func AllUsersGas(limit, offset int, search string) ([]Users, int64, error) {
var users []Users
var total int64
db := app.Http.Database.DB.Model(&Users{})
// ILIKE y no LIKE: en Postgres LIKE distingue mayúsculas, así que buscar
// "lizandro" no encontraba a "Lizandro". Se agrega el email porque es lo
// que la mayoría escribe cuando busca a una persona.
if search != "" {
patron := "%" + search + "%"
db = db.Where("name ILIKE ? OR nombre_usuario ILIKE ? OR email ILIKE ?", patron, patron, patron)
}
// Filtrar por tipo_usuario = 'gas'
db = db.Where("tipo_usuario = ?", "gas")
// Obtener el total de usuarios
if err := db.Count(&total).Error; err != nil {
return nil, 0, err
}
// Obtener los usuarios con paginación y precargar los roles
if err := db.Order("id DESC").Limit(limit).Offset(offset).
Preload("Role"). // Precargar la relación Role
Find(&users).Error; err != nil {
return nil, 0, err
}
return users, total, nil
}
func AllUsersSistema(limit, offset int, search string) ([]Users, int64, error) {
var users []Users
var total int64
db := app.Http.Database.DB.Model(&Users{})
// ILIKE y no LIKE: en Postgres LIKE distingue mayúsculas, así que buscar
// "lizandro" no encontraba a "Lizandro". Se agrega el email porque es lo
// que la mayoría escribe cuando busca a una persona.
if search != "" {
patron := "%" + search + "%"
db = db.Where("name ILIKE ? OR nombre_usuario ILIKE ? OR email ILIKE ?", patron, patron, patron)
}
// Se excluye 'gas' en vez de exigir 'sistema'.
//
// Antes era una lista blanca ('sistema', '' o NULL) y la pantalla de 'gas'
// es la complementaria, así que un usuario con cualquier otro valor —o con
// uno viejo de antes de que existiera el campo— no aparecía en NINGUNA de
// las dos listas: quedaba invisible en todo el panel aunque pudiera entrar
// y fuera administrador.
//
// Invertirlo garantiza que todo usuario esté en exactamente una de las dos.
db = db.Where("COALESCE(tipo_usuario, '') <> ?", "gas")
// Obtener el total de usuarios
if err := db.Count(&total).Error; err != nil {
return nil, 0, err
}
// Obtener los usuarios con paginación y precargar los roles
if err := db.Order("id DESC").Limit(limit).Offset(offset).
Preload("Role"). // Precargar la relación Role
Find(&users).Error; err != nil {
return nil, 0, err
}
return users, total, nil
}
// CreateModule creates a new module
func CreateUser(User Users) error {
if err := app.Http.Database.DB.Create(&User).Error; err != nil {
return err
}
return nil
}
// UpdateUser updates an existing user
func UpdateUser(userID uint, Name string, NombreUsuario string, Email string, RoleID int, TelegramChatID string) error {
updates := map[string]interface{}{
"name": Name,
"nombre_usuario": NombreUsuario,
"email": Email,
"role_id": RoleID,
"telegram_chat_id": TelegramChatID,
}
if err := app.Http.Database.DB.Model(&Users{}).Where("id = ?", userID).Updates(updates).Error; err != nil {
return err
}
return nil
}
// UpdateUser updates an existing user
func UpdateUserGas(userID uint, Name string, NombreUsuario string, Email string, Celular string) error {
// Crea un mapa con los campos a actualizar
updates := map[string]interface{}{
"name": Name,
"nombre_usuario": NombreUsuario,
"email": Email,
"celular": Celular,
}
// Realiza la actualización de los campos en la base de datos
if err := app.Http.Database.DB.Model(&Users{}).Where("id = ?", userID).Updates(updates).Error; err != nil {
return err
}
return nil
}
// UpdateUserPassword actualiza solo la contraseña de un usuario existente
func UpdateUserPassword(userID uint, newPassword string) error {
// Utiliza `Model` para especificar el modelo de Users y `Where` para buscar el usuario
if err := app.Http.Database.DB.Model(&Users{}).Where("id = ?", userID).Update("password", newPassword).Error; err != nil {
return err
}
return nil
}
// UpdateUser updates an existing user
func UpdateUserEstado(userID uint, Estado bool) error {
// Crea un mapa con los campos a actualizar
updates := map[string]interface{}{
"estado": Estado,
}
// Realiza la actualización de los campos en la base de datos
if err := app.Http.Database.DB.Model(&Users{}).Where("id = ?", userID).Updates(updates).Error; err != nil {
return err
}
return nil
}
// DeleteModule deletes a module by its ID
func DeleteUser(id uint) error {
if err := app.Http.Database.DB.Delete(&Users{}, id).Error; err != nil {
return err
}
return nil
}
// FindUserByID recupera un solo usuario por su ID
func FindUserByID(id interface{}) (*Users, error) {
var user Users
// Asumimos que 'db' está correctamente inicializado en otro lugar de tu aplicación
db := app.Http.Database.DB.Model(&Users{})
// Buscar el usuario por ID
if err := db.Where("id = ?", id).Preload("Role.Submodules.Module").Preload("Role.ConxDBs").First(&user).Error; err != nil {
// Manejar el error si el registro no se encuentra
if errors.Is(err, gorm.ErrRecordNotFound) {
return nil, fmt.Errorf("usuario no encontrado con ID: %d", id)
}
return nil, fmt.Errorf("error al buscar usuario: %v", err)
}
return &user, nil
}
func GetUserByUsuario(usuario string) (*Users, error) {
var user Users
fmt.Println(usuario) // Verifica el usuario recibido
db := app.Http.Database.DB.Model(&Users{})
if err := db.Where("nombre_usuario = ? AND email_verified = ? AND estado = ?", usuario, true, true).Preload("Role").First(&user).Error; err != nil {
return nil, err
}
fmt.Println(user) // Verifica el resultado
return &user, nil
}
func GetUserByUsuarioVerify(usuario string) (*Users, error) {
var user Users
if err := app.Http.Database.Where(&Users{NombreUsuario: usuario}).First(&user).Error; err != nil {
return nil, err
}
fmt.Println(user)
return &user, nil //nolint:wsl
}
func CheckUsernameExists(username string) (bool, error) {
var user Users
// Busca un registro en la base de datos
err := app.Http.Database.Where("nombre_usuario = ?", username).First(&user).Error
// Si no se encontró el registro, no es un error real
if err == gorm.ErrRecordNotFound {
return false, nil
}
// Retorna verdadero si no hubo error y falso si ocurrió un error
if err != nil {
return false, err
}
// Si no hubo error, significa que el usuario existe
return true, nil
}