основное сделано
This commit is contained in:
@@ -0,0 +1,95 @@
|
||||
using System.Text.Json;
|
||||
|
||||
namespace Tnsu.ApprovalRoute.Application.Reminders;
|
||||
|
||||
/// <summary>
|
||||
/// Строка списка «… — согласование», разобранная из ответа SharePoint.
|
||||
/// Имена колонок — как в request-portal (FIELDS в approvalList.service.ts):
|
||||
/// именно он эти списки и создаёт.
|
||||
/// </summary>
|
||||
internal sealed record ApprovalRow(
|
||||
int Id,
|
||||
int TicketId,
|
||||
int StepOrder,
|
||||
string Status,
|
||||
string Phase,
|
||||
DateTimeOffset? Date,
|
||||
string? ApproverEmail,
|
||||
int? SlaHours,
|
||||
bool? AskOverdueReason)
|
||||
{
|
||||
public static ApprovalRow? TryParse(JsonElement item)
|
||||
{
|
||||
// TicketId — Lookup на заявку; без него строку не с чем связать.
|
||||
if (!TryGetInt(item, "TicketId", out var ticketId)) return null;
|
||||
|
||||
var approver = item.TryGetProperty("TansuSiteApprover", out var a) && a.ValueKind == JsonValueKind.Object
|
||||
? GetString(a, "EMail")
|
||||
: null;
|
||||
|
||||
return new ApprovalRow(
|
||||
TryGetInt(item, "Id", out var id) ? id : 0,
|
||||
ticketId,
|
||||
TryGetInt(item, "StepOrder", out var order) ? order : 0,
|
||||
GetString(item, "ApprovalStatus") ?? string.Empty,
|
||||
// Пустая фаза — старые строки, заведённые до появления колонки;
|
||||
// трактуем как «Согласование» (так же поступает request-portal).
|
||||
GetString(item, "Phase") is { Length: > 0 } phase ? phase : ApprovalPhases.Approval,
|
||||
TryGetDate(item, "Date"),
|
||||
approver,
|
||||
TryGetInt(item, "SLAhours", out var sla) ? sla : null,
|
||||
TryGetBool(item, "AskOverdueReason", out var ask) ? ask : null);
|
||||
}
|
||||
|
||||
private static string? GetString(JsonElement e, string name) =>
|
||||
e.TryGetProperty(name, out var v) && v.ValueKind == JsonValueKind.String ? v.GetString() : null;
|
||||
|
||||
private static bool TryGetInt(JsonElement e, string name, out int value)
|
||||
{
|
||||
value = 0;
|
||||
return e.TryGetProperty(name, out var v) && v.ValueKind == JsonValueKind.Number && v.TryGetInt32(out value);
|
||||
}
|
||||
|
||||
private static bool TryGetBool(JsonElement e, string name, out bool value)
|
||||
{
|
||||
value = false;
|
||||
if (!e.TryGetProperty(name, out var v)) return false;
|
||||
if (v.ValueKind is not (JsonValueKind.True or JsonValueKind.False)) return false;
|
||||
value = v.GetBoolean();
|
||||
return true;
|
||||
}
|
||||
|
||||
private static DateTimeOffset? TryGetDate(JsonElement e, string name) =>
|
||||
e.TryGetProperty(name, out var v) &&
|
||||
v.ValueKind == JsonValueKind.String &&
|
||||
DateTimeOffset.TryParse(v.GetString(), out var parsed)
|
||||
? parsed
|
||||
: null;
|
||||
}
|
||||
|
||||
internal static class ApprovalPhases
|
||||
{
|
||||
public const string Approval = "Согласование";
|
||||
public const string Execution = "Исполнение";
|
||||
}
|
||||
|
||||
internal static class ApprovalStatuses
|
||||
{
|
||||
public const string OnApproval = "На согласовании";
|
||||
public const string OnExecution = "На исполнении";
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Managed property статуса строки маршрута для KQL — ApprovalStatusOWSCHCS.
|
||||
/// Имя нестандартное (суффикс OWSCHCS у Choice-поля, префикс группы колонок
|
||||
/// сайта у самого имени) — совпадает с MP_STATUS в
|
||||
/// request-portal/src/webparts/requestPortal/features/myRequests/myRequests.service.ts,
|
||||
/// это тот же список и та же колонка, имя проверено там же.
|
||||
/// </summary>
|
||||
internal static class SlaStatus
|
||||
{
|
||||
private const string ManagedProperty = "ApprovalStatusOWSCHCS";
|
||||
|
||||
public static readonly string OnApprovalProperty = $"{ManagedProperty}:\"{ApprovalStatuses.OnApproval}\"";
|
||||
public static readonly string OnExecutionProperty = $"{ManagedProperty}:\"{ApprovalStatuses.OnExecution}\"";
|
||||
}
|
||||
Reference in New Issue
Block a user