using Microsoft.EntityFrameworkCore; using Elwig.Models; using System.Linq; using System.Threading.Tasks; using System.IO; using System; using System.Windows; using Microsoft.Extensions.Logging; namespace Elwig.Helpers { public class AppDbContext : DbContext { public DbSet Countries { get; private set; } public DbSet Currencies { get; private set; } public DbSet Gemeinden { get; private set; } public DbSet Katastralgemeinden { get; private set; } public DbSet Orte { get; private set; } public DbSet Postleitzahlen { get; private set; } public DbSet PlzDestinations { get; private set; } public DbSet PostalDestinations { get; private set; } public DbSet WineOrigins { get; private set; } public DbSet WineQualityLevels { get; private set; } public DbSet WineVarieties { get; private set; } public DbSet ClientParameters { get; private set; } public DbSet WbKgs { get; private set; } public DbSet WbRde { get; private set; } public DbSet WineAttributes { get; private set; } public DbSet WineCultivations { get; private set; } public DbSet Branches { get; private set; } public DbSet Members { get; private set; } public DbSet BillingAddresses { get; private set; } public DbSet MemberTelephoneNrs { get; private set; } public DbSet AreaCommitments { get; private set; } public DbSet AreaCommitmentAttributes { get; private set; } public DbSet Seasons { get; private set; } public DbSet Modifiers { get; private set; } public DbSet Deliveries { get; private set; } public DbSet DeliveryParts { get; private set; } public DbSet DeliveryPartAttributes { get; private set; } public DbSet DeliveryPartModifiers { get; private set; } private readonly StreamWriter? LogFile = null; public static DateTime LastWriteTime => File.GetLastWriteTime(App.Config.DatabaseFile); public DateTime SavedLastWriteTime { get; private set; } public bool HasBackendChanged => SavedLastWriteTime != LastWriteTime; public static string ConnectionString => $"Data Source=\"{App.Config.DatabaseFile}\"; Foreign Keys=True; Mode=ReadWrite; Cache=Default"; public AppDbContext() { if (App.Config.DatabaseLog != null) { try { var file = File.Open(App.Config.DatabaseLog, FileMode.Append, FileAccess.Write, FileShare.Write); LogFile = new(file) { AutoFlush = true }; } catch (Exception e) { MessageBox.Show($"Unable to open database log file:\n\n{e.Message}", "Database Log", MessageBoxButton.OK, MessageBoxImage.Error); } } SavedLastWriteTime = LastWriteTime; SavedChanges += OnSavedChanges; } protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder) { optionsBuilder.UseSqlite(ConnectionString); optionsBuilder.UseLazyLoadingProxies(); optionsBuilder.LogTo(Log, LogLevel.Information); base.OnConfiguring(optionsBuilder); } public override void Dispose() { base.Dispose(); LogFile?.Dispose(); GC.SuppressFinalize(this); } private void OnSavedChanges(object? sender, SavedChangesEventArgs evt) { SavedLastWriteTime = LastWriteTime; } protected void Log(string msg) { LogFile?.WriteLine(msg); } public async Task MgNrExists(int mgnr) { return await Members.FindAsync(mgnr) != null; } public async Task FbNrExists(int fbnr) { return await AreaCommitments.FindAsync(fbnr) != null; } public async Task SortIdExists(string sortId) { return await WineVarieties.FindAsync(sortId) != null; } public async Task AttrIdExists(string attrId) { return await WineAttributes.FindAsync(attrId) != null; } public async Task NextMgNr() { int c = await Members.Select(m => m.MgNr).MinAsync(); (await Members.OrderBy(m => m.MgNr).Select(m => m.MgNr).ToListAsync()) .ForEach(a => { if (a <= c + 100) c = a; }); return c + 1; } public async Task NextFbNr() { int c = await AreaCommitments.Select(ac => ac.FbNr).MinAsync(); (await AreaCommitments.OrderBy(ac => ac.FbNr).Select(ac => ac.FbNr).ToListAsync()) .ForEach(a => { if (a <= c + 100) c = a; }); return c + 1; } public async Task NextLNr(DateOnly date) { var dateStr = date.ToString("yyyy-MM-dd"); int c = 0; (await Deliveries.Where(d => d.DateString == dateStr).Select(d => d.LNr).ToListAsync()) .ForEach(a => { if (a <= c + 10) c = a; }); return c + 1; } public async Task GetWineQualityLevel(double kmw) { return await WineQualityLevels .Where(q => !q.IsPredicate && (q.MinKmw == null || q.MinKmw <= kmw)) .OrderBy(q => q.MinKmw) .LastOrDefaultAsync(); } } }