first commit
This commit is contained in:
93
RS_system/Models/AsistenciaCulto.cs
Normal file
93
RS_system/Models/AsistenciaCulto.cs
Normal file
@@ -0,0 +1,93 @@
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
using System.ComponentModel.DataAnnotations.Schema;
|
||||
using Rs_system.Models.Enums;
|
||||
|
||||
namespace Rs_system.Models;
|
||||
|
||||
[Table("asistencias_culto")]
|
||||
public class AsistenciaCulto
|
||||
{
|
||||
[Key]
|
||||
[Column("id")]
|
||||
public long Id { get; set; }
|
||||
|
||||
[Column("fecha_hora_inicio")]
|
||||
[Required]
|
||||
public DateTime FechaHoraInicio { get; set; }
|
||||
|
||||
[Column("tipo_culto")]
|
||||
[Required]
|
||||
public TipoCulto TipoCulto { get; set; }
|
||||
|
||||
[Column("tipo_conteo")]
|
||||
[Required]
|
||||
public TipoConteo TipoConteo { get; set; }
|
||||
|
||||
// Campos para TipoConteo.Detallado
|
||||
[Column("hermanas_misioneras")]
|
||||
public int? HermanasMisioneras { get; set; }
|
||||
|
||||
[Column("hermanos_fraternidad")]
|
||||
public int? HermanosFraternidad { get; set; }
|
||||
|
||||
[Column("embajadores_cristo")]
|
||||
public int? EmbajadoresCristo { get; set; }
|
||||
|
||||
[Column("ninos")]
|
||||
public int? Ninos { get; set; }
|
||||
|
||||
[Column("visitas")]
|
||||
public int? Visitas { get; set; }
|
||||
|
||||
[Column("amigos")]
|
||||
public int? Amigos { get; set; }
|
||||
|
||||
// Campos para TipoConteo.General
|
||||
[Column("adultos_general")]
|
||||
public int? AdultosGeneral { get; set; }
|
||||
|
||||
// Campo para TipoConteo.Total
|
||||
[Column("total_manual")]
|
||||
public int? TotalManual { get; set; }
|
||||
|
||||
// Campos de auditoría
|
||||
[Column("observaciones")]
|
||||
[StringLength(500)]
|
||||
public string? Observaciones { get; set; }
|
||||
|
||||
[Column("creado_por")]
|
||||
public string? CreadoPor { get; set; }
|
||||
|
||||
[Column("creado_en")]
|
||||
public DateTime CreadoEn { get; set; } = DateTime.UtcNow;
|
||||
|
||||
[Column("actualizado_en")]
|
||||
public DateTime ActualizadoEn { get; set; } = DateTime.UtcNow;
|
||||
|
||||
[NotMapped]
|
||||
public int Total
|
||||
{
|
||||
get
|
||||
{
|
||||
return TipoConteo switch
|
||||
{
|
||||
TipoConteo.Detallado => (HermanasMisioneras ?? 0) +
|
||||
(HermanosFraternidad ?? 0) +
|
||||
(EmbajadoresCristo ?? 0) +
|
||||
(Ninos ?? 0) +
|
||||
(Visitas ?? 0) +
|
||||
(Amigos ?? 0),
|
||||
TipoConteo.General => (AdultosGeneral ?? 0) + (Ninos ?? 0),
|
||||
TipoConteo.Total => TotalManual ?? 0,
|
||||
_ => 0
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
[NotMapped]
|
||||
public int TotalAdultosDetallado => (HermanasMisioneras ?? 0) +
|
||||
(HermanosFraternidad ?? 0) +
|
||||
(EmbajadoresCristo ?? 0) +
|
||||
(Visitas ?? 0) +
|
||||
(Amigos ?? 0);
|
||||
}
|
||||
57
RS_system/Models/ConfiguracionSistema.cs
Normal file
57
RS_system/Models/ConfiguracionSistema.cs
Normal file
@@ -0,0 +1,57 @@
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
using System.ComponentModel.DataAnnotations.Schema;
|
||||
|
||||
namespace Rs_system.Models;
|
||||
|
||||
[Table("configuracion_sistema")]
|
||||
public class ConfiguracionSistema
|
||||
{
|
||||
[Key]
|
||||
[Column("id")]
|
||||
public int Id { get; set; }
|
||||
|
||||
[Required]
|
||||
[Column("clave")]
|
||||
[StringLength(100)]
|
||||
public string Clave { get; set; } = string.Empty;
|
||||
|
||||
[Column("valor")]
|
||||
public string? Valor { get; set; }
|
||||
|
||||
[Column("tipo_dato")]
|
||||
[StringLength(20)]
|
||||
public string TipoDato { get; set; } = "TEXTO";
|
||||
|
||||
[Column("categoria")]
|
||||
[StringLength(50)]
|
||||
public string Categoria { get; set; } = "GENERAL";
|
||||
|
||||
[Column("grupo")]
|
||||
[StringLength(50)]
|
||||
public string Grupo { get; set; } = "SISTEMA";
|
||||
|
||||
[Column("descripcion")]
|
||||
public string? Descripcion { get; set; }
|
||||
|
||||
[Column("es_editable")]
|
||||
public bool EsEditable { get; set; } = true;
|
||||
|
||||
[Column("es_publico")]
|
||||
public bool EsPublico { get; set; } = false;
|
||||
|
||||
[Column("orden")]
|
||||
public int Orden { get; set; } = 0;
|
||||
|
||||
[Column("opciones", TypeName = "jsonb")]
|
||||
public string? Opciones { get; set; }
|
||||
|
||||
[Column("validacion_regex")]
|
||||
[StringLength(200)]
|
||||
public string? ValidacionRegex { get; set; }
|
||||
|
||||
[Column("creado_en")]
|
||||
public DateTime CreadoEn { get; set; } = DateTime.UtcNow;
|
||||
|
||||
[Column("actualizado_en")]
|
||||
public DateTime ActualizadoEn { get; set; } = DateTime.UtcNow;
|
||||
}
|
||||
36
RS_system/Models/DescuentoOfrenda.cs
Normal file
36
RS_system/Models/DescuentoOfrenda.cs
Normal file
@@ -0,0 +1,36 @@
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
using System.ComponentModel.DataAnnotations.Schema;
|
||||
|
||||
namespace Rs_system.Models;
|
||||
|
||||
/// <summary>
|
||||
/// Descuento aplicado a una ofrenda (diezmo, asignaciones, etc.)
|
||||
/// </summary>
|
||||
[Table("descuentos_ofrenda")]
|
||||
public class DescuentoOfrenda
|
||||
{
|
||||
[Key]
|
||||
[Column("id")]
|
||||
public long Id { get; set; }
|
||||
|
||||
[Column("ofrenda_id")]
|
||||
[Required]
|
||||
public long OfrendaId { get; set; }
|
||||
|
||||
[Column("monto")]
|
||||
[Required]
|
||||
[Range(0.01, 999999.99)]
|
||||
public decimal Monto { get; set; }
|
||||
|
||||
[Column("concepto")]
|
||||
[Required]
|
||||
[StringLength(200)]
|
||||
public string Concepto { get; set; } = string.Empty;
|
||||
|
||||
[Column("eliminado")]
|
||||
public bool Eliminado { get; set; } = false;
|
||||
|
||||
// Navigation property
|
||||
[ForeignKey("OfrendaId")]
|
||||
public virtual Ofrenda? Ofrenda { get; set; }
|
||||
}
|
||||
8
RS_system/Models/Enums/TipoConteo.cs
Normal file
8
RS_system/Models/Enums/TipoConteo.cs
Normal file
@@ -0,0 +1,8 @@
|
||||
namespace Rs_system.Models.Enums;
|
||||
|
||||
public enum TipoConteo
|
||||
{
|
||||
Detallado = 1,
|
||||
General = 2,
|
||||
Total = 3
|
||||
}
|
||||
16
RS_system/Models/Enums/TipoCulto.cs
Normal file
16
RS_system/Models/Enums/TipoCulto.cs
Normal file
@@ -0,0 +1,16 @@
|
||||
namespace Rs_system.Models.Enums;
|
||||
|
||||
public enum TipoCulto
|
||||
{
|
||||
Matutinos = 1,
|
||||
Dominicales = 2,
|
||||
Generales = 3,
|
||||
ConcilioMisionero = 4,
|
||||
Fraternidad = 5,
|
||||
Embajadores = 6,
|
||||
AccionDeGracias = 7,
|
||||
CampanasEvangelisticas = 8,
|
||||
CultosEspeciales = 9,
|
||||
Vigilias = 10,
|
||||
Velas = 11
|
||||
}
|
||||
8
RS_system/Models/ErrorViewModel.cs
Normal file
8
RS_system/Models/ErrorViewModel.cs
Normal file
@@ -0,0 +1,8 @@
|
||||
namespace Rs_system.Models;
|
||||
|
||||
public class ErrorViewModel
|
||||
{
|
||||
public string? RequestId { get; set; }
|
||||
|
||||
public bool ShowRequestId => !string.IsNullOrEmpty(RequestId);
|
||||
}
|
||||
41
RS_system/Models/Modulo.cs
Normal file
41
RS_system/Models/Modulo.cs
Normal file
@@ -0,0 +1,41 @@
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
using System.ComponentModel.DataAnnotations.Schema;
|
||||
|
||||
namespace Rs_system.Models;
|
||||
|
||||
[Table("modulos")]
|
||||
public class Modulo
|
||||
{
|
||||
[Key]
|
||||
[Column("id")]
|
||||
public int Id { get; set; }
|
||||
|
||||
[Column("nombre")]
|
||||
[Required]
|
||||
[StringLength(100)]
|
||||
public string Nombre { get; set; } = string.Empty;
|
||||
|
||||
[Column("icono")]
|
||||
[StringLength(50)]
|
||||
public string? Icono { get; set; }
|
||||
|
||||
[Column("orden")]
|
||||
public int Orden { get; set; } = 0;
|
||||
|
||||
[Column("activo")]
|
||||
public bool Activo { get; set; } = true;
|
||||
|
||||
[Column("creado_en")]
|
||||
public DateTime CreadoEn { get; set; } = DateTime.UtcNow;
|
||||
|
||||
[Column("parent_id")]
|
||||
public int? ParentId { get; set; }
|
||||
|
||||
// Navigation properties
|
||||
[ForeignKey("ParentId")]
|
||||
public virtual Modulo? Parent { get; set; }
|
||||
|
||||
public virtual ICollection<Modulo> SubModulos { get; set; } = new List<Modulo>();
|
||||
|
||||
public virtual ICollection<Permiso> Permisos { get; set; } = new List<Permiso>();
|
||||
}
|
||||
45
RS_system/Models/Ofrenda.cs
Normal file
45
RS_system/Models/Ofrenda.cs
Normal file
@@ -0,0 +1,45 @@
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
using System.ComponentModel.DataAnnotations.Schema;
|
||||
|
||||
namespace Rs_system.Models;
|
||||
|
||||
/// <summary>
|
||||
/// Ofrenda individual dentro de un registro de culto
|
||||
/// </summary>
|
||||
[Table("ofrendas")]
|
||||
public class Ofrenda
|
||||
{
|
||||
[Key]
|
||||
[Column("id")]
|
||||
public long Id { get; set; }
|
||||
|
||||
[Column("registro_culto_id")]
|
||||
[Required]
|
||||
public long RegistroCultoId { get; set; }
|
||||
|
||||
[Column("monto")]
|
||||
[Required]
|
||||
[Range(0.01, 999999.99)]
|
||||
public decimal Monto { get; set; }
|
||||
|
||||
[Column("concepto")]
|
||||
[Required]
|
||||
[StringLength(200)]
|
||||
public string Concepto { get; set; } = string.Empty;
|
||||
|
||||
[Column("eliminado")]
|
||||
public bool Eliminado { get; set; } = false;
|
||||
|
||||
// Navigation properties
|
||||
[ForeignKey("RegistroCultoId")]
|
||||
public virtual RegistroCulto? RegistroCulto { get; set; }
|
||||
|
||||
public virtual ICollection<DescuentoOfrenda> Descuentos { get; set; } = new List<DescuentoOfrenda>();
|
||||
|
||||
// Calculated properties
|
||||
[NotMapped]
|
||||
public decimal TotalDescuentos => Descuentos?.Where(d => !d.Eliminado).Sum(d => d.Monto) ?? 0;
|
||||
|
||||
[NotMapped]
|
||||
public decimal MontoNeto => Monto - TotalDescuentos;
|
||||
}
|
||||
47
RS_system/Models/Permiso.cs
Normal file
47
RS_system/Models/Permiso.cs
Normal file
@@ -0,0 +1,47 @@
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
using System.ComponentModel.DataAnnotations.Schema;
|
||||
|
||||
namespace Rs_system.Models;
|
||||
|
||||
[Table("permisos")]
|
||||
public class Permiso
|
||||
{
|
||||
[Key]
|
||||
[Column("id")]
|
||||
public int Id { get; set; }
|
||||
|
||||
[Column("modulo_id")]
|
||||
[Required]
|
||||
public int ModuloId { get; set; }
|
||||
|
||||
[ForeignKey("ModuloId")]
|
||||
public virtual Modulo? Modulo { get; set; }
|
||||
|
||||
[Column("codigo")]
|
||||
[Required]
|
||||
[StringLength(100)]
|
||||
public string Codigo { get; set; } = string.Empty;
|
||||
|
||||
[Column("nombre")]
|
||||
[Required]
|
||||
[StringLength(100)]
|
||||
public string Nombre { get; set; } = string.Empty;
|
||||
|
||||
[Column("descripcion")]
|
||||
public string? Descripcion { get; set; }
|
||||
|
||||
[Column("url")]
|
||||
public string? Url { get; set; }
|
||||
|
||||
[Column("icono")]
|
||||
public string? Icono { get; set; }
|
||||
|
||||
[Column("orden")]
|
||||
public int Orden { get; set; } = 0;
|
||||
|
||||
[Column("es_menu")]
|
||||
public bool EsMenu { get; set; } = true;
|
||||
|
||||
[Column("creado_en")]
|
||||
public DateTime CreadoEn { get; set; } = DateTime.UtcNow;
|
||||
}
|
||||
64
RS_system/Models/Persona.cs
Normal file
64
RS_system/Models/Persona.cs
Normal file
@@ -0,0 +1,64 @@
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
using System.ComponentModel.DataAnnotations.Schema;
|
||||
|
||||
namespace Rs_system.Models;
|
||||
|
||||
[Table("personas")]
|
||||
public class Persona
|
||||
{
|
||||
[Key]
|
||||
[Column("id")]
|
||||
public long Id { get; set; }
|
||||
|
||||
[Column("nombres")]
|
||||
[Required]
|
||||
[StringLength(100)]
|
||||
public string Nombres { get; set; } = string.Empty;
|
||||
|
||||
[Column("apellidos")]
|
||||
[Required]
|
||||
[StringLength(100)]
|
||||
public string Apellidos { get; set; } = string.Empty;
|
||||
|
||||
[Column("dui")]
|
||||
[StringLength(12)]
|
||||
public string? Dui { get; set; }
|
||||
|
||||
[Column("nit")]
|
||||
[StringLength(17)]
|
||||
public string? Nit { get; set; }
|
||||
|
||||
[Column("fecha_nacimiento")]
|
||||
public DateOnly? FechaNacimiento { get; set; }
|
||||
|
||||
[Column("genero")]
|
||||
[StringLength(1)]
|
||||
public string? Genero { get; set; }
|
||||
|
||||
[Column("email")]
|
||||
[StringLength(255)]
|
||||
public string? Email { get; set; }
|
||||
|
||||
[Column("telefono")]
|
||||
[StringLength(20)]
|
||||
public string? Telefono { get; set; }
|
||||
|
||||
[Column("direccion")]
|
||||
public string? Direccion { get; set; }
|
||||
|
||||
[Column("foto_url")]
|
||||
public string? FotoUrl { get; set; }
|
||||
|
||||
[Column("activo")]
|
||||
public bool Activo { get; set; } = true;
|
||||
|
||||
[Column("creado_en")]
|
||||
public DateTime CreadoEn { get; set; } = DateTime.UtcNow;
|
||||
|
||||
[Column("actualizado_en")]
|
||||
public DateTime ActualizadoEn { get; set; } = DateTime.UtcNow;
|
||||
|
||||
// Nombre completo
|
||||
[NotMapped]
|
||||
public string NombreCompleto => $"{Nombres} {Apellidos}";
|
||||
}
|
||||
49
RS_system/Models/RegistroCulto.cs
Normal file
49
RS_system/Models/RegistroCulto.cs
Normal file
@@ -0,0 +1,49 @@
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
using System.ComponentModel.DataAnnotations.Schema;
|
||||
|
||||
namespace Rs_system.Models;
|
||||
|
||||
/// <summary>
|
||||
/// Registro de ofrendas de un culto específico
|
||||
/// </summary>
|
||||
[Table("registros_culto")]
|
||||
public class RegistroCulto
|
||||
{
|
||||
[Key]
|
||||
[Column("id")]
|
||||
public long Id { get; set; }
|
||||
|
||||
[Column("fecha")]
|
||||
[Required]
|
||||
public DateOnly Fecha { get; set; }
|
||||
|
||||
[Column("observaciones")]
|
||||
[StringLength(500)]
|
||||
public string? Observaciones { get; set; }
|
||||
|
||||
[Column("creado_por")]
|
||||
[StringLength(100)]
|
||||
public string? CreadoPor { get; set; }
|
||||
|
||||
[Column("creado_en")]
|
||||
public DateTime CreadoEn { get; set; } = DateTime.UtcNow;
|
||||
|
||||
[Column("actualizado_en")]
|
||||
public DateTime ActualizadoEn { get; set; } = DateTime.UtcNow;
|
||||
|
||||
[Column("eliminado")]
|
||||
public bool Eliminado { get; set; } = false;
|
||||
|
||||
// Navigation property
|
||||
public virtual ICollection<Ofrenda> Ofrendas { get; set; } = new List<Ofrenda>();
|
||||
|
||||
// Calculated properties
|
||||
[NotMapped]
|
||||
public decimal TotalOfrendas => Ofrendas?.Sum(o => o.Monto) ?? 0;
|
||||
|
||||
[NotMapped]
|
||||
public decimal TotalDescuentos => Ofrendas?.Sum(o => o.TotalDescuentos) ?? 0;
|
||||
|
||||
[NotMapped]
|
||||
public decimal MontoNeto => TotalOfrendas - TotalDescuentos;
|
||||
}
|
||||
24
RS_system/Models/RolPermiso.cs
Normal file
24
RS_system/Models/RolPermiso.cs
Normal file
@@ -0,0 +1,24 @@
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
using System.ComponentModel.DataAnnotations.Schema;
|
||||
|
||||
namespace Rs_system.Models;
|
||||
|
||||
[Table("roles_permisos")]
|
||||
public class RolPermiso
|
||||
{
|
||||
[Column("rol_id")]
|
||||
public int RolId { get; set; }
|
||||
|
||||
[Column("permiso_id")]
|
||||
public int PermisoId { get; set; }
|
||||
|
||||
[Column("asignado_en")]
|
||||
public DateTime AsignadoEn { get; set; } = DateTime.UtcNow;
|
||||
|
||||
// Navigation properties
|
||||
[ForeignKey("RolId")]
|
||||
public RolSistema Rol { get; set; } = null!;
|
||||
|
||||
[ForeignKey("PermisoId")]
|
||||
public Permiso Permiso { get; set; } = null!;
|
||||
}
|
||||
31
RS_system/Models/RolSistema.cs
Normal file
31
RS_system/Models/RolSistema.cs
Normal file
@@ -0,0 +1,31 @@
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
using System.ComponentModel.DataAnnotations.Schema;
|
||||
|
||||
namespace Rs_system.Models;
|
||||
|
||||
[Table("roles_sistema")]
|
||||
public class RolSistema
|
||||
{
|
||||
[Key]
|
||||
[Column("id")]
|
||||
public int Id { get; set; }
|
||||
|
||||
[Column("codigo")]
|
||||
[Required]
|
||||
[StringLength(50)]
|
||||
public string Codigo { get; set; } = string.Empty;
|
||||
|
||||
[Column("nombre")]
|
||||
[Required]
|
||||
[StringLength(100)]
|
||||
public string Nombre { get; set; } = string.Empty;
|
||||
|
||||
[Column("descripcion")]
|
||||
public string? Descripcion { get; set; }
|
||||
|
||||
[Column("creado_en")]
|
||||
public DateTime CreadoEn { get; set; } = DateTime.UtcNow;
|
||||
|
||||
public ICollection<RolUsuario> RolesUsuario { get; set; } = new List<RolUsuario>();
|
||||
public ICollection<RolPermiso> RolesPermisos { get; set; } = new List<RolPermiso>();
|
||||
}
|
||||
24
RS_system/Models/RolUsuario.cs
Normal file
24
RS_system/Models/RolUsuario.cs
Normal file
@@ -0,0 +1,24 @@
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
using System.ComponentModel.DataAnnotations.Schema;
|
||||
|
||||
namespace Rs_system.Models;
|
||||
|
||||
[Table("roles_usuario")]
|
||||
public class RolUsuario
|
||||
{
|
||||
[Column("usuario_id")]
|
||||
public long UsuarioId { get; set; }
|
||||
|
||||
[Column("rol_id")]
|
||||
public int RolId { get; set; }
|
||||
|
||||
[Column("asignado_en")]
|
||||
public DateTime AsignadoEn { get; set; } = DateTime.UtcNow;
|
||||
|
||||
// Navigation properties
|
||||
[ForeignKey("UsuarioId")]
|
||||
public Usuario Usuario { get; set; } = null!;
|
||||
|
||||
[ForeignKey("RolId")]
|
||||
public RolSistema Rol { get; set; } = null!;
|
||||
}
|
||||
47
RS_system/Models/Usuario.cs
Normal file
47
RS_system/Models/Usuario.cs
Normal file
@@ -0,0 +1,47 @@
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
using System.ComponentModel.DataAnnotations.Schema;
|
||||
|
||||
namespace Rs_system.Models;
|
||||
|
||||
[Table("usuarios")]
|
||||
public class Usuario
|
||||
{
|
||||
[Key]
|
||||
[Column("id")]
|
||||
public long Id { get; set; }
|
||||
|
||||
[Column("persona_id")]
|
||||
public long? PersonaId { get; set; }
|
||||
|
||||
[Column("nombre_usuario")]
|
||||
[Required]
|
||||
[StringLength(50)]
|
||||
public string NombreUsuario { get; set; } = string.Empty;
|
||||
|
||||
[Column("email")]
|
||||
[Required]
|
||||
[StringLength(255)]
|
||||
public string Email { get; set; } = string.Empty;
|
||||
|
||||
[Column("hash_contrasena")]
|
||||
[Required]
|
||||
public string HashContrasena { get; set; } = string.Empty;
|
||||
|
||||
[Column("activo")]
|
||||
public bool Activo { get; set; } = true;
|
||||
|
||||
[Column("ultimo_login")]
|
||||
public DateTime? UltimoLogin { get; set; }
|
||||
|
||||
[Column("creado_en")]
|
||||
public DateTime CreadoEn { get; set; } = DateTime.UtcNow;
|
||||
|
||||
[Column("actualizado_en")]
|
||||
public DateTime ActualizadoEn { get; set; } = DateTime.UtcNow;
|
||||
|
||||
// Navigation properties
|
||||
[ForeignKey("PersonaId")]
|
||||
public Persona? Persona { get; set; }
|
||||
|
||||
public ICollection<RolUsuario> RolesUsuario { get; set; } = new List<RolUsuario>();
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
using System.ComponentModel;
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
using Rs_system.Models.Enums;
|
||||
|
||||
namespace Rs_system.Models.ViewModels;
|
||||
|
||||
public class AsistenciaCultoFiltroViewModel
|
||||
{
|
||||
[Display(Name = "Fecha Desde")]
|
||||
[DataType(DataType.Date)]
|
||||
public DateTime? FechaDesde { get; set; }
|
||||
|
||||
[Display(Name = "Fecha Hasta")]
|
||||
[DataType(DataType.Date)]
|
||||
public DateTime? FechaHasta { get; set; }
|
||||
|
||||
[Display(Name = "Tipo de Culto")]
|
||||
public TipoCulto? TipoCulto { get; set; }
|
||||
|
||||
[Display(Name = "Tipo de Conteo")]
|
||||
public TipoConteo? TipoConteo { get; set; }
|
||||
|
||||
public IEnumerable<AsistenciaCulto>? Resultados { get; set; }
|
||||
}
|
||||
149
RS_system/Models/ViewModels/AsistenciaCultoViewModel.cs
Normal file
149
RS_system/Models/ViewModels/AsistenciaCultoViewModel.cs
Normal file
@@ -0,0 +1,149 @@
|
||||
using System.ComponentModel;
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
using Rs_system.Models.Enums;
|
||||
|
||||
namespace Rs_system.Models.ViewModels;
|
||||
|
||||
public class AsistenciaCultoViewModel : IValidatableObject
|
||||
{
|
||||
public long? Id { get; set; }
|
||||
|
||||
[Required(ErrorMessage = "La fecha y hora de inicio es requerida")]
|
||||
[Display(Name = "Fecha y Hora de Inicio")]
|
||||
[DataType(DataType.DateTime)]
|
||||
public DateTime FechaHoraInicio { get; set; } = DateTime.Now;
|
||||
|
||||
[Required(ErrorMessage = "El tipo de culto es requerido")]
|
||||
[Display(Name = "Tipo de Culto")]
|
||||
public TipoCulto TipoCulto { get; set; }
|
||||
|
||||
[Required(ErrorMessage = "El tipo de conteo es requerido")]
|
||||
[Display(Name = "Tipo de Conteo")]
|
||||
public TipoConteo TipoConteo { get; set; }
|
||||
|
||||
// Campos para TipoConteo.Detallado
|
||||
[Display(Name = "Hermanas (Concilio Misionero Femenil)")]
|
||||
[Range(0, 10000, ErrorMessage = "El valor debe estar entre 0 y 10000")]
|
||||
public int? HermanasMisioneras { get; set; }
|
||||
|
||||
[Display(Name = "Hermanos (Fraternidad de Varones)")]
|
||||
[Range(0, 10000, ErrorMessage = "El valor debe estar entre 0 y 10000")]
|
||||
public int? HermanosFraternidad { get; set; }
|
||||
|
||||
[Display(Name = "Embajadores de Cristo")]
|
||||
[Range(0, 10000, ErrorMessage = "El valor debe estar entre 0 y 10000")]
|
||||
public int? EmbajadoresCristo { get; set; }
|
||||
|
||||
[Display(Name = "Niños")]
|
||||
[Range(0, 10000, ErrorMessage = "El valor debe estar entre 0 y 10000")]
|
||||
public int? Ninos { get; set; }
|
||||
|
||||
[Display(Name = "Visitas")]
|
||||
[Range(0, 10000, ErrorMessage = "El valor debe estar entre 0 y 10000")]
|
||||
public int? Visitas { get; set; }
|
||||
|
||||
[Display(Name = "Amigos")]
|
||||
[Range(0, 10000, ErrorMessage = "El valor debe estar entre 0 y 10000")]
|
||||
public int? Amigos { get; set; }
|
||||
|
||||
// Campo para TipoConteo.General
|
||||
[Display(Name = "Adultos en General")]
|
||||
[Range(0, 10000, ErrorMessage = "El valor debe estar entre 0 y 10000")]
|
||||
public int? AdultosGeneral { get; set; }
|
||||
|
||||
// Campo para TipoConteo.Total
|
||||
[Display(Name = "Total Presente")]
|
||||
[Range(0, 10000, ErrorMessage = "El valor debe estar entre 0 y 10000")]
|
||||
public int? TotalManual { get; set; }
|
||||
|
||||
[Display(Name = "Observaciones")]
|
||||
[StringLength(500, ErrorMessage = "Las observaciones no pueden exceder 500 caracteres")]
|
||||
public string? Observaciones { get; set; }
|
||||
|
||||
// Propiedades calculadas (solo lectura)
|
||||
[Display(Name = "Total Calculado")]
|
||||
[ReadOnly(true)]
|
||||
public int Total
|
||||
{
|
||||
get
|
||||
{
|
||||
return TipoConteo switch
|
||||
{
|
||||
TipoConteo.Detallado => (HermanasMisioneras ?? 0) +
|
||||
(HermanosFraternidad ?? 0) +
|
||||
(EmbajadoresCristo ?? 0) +
|
||||
(Ninos ?? 0) +
|
||||
(Visitas ?? 0) +
|
||||
(Amigos ?? 0),
|
||||
TipoConteo.General => (AdultosGeneral ?? 0) + (Ninos ?? 0),
|
||||
TipoConteo.Total => TotalManual ?? 0,
|
||||
_ => 0
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
public IEnumerable<ValidationResult> Validate(ValidationContext validationContext)
|
||||
{
|
||||
var results = new List<ValidationResult>();
|
||||
|
||||
// Validar según TipoConteo
|
||||
switch (TipoConteo)
|
||||
{
|
||||
case TipoConteo.Detallado:
|
||||
// Todos los campos detallados son requeridos
|
||||
if (!HermanasMisioneras.HasValue)
|
||||
results.Add(new ValidationResult("El campo 'Hermanas' es requerido para conteo detallado", new[] { nameof(HermanasMisioneras) }));
|
||||
else if (HermanasMisioneras.Value < 0)
|
||||
results.Add(new ValidationResult("El campo 'Hermanas' debe ser mayor o igual a 0", new[] { nameof(HermanasMisioneras) }));
|
||||
|
||||
if (!HermanosFraternidad.HasValue)
|
||||
results.Add(new ValidationResult("El campo 'Hermanos' es requerido para conteo detallado", new[] { nameof(HermanosFraternidad) }));
|
||||
else if (HermanosFraternidad.Value < 0)
|
||||
results.Add(new ValidationResult("El campo 'Hermanos' debe ser mayor o igual a 0", new[] { nameof(HermanosFraternidad) }));
|
||||
|
||||
if (!EmbajadoresCristo.HasValue)
|
||||
results.Add(new ValidationResult("El campo 'Embajadores' es requerido para conteo detallado", new[] { nameof(EmbajadoresCristo) }));
|
||||
else if (EmbajadoresCristo.Value < 0)
|
||||
results.Add(new ValidationResult("El campo 'Embajadores' debe ser mayor o igual a 0", new[] { nameof(EmbajadoresCristo) }));
|
||||
|
||||
if (!Ninos.HasValue)
|
||||
results.Add(new ValidationResult("El campo 'Niños' es requerido para conteo detallado", new[] { nameof(Ninos) }));
|
||||
else if (Ninos.Value < 0)
|
||||
results.Add(new ValidationResult("El campo 'Niños' debe ser mayor o igual a 0", new[] { nameof(Ninos) }));
|
||||
|
||||
if (!Visitas.HasValue)
|
||||
results.Add(new ValidationResult("El campo 'Visitas' es requerido para conteo detallado", new[] { nameof(Visitas) }));
|
||||
else if (Visitas.Value < 0)
|
||||
results.Add(new ValidationResult("El campo 'Visitas' debe ser mayor o igual a 0", new[] { nameof(Visitas) }));
|
||||
|
||||
if (!Amigos.HasValue)
|
||||
results.Add(new ValidationResult("El campo 'Amigos' es requerido para conteo detallado", new[] { nameof(Amigos) }));
|
||||
else if (Amigos.Value < 0)
|
||||
results.Add(new ValidationResult("El campo 'Amigos' debe ser mayor o igual a 0", new[] { nameof(Amigos) }));
|
||||
break;
|
||||
|
||||
case TipoConteo.General:
|
||||
// AdultosGeneral y Ninos son requeridos
|
||||
if (!AdultosGeneral.HasValue)
|
||||
results.Add(new ValidationResult("El campo 'Adultos en General' es requerido para conteo general", new[] { nameof(AdultosGeneral) }));
|
||||
else if (AdultosGeneral.Value < 0)
|
||||
results.Add(new ValidationResult("El campo 'Adultos en General' debe ser mayor o igual a 0", new[] { nameof(AdultosGeneral) }));
|
||||
|
||||
if (!Ninos.HasValue)
|
||||
results.Add(new ValidationResult("El campo 'Niños' es requerido para conteo general", new[] { nameof(Ninos) }));
|
||||
else if (Ninos.Value < 0)
|
||||
results.Add(new ValidationResult("El campo 'Niños' debe ser mayor o igual a 0", new[] { nameof(Ninos) }));
|
||||
break;
|
||||
|
||||
case TipoConteo.Total:
|
||||
// Solo TotalManual es requerido
|
||||
if (!TotalManual.HasValue)
|
||||
results.Add(new ValidationResult("El campo 'Total Presente' es requerido para conteo total", new[] { nameof(TotalManual) }));
|
||||
else if (TotalManual.Value < 0)
|
||||
results.Add(new ValidationResult("El campo 'Total Presente' debe ser mayor o igual a 0", new[] { nameof(TotalManual) }));
|
||||
break;
|
||||
}
|
||||
|
||||
return results;
|
||||
}
|
||||
}
|
||||
18
RS_system/Models/ViewModels/LoginViewModel.cs
Normal file
18
RS_system/Models/ViewModels/LoginViewModel.cs
Normal file
@@ -0,0 +1,18 @@
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
|
||||
namespace Rs_system.Models.ViewModels;
|
||||
|
||||
public class LoginViewModel
|
||||
{
|
||||
[Required(ErrorMessage = "El nombre de usuario es requerido")]
|
||||
[Display(Name = "Usuario")]
|
||||
public string NombreUsuario { get; set; } = string.Empty;
|
||||
|
||||
[Required(ErrorMessage = "La contraseña es requerida")]
|
||||
[DataType(DataType.Password)]
|
||||
[Display(Name = "Contraseña")]
|
||||
public string Contrasena { get; set; } = string.Empty;
|
||||
|
||||
[Display(Name = "Recordarme")]
|
||||
public bool RecordarMe { get; set; }
|
||||
}
|
||||
20
RS_system/Models/ViewModels/MenuViewModel.cs
Normal file
20
RS_system/Models/ViewModels/MenuViewModel.cs
Normal file
@@ -0,0 +1,20 @@
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace Rs_system.Models.ViewModels
|
||||
{
|
||||
public class MenuViewModel
|
||||
{
|
||||
public List<MenuItem> Items { get; set; } = new List<MenuItem>();
|
||||
}
|
||||
|
||||
public class MenuItem
|
||||
{
|
||||
public string Title { get; set; } = string.Empty;
|
||||
public string? Icon { get; set; }
|
||||
public string? Url { get; set; }
|
||||
public bool IsActive { get; set; }
|
||||
public bool IsGroup { get; set; } // True if it's a module with children
|
||||
public List<MenuItem> Children { get; set; } = new List<MenuItem>();
|
||||
public int Order { get; set; }
|
||||
}
|
||||
}
|
||||
39
RS_system/Models/ViewModels/RegisterViewModel.cs
Normal file
39
RS_system/Models/ViewModels/RegisterViewModel.cs
Normal file
@@ -0,0 +1,39 @@
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
|
||||
namespace Rs_system.Models.ViewModels;
|
||||
|
||||
public class RegisterViewModel
|
||||
{
|
||||
[Required(ErrorMessage = "Los nombres son requeridos")]
|
||||
[StringLength(100, ErrorMessage = "Máximo 100 caracteres")]
|
||||
[Display(Name = "Nombres")]
|
||||
public string Nombres { get; set; } = string.Empty;
|
||||
|
||||
[Required(ErrorMessage = "Los apellidos son requeridos")]
|
||||
[StringLength(100, ErrorMessage = "Máximo 100 caracteres")]
|
||||
[Display(Name = "Apellidos")]
|
||||
public string Apellidos { get; set; } = string.Empty;
|
||||
|
||||
[Required(ErrorMessage = "El nombre de usuario es requerido")]
|
||||
[StringLength(50, MinimumLength = 3, ErrorMessage = "El usuario debe tener entre 3 y 50 caracteres")]
|
||||
[RegularExpression(@"^[a-zA-Z0-9_]+$", ErrorMessage = "Solo letras, números y guiones bajos")]
|
||||
[Display(Name = "Nombre de Usuario")]
|
||||
public string NombreUsuario { get; set; } = string.Empty;
|
||||
|
||||
[Required(ErrorMessage = "El correo electrónico es requerido")]
|
||||
[EmailAddress(ErrorMessage = "Correo electrónico inválido")]
|
||||
[Display(Name = "Correo Electrónico")]
|
||||
public string Email { get; set; } = string.Empty;
|
||||
|
||||
[Required(ErrorMessage = "La contraseña es requerida")]
|
||||
[StringLength(100, MinimumLength = 6, ErrorMessage = "La contraseña debe tener al menos 6 caracteres")]
|
||||
[DataType(DataType.Password)]
|
||||
[Display(Name = "Contraseña")]
|
||||
public string Contrasena { get; set; } = string.Empty;
|
||||
|
||||
[Required(ErrorMessage = "Debe confirmar la contraseña")]
|
||||
[Compare("Contrasena", ErrorMessage = "Las contraseñas no coinciden")]
|
||||
[DataType(DataType.Password)]
|
||||
[Display(Name = "Confirmar Contraseña")]
|
||||
public string ConfirmarContrasena { get; set; } = string.Empty;
|
||||
}
|
||||
71
RS_system/Models/ViewModels/RegistroCultoViewModel.cs
Normal file
71
RS_system/Models/ViewModels/RegistroCultoViewModel.cs
Normal file
@@ -0,0 +1,71 @@
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
|
||||
namespace Rs_system.Models.ViewModels;
|
||||
|
||||
/// <summary>
|
||||
/// ViewModel for creating/editing offering records
|
||||
/// </summary>
|
||||
public class RegistroCultoViewModel
|
||||
{
|
||||
public long? Id { get; set; }
|
||||
|
||||
[Required(ErrorMessage = "La fecha es requerida")]
|
||||
[Display(Name = "Fecha del Culto")]
|
||||
[DataType(DataType.Date)]
|
||||
public DateOnly Fecha { get; set; } = DateOnly.FromDateTime(DateTime.Today);
|
||||
|
||||
[Display(Name = "Observaciones")]
|
||||
[StringLength(500, ErrorMessage = "Las observaciones no pueden exceder 500 caracteres")]
|
||||
public string? Observaciones { get; set; }
|
||||
|
||||
public List<OfrendaItemViewModel> Ofrendas { get; set; } = new();
|
||||
|
||||
// Calculated properties for display
|
||||
public decimal TotalOfrendas => Ofrendas?.Sum(o => o.Monto) ?? 0;
|
||||
public decimal TotalDescuentos => Ofrendas?.Sum(o => o.TotalDescuentos) ?? 0;
|
||||
public decimal MontoNeto => TotalOfrendas - TotalDescuentos;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// ViewModel for an individual offering
|
||||
/// </summary>
|
||||
public class OfrendaItemViewModel
|
||||
{
|
||||
public long? Id { get; set; }
|
||||
|
||||
[Required(ErrorMessage = "El monto es requerido")]
|
||||
[Display(Name = "Monto")]
|
||||
[Range(0.01, 999999.99, ErrorMessage = "El monto debe ser mayor a 0")]
|
||||
[DataType(DataType.Currency)]
|
||||
public decimal Monto { get; set; }
|
||||
|
||||
[Required(ErrorMessage = "El concepto es requerido")]
|
||||
[Display(Name = "Concepto")]
|
||||
[StringLength(200, ErrorMessage = "El concepto no puede exceder 200 caracteres")]
|
||||
public string Concepto { get; set; } = string.Empty;
|
||||
|
||||
public List<DescuentoItemViewModel> Descuentos { get; set; } = new();
|
||||
|
||||
// Calculated properties
|
||||
public decimal TotalDescuentos => Descuentos?.Sum(d => d.Monto) ?? 0;
|
||||
public decimal MontoNeto => Monto - TotalDescuentos;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// ViewModel for a deduction from an offering
|
||||
/// </summary>
|
||||
public class DescuentoItemViewModel
|
||||
{
|
||||
public long? Id { get; set; }
|
||||
|
||||
[Required(ErrorMessage = "El monto es requerido")]
|
||||
[Display(Name = "Monto")]
|
||||
[Range(0.01, 999999.99, ErrorMessage = "El monto debe ser mayor a 0")]
|
||||
[DataType(DataType.Currency)]
|
||||
public decimal Monto { get; set; }
|
||||
|
||||
[Required(ErrorMessage = "El concepto es requerido")]
|
||||
[Display(Name = "Concepto")]
|
||||
[StringLength(200, ErrorMessage = "El concepto no puede exceder 200 caracteres")]
|
||||
public string Concepto { get; set; } = string.Empty;
|
||||
}
|
||||
45
RS_system/Models/ViewModels/UsuarioViewModel.cs
Normal file
45
RS_system/Models/ViewModels/UsuarioViewModel.cs
Normal file
@@ -0,0 +1,45 @@
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
|
||||
namespace Rs_system.Models.ViewModels;
|
||||
|
||||
public class UsuarioViewModel
|
||||
{
|
||||
public long? Id { get; set; }
|
||||
|
||||
[Required(ErrorMessage = "Los nombres son requeridos")]
|
||||
[Display(Name = "Nombres")]
|
||||
public string Nombres { get; set; } = string.Empty;
|
||||
|
||||
[Required(ErrorMessage = "Los apellidos son requeridos")]
|
||||
[Display(Name = "Apellidos")]
|
||||
public string Apellidos { get; set; } = string.Empty;
|
||||
|
||||
[Required(ErrorMessage = "El nombre de usuario es requerido")]
|
||||
[Display(Name = "Nombre de Usuario")]
|
||||
[StringLength(50)]
|
||||
public string NombreUsuario { get; set; } = string.Empty;
|
||||
|
||||
[Required(ErrorMessage = "El correo electrónico es requerido")]
|
||||
[EmailAddress(ErrorMessage = "Correo electrónico inválido")]
|
||||
[Display(Name = "Email")]
|
||||
public string Email { get; set; } = string.Empty;
|
||||
|
||||
[Display(Name = "Contraseña")]
|
||||
[DataType(DataType.Password)]
|
||||
[StringLength(100, MinimumLength = 6, ErrorMessage = "La contraseña debe tener al menos 6 caracteres")]
|
||||
public string? Contrasena { get; set; }
|
||||
|
||||
[Display(Name = "Confirmar Contraseña")]
|
||||
[DataType(DataType.Password)]
|
||||
[Compare("Contrasena", ErrorMessage = "Las contraseñas no coinciden")]
|
||||
public string? ConfirmarContrasena { get; set; }
|
||||
|
||||
[Display(Name = "Estado")]
|
||||
public bool Activo { get; set; } = true;
|
||||
|
||||
[Display(Name = "Teléfono")]
|
||||
public string? Telefono { get; set; }
|
||||
|
||||
[Display(Name = "Roles Asignados")]
|
||||
public List<int> SelectedRoles { get; set; } = new List<int>();
|
||||
}
|
||||
Reference in New Issue
Block a user