* Extended functionalities
* Added different UIs
This commit is contained in:
60
MealPlan.Api/Services/Generators/CatalogMatchingService.cs
Normal file
60
MealPlan.Api/Services/Generators/CatalogMatchingService.cs
Normal file
@@ -0,0 +1,60 @@
|
||||
using MealPlan.Api.Data;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
|
||||
namespace MealPlan.Api.Services.Generators;
|
||||
|
||||
public interface ICatalogMatchingService
|
||||
{
|
||||
Task<int?> ResolveCatalogItemIdAsync(string nameOrCatalogName, CancellationToken ct = default);
|
||||
}
|
||||
|
||||
public class CatalogMatchingService : ICatalogMatchingService
|
||||
{
|
||||
private readonly AppDbContext _db;
|
||||
private List<CatalogEntry>? _cache;
|
||||
|
||||
public CatalogMatchingService(AppDbContext db) => _db = db;
|
||||
|
||||
public async Task<int?> ResolveCatalogItemIdAsync(string nameOrCatalogName, CancellationToken ct = default)
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(nameOrCatalogName)) return null;
|
||||
|
||||
var cache = await GetCacheAsync(ct);
|
||||
var key = Normalize(nameOrCatalogName);
|
||||
|
||||
var exact = cache.FirstOrDefault(c =>
|
||||
c.NameKey == key || c.NamePlKey == key || c.CatalogNameKey == key);
|
||||
if (exact is not null) return exact.Id;
|
||||
|
||||
return cache
|
||||
.Where(c => key.Contains(c.NameKey, StringComparison.Ordinal) ||
|
||||
c.NameKey.Contains(key, StringComparison.Ordinal) ||
|
||||
(!string.IsNullOrEmpty(c.NamePlKey) &&
|
||||
(key.Contains(c.NamePlKey, StringComparison.Ordinal) ||
|
||||
c.NamePlKey.Contains(key, StringComparison.Ordinal))))
|
||||
.OrderBy(c => Math.Abs(c.NameKey.Length - key.Length))
|
||||
.FirstOrDefault()
|
||||
?.Id;
|
||||
}
|
||||
|
||||
private async Task<List<CatalogEntry>> GetCacheAsync(CancellationToken ct)
|
||||
{
|
||||
if (_cache is not null) return _cache;
|
||||
|
||||
_cache = await _db.IngredientNutritionCatalog.AsNoTracking()
|
||||
.Where(i => i.IsActive)
|
||||
.Select(i => new CatalogEntry(i.Id, i.Name, i.NamePl))
|
||||
.ToListAsync(ct);
|
||||
|
||||
return _cache;
|
||||
}
|
||||
|
||||
private static string Normalize(string value) => value.Trim().ToLowerInvariant();
|
||||
|
||||
private sealed record CatalogEntry(int Id, string Name, string? NamePl)
|
||||
{
|
||||
public string NameKey { get; } = Name.Trim().ToLowerInvariant();
|
||||
public string NamePlKey { get; } = NamePl?.Trim().ToLowerInvariant() ?? string.Empty;
|
||||
public string CatalogNameKey { get; } = Name.Trim().ToLowerInvariant();
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user