using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore.ChangeTracking; using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using WorkFlowCheck.Common.RequestContext; using WorkFlowCheck.Common.Security; using WorkFlowCheck.DL.Configurations; using WorkFlowCheck.DL.Entities; using WorkFlowCheck.DL.Extensions; using WorkFlowCheck.DL.Interfaces; namespace WorkFlowCheck.DL { public class AppDbContext : DbContext { private readonly IRequestContext _requestContext; public AppDbContext(DbContextOptions options, IRequestContext requestContext) : base(options) { _requestContext = requestContext; } #if !DEBUG private dynamic _requestContext; public AppDbContext(DbContextOptions options) : base(options) { _requestContext = new { CurrentUserEmail = "", CurrentUsername = "admin", TraceId = 0 }; } #endif #region Entities DbSet public DbSet CheckListHeaders { get; set; } = null!; public DbSet CheckListRows { get; set; } = null!; public DbSet CheckListTemplateHeaders { get; set; } = null!; public DbSet CheckListTemplateRows { get; set; } = null!; public DbSet CheckPoints { get; set; } = null!; public DbSet Equipments { get; set; } = null!; public DbSet Locations { get; set; } = null!; public DbSet NumberGeneratorTemplates { get; set; } = null!; public DbSet NumberGeneratorTemplateDatess { get; set; } = null!; public DbSet Roles { get; set; } = null!; public DbSet Users { get; set; } = null!; public DbSet UserRoles { get; set; } = null!; public DbSet RoleCheckListTemplateHeaders { get; set; } = null!; #endregion protected override void OnModelCreating(ModelBuilder modelBuilder) { modelBuilder.ApplyConfiguration(new CheckListHeaderTypeConfiguration()); modelBuilder.ApplyConfiguration(new CheckListRowTypeConfiguration()); modelBuilder.ApplyConfiguration(new CheckListTemplateHeaderTypeConfiguration()); modelBuilder.ApplyConfiguration(new CheckListTemplateRowTypeConfiguration()); modelBuilder.ApplyConfiguration(new CheckPointTypeConfiguration()); modelBuilder.ApplyConfiguration(new EquipmentTypeConfiguration()); modelBuilder.ApplyConfiguration(new LocationTypeConfiguration()); modelBuilder.ApplyConfiguration(new NumberGeneratorTypeConfiguration()); modelBuilder.ApplyConfiguration(new NumberGeneratorDateTypeConfiguration()); modelBuilder.ApplyConfiguration(new RoleTypeConfiguration()); modelBuilder.ApplyConfiguration(new RoleCheckListTemplateHeaderTypeConfiguration()); modelBuilder.ApplyConfiguration(new UserTypeConfiguration()); modelBuilder.ApplyConfiguration(new UserRoleTypeConfiguration()); modelBuilder.RegisterSoftDeleteQueryFilters(); SeedInit(modelBuilder); } public override async Task SaveChangesAsync(CancellationToken cancellationToken = default) { SaveChangesCore(); return await base.SaveChangesAsync(cancellationToken); } protected virtual void SaveChangesCore() { var utcNow = DateTime.UtcNow; var deletedEntries = ChangeTracker .Entries() .Where(e => e.Entity is ISoftDeletableEntity && e.State == EntityState.Deleted); UpdateDeletedEntries(deletedEntries); var modifiedEntries = ChangeTracker .Entries() .Where(e => e.Entity is IAuditableEntity && e.State == EntityState.Modified); UpdateModifiedEntires(modifiedEntries, utcNow); var addedEntries = ChangeTracker .Entries() .Where(e => e.Entity is IAuditableEntity && e.State == EntityState.Added); UpdateAddedEntries(addedEntries, utcNow); } private void UpdateAddedEntries(IEnumerable addedEntries, DateTime utcNow) { foreach (var entry in addedEntries) { ((IAuditableEntity)entry.Entity).CreatedAt = utcNow; ((IAuditableEntity)entry.Entity).LastModAt = utcNow; ((IAuditableEntity)entry.Entity).CreatedBy = _requestContext.CurrentUsername ?? "Admin"; ((IAuditableEntity)entry.Entity).LastModBy = _requestContext.CurrentUsername ?? "Admin"; } } private void UpdateModifiedEntires(IEnumerable modifiedEntries, DateTime utcNow) { foreach (var entry in modifiedEntries) { ((IAuditableEntity)entry.Entity).LastModAt = utcNow; ((IAuditableEntity)entry.Entity).LastModBy = _requestContext.CurrentUsername ?? "Admin"; } } private void UpdateDeletedEntries(IEnumerable deletedEntries) { foreach (var entry in deletedEntries) { ((ISoftDeletableEntity)entry.Entity).IsDeleted = true; entry.State = EntityState.Modified; } } private void SeedInit(ModelBuilder modelBuilder) { modelBuilder.Entity().HasData( new User { Id = 1, Email = "admin@nuvolar.hu", FirstName = "Administrator", LastName = "System", IsDeleted = false, UserName = "admin", PasswordHash = PasswordHasher.HashPassword("111111"), CreatedAt = DateTime.UtcNow, CreatedBy = "System", LastModAt = DateTime.UtcNow, LastModBy = "System", JwtToken = "", Active = true, Token2FA = "" }, new User { Id = 2, Email = "user@nuvolar.hu", FirstName = "User", LastName = "System", IsDeleted = false, UserName = "user", PasswordHash = PasswordHasher.HashPassword("222222"), CreatedAt = DateTime.UtcNow, CreatedBy = "System", LastModAt = DateTime.UtcNow, LastModBy = "System", JwtToken = "", Active = true, Token2FA = "" } ); modelBuilder.Entity().HasData( new NumberGeneratorTemplate { Id = 1, CurrentNumber = 0, DigitFormat = "D4", GenerateType = GenerateType.OnlyYear, LastGeneratedNumber = "", Prefix = "CHK", PrefixSeparator = "-", ShortName = "Ellenőrzési dokumentum sorszámozása", Suffix = "", SuffixSeparator = "-", } ); modelBuilder.Entity().HasData( new NumberGeneratorTemplateDate { Id = 1, CurrentNumber = 0, LastGeneratedNumber = "", Month = 0, Year = 1, NumberGeneratorTemplateId = 1, } ); } } }