137 lines
4.4 KiB
C#
137 lines
4.4 KiB
C#
using UtopiaCanteenSystem.Models;
|
|
|
|
namespace UtopiaCanteenSystem.Services;
|
|
|
|
/// <summary>
|
|
/// Resolves current meal session from production (MySQL meal_schedule). Caches schedules per site for 60 seconds.
|
|
/// No SQLite; scan validation uses production data only.
|
|
/// </summary>
|
|
public class DbMealSessionResolver : IMealSessionResolver
|
|
{
|
|
private readonly IMealScheduleService _mealScheduleService;
|
|
private readonly TimeSpan _cacheTtl = TimeSpan.FromSeconds(60);
|
|
|
|
private readonly Dictionary<string, (List<MealSchedule> Schedules, DateTime ExpiryUtc)> _cache = new(StringComparer.OrdinalIgnoreCase);
|
|
private readonly object _cacheLock = new();
|
|
|
|
public DbMealSessionResolver(IMealScheduleService mealScheduleService)
|
|
{
|
|
_mealScheduleService = mealScheduleService;
|
|
}
|
|
|
|
|
|
private static MealSession MapMealNameToSession(string? mealName)
|
|
{
|
|
if (string.IsNullOrWhiteSpace(mealName))
|
|
return MealSession.None;
|
|
|
|
var name = mealName.Trim();
|
|
|
|
return name.ToLowerInvariant() switch
|
|
{
|
|
"breakfast" => MealSession.Breakfast,
|
|
"sehri" => MealSession.Breakfast,
|
|
"lunch" => MealSession.Lunch,
|
|
"iftari" => MealSession.Lunch,
|
|
"tea" => MealSession.Tea,
|
|
"dinner" => MealSession.Dinner,
|
|
_ => MealSession.None
|
|
};
|
|
}
|
|
|
|
|
|
/// <inheritdoc />
|
|
//public MealSession GetCurrentSession(DateTime nowLocal, string siteId)
|
|
//{
|
|
// var normalizedSite = (siteId ?? string.Empty).Trim();
|
|
// if (string.IsNullOrEmpty(normalizedSite))
|
|
// normalizedSite = "01";
|
|
// if (normalizedSite.Length == 1 && char.IsDigit(normalizedSite[0]))
|
|
// normalizedSite = normalizedSite.PadLeft(2, '0');
|
|
|
|
// var schedules = GetSchedulesForSiteCached(normalizedSite);
|
|
// var t = nowLocal.TimeOfDay;
|
|
|
|
// //foreach (var s in schedules)
|
|
// //{
|
|
// // if (!TryParseTime(s.StartTime, out var start) || !TryParseTime(s.EndTime, out var end))
|
|
// // continue;
|
|
// // if (t >= start && t < end)
|
|
// // return (MealSession)s.MealSession;
|
|
// //}
|
|
// foreach (var s in schedules)
|
|
// {
|
|
// if (!TryParseTime(s.StartTime, out var start) || !TryParseTime(s.EndTime, out var end))
|
|
// continue;
|
|
|
|
// if (t >= start && t < end)
|
|
// return MapMealNameToSession(s.MealName);
|
|
// }
|
|
|
|
// return MealSession.None;
|
|
//}
|
|
|
|
|
|
|
|
|
|
public ResolvedMealSession? GetCurrentSession(DateTime nowLocal, string siteId)
|
|
{
|
|
var normalizedSite = (siteId ?? string.Empty).Trim();
|
|
if (string.IsNullOrEmpty(normalizedSite))
|
|
normalizedSite = "01";
|
|
if (normalizedSite.Length == 1 && char.IsDigit(normalizedSite[0]))
|
|
normalizedSite = normalizedSite.PadLeft(2, '0');
|
|
|
|
var schedules = GetSchedulesForSiteCached(normalizedSite);
|
|
var t = nowLocal.TimeOfDay;
|
|
|
|
foreach (var s in schedules)
|
|
{
|
|
if (!TryParseTime(s.StartTime, out var start) || !TryParseTime(s.EndTime, out var end))
|
|
continue;
|
|
|
|
if (t >= start && t < end)
|
|
{
|
|
return new ResolvedMealSession
|
|
{
|
|
Session = MapMealNameToSession(s.MealName),
|
|
MealName = s.MealName ?? string.Empty,
|
|
SiteId = normalizedSite,
|
|
StartTime = s.StartTime ?? string.Empty,
|
|
EndTime = s.EndTime ?? string.Empty
|
|
};
|
|
}
|
|
}
|
|
|
|
return null;
|
|
}
|
|
|
|
|
|
private List<MealSchedule> GetSchedulesForSiteCached(string siteId)
|
|
{
|
|
lock (_cacheLock)
|
|
{
|
|
if (_cache.TryGetValue(siteId, out var entry) && DateTime.UtcNow < entry.ExpiryUtc)
|
|
return entry.Schedules;
|
|
}
|
|
|
|
var list = _mealScheduleService.GetActiveSchedulesForSite(siteId).ToList();
|
|
|
|
lock (_cacheLock)
|
|
{
|
|
_cache[siteId] = (list, DateTime.UtcNow.Add(_cacheTtl));
|
|
}
|
|
|
|
return list;
|
|
}
|
|
|
|
private static bool TryParseTime(string value, out TimeSpan time)
|
|
{
|
|
time = TimeSpan.Zero;
|
|
if (string.IsNullOrWhiteSpace(value))
|
|
return false;
|
|
return TimeSpan.TryParse(value.Trim(), null, out time)
|
|
|| TimeSpan.TryParse(value.Trim().Replace(".", ":"), null, out time);
|
|
}
|
|
}
|