diff --git a/App.xaml.cs b/App.xaml.cs
index 2139ac9..b93ca37 100644
--- a/App.xaml.cs
+++ b/App.xaml.cs
@@ -55,10 +55,10 @@ public partial class App : Application
NavigationService navigationService = null!;
navigationService = new NavigationService(
session,
- () => new AdminLoginViewModel(authService, session, navigationService, configService, adminAuditService),
+ () => new AdminLoginViewModel(authService, session, navigationService, configService, adminAuditService, employeeLookupService),
() => new ScannerDashboardViewModel(rfidService, navigationService, session, configService, menuLookupService, employeePhotoService),
() => new MainDashboardViewModel(navigationService, rfidService, configService, session),
- () => new AdminSettingsAuthViewModel(authService, session, navigationService, configService),
+ () => new AdminSettingsAuthViewModel(authService, session, navigationService, configService, employeeLookupService),
() => new SettingsViewModel(configService, navigationService, adminAuditService, syncService),
() => new MealSchedulesViewModel(mealScheduleService, navigationService, configService));
diff --git a/Services/AuthResult.cs b/Services/AuthResult.cs
index f5459a7..d343723 100644
--- a/Services/AuthResult.cs
+++ b/Services/AuthResult.cs
@@ -6,4 +6,3 @@ namespace UtopiaCanteenSystem.Services;
public readonly record struct AuthResult(
bool Success,
string EmployeeId);
-
diff --git a/Services/AuthService.cs b/Services/AuthService.cs
index 45ee2b5..584a38a 100644
--- a/Services/AuthService.cs
+++ b/Services/AuthService.cs
@@ -53,4 +53,3 @@ public class AuthService : IAuthService
}
}
}
-
diff --git a/Services/ConfigService.cs b/Services/ConfigService.cs
index bf8c349..896fdcc 100644
--- a/Services/ConfigService.cs
+++ b/Services/ConfigService.cs
@@ -105,6 +105,16 @@ public class ConfigService : IConfigService
SaveConfig();
}
+ public void ApplyLocationSiteIdFromAuth(string? locationSiteId)
+ {
+ if (string.IsNullOrWhiteSpace(locationSiteId))
+ return;
+ var digits = new string(locationSiteId.Where(char.IsDigit).ToArray());
+ if (string.IsNullOrEmpty(digits))
+ return;
+ SetSiteId("SITE : " + digits);
+ }
+
public string GetDeviceId()
{
//var id = _config.DeviceId ?? string.Empty;
diff --git a/Services/EmployeeLookupService.cs b/Services/EmployeeLookupService.cs
index 19ae2a4..1c71c25 100644
--- a/Services/EmployeeLookupService.cs
+++ b/Services/EmployeeLookupService.cs
@@ -72,6 +72,39 @@ public class EmployeeLookupService : IEmployeeLookupService
};
}
+ ///
+ public async Task GetLocationSiteIdByEmployeeSerialAsync(string employeeSerial, CancellationToken cancellationToken = default)
+ {
+ var serial = employeeSerial?.Trim() ?? string.Empty;
+ if (string.IsNullOrEmpty(serial))
+ return null;
+
+ var connectionString = _configService.GetHrmsLookupConnectionString();
+ if (string.IsNullOrWhiteSpace(connectionString))
+ return null;
+
+ const string sql = @"
+ SELECT location_site_id
+ FROM employee
+ WHERE serial_number = @serial
+ LIMIT 1";
+
+ await using var conn = new MySqlConnection(connectionString);
+ await conn.OpenAsync(cancellationToken).ConfigureAwait(false);
+ await using var cmd = new MySqlCommand(sql, conn);
+ cmd.Parameters.AddWithValue("@serial", serial);
+
+ await using var reader = await cmd.ExecuteReaderAsync(cancellationToken).ConfigureAwait(false);
+ if (!await reader.ReadAsync(cancellationToken).ConfigureAwait(false))
+ return null;
+
+ if (reader.IsDBNull(0))
+ return null;
+
+ var raw = reader.GetValue(0)?.ToString()?.Trim();
+ return string.IsNullOrEmpty(raw) ? null : raw;
+ }
+
private static string GetString(MySqlDataReader reader, int ordinal)
{
if (reader.IsDBNull(ordinal)) return string.Empty;
diff --git a/Services/IConfigService.cs b/Services/IConfigService.cs
index c2a1d19..89ff5ea 100644
--- a/Services/IConfigService.cs
+++ b/Services/IConfigService.cs
@@ -25,6 +25,8 @@ public interface IConfigService
string GetSiteId();
void SetSiteId(string siteId);
+ /// Persist HRMS location_site_id in the same format as the scanner dashboard (digits → "SITE : …").
+ void ApplyLocationSiteIdFromAuth(string? locationSiteId);
string GetDeviceId();
void SetDeviceId(string deviceId);
diff --git a/Services/IEmployeeLookupService.cs b/Services/IEmployeeLookupService.cs
index c7290b6..b7190c7 100644
--- a/Services/IEmployeeLookupService.cs
+++ b/Services/IEmployeeLookupService.cs
@@ -12,4 +12,9 @@ public interface IEmployeeLookupService
/// Finds employee by RFID. Returns null if card is not registered in HRMS.
///
Task GetEmployeeByRfidAsync(string rfid, CancellationToken cancellationToken = default);
+
+ ///
+ /// Reads employee.location_site_id where employee.serial_number matches the login employee id. Null if missing or not configured.
+ ///
+ Task GetLocationSiteIdByEmployeeSerialAsync(string employeeSerial, CancellationToken cancellationToken = default);
}
diff --git a/ViewModels/AdminLoginViewModel.cs b/ViewModels/AdminLoginViewModel.cs
index 1817e66..51a96ee 100644
--- a/ViewModels/AdminLoginViewModel.cs
+++ b/ViewModels/AdminLoginViewModel.cs
@@ -11,6 +11,7 @@ public partial class AdminLoginViewModel : ObservableObject
private readonly INavigationService _navigation;
private readonly IConfigService _config;
private readonly IAdminAuditService _adminAudit;
+ private readonly IEmployeeLookupService _employeeLookup;
[ObservableProperty]
private string _username = string.Empty;
@@ -33,13 +34,15 @@ public partial class AdminLoginViewModel : ObservableObject
AppSession session,
INavigationService navigation,
IConfigService config,
- IAdminAuditService adminAudit)
+ IAdminAuditService adminAudit,
+ IEmployeeLookupService employeeLookup)
{
_authService = authService;
_session = session;
_navigation = navigation;
_config = config;
_adminAudit = adminAudit;
+ _employeeLookup = employeeLookup;
RememberCredentials = _config.GetRememberAdminCredentials();
if (RememberCredentials)
@@ -83,6 +86,16 @@ public partial class AdminLoginViewModel : ObservableObject
_session.SetAdminAuthenticated(user, result.EmployeeId);
+ try
+ {
+ var siteId = await _employeeLookup.GetLocationSiteIdByEmployeeSerialAsync(result.EmployeeId).ConfigureAwait(true);
+ _config.ApplyLocationSiteIdFromAuth(siteId);
+ }
+ catch
+ {
+ // HRMS lookup optional; login still succeeds.
+ }
+
// Persist who logged in (for audit / reporting).
await _adminAudit.RecordLoginAsync(user, result.EmployeeId).ConfigureAwait(false);
diff --git a/ViewModels/AdminSettingsAuthViewModel.cs b/ViewModels/AdminSettingsAuthViewModel.cs
index 5ee7f4c..fc28723 100644
--- a/ViewModels/AdminSettingsAuthViewModel.cs
+++ b/ViewModels/AdminSettingsAuthViewModel.cs
@@ -10,6 +10,7 @@ public partial class AdminSettingsAuthViewModel : ObservableObject
private readonly AppSession _session;
private readonly INavigationService _navigation;
private readonly IConfigService _config;
+ private readonly IEmployeeLookupService _employeeLookup;
[ObservableProperty]
private string _username = string.Empty;
@@ -27,12 +28,18 @@ public partial class AdminSettingsAuthViewModel : ObservableObject
[ObservableProperty]
private bool _rememberCredentials;
- public AdminSettingsAuthViewModel(IAuthService authService, AppSession session, INavigationService navigation, IConfigService config)
+ public AdminSettingsAuthViewModel(
+ IAuthService authService,
+ AppSession session,
+ INavigationService navigation,
+ IConfigService config,
+ IEmployeeLookupService employeeLookup)
{
_authService = authService;
_session = session;
_navigation = navigation;
_config = config;
+ _employeeLookup = employeeLookup;
RememberCredentials = _config.GetRememberAdminCredentials();
if (RememberCredentials)
@@ -83,6 +90,16 @@ public partial class AdminSettingsAuthViewModel : ObservableObject
// Refresh session details (who authenticated for Settings).
_session.SetAdminAuthenticated(user, result.EmployeeId);
+ try
+ {
+ var siteId = await _employeeLookup.GetLocationSiteIdByEmployeeSerialAsync(result.EmployeeId).ConfigureAwait(true);
+ _config.ApplyLocationSiteIdFromAuth(siteId);
+ }
+ catch
+ {
+ // HRMS lookup optional; auth still succeeds.
+ }
+
// Persist credentials only if user opted in.
_config.SetRememberAdminCredentials(RememberCredentials);
if (RememberCredentials)