using Microsoft.EntityFrameworkCore; using Rs_system.Models; namespace Rs_system.Data; public class ApplicationDbContext : DbContext { public ApplicationDbContext(DbContextOptions options) : base(options) { } public DbSet Personas { get; set; } public DbSet Usuarios { get; set; } public DbSet RolesSistema { get; set; } public DbSet RolesUsuario { get; set; } public DbSet Permisos { get; set; } public DbSet Modulos { get; set; } public DbSet RolesPermisos { get; set; } public DbSet Configuraciones { get; set; } public DbSet AsistenciasCulto { get; set; } // Offerings module public DbSet RegistrosCulto { get; set; } public DbSet Ofrendas { get; set; } public DbSet DescuentosOfrenda { get; set; } // Church Members module public DbSet GruposTrabajo { get; set; } public DbSet Miembros { get; set; } public DbSet ContabilidadRegistros { get; set; } public DbSet ReportesMensualesContables { get; set; } // General church accounting module public DbSet CategoriasIngreso { get; set; } public DbSet CategoriasEgreso { get; set; } public DbSet MovimientosGenerales { get; set; } public DbSet MovimientosGeneralesAdjuntos { get; set; } public DbSet ReportesMensualesGenerales { get; set; } // Inventory module public DbSet Categorias { get; set; } public DbSet EstadosArticulos { get; set; } public DbSet Ubicaciones { get; set; } public DbSet Existencias { get; set; } public DbSet Articulos { get; set; } public DbSet MovimientosInventario { get; set; } public DbSet Prestamos { get; set; } public DbSet PrestamoDetalles { get; set; } // Collaborations module public DbSet TiposColaboracion { get; set; } public DbSet Colaboraciones { get; set; } public DbSet DetalleColaboraciones { get; set; } protected override void OnModelCreating(ModelBuilder modelBuilder) { // 1. Registrar el enum de PostgreSQL modelBuilder.HasPostgresEnum("tipo_movimiento_general"); // 2. Asegurar que la propiedad use ese tipo modelBuilder.Entity() .Property(e => e.Tipo) .HasColumnType("tipo_movimiento_general"); base.OnModelCreating(modelBuilder); // Configure composite key for RolUsuario modelBuilder.Entity() .HasKey(ru => new { ru.UsuarioId, ru.RolId }); // Configure relationships modelBuilder.Entity() .HasOne(ru => ru.Usuario) .WithMany(u => u.RolesUsuario) .HasForeignKey(ru => ru.UsuarioId); modelBuilder.Entity() .HasOne(ru => ru.Rol) .WithMany(r => r.RolesUsuario) .HasForeignKey(ru => ru.RolId); // Configure composite key for RolPermiso modelBuilder.Entity() .HasKey(rp => new { rp.RolId, rp.PermisoId }); modelBuilder.Entity() .HasOne(rp => rp.Rol) .WithMany(r => r.RolesPermisos) .HasForeignKey(rp => rp.RolId); modelBuilder.Entity() .HasOne(rp => rp.Permiso) .WithMany() .HasForeignKey(rp => rp.PermisoId); modelBuilder.Entity() .HasOne(p => p.Modulo) .WithMany(m => m.Permisos) .HasForeignKey(p => p.ModuloId); modelBuilder.Entity() .HasOne(u => u.Persona) .WithMany() .HasForeignKey(u => u.PersonaId); // Church Members module relationships modelBuilder.Entity() .HasOne(m => m.GrupoTrabajo) .WithMany(g => g.Miembros) .HasForeignKey(m => m.GrupoTrabajoId) .OnDelete(DeleteBehavior.Restrict); modelBuilder.Entity() .HasOne(m => m.Persona) .WithMany() .HasForeignKey(m => m.PersonaId) .OnDelete(DeleteBehavior.Restrict); modelBuilder.Entity() .HasOne(c => c.GrupoTrabajo) .WithMany() .HasForeignKey(c => c.GrupoTrabajoId) .OnDelete(DeleteBehavior.Restrict); modelBuilder.Entity() .HasOne(r => r.GrupoTrabajo) .WithMany() .HasForeignKey(r => r.GrupoTrabajoId) .OnDelete(DeleteBehavior.Restrict); modelBuilder.Entity() .HasMany(r => r.Registros) .WithOne(c => c.ReporteMensual) .HasForeignKey(c => c.ReporteMensualId) .OnDelete(DeleteBehavior.Cascade); // General accounting module relationships modelBuilder.Entity() .HasMany(r => r.Movimientos) .WithOne(m => m.ReporteMensualGeneral) .HasForeignKey(m => m.ReporteMensualGeneralId) .OnDelete(DeleteBehavior.Cascade); modelBuilder.Entity() .HasIndex(r => new { r.Mes, r.Anio }) .IsUnique(); modelBuilder.Entity() .HasOne(m => m.CategoriaIngreso) .WithMany(c => c.Movimientos) .HasForeignKey(m => m.CategoriaIngresoId) .OnDelete(DeleteBehavior.Restrict); modelBuilder.Entity() .HasOne(m => m.CategoriaEgreso) .WithMany(c => c.Movimientos) .HasForeignKey(m => m.CategoriaEgresoId) .OnDelete(DeleteBehavior.Restrict); modelBuilder.Entity() .HasMany(m => m.Adjuntos) .WithOne(a => a.MovimientoGeneral) .HasForeignKey(a => a.MovimientoGeneralId) .OnDelete(DeleteBehavior.Cascade); modelBuilder.HasPostgresEnum("tipo_movimiento"); modelBuilder.Entity() .Property(e => e.TipoMovimiento) .HasColumnType("tipo_movimiento"); // Collaborations module configuration modelBuilder.Entity(entity => { entity.ToTable("tipos_colaboracion", "public"); entity.HasKey(e => e.Id); entity.Property(e => e.Nombre).HasMaxLength(100).IsRequired(); entity.Property(e => e.MontoSugerido).HasColumnType("decimal(10,2)"); }); modelBuilder.Entity(entity => { entity.ToTable("colaboraciones", "public"); entity.HasKey(e => e.Id); entity.Property(e => e.MontoTotal).HasColumnType("decimal(10,2)"); entity.HasOne(e => e.Miembro) .WithMany() .HasForeignKey(e => e.MiembroId) .OnDelete(DeleteBehavior.Restrict); entity.HasMany(e => e.Detalles) .WithOne(d => d.Colaboracion) .HasForeignKey(d => d.ColaboracionId) .OnDelete(DeleteBehavior.Cascade); }); modelBuilder.Entity(entity => { entity.ToTable("detalle_colaboraciones", "public"); entity.HasKey(e => e.Id); entity.Property(e => e.Monto).HasColumnType("decimal(10,2)"); entity.HasOne(e => e.TipoColaboracion) .WithMany(t => t.Detalles) .HasForeignKey(e => e.TipoColaboracionId) .OnDelete(DeleteBehavior.Restrict); entity.HasIndex(e => new { e.ColaboracionId, e.TipoColaboracionId, e.Mes, e.Anio }) .IsUnique(); }); // Global configuration: Convert all dates to UTC when saving foreach (var entityType in modelBuilder.Model.GetEntityTypes()) { var properties = entityType.GetProperties() .Where(p => p.ClrType == typeof(DateTime) || p.ClrType == typeof(DateTime?)); foreach (var property in properties) { property.SetValueConverter(new Microsoft.EntityFrameworkCore.Storage.ValueConversion.ValueConverter( v => v.Kind == DateTimeKind.Utc ? v : DateTime.SpecifyKind(v, DateTimeKind.Utc), v => v)); } } } }