Merge pull request 'fixes' (#6) from fixes into main

Reviewed-on: #6
pull/7/head^2
SYED MUSTUFA AHMED NAQVI 2026-04-08 07:42:40 +00:00
commit f17c282369
3 changed files with 60 additions and 1 deletions

View File

@ -107,6 +107,35 @@ public class EmployeeLookupService : IEmployeeLookupService
return string.IsNullOrEmpty(raw) ? null : raw;
}
/// <inheritdoc />
public async Task<bool> IsMenuItemAuthorizedForRfidAsync(string rfid, int menuItemId, CancellationToken cancellationToken = default)
{
var card = rfid?.Trim() ?? string.Empty;
if (string.IsNullOrEmpty(card) || menuItemId <= 0)
return false;
var connectionString = _configService.GetHrmsLookupConnectionString();
if (string.IsNullOrWhiteSpace(connectionString))
return false;
const string sql = @"
SELECT 1
FROM employee_rfid_tag r
JOIN employee_menu_item_tag em ON em.employee_rfid_tag_id = r.id
WHERE r.manufacturer_serial = @rfid
AND em.item_id = @itemId
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("@rfid", card);
cmd.Parameters.AddWithValue("@itemId", menuItemId);
var exists = await cmd.ExecuteScalarAsync(cancellationToken).ConfigureAwait(false);
return exists != null && exists != DBNull.Value;
}
private static string GetString(MySqlDataReader reader, int ordinal)
{
if (reader.IsDBNull(ordinal)) return string.Empty;

View File

@ -17,4 +17,9 @@ public interface IEmployeeLookupService
/// Reads <c>employee.location_site_id</c> where <c>employee.serial_number</c> matches the login employee id. Null if missing or not configured.
/// </summary>
Task<string?> GetLocationSiteIdByEmployeeSerialAsync(string employeeSerial, CancellationToken cancellationToken = default);
/// <summary>
/// Validates that a menu item is authorized for the employee RFID via <c>employee_menu_item_tag</c>.
/// </summary>
Task<bool> IsMenuItemAuthorizedForRfidAsync(string rfid, int menuItemId, CancellationToken cancellationToken = default);
}

View File

@ -333,7 +333,32 @@ public class RfidService : IRfidService
.GetAwaiter()
.GetResult();
var matching = menuItems.ToList();
var matching = menuItems
.Where(i => i.MenuItemId > 0)
.Where(i =>
{
try
{
return _employeeLookup
.IsMenuItemAuthorizedForRfidAsync(cardId, i.MenuItemId)
.GetAwaiter()
.GetResult();
}
catch (Exception ex)
{
Logger.Log(ex, $"RfidService.EmployeeMenuValidation card={cardId}, menuItemId={i.MenuItemId}");
return false;
}
})
.ToList();
if (matching.Count == 0)
{
Logger.Log(
new Exception($"No authorized menu item found for card={cardId}, site={siteNumeric}, date={nowLocal:yyyy-MM-dd}, meal={mealLabel}, grade={employee.GradeType}"),
"RfidService.ProcessScanDetailed authorization");
return new ScanResult(false, "No menu item selected.", 0, employee, session);
}
var names = matching
.Select(i => i.ItemName)