From 306e03e71a4a0b01f8abc704357db8292e0c35ee Mon Sep 17 00:00:00 2001 From: "mustafa.ahmed" Date: Mon, 9 Feb 2026 12:17:08 +0500 Subject: [PATCH] chnage in layout of view all 'order' modal and chnage the local table name from ScanRecords to lunch_order_transactions --- App.xaml.cs | 2 +- Data/AppDbContext.cs | 80 ++++++++++++++++++++++++++++----- Services/IRfidService.cs | 2 +- Services/ISyncService.cs | 2 +- Services/RfidService.cs | 24 +++++----- Services/SyncService.cs | 10 ++--- Views/ScannerDashboardView.xaml | 25 +++++++---- 7 files changed, 106 insertions(+), 39 deletions(-) diff --git a/App.xaml.cs b/App.xaml.cs index 39c3e97..67bf3d6 100644 --- a/App.xaml.cs +++ b/App.xaml.cs @@ -54,7 +54,7 @@ public partial class App : Application }; mainWindow.Show(); - // Background sync: every 15 minutes, POST unsynced ScanRecords to API + // Background sync: every 15 minutes, POST unsynced lunch_order_transactions to API _syncTimer = new System.Timers.Timer(TimeSpan.FromMinutes(15).TotalMilliseconds) { AutoReset = true diff --git a/Data/AppDbContext.cs b/Data/AppDbContext.cs index a912085..6b9bbe3 100644 --- a/Data/AppDbContext.cs +++ b/Data/AppDbContext.cs @@ -6,7 +6,7 @@ using UtopiaCanteenSystem.Models; namespace UtopiaCanteenSystem.Data; /// -/// SQLite DbContext for Labour and ScanRecord tables. +/// SQLite DbContext for Labour and lunch_order_transactions (scan records) tables. /// Database file is created in application directory on first run. /// public class AppDbContext : DbContext @@ -16,7 +16,7 @@ public class AppDbContext : DbContext "utopia_canteen.db"); public DbSet Labour { get; set; } - public DbSet ScanRecords { get; set; } + public DbSet LunchOrderTransactions { get; set; } public DbSet AdminLoginRecords { get; set; } public AppDbContext() { } @@ -38,9 +38,10 @@ public class AppDbContext : DbContext e.HasIndex(x => x.CardId); }); - // ScanRecord: Index for unsynced queries and by ScanTime. + // lunch_order_transactions (scan records): Index for unsynced queries and by ScanTime. modelBuilder.Entity(e => { + e.ToTable("lunch_order_transactions"); e.HasKey(x => x.Id); e.HasIndex(x => x.IsSynced); e.HasIndex(x => x.ScanTime); @@ -59,15 +60,72 @@ public class AppDbContext : DbContext public void EnsureDatabaseCreated() { Database.EnsureCreated(); - UpgradeScanRecordsSchemaIfNeeded(); + MigrateScanRecordsToLunchOrderTransactionsIfNeeded(); + UpgradeLunchOrderTransactionsSchemaIfNeeded(); EnsureAdminLoginTableExists(); } /// - /// Lightweight schema upgrade: add SiteId and DeviceId to ScanRecords if missing (no EF migrations). + /// One-time migration: rename old tables (ScanRecords or CanteenScanEvents) to lunch_order_transactions for existing databases. + /// + private void MigrateScanRecordsToLunchOrderTransactionsIfNeeded() + { + try + { + var conn = Database.GetDbConnection(); + if (conn.State != ConnectionState.Open) + conn.Open(); + + var hasOldScanRecords = false; + var hasOldCanteenScanEvents = false; + var hasNew = false; + + using (var cmd = conn.CreateCommand()) + { + cmd.CommandText = "SELECT name FROM sqlite_master WHERE type='table' AND name='ScanRecords'"; + using var r = cmd.ExecuteReader(); + hasOldScanRecords = r.Read(); + } + using (var cmd = conn.CreateCommand()) + { + cmd.CommandText = "SELECT name FROM sqlite_master WHERE type='table' AND name='CanteenScanEvents'"; + using var r = cmd.ExecuteReader(); + hasOldCanteenScanEvents = r.Read(); + } + using (var cmd = conn.CreateCommand()) + { + cmd.CommandText = "SELECT name FROM sqlite_master WHERE type='table' AND name='lunch_order_transactions'"; + using var r = cmd.ExecuteReader(); + hasNew = r.Read(); + } + + if (!hasNew) + { + if (hasOldScanRecords) + { + using var cmd = conn.CreateCommand(); + cmd.CommandText = "ALTER TABLE ScanRecords RENAME TO lunch_order_transactions"; + cmd.ExecuteNonQuery(); + } + else if (hasOldCanteenScanEvents) + { + using var cmd = conn.CreateCommand(); + cmd.CommandText = "ALTER TABLE CanteenScanEvents RENAME TO lunch_order_transactions"; + cmd.ExecuteNonQuery(); + } + } + } + catch + { + // Ignore; DB may be new or already migrated + } + } + + /// + /// Lightweight schema upgrade: add SiteId and DeviceId to lunch_order_transactions if missing (no EF migrations). /// Does not delete any data. /// - private void UpgradeScanRecordsSchemaIfNeeded() + private void UpgradeLunchOrderTransactionsSchemaIfNeeded() { try { @@ -78,23 +136,23 @@ public class AppDbContext : DbContext var columns = new List(); using (var cmd = conn.CreateCommand()) { - cmd.CommandText = "SELECT name FROM pragma_table_info('ScanRecords')"; + cmd.CommandText = "SELECT name FROM pragma_table_info('lunch_order_transactions')"; using var r = cmd.ExecuteReader(); while (r.Read()) columns.Add(r.GetString(0)); } - if (!columns.Contains("SiteId", StringComparer.OrdinalIgnoreCase)) + if (columns.Count > 0 && !columns.Contains("SiteId", StringComparer.OrdinalIgnoreCase)) { using var cmd = conn.CreateCommand(); - cmd.CommandText = "ALTER TABLE ScanRecords ADD COLUMN SiteId TEXT DEFAULT ''"; + cmd.CommandText = "ALTER TABLE lunch_order_transactions ADD COLUMN SiteId TEXT DEFAULT ''"; cmd.ExecuteNonQuery(); } - if (!columns.Contains("DeviceId", StringComparer.OrdinalIgnoreCase)) + if (columns.Count > 0 && !columns.Contains("DeviceId", StringComparer.OrdinalIgnoreCase)) { using var cmd = conn.CreateCommand(); - cmd.CommandText = "ALTER TABLE ScanRecords ADD COLUMN DeviceId TEXT DEFAULT ''"; + cmd.CommandText = "ALTER TABLE lunch_order_transactions ADD COLUMN DeviceId TEXT DEFAULT ''"; cmd.ExecuteNonQuery(); } } diff --git a/Services/IRfidService.cs b/Services/IRfidService.cs index 77f71c4..73a80ea 100644 --- a/Services/IRfidService.cs +++ b/Services/IRfidService.cs @@ -11,7 +11,7 @@ public interface IRfidService { /// /// Processes a scan for the given card ID. Applies configured timeout, - /// saves to ScanRecords if allowed, and returns result message. + /// saves to lunch_order_transactions if allowed, and returns result message. /// (bool Success, string Message) ProcessScan(string cardId); diff --git a/Services/ISyncService.cs b/Services/ISyncService.cs index 921839c..970dd60 100644 --- a/Services/ISyncService.cs +++ b/Services/ISyncService.cs @@ -1,7 +1,7 @@ namespace UtopiaCanteenSystem.Services; /// -/// Syncs unsynced ScanRecords to the configured UIND API endpoint. +/// Syncs unsynced lunch_order_transactions to the configured UIND API endpoint. /// public interface ISyncService { diff --git a/Services/RfidService.cs b/Services/RfidService.cs index 842510f..12bbf0f 100644 --- a/Services/RfidService.cs +++ b/Services/RfidService.cs @@ -9,7 +9,7 @@ namespace UtopiaCanteenSystem.Services; /// /// Handles RFID scan logic: validates input, enforces configurable timeout, -/// and saves ScanRecord to SQLite. +/// and saves scan events to SQLite (lunch_order_transactions table). /// public class RfidService : IRfidService { @@ -45,7 +45,7 @@ public class RfidService : IRfidService var windowStart = nowUtc.AddSeconds(-timeoutSeconds); // Enforce timeout: no duplicate scan within the timeout window - var lastInWindow = db.ScanRecords + var lastInWindow = db.LunchOrderTransactions .Where(r => r.CardId == cardId) .Where(r => r.ScanTime >= windowStart) .OrderByDescending(r => r.ScanTime) @@ -61,7 +61,7 @@ public class RfidService : IRfidService } // Optional: prevent any scan within the timeout window (any card). - var lastAnyScanInWindow = db.ScanRecords + var lastAnyScanInWindow = db.LunchOrderTransactions .Where(r => r.ScanTime >= windowStart) .OrderByDescending(r => r.ScanTime) .FirstOrDefault(); @@ -83,7 +83,7 @@ public class RfidService : IRfidService SiteId = _configService.GetSiteId(), DeviceId = _configService.GetDeviceId() }; - db.ScanRecords.Add(record); + db.LunchOrderTransactions.Add(record); db.SaveChanges(); return new ScanResult(true, "Order recorded successfully.", 0); @@ -92,7 +92,7 @@ public class RfidService : IRfidService public ScanRecord? GetLastScan() { using var db = _dbFactory.CreateDbContext(); - return db.ScanRecords + return db.LunchOrderTransactions .OrderByDescending(r => r.ScanTime) .FirstOrDefault(); } @@ -101,7 +101,7 @@ public class RfidService : IRfidService { if (count <= 0) return Array.Empty(); using var db = _dbFactory.CreateDbContext(); - return db.ScanRecords + return db.LunchOrderTransactions .OrderByDescending(r => r.ScanTime) .Take(count) .ToList(); @@ -114,7 +114,7 @@ public class RfidService : IRfidService var startUtc = startOfTodayLocal.ToUniversalTime(); var endUtc = startOfTomorrowLocal.ToUniversalTime(); using var db = _dbFactory.CreateDbContext(); - return db.ScanRecords + return db.LunchOrderTransactions .Where(r => r.ScanTime >= startUtc && r.ScanTime < endUtc) .OrderByDescending(r => r.ScanTime) .ToList(); @@ -130,7 +130,7 @@ public class RfidService : IRfidService var endUtc = startOfTomorrowLocal.ToUniversalTime(); using var db = _dbFactory.CreateDbContext(); - return db.ScanRecords + return db.LunchOrderTransactions .Count(r => r.ScanTime >= startUtc && r.ScanTime < endUtc); } @@ -144,7 +144,7 @@ public class RfidService : IRfidService var endUtc = startOfTomorrowLocal.ToUniversalTime(); await using var db = await _dbFactory.CreateDbContextAsync(cancellationToken).ConfigureAwait(false); - return await db.ScanRecords + return await db.LunchOrderTransactions .CountAsync(r => r.ScanTime >= startUtc && r.ScanTime < endUtc, cancellationToken) .ConfigureAwait(false); } @@ -152,7 +152,7 @@ public class RfidService : IRfidService public async Task GetTotalScanCountAsync(CancellationToken cancellationToken = default) { await using var db = await _dbFactory.CreateDbContextAsync(cancellationToken).ConfigureAwait(false); - return await db.ScanRecords.CountAsync(cancellationToken).ConfigureAwait(false); + return await db.LunchOrderTransactions.CountAsync(cancellationToken).ConfigureAwait(false); } public async Task GetTotalScanCountForCardAsync(string cardId, CancellationToken cancellationToken = default) @@ -163,7 +163,7 @@ public class RfidService : IRfidService cardId = cardId.Trim(); await using var db = await _dbFactory.CreateDbContextAsync(cancellationToken).ConfigureAwait(false); - return await db.ScanRecords + return await db.LunchOrderTransactions .CountAsync(r => r.CardId == cardId, cancellationToken) .ConfigureAwait(false); } @@ -183,7 +183,7 @@ public class RfidService : IRfidService var endUtc = startOfTomorrowLocal.ToUniversalTime(); await using var db = await _dbFactory.CreateDbContextAsync(cancellationToken).ConfigureAwait(false); - return await db.ScanRecords + return await db.LunchOrderTransactions .CountAsync(r => r.CardId == cardId && r.ScanTime >= startUtc && r.ScanTime < endUtc, cancellationToken) .ConfigureAwait(false); } diff --git a/Services/SyncService.cs b/Services/SyncService.cs index f2151b3..0e34011 100644 --- a/Services/SyncService.cs +++ b/Services/SyncService.cs @@ -8,7 +8,7 @@ using System.Net.Http; namespace UtopiaCanteenSystem.Services; /// -/// Scheduled sync: fetches unsynced ScanRecords, POSTs them to the configured API, +/// Scheduled sync: fetches unsynced lunch_order_transactions, POSTs them to the configured API, /// and deletes uploaded records from local SQLite on success. /// public class SyncService : ISyncService @@ -32,7 +32,7 @@ public class SyncService : ISyncService List toSync; using (var db = _dbFactory.CreateDbContext()) { - toSync = await db.ScanRecords + toSync = await db.LunchOrderTransactions .Where(r => !r.IsSynced) .OrderBy(r => r.ScanTime) .ToListAsync(cancellationToken) @@ -63,12 +63,12 @@ public class SyncService : ISyncService var ids = toSync.Select(r => r.Id).ToList(); using (var db = _dbFactory.CreateDbContext()) { - var records = await db.ScanRecords + var records = await db.LunchOrderTransactions .Where(r => ids.Contains(r.Id)) .ToListAsync(cancellationToken) .ConfigureAwait(false); - // On successful upload, delete uploaded scan records from local SQLite. - db.ScanRecords.RemoveRange(records); + // On successful upload, delete uploaded scan events from local SQLite. + db.LunchOrderTransactions.RemoveRange(records); await db.SaveChangesAsync(cancellationToken).ConfigureAwait(false); } } diff --git a/Views/ScannerDashboardView.xaml b/Views/ScannerDashboardView.xaml index 91cdab3..56cd05c 100644 --- a/Views/ScannerDashboardView.xaml +++ b/Views/ScannerDashboardView.xaml @@ -454,11 +454,13 @@ + - + + @@ -468,18 +470,17 @@ + - - - - - - + + + + - + +