Add store log analysis feature and related data structures
- Implement AnalyzeSlotUnregistrationsAsync method to retrieve and report store log data for cooperating stores in region 139. - Introduce StoreLogProfileEntry record to aggregate log information. - Add StoreLog endpoint for API access. - Create GetStoreLogAsync and GetStoreLogEntriesAsync methods for fetching and deserializing store log entries. - Update Program.cs to include the new analysis task option.
This commit is contained in:
@@ -70,6 +70,95 @@ namespace FsToolbox.Cli
|
||||
|
||||
#endregion
|
||||
|
||||
#region Public Method AnalyzeSlotUnregistrationsAsync
|
||||
|
||||
/// <summary>
|
||||
/// Retrieves the store log for the first cooperating store in region 135 for the last month.
|
||||
/// </summary>
|
||||
/// <param name="httpClient">The HTTP client used to perform the requests.</param>
|
||||
public static async Task AnalyzeSlotUnregistrationsAsync(HttpClient httpClient)
|
||||
{
|
||||
await AuthHelper.EnsureAuthenticationAsync(httpClient);
|
||||
|
||||
var stores = await RegionTasks.GetStoresInRegionAsync(httpClient, 139);
|
||||
var cooperatingStores = stores.Where(x => x.CooperationStatus == RegionTasks.CooperationStatus.Cooperating).ToList();
|
||||
|
||||
if (cooperatingStores.Count == 0)
|
||||
{
|
||||
Logger.Info("No cooperating stores found in region 139.");
|
||||
return;
|
||||
}
|
||||
|
||||
var fromDate = DateTime.Today.AddMonths(-1).ToString("yyyy-MM-dd");
|
||||
var toDate = DateTime.Today.ToString("yyyy-MM-dd");
|
||||
const string storeLogActionIds = "12";
|
||||
|
||||
var collected = new List<StoreLogProfileEntry>();
|
||||
|
||||
foreach (var store in cooperatingStores)
|
||||
{
|
||||
Logger.Info("Fetching store log for {StoreId} {StoreName} ({From} to {To})", store.Id, store.Name, fromDate, toDate);
|
||||
|
||||
var logEntries = await StoreTasks.GetStoreLogEntriesAsync(httpClient, store.Id, fromDate, toDate, storeLogActionIds);
|
||||
|
||||
foreach (var entry in logEntries)
|
||||
{
|
||||
if (entry.ActingFoodsaver == null) continue;
|
||||
collected.Add(new StoreLogProfileEntry(entry.ActingFoodsaver, store, entry.DateReference, entry.PerformedAt));
|
||||
}
|
||||
|
||||
Logger.Info("Collected {Count} log entries for {StoreName}.", collected.Count, store.Name);
|
||||
|
||||
Thread.Sleep(1000);
|
||||
}
|
||||
|
||||
// Group entries by profile and sort by count
|
||||
var grouped = collected
|
||||
.GroupBy(x => x.Profile.Id)
|
||||
.Select(g => new
|
||||
{
|
||||
Profile = g.First().Profile,
|
||||
Count = g.Count()
|
||||
})
|
||||
.OrderByDescending(x => x.Count)
|
||||
.ToList();
|
||||
|
||||
// Create txt file report
|
||||
var sb = new StringBuilder();
|
||||
sb.AppendLine("Store Log Unregistration Report");
|
||||
sb.AppendLine("Generated: " + DateTime.Now.ToString("dd.MM.yyyy HH:mm"));
|
||||
sb.AppendLine($"Timeframe: {fromDate} to {toDate}");
|
||||
sb.AppendLine($"Total analyzed stores: {cooperatingStores.Count} (cooperating)");
|
||||
sb.AppendLine($"Total unregistrations: {collected.Count}");
|
||||
sb.AppendLine("Region: Siegen (139)");
|
||||
sb.AppendLine("============================");
|
||||
sb.AppendLine();
|
||||
|
||||
foreach (var entry in grouped)
|
||||
{
|
||||
sb.AppendLine($"{entry.Profile.Name} ({entry.Profile.Id}) - {entry.Count} unregistrations");
|
||||
sb.AppendLine("----------------------------");
|
||||
|
||||
// List the stores and dates
|
||||
var userEntries = collected
|
||||
.Where(x => x.Profile.Id == entry.Profile.Id)
|
||||
.OrderBy(x => x.DateReference)
|
||||
.ToList();
|
||||
|
||||
foreach (var userEntry in userEntries)
|
||||
sb.AppendLine($" - {userEntry.Store.Name} on {userEntry.DateReference} (Performed at: {userEntry.PerformedAt})");
|
||||
|
||||
sb.AppendLine();
|
||||
}
|
||||
|
||||
// Write to file with timestamp
|
||||
var timestamp = DateTime.Now.ToString("yyyyMMdd_HHmmss");
|
||||
var filename = $"SlotUnregistrations_{timestamp}.txt";
|
||||
await File.WriteAllTextAsync(filename, sb.ToString());
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Public Method ConfirmUnconfirmedPickupsLindenbergAsync
|
||||
|
||||
/// <summary>
|
||||
@@ -85,15 +174,15 @@ namespace FsToolbox.Cli
|
||||
// Collect unconfirmed slots
|
||||
var pickups = await StoreTasks.GetPickupsAsync(httpClient, 56749);
|
||||
foreach (var pickup in pickups)
|
||||
foreach (var slot in pickup.OccupiedSlots)
|
||||
if (!slot.IsConfirmed)
|
||||
{
|
||||
var pickupDate = pickup.Date;
|
||||
var userId = slot.Profile.Id;
|
||||
var userName = slot.Profile.Name;
|
||||
foreach (var slot in pickup.OccupiedSlots)
|
||||
if (!slot.IsConfirmed)
|
||||
{
|
||||
var pickupDate = pickup.Date;
|
||||
var userId = slot.Profile.Id;
|
||||
var userName = slot.Profile.Name;
|
||||
|
||||
toConfirm.Add((userName, pickupDate, userId));
|
||||
}
|
||||
toConfirm.Add((userName, pickupDate, userId));
|
||||
}
|
||||
|
||||
if (toConfirm.Count != 0)
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user