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<Country> Countries { get; private set; } public DbSet<Currency> Currencies { get; private set; } public DbSet<AT_Gem> Gemeinden { get; private set; } public DbSet<AT_Kg> Katastralgemeinden { get; private set; } public DbSet<AT_Ort> Orte { get; private set; } public DbSet<AT_Plz> Postleitzahlen { get; private set; } public DbSet<AT_PlzDest> PlzDestinations { get; private set; } public DbSet<PostalDest> PostalDestinations { get; private set; } public DbSet<WineOrigin> WineOrigins { get; private set; } public DbSet<WineQualLevel> WineQualityLevels { get; private set; } public DbSet<WineVar> WineVarieties { get; private set; } public DbSet<ClientParam> ClientParameters { get; private set; } public DbSet<WbKg> WbKgs { get; private set; } public DbSet<WbRd> WbRde { get; private set; } public DbSet<WineAttr> WineAttributes { get; private set; } public DbSet<WineCult> WineCultivations { get; private set; } public DbSet<Branch> Branches { get; private set; } public DbSet<Member> Members { get; private set; } public DbSet<BillingAddr> BillingAddresses { get; private set; } public DbSet<MemberTelNr> MemberTelephoneNrs { get; private set; } public DbSet<AreaCom> AreaCommitments { get; private set; } public DbSet<AreaComAttr> AreaCommitmentAttributes { get; private set; } public DbSet<Season> Seasons { get; private set; } public DbSet<Modifier> Modifiers { get; private set; } public DbSet<Delivery> Deliveries { get; private set; } public DbSet<DeliveryPart> DeliveryParts { get; private set; } public DbSet<DeliveryPartAttr> DeliveryPartAttributes { get; private set; } public DbSet<DeliveryPartModifier> 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 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($"Data Source=\"{App.Config.DatabaseFile}\"; Foreign Keys=True; Mode=ReadWrite; Cache=Default"); 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<bool> MgNrExists(int mgnr) { return await Members.FindAsync(mgnr) != null; } public async Task<bool> FbNrExists(int fbnr) { return await AreaCommitments.FindAsync(fbnr) != null; } public async Task<bool> SortIdExists(string sortId) { return await WineVarieties.FindAsync(sortId) != null; } public async Task<bool> AttrIdExists(string attrId) { return await WineAttributes.FindAsync(attrId) != null; } public async Task<int> 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<int> 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<int> 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; } } }