Add AnalyzeEarlySlotRegistrationsAsync method and update Program menu
This commit is contained in:
@@ -159,6 +159,105 @@ namespace FsToolbox.Cli
|
||||
|
||||
#endregion
|
||||
|
||||
#region Public Method AnalyzeEarlySlotRegistrationsAsync
|
||||
|
||||
/// <summary>
|
||||
/// Identifies store log entries where a user registered earlier than the automatic slot creation interval.
|
||||
/// </summary>
|
||||
/// <param name="httpClient">The HTTP client used to perform the requests.</param>
|
||||
public static async Task AnalyzeEarlySlotRegistrationsAsync(HttpClient httpClient)
|
||||
{
|
||||
await AuthHelper.EnsureAuthenticationAsync(httpClient);
|
||||
|
||||
const int regionId = 139;
|
||||
var stores = await RegionTasks.GetStoresInRegionAsync(httpClient, regionId);
|
||||
var cooperatingStores = stores.Where(x => x.CooperationStatus == RegionTasks.CooperationStatus.Cooperating).ToList();
|
||||
|
||||
if (cooperatingStores.Count == 0)
|
||||
{
|
||||
Logger.Info("No cooperating stores found in region {RegionId}.", regionId);
|
||||
return;
|
||||
}
|
||||
|
||||
var fromDate = DateTime.Today.AddMonths(-6).ToString("yyyy-MM-dd");
|
||||
var toDate = DateTime.Today.ToString("yyyy-MM-dd");
|
||||
const string storeLogActionIds = "11";
|
||||
|
||||
var ignoredStoreIds = new HashSet<int> { 51224, 61913 };
|
||||
var storesToProcess = cooperatingStores
|
||||
.Where(x => !ignoredStoreIds.Contains(x.Id))
|
||||
.ToList();
|
||||
Logger.Info("Debug mode: processing first {Count} cooperating stores.", storesToProcess.Count);
|
||||
|
||||
var analyzed = new List<StoreLogIntervalEntry>();
|
||||
|
||||
foreach (var store in storesToProcess)
|
||||
{
|
||||
var info = await StoreTasks.GetStoreInformationAsync(httpClient, store.Id);
|
||||
if (info == null)
|
||||
{
|
||||
Logger.Info("Store information not available for {StoreId}.", store.Id);
|
||||
continue;
|
||||
}
|
||||
|
||||
var calendarInterval = info.CalendarInterval;
|
||||
if (calendarInterval <= 0)
|
||||
{
|
||||
Logger.Info("Skipping {StoreName} because calendar interval is {Interval}.", store.Name, calendarInterval);
|
||||
continue;
|
||||
}
|
||||
Logger.Info("Calendar interval for {StoreName} is {Interval} seconds.", store.Name, calendarInterval);
|
||||
|
||||
var logEntries = await StoreTasks.GetStoreLogEntriesAsync(httpClient, store.Id, fromDate, toDate, storeLogActionIds);
|
||||
Thread.Sleep(1000);
|
||||
|
||||
foreach (var entry in logEntries)
|
||||
{
|
||||
if (entry.DateReference == null) continue;
|
||||
|
||||
var secondsDifference = (entry.DateReference.Value - entry.PerformedAt).TotalSeconds;
|
||||
if (secondsDifference <= calendarInterval) continue;
|
||||
|
||||
analyzed.Add(new StoreLogIntervalEntry(store, entry, secondsDifference, calendarInterval, true));
|
||||
}
|
||||
}
|
||||
|
||||
var exceeding = analyzed.Count;
|
||||
|
||||
var sb = new StringBuilder();
|
||||
sb.AppendLine("Early Slot Registration Report");
|
||||
sb.AppendLine("Generated: " + DateTime.Now.ToString("dd.MM.yyyy HH:mm"));
|
||||
sb.AppendLine($"Region: {regionId}");
|
||||
sb.AppendLine($"Stores analyzed: {storesToProcess.Count}");
|
||||
sb.AppendLine($"Timeframe: {fromDate} to {toDate}");
|
||||
sb.AppendLine($"Total log entries: {analyzed.Count}");
|
||||
sb.AppendLine($"Exceeding interval: {exceeding}");
|
||||
sb.AppendLine("============================");
|
||||
sb.AppendLine();
|
||||
|
||||
foreach (var entry in analyzed.OrderByDescending(x => x.SecondsDifference))
|
||||
{
|
||||
var foodsaver = entry.Entry.ActingFoodsaver;
|
||||
var foodsaverName = foodsaver?.Name ?? "(unknown)";
|
||||
var foodsaverId = foodsaver?.Id.ToString() ?? "n/a";
|
||||
var reference = entry.Entry.DateReference?.ToString("dd.MM.yyyy - HH:mm") ?? "n/a";
|
||||
var performed = entry.Entry.PerformedAt.ToString("dd.MM.yyyy - HH:mm");
|
||||
var intervalWeeks = entry.CalendarIntervalSeconds / (60.0 * 60 * 24 * 7);
|
||||
var earlySeconds = entry.SecondsDifference - entry.CalendarIntervalSeconds;
|
||||
var earlySpan = TimeSpan.FromSeconds(earlySeconds);
|
||||
|
||||
sb.AppendLine($"- {foodsaverName} ({foodsaverId}) | Store: {entry.Store.Name} ({entry.Store.Id}) | Performed: {performed} | Slot Date: {reference} | Interval: {intervalWeeks:F2} weeks | Early: {earlySpan.Days}d {earlySpan.Hours}h {earlySpan.Minutes}m");
|
||||
}
|
||||
|
||||
var timestamp = DateTime.Now.ToString("yyyyMMdd_HHmmss");
|
||||
var filename = $"EarlySlotRegistrations_{timestamp}.txt";
|
||||
await File.WriteAllTextAsync(filename, sb.ToString());
|
||||
|
||||
Logger.Info("Report saved: {FileName}", filename);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Public Method ConfirmUnconfirmedPickupsLindenbergAsync
|
||||
|
||||
/// <summary>
|
||||
|
||||
Reference in New Issue
Block a user