219 lines
9.2 KiB
C#
219 lines
9.2 KiB
C#
using System.Net.Http.Json;
|
|
using System.Text.Json;
|
|
using System.Text.Json.Nodes;
|
|
using FsToolbox.Cli.Helper;
|
|
using NLog;
|
|
|
|
namespace FsToolbox.Cli.Tasks
|
|
{
|
|
public static partial class StoreTasks
|
|
{
|
|
private static readonly Logger Logger = LoggingService.GetLogger(nameof(StoreTasks));
|
|
|
|
#region Public Method GetPickupsAsync
|
|
|
|
/// <summary>
|
|
/// Retrieves all pickups for the specified store with authentication handled automatically.
|
|
/// </summary>
|
|
/// <param name="httpClient">The HTTP client used to send the request.</param>
|
|
/// <param name="storeId">The store identifier to query.</param>
|
|
/// <returns>A list of pickups, or an empty list when no data is available.</returns>
|
|
public static async Task<List<Pickup>> GetPickupsAsync(HttpClient httpClient, int storeId)
|
|
{
|
|
await AuthHelper.EnsureAuthenticationAsync(httpClient);
|
|
|
|
var uri = string.Format(Endpoints.StorePickups, storeId);
|
|
var response = await httpClient.GetAsync(uri);
|
|
var responseBody = await response.Content.ReadAsStringAsync();
|
|
|
|
// handle unsuccessful response
|
|
if (!response.IsSuccessStatusCode) Logger.Error("Pickup retrieval failed ({Status} {Reason}): {Body}", (int)response.StatusCode, response.ReasonPhrase, responseBody);
|
|
|
|
var root = JsonNode.Parse(responseBody);
|
|
if (root == null) return [];
|
|
|
|
// Deserialize JsonNode to List<Pickup>
|
|
var opts = new JsonSerializerOptions
|
|
{
|
|
PropertyNameCaseInsensitive = true,
|
|
PropertyNamingPolicy = null // <── WICHTIG
|
|
};
|
|
|
|
return root["pickups"].Deserialize<List<Pickup>>(opts) ?? [];
|
|
}
|
|
|
|
#endregion
|
|
|
|
#region Public Method GetStoreMembersAsync
|
|
|
|
/// <summary>
|
|
/// Retrieves the members of the specified store, requiring authentication before the request.
|
|
/// </summary>
|
|
/// <param name="httpClient">The HTTP client used to send the request.</param>
|
|
/// <param name="storeId">The store identifier to query.</param>
|
|
/// <returns>A list of store members, or an empty list when the call fails.</returns>
|
|
public static async Task<List<Member>> GetStoreMembersAsync(HttpClient httpClient, int storeId)
|
|
{
|
|
await AuthHelper.EnsureAuthenticationAsync(httpClient);
|
|
|
|
var uri = string.Format(Endpoints.StoreMembers, storeId);
|
|
var response = await httpClient.GetAsync(uri);
|
|
var responseBody = await response.Content.ReadAsStringAsync();
|
|
|
|
// handle unsuccessful response
|
|
if (!response.IsSuccessStatusCode)
|
|
{
|
|
Logger.Error("Store members retrieval failed ({Status} {Reason}): {Body}", (int)response.StatusCode, response.ReasonPhrase, responseBody);
|
|
return [];
|
|
}
|
|
|
|
var root = JsonNode.Parse(responseBody);
|
|
if (root == null) return [];
|
|
|
|
// Deserialize JsonNode to List<Pickup>
|
|
var opts = new JsonSerializerOptions
|
|
{
|
|
PropertyNameCaseInsensitive = true,
|
|
PropertyNamingPolicy = null // <── WICHTIG
|
|
};
|
|
|
|
return root.Deserialize<List<Member>>(opts) ?? [];
|
|
}
|
|
|
|
#endregion
|
|
|
|
#region Public Method GetStoreInformationAsync
|
|
|
|
/// <summary>
|
|
/// Retrieves store information including the calendar interval.
|
|
/// </summary>
|
|
/// <param name="httpClient">The HTTP client used to send the request.</param>
|
|
/// <param name="storeId">The store identifier to query.</param>
|
|
/// <returns>The store information, or null when the call fails.</returns>
|
|
public static async Task<StoreInformation?> GetStoreInformationAsync(HttpClient httpClient, int storeId)
|
|
{
|
|
await AuthHelper.EnsureAuthenticationAsync(httpClient);
|
|
|
|
var uri = string.Format(Endpoints.StoreInformation, storeId);
|
|
var response = await httpClient.GetAsync(uri);
|
|
var responseBody = await response.Content.ReadAsStringAsync();
|
|
|
|
if (!response.IsSuccessStatusCode)
|
|
{
|
|
Logger.Error("Store information retrieval failed ({Status} {Reason}): {Body}", (int)response.StatusCode, response.ReasonPhrase, responseBody);
|
|
return null;
|
|
}
|
|
|
|
var opts = new JsonSerializerOptions
|
|
{
|
|
PropertyNameCaseInsensitive = true,
|
|
PropertyNamingPolicy = null
|
|
};
|
|
|
|
try
|
|
{
|
|
return JsonSerializer.Deserialize<StoreInformation>(responseBody, opts);
|
|
}
|
|
catch (JsonException ex)
|
|
{
|
|
Logger.Error(ex, "Failed to parse store information response.");
|
|
return null;
|
|
}
|
|
}
|
|
|
|
#endregion
|
|
|
|
#region Public Method GetStoreLogAsync
|
|
|
|
/// <summary>
|
|
/// Retrieves the store log for a specified store and date range.
|
|
/// </summary>
|
|
/// <param name="httpClient">The HTTP client used to send the request.</param>
|
|
/// <param name="storeId">The store identifier to query.</param>
|
|
/// <param name="fromDate">Start date (formatted for the API).</param>
|
|
/// <param name="toDate">End date (formatted for the API).</param>
|
|
/// <param name="storeLogActionIds">Comma-separated action IDs.</param>
|
|
/// <returns>The raw response body from the API.</returns>
|
|
public static async Task<string> GetStoreLogAsync(HttpClient httpClient, int storeId, string fromDate, string toDate, string storeLogActionIds)
|
|
{
|
|
await AuthHelper.EnsureAuthenticationAsync(httpClient);
|
|
|
|
var uri = string.Format(Endpoints.StoreLog, storeId, fromDate, toDate, storeLogActionIds);
|
|
var response = await httpClient.GetAsync(uri);
|
|
var responseBody = await response.Content.ReadAsStringAsync();
|
|
|
|
// handle unsuccessful response
|
|
if (!response.IsSuccessStatusCode)
|
|
Logger.Error("Store log retrieval failed ({Status} {Reason}): {Body}", (int)response.StatusCode, response.ReasonPhrase, responseBody);
|
|
|
|
return responseBody;
|
|
}
|
|
|
|
#endregion
|
|
|
|
#region Public Method GetStoreLogEntriesAsync
|
|
|
|
/// <summary>
|
|
/// Retrieves and deserializes store log entries for a specified store and date range.
|
|
/// </summary>
|
|
/// <param name="httpClient">The HTTP client used to send the request.</param>
|
|
/// <param name="storeId">The store identifier to query.</param>
|
|
/// <param name="fromDate">Start date (formatted for the API).</param>
|
|
/// <param name="toDate">End date (formatted for the API).</param>
|
|
/// <param name="storeLogActionIds">Comma-separated action IDs.</param>
|
|
/// <returns>A list of store log entries, or an empty list when parsing fails.</returns>
|
|
public static async Task<List<StoreLogEntry>> GetStoreLogEntriesAsync(HttpClient httpClient, int storeId, string fromDate, string toDate, string storeLogActionIds)
|
|
{
|
|
var responseBody = await GetStoreLogAsync(httpClient, storeId, fromDate, toDate, storeLogActionIds);
|
|
|
|
var opts = new JsonSerializerOptions
|
|
{
|
|
PropertyNameCaseInsensitive = true,
|
|
PropertyNamingPolicy = null
|
|
};
|
|
|
|
try
|
|
{
|
|
return JsonSerializer.Deserialize<List<StoreLogEntry>>(responseBody, opts) ?? [];
|
|
}
|
|
catch (JsonException ex)
|
|
{
|
|
Logger.Error(ex, "Failed to parse store log response.");
|
|
return [];
|
|
}
|
|
}
|
|
|
|
#endregion
|
|
|
|
#region Public Method PatchPickupAsync
|
|
|
|
/// <summary>
|
|
/// Marks a pickup slot as confirmed for the specified store, date, and user.
|
|
/// </summary>
|
|
/// <param name="httpClient">The HTTP client used to send the request.</param>
|
|
/// <param name="storeId">The store identifier containing the pickup.</param>
|
|
/// <param name="pickupDate">The date of the pickup to patch.</param>
|
|
/// <param name="fsId">The Foodsharing user identifier associated with the slot.</param>
|
|
/// <returns>A task representing the asynchronous operation.</returns>
|
|
public static async Task PatchPickupAsync(HttpClient httpClient, int storeId, string pickupDate, int fsId)
|
|
{
|
|
await AuthHelper.EnsureAuthenticationAsync(httpClient);
|
|
|
|
var uri = string.Format(Endpoints.StorePickupsSlot, storeId, pickupDate, fsId);
|
|
var payload = new JsonObject
|
|
{
|
|
["isConfirmed"] = true
|
|
};
|
|
var response = await httpClient.PatchAsync(uri, JsonContent.Create(payload));
|
|
var responseBody = await response.Content.ReadAsStringAsync();
|
|
|
|
// handle unsuccessful response
|
|
if (!response.IsSuccessStatusCode)
|
|
Logger.Error("Pickup patch failed ({Status} {Reason}): {Body}", (int)response.StatusCode, response.ReasonPhrase, responseBody);
|
|
else
|
|
Logger.Info("Pickup patch succeeded {FsId} on {PickupDate}", fsId, pickupDate);
|
|
}
|
|
|
|
#endregion
|
|
}
|
|
} |