cinu
This commit is contained in:
48
RS_system/Models/DiezmoBeneficiario.cs
Normal file
48
RS_system/Models/DiezmoBeneficiario.cs
Normal file
@@ -0,0 +1,48 @@
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
using System.ComponentModel.DataAnnotations.Schema;
|
||||
|
||||
namespace Rs_system.Models;
|
||||
|
||||
/// <summary>
|
||||
/// Personas o entidades que pueden recibir salidas de diezmos
|
||||
/// (pastor, tesorero, organismos externos, etc.)
|
||||
/// </summary>
|
||||
[Table("diezmo_beneficiarios")]
|
||||
public class DiezmoBeneficiario
|
||||
{
|
||||
[Key]
|
||||
[Column("id")]
|
||||
public long Id { get; set; }
|
||||
|
||||
[Column("nombre")]
|
||||
[Required]
|
||||
[StringLength(150)]
|
||||
public string Nombre { get; set; } = string.Empty;
|
||||
|
||||
[Column("descripcion")]
|
||||
[StringLength(300)]
|
||||
public string? Descripcion { get; set; }
|
||||
|
||||
[Column("activo")]
|
||||
public bool Activo { get; set; } = true;
|
||||
|
||||
[Column("eliminado")]
|
||||
public bool Eliminado { get; set; } = false;
|
||||
|
||||
[Column("creado_en")]
|
||||
public DateTime CreadoEn { get; set; } = DateTime.UtcNow;
|
||||
|
||||
[Column("creado_por")]
|
||||
[StringLength(100)]
|
||||
public string? CreadoPor { get; set; }
|
||||
|
||||
[Column("actualizado_en")]
|
||||
public DateTime ActualizadoEn { get; set; } = DateTime.UtcNow;
|
||||
|
||||
[Column("actualizado_por")]
|
||||
[StringLength(100)]
|
||||
public string? ActualizadoPor { get; set; }
|
||||
|
||||
// Navegación
|
||||
public virtual ICollection<DiezmoSalida> Salidas { get; set; } = new List<DiezmoSalida>();
|
||||
}
|
||||
74
RS_system/Models/DiezmoCierre.cs
Normal file
74
RS_system/Models/DiezmoCierre.cs
Normal file
@@ -0,0 +1,74 @@
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
using System.ComponentModel.DataAnnotations.Schema;
|
||||
|
||||
namespace Rs_system.Models;
|
||||
|
||||
/// <summary>
|
||||
/// Agregado raíz del módulo de diezmos.
|
||||
/// Representa un período/corte de diezmos (la fecha la elige el operador libremente).
|
||||
/// Un cierre por fecha (UNIQUE en fecha).
|
||||
/// </summary>
|
||||
[Table("diezmo_cierres")]
|
||||
public class DiezmoCierre
|
||||
{
|
||||
[Key]
|
||||
[Column("id")]
|
||||
public long Id { get; set; }
|
||||
|
||||
/// <summary>Fecha del cierre. UNIQUE — no pueden existir dos cierres para el mismo día.</summary>
|
||||
[Column("fecha")]
|
||||
[Required]
|
||||
public DateOnly Fecha { get; set; }
|
||||
|
||||
[Column("cerrado")]
|
||||
public bool Cerrado { get; set; } = false;
|
||||
|
||||
[Column("fecha_cierre")]
|
||||
public DateTime? FechaCierre { get; set; }
|
||||
|
||||
[Column("cerrado_por")]
|
||||
[StringLength(100)]
|
||||
public string? CerradoPor { get; set; }
|
||||
|
||||
[Column("observaciones")]
|
||||
[StringLength(500)]
|
||||
public string? Observaciones { get; set; }
|
||||
|
||||
// ── Totales calculados (persistidos para consulta rápida en el listado) ──
|
||||
[Column("total_recibido", TypeName = "numeric(12,2)")]
|
||||
public decimal TotalRecibido { get; set; } = 0;
|
||||
|
||||
[Column("total_cambio", TypeName = "numeric(12,2)")]
|
||||
public decimal TotalCambio { get; set; } = 0;
|
||||
|
||||
[Column("total_neto", TypeName = "numeric(12,2)")]
|
||||
public decimal TotalNeto { get; set; } = 0;
|
||||
|
||||
[Column("total_salidas", TypeName = "numeric(12,2)")]
|
||||
public decimal TotalSalidas { get; set; } = 0;
|
||||
|
||||
[Column("saldo_final", TypeName = "numeric(12,2)")]
|
||||
public decimal SaldoFinal { get; set; } = 0;
|
||||
|
||||
// ── Auditoría ──
|
||||
[Column("creado_en")]
|
||||
public DateTime CreadoEn { get; set; } = DateTime.UtcNow;
|
||||
|
||||
[Column("creado_por")]
|
||||
[StringLength(100)]
|
||||
public string? CreadoPor { get; set; }
|
||||
|
||||
[Column("actualizado_en")]
|
||||
public DateTime ActualizadoEn { get; set; } = DateTime.UtcNow;
|
||||
|
||||
[Column("actualizado_por")]
|
||||
[StringLength(100)]
|
||||
public string? ActualizadoPor { get; set; }
|
||||
|
||||
[Column("eliminado")]
|
||||
public bool Eliminado { get; set; } = false;
|
||||
|
||||
// ── Navegación ──
|
||||
public virtual ICollection<DiezmoDetalle> Detalles { get; set; } = new List<DiezmoDetalle>();
|
||||
public virtual ICollection<DiezmoSalida> Salidas { get; set; } = new List<DiezmoSalida>();
|
||||
}
|
||||
67
RS_system/Models/DiezmoDetalle.cs
Normal file
67
RS_system/Models/DiezmoDetalle.cs
Normal file
@@ -0,0 +1,67 @@
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
using System.ComponentModel.DataAnnotations.Schema;
|
||||
|
||||
namespace Rs_system.Models;
|
||||
|
||||
/// <summary>
|
||||
/// Diezmo individual aportado por un miembro dentro de un cierre.
|
||||
/// MontoNeto = MontoEntregado - CambioEntregado (calculado por el sistema).
|
||||
/// </summary>
|
||||
[Table("diezmo_detalles")]
|
||||
public class DiezmoDetalle
|
||||
{
|
||||
[Key]
|
||||
[Column("id")]
|
||||
public long Id { get; set; }
|
||||
|
||||
[Column("diezmo_cierre_id")]
|
||||
public long DiezmoCierreId { get; set; }
|
||||
|
||||
[Column("miembro_id")]
|
||||
public long MiembroId { get; set; }
|
||||
|
||||
/// <summary>Monto físico que el miembro entregó (puede incluir cambio).</summary>
|
||||
[Column("monto_entregado", TypeName = "numeric(12,2)")]
|
||||
[Required]
|
||||
public decimal MontoEntregado { get; set; }
|
||||
|
||||
/// <summary>Cambio devuelto al miembro.</summary>
|
||||
[Column("cambio_entregado", TypeName = "numeric(12,2)")]
|
||||
public decimal CambioEntregado { get; set; } = 0;
|
||||
|
||||
/// <summary>Diezmo neto real = MontoEntregado - CambioEntregado. Calculado por el sistema.</summary>
|
||||
[Column("monto_neto", TypeName = "numeric(12,2)")]
|
||||
public decimal MontoNeto { get; set; }
|
||||
|
||||
[Column("observaciones")]
|
||||
[StringLength(300)]
|
||||
public string? Observaciones { get; set; }
|
||||
|
||||
[Column("fecha")]
|
||||
public DateTime Fecha { get; set; } = DateTime.UtcNow;
|
||||
|
||||
// ── Auditoría ──
|
||||
[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("actualizado_por")]
|
||||
[StringLength(100)]
|
||||
public string? ActualizadoPor { get; set; }
|
||||
|
||||
[Column("eliminado")]
|
||||
public bool Eliminado { get; set; } = false;
|
||||
|
||||
// ── Navegación ──
|
||||
[ForeignKey("DiezmoCierreId")]
|
||||
public virtual DiezmoCierre DiezmoCierre { get; set; } = null!;
|
||||
|
||||
[ForeignKey("MiembroId")]
|
||||
public virtual Miembro Miembro { get; set; } = null!;
|
||||
}
|
||||
66
RS_system/Models/DiezmoSalida.cs
Normal file
66
RS_system/Models/DiezmoSalida.cs
Normal file
@@ -0,0 +1,66 @@
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
using System.ComponentModel.DataAnnotations.Schema;
|
||||
|
||||
namespace Rs_system.Models;
|
||||
|
||||
/// <summary>
|
||||
/// Salida de fondos registrada contra un cierre de diezmos.
|
||||
/// Incluye entregas al pastor, gastos administrativos, misiones, etc.
|
||||
/// </summary>
|
||||
[Table("diezmo_salidas")]
|
||||
public class DiezmoSalida
|
||||
{
|
||||
[Key]
|
||||
[Column("id")]
|
||||
public long Id { get; set; }
|
||||
|
||||
[Column("diezmo_cierre_id")]
|
||||
public long DiezmoCierreId { get; set; }
|
||||
|
||||
[Column("tipo_salida_id")]
|
||||
public long TipoSalidaId { get; set; }
|
||||
|
||||
[Column("beneficiario_id")]
|
||||
public long? BeneficiarioId { get; set; }
|
||||
|
||||
[Column("monto", TypeName = "numeric(12,2)")]
|
||||
[Required]
|
||||
public decimal Monto { get; set; }
|
||||
|
||||
[Column("concepto")]
|
||||
[Required]
|
||||
[StringLength(300)]
|
||||
public string Concepto { get; set; } = string.Empty;
|
||||
|
||||
/// <summary>Correlativo de recibo asignado al momento de generar el comprobante.</summary>
|
||||
[Column("numero_recibo")]
|
||||
[StringLength(30)]
|
||||
public string? NumeroRecibo { get; set; }
|
||||
|
||||
[Column("fecha")]
|
||||
public DateTime Fecha { get; set; } = DateTime.UtcNow;
|
||||
|
||||
// ── Auditoría ──
|
||||
[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;
|
||||
|
||||
// ── Navegación ──
|
||||
[ForeignKey("DiezmoCierreId")]
|
||||
public virtual DiezmoCierre DiezmoCierre { get; set; } = null!;
|
||||
|
||||
[ForeignKey("TipoSalidaId")]
|
||||
public virtual DiezmoTipoSalida TipoSalida { get; set; } = null!;
|
||||
|
||||
[ForeignKey("BeneficiarioId")]
|
||||
public virtual DiezmoBeneficiario? Beneficiario { get; set; }
|
||||
}
|
||||
51
RS_system/Models/DiezmoTipoSalida.cs
Normal file
51
RS_system/Models/DiezmoTipoSalida.cs
Normal file
@@ -0,0 +1,51 @@
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
using System.ComponentModel.DataAnnotations.Schema;
|
||||
|
||||
namespace Rs_system.Models;
|
||||
|
||||
/// <summary>
|
||||
/// Catálogo de tipos de salida del módulo de diezmos
|
||||
/// (Entrega al Pastor, Gastos Administrativos, Misiones, etc.)
|
||||
/// </summary>
|
||||
[Table("diezmo_tipos_salida")]
|
||||
public class DiezmoTipoSalida
|
||||
{
|
||||
[Key]
|
||||
[Column("id")]
|
||||
public long Id { get; set; }
|
||||
|
||||
[Column("nombre")]
|
||||
[Required]
|
||||
[StringLength(100)]
|
||||
public string Nombre { get; set; } = string.Empty;
|
||||
|
||||
[Column("descripcion")]
|
||||
[StringLength(300)]
|
||||
public string? Descripcion { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Marca este tipo como la entrega oficial al pastor.
|
||||
/// Permite sugerirlo/forzarlo automáticamente al cerrar con saldo pendiente.
|
||||
/// </summary>
|
||||
[Column("es_entrega_pastor")]
|
||||
public bool EsEntregaPastor { get; set; } = false;
|
||||
|
||||
[Column("activo")]
|
||||
public bool Activo { get; set; } = true;
|
||||
|
||||
[Column("eliminado")]
|
||||
public bool Eliminado { get; set; } = false;
|
||||
|
||||
[Column("creado_en")]
|
||||
public DateTime CreadoEn { get; set; } = DateTime.UtcNow;
|
||||
|
||||
[Column("creado_por")]
|
||||
[StringLength(100)]
|
||||
public string? CreadoPor { get; set; }
|
||||
|
||||
[Column("actualizado_en")]
|
||||
public DateTime ActualizadoEn { get; set; } = DateTime.UtcNow;
|
||||
|
||||
// Navegación
|
||||
public virtual ICollection<DiezmoSalida> Salidas { get; set; } = new List<DiezmoSalida>();
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
|
||||
namespace Rs_system.Models.ViewModels.Catalogos;
|
||||
|
||||
public class TipoSalidaViewModel
|
||||
{
|
||||
public long Id { get; set; }
|
||||
|
||||
[Required(ErrorMessage = "El nombre es obligatorio")]
|
||||
[StringLength(100)]
|
||||
public string Nombre { get; set; } = string.Empty;
|
||||
|
||||
[StringLength(300)]
|
||||
public string? Descripcion { get; set; }
|
||||
|
||||
[Display(Name = "Es Entrega Directa a Pastor")]
|
||||
public bool EsEntregaPastor { get; set; }
|
||||
}
|
||||
|
||||
public class BeneficiarioViewModel
|
||||
{
|
||||
public long Id { get; set; }
|
||||
|
||||
[Required(ErrorMessage = "El nombre es obligatorio")]
|
||||
[StringLength(150)]
|
||||
public string Nombre { get; set; } = string.Empty;
|
||||
|
||||
[StringLength(300)]
|
||||
public string? Descripcion { get; set; }
|
||||
}
|
||||
84
RS_system/Models/ViewModels/DiezmoCierreDetalleViewModel.cs
Normal file
84
RS_system/Models/ViewModels/DiezmoCierreDetalleViewModel.cs
Normal file
@@ -0,0 +1,84 @@
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
|
||||
namespace Rs_system.Models.ViewModels;
|
||||
|
||||
// ─────────────────────────────────────────────────────────────────────────────
|
||||
// Formulario — Nuevo cierre
|
||||
// ─────────────────────────────────────────────────────────────────────────────
|
||||
public class DiezmoCierreCreateViewModel
|
||||
{
|
||||
[Required(ErrorMessage = "La fecha es obligatoria.")]
|
||||
[Display(Name = "Fecha del cierre")]
|
||||
public DateOnly Fecha { get; set; } = DateOnly.FromDateTime(DateTime.Today);
|
||||
|
||||
[Display(Name = "Observaciones")]
|
||||
[StringLength(500)]
|
||||
public string? Observaciones { get; set; }
|
||||
}
|
||||
|
||||
// ─────────────────────────────────────────────────────────────────────────────
|
||||
// Pantalla operativa de detalle del cierre
|
||||
// ─────────────────────────────────────────────────────────────────────────────
|
||||
public class DiezmoCierreDetalleViewModel
|
||||
{
|
||||
public long Id { get; set; }
|
||||
public DateOnly Fecha { get; set; }
|
||||
public bool Cerrado { get; set; }
|
||||
public string? Observaciones { get; set; }
|
||||
public string? CerradoPor { get; set; }
|
||||
public DateTime? FechaCierre { get; set; }
|
||||
|
||||
// Totales
|
||||
public decimal TotalRecibido { get; set; }
|
||||
public decimal TotalCambio { get; set; }
|
||||
public decimal TotalNeto { get; set; }
|
||||
public decimal TotalSalidas { get; set; }
|
||||
public decimal SaldoFinal { get; set; }
|
||||
|
||||
// Datos de detalles
|
||||
public List<DiezmoDetalleRowViewModel> Detalles { get; set; } = new();
|
||||
|
||||
// Datos de salidas
|
||||
public List<DiezmoSalidaRowViewModel> Salidas { get; set; } = new();
|
||||
|
||||
// Formularios embebidos para modales
|
||||
public DiezmoDetalleFormViewModel FormDetalle { get; set; } = new();
|
||||
public DiezmoSalidaFormViewModel FormSalida { get; set; } = new();
|
||||
|
||||
// Datos de selectores para los modales
|
||||
public List<Microsoft.AspNetCore.Mvc.Rendering.SelectListItem> MiembrosSelect { get; set; } = new();
|
||||
public List<Microsoft.AspNetCore.Mvc.Rendering.SelectListItem> TiposSalidaSelect { get; set; } = new();
|
||||
public List<Microsoft.AspNetCore.Mvc.Rendering.SelectListItem> BeneficiariosSelect { get; set; } = new();
|
||||
|
||||
public string EstadoBadge => Cerrado ? "badge bg-secondary" : "badge bg-success";
|
||||
public string EstadoTexto => Cerrado ? "Cerrado" : "Abierto";
|
||||
}
|
||||
|
||||
// ─────────────────────────────────────────────────────────────────────────────
|
||||
// Fila de un detalle en la tabla
|
||||
// ─────────────────────────────────────────────────────────────────────────────
|
||||
public class DiezmoDetalleRowViewModel
|
||||
{
|
||||
public long Id { get; set; }
|
||||
public long MiembroId { get; set; }
|
||||
public string NombreMiembro { get; set; } = string.Empty;
|
||||
public decimal MontoEntregado { get; set; }
|
||||
public decimal CambioEntregado { get; set; }
|
||||
public decimal MontoNeto { get; set; }
|
||||
public string? Observaciones { get; set; }
|
||||
public DateTime Fecha { get; set; }
|
||||
}
|
||||
|
||||
// ─────────────────────────────────────────────────────────────────────────────
|
||||
// Fila de una salida en la tabla
|
||||
// ─────────────────────────────────────────────────────────────────────────────
|
||||
public class DiezmoSalidaRowViewModel
|
||||
{
|
||||
public long Id { get; set; }
|
||||
public string TipoSalidaNombre { get; set; } = string.Empty;
|
||||
public string? BeneficiarioNombre { get; set; }
|
||||
public decimal Monto { get; set; }
|
||||
public string Concepto { get; set; } = string.Empty;
|
||||
public string? NumeroRecibo { get; set; }
|
||||
public DateTime Fecha { get; set; }
|
||||
}
|
||||
19
RS_system/Models/ViewModels/DiezmoCierreListViewModel.cs
Normal file
19
RS_system/Models/ViewModels/DiezmoCierreListViewModel.cs
Normal file
@@ -0,0 +1,19 @@
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
|
||||
namespace Rs_system.Models.ViewModels;
|
||||
|
||||
/// <summary>Fila del listado de cierres de diezmos.</summary>
|
||||
public class DiezmoCierreListViewModel
|
||||
{
|
||||
public long Id { get; set; }
|
||||
public DateOnly Fecha { get; set; }
|
||||
public bool Cerrado { get; set; }
|
||||
public decimal TotalRecibido { get; set; }
|
||||
public decimal TotalNeto { get; set; }
|
||||
public decimal TotalSalidas { get; set; }
|
||||
public decimal SaldoFinal { get; set; }
|
||||
public int NumeroDetalles { get; set; }
|
||||
public int NumeroSalidas { get; set; }
|
||||
public string EstadoBadge => Cerrado ? "badge bg-secondary" : "badge bg-success";
|
||||
public string EstadoTexto => Cerrado ? "Cerrado" : "Abierto";
|
||||
}
|
||||
28
RS_system/Models/ViewModels/DiezmoDetalleFormViewModel.cs
Normal file
28
RS_system/Models/ViewModels/DiezmoDetalleFormViewModel.cs
Normal file
@@ -0,0 +1,28 @@
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
|
||||
namespace Rs_system.Models.ViewModels;
|
||||
|
||||
/// <summary>Formulario modal para agregar un diezmo de un miembro.</summary>
|
||||
public class DiezmoDetalleFormViewModel
|
||||
{
|
||||
[Required(ErrorMessage = "Seleccione un miembro.")]
|
||||
[Display(Name = "Miembro")]
|
||||
public long MiembroId { get; set; }
|
||||
|
||||
[Required(ErrorMessage = "El monto entregado es obligatorio.")]
|
||||
[Range(0.01, 999999.99, ErrorMessage = "El monto debe ser mayor a 0.")]
|
||||
[Display(Name = "Monto entregado")]
|
||||
public decimal MontoEntregado { get; set; }
|
||||
|
||||
[Required(ErrorMessage = "El monto del diezmo (neto) es obligatorio.")]
|
||||
[Range(0.01, 999999.99, ErrorMessage = "El diezmo debe ser mayor a 0.")]
|
||||
[Display(Name = "Diezmo (Neto)")]
|
||||
public decimal MontoNeto { get; set; }
|
||||
|
||||
// Este campo ahora vendrá como solo-lectura desde el formulario
|
||||
public decimal CambioEntregado { get; set; } = 0;
|
||||
|
||||
[Display(Name = "Observaciones")]
|
||||
[StringLength(300)]
|
||||
public string? Observaciones { get; set; }
|
||||
}
|
||||
24
RS_system/Models/ViewModels/DiezmoSalidaFormViewModel.cs
Normal file
24
RS_system/Models/ViewModels/DiezmoSalidaFormViewModel.cs
Normal file
@@ -0,0 +1,24 @@
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
|
||||
namespace Rs_system.Models.ViewModels;
|
||||
|
||||
/// <summary>Formulario modal para registrar una salida/entrega de fondos.</summary>
|
||||
public class DiezmoSalidaFormViewModel
|
||||
{
|
||||
[Required(ErrorMessage = "Seleccione el tipo de salida.")]
|
||||
[Display(Name = "Tipo de salida")]
|
||||
public long TipoSalidaId { get; set; }
|
||||
|
||||
[Display(Name = "Beneficiario")]
|
||||
public long? BeneficiarioId { get; set; }
|
||||
|
||||
[Required(ErrorMessage = "El monto es obligatorio.")]
|
||||
[Range(0.01, 999999.99, ErrorMessage = "El monto debe ser mayor a 0.")]
|
||||
[Display(Name = "Monto")]
|
||||
public decimal Monto { get; set; }
|
||||
|
||||
[Required(ErrorMessage = "El concepto es obligatorio.")]
|
||||
[StringLength(300)]
|
||||
[Display(Name = "Concepto")]
|
||||
public string Concepto { get; set; } = string.Empty;
|
||||
}
|
||||
14
RS_system/Models/ViewModels/PaginatedViewModel.cs
Normal file
14
RS_system/Models/ViewModels/PaginatedViewModel.cs
Normal file
@@ -0,0 +1,14 @@
|
||||
namespace Rs_system.Models.ViewModels;
|
||||
|
||||
public class PaginatedViewModel<T>
|
||||
{
|
||||
public List<T> Items { get; set; } = new();
|
||||
public int CurrentPage { get; set; }
|
||||
public int PageSize { get; set; }
|
||||
public int TotalItems { get; set; }
|
||||
public int TotalPages => (int)Math.Ceiling((double)TotalItems / PageSize);
|
||||
public string? SearchQuery { get; set; }
|
||||
|
||||
public bool HasPreviousPage => CurrentPage > 1;
|
||||
public bool HasNextPage => CurrentPage < TotalPages;
|
||||
}
|
||||
Reference in New Issue
Block a user