Fix/by approver silent failures #25
@@ -1,3 +1,4 @@
|
|||||||
|
using System.Collections.Concurrent;
|
||||||
using System.Text.Json;
|
using System.Text.Json;
|
||||||
using System.Text.RegularExpressions;
|
using System.Text.RegularExpressions;
|
||||||
using FluentResults;
|
using FluentResults;
|
||||||
@@ -266,6 +267,29 @@ public sealed class RequestManageService(
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Пара «список согласования → (его заголовок, адрес парного списка данных)»
|
||||||
|
// не меняется, пока список не переименуют, — запоминаем на время жизни процесса,
|
||||||
|
// чтобы не тратить два запроса к SharePoint на каждый вызов. Ключ — адрес списка.
|
||||||
|
private static readonly ConcurrentDictionary<string, (string ApprovalTitle, string DataListUrl)> ListPairs =
|
||||||
|
new(StringComparer.OrdinalIgnoreCase);
|
||||||
|
|
||||||
|
private async Task<(string ApprovalTitle, string DataListUrl)?> ResolveListPairAsync(
|
||||||
|
string siteUrl, string approvalListUrl, CancellationToken cancellationToken)
|
||||||
|
{
|
||||||
|
if (ListPairs.TryGetValue(approvalListUrl, out var cached)) return cached;
|
||||||
|
|
||||||
|
var approvalList = await sharePoint.GetListByUrlAsync(siteUrl, approvalListUrl, cancellationToken);
|
||||||
|
if (approvalList is null || !ApprovalListSuffix.IsMatch(approvalList.Title)) return null;
|
||||||
|
|
||||||
|
var dataTitle = ApprovalListSuffix.Replace(approvalList.Title, " — данные");
|
||||||
|
var dataList = await sharePoint.GetListByTitleAsync(siteUrl, dataTitle, cancellationToken);
|
||||||
|
if (dataList is null) return null;
|
||||||
|
|
||||||
|
var pair = (approvalList.Title, dataList.ServerRelativeUrl);
|
||||||
|
ListPairs[approvalListUrl] = pair;
|
||||||
|
return pair;
|
||||||
|
}
|
||||||
|
|
||||||
private static string? ListUrlFromHitPath(string? path)
|
private static string? ListUrlFromHitPath(string? path)
|
||||||
{
|
{
|
||||||
if (string.IsNullOrWhiteSpace(path) || !Uri.TryCreate(path, UriKind.Absolute, out var uri)) return null;
|
if (string.IsNullOrWhiteSpace(path) || !Uri.TryCreate(path, UriKind.Absolute, out var uri)) return null;
|
||||||
@@ -287,18 +311,15 @@ public sealed class RequestManageService(
|
|||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
var approvalList = await sharePoint.GetListByUrlAsync(siteUrl, approvalListUrl, cancellationToken);
|
var pair = await ResolveListPairAsync(siteUrl, approvalListUrl, cancellationToken);
|
||||||
if (approvalList is null || !ApprovalListSuffix.IsMatch(approvalList.Title)) return [];
|
if (pair is null) return [];
|
||||||
|
var (approvalTitle, dataListUrl) = pair.Value;
|
||||||
var dataTitle = ApprovalListSuffix.Replace(approvalList.Title, " — данные");
|
|
||||||
var dataList = await sharePoint.GetListByTitleAsync(siteUrl, dataTitle, cancellationToken);
|
|
||||||
if (dataList is null) return [];
|
|
||||||
|
|
||||||
// Какому типу заявок принадлежит эта партиция (текущая или архивная).
|
// Какому типу заявок принадлежит эта партиция (текущая или архивная).
|
||||||
var requestType = siteTypes.FirstOrDefault(rt =>
|
var requestType = siteTypes.FirstOrDefault(rt =>
|
||||||
string.Equals(rt.ListId, dataList.ServerRelativeUrl, StringComparison.OrdinalIgnoreCase)
|
string.Equals(rt.ListId, dataListUrl, StringComparison.OrdinalIgnoreCase)
|
||||||
|| archivedByType[rt.Id].Any(a =>
|
|| archivedByType[rt.Id].Any(a =>
|
||||||
string.Equals(a.ListId, dataList.ServerRelativeUrl, StringComparison.OrdinalIgnoreCase)));
|
string.Equals(a.ListId, dataListUrl, StringComparison.OrdinalIgnoreCase)));
|
||||||
if (requestType is null) return [];
|
if (requestType is null) return [];
|
||||||
|
|
||||||
var rows = new List<ManagedApprovalRowDto>();
|
var rows = new List<ManagedApprovalRowDto>();
|
||||||
@@ -318,12 +339,12 @@ public sealed class RequestManageService(
|
|||||||
if (matched.Count == 0) return [];
|
if (matched.Count == 0) return [];
|
||||||
|
|
||||||
var dataById = await ReadDataRowsAsync(
|
var dataById = await ReadDataRowsAsync(
|
||||||
siteUrl, dataList.ServerRelativeUrl, matched.Select(r => r.TicketId).Distinct().ToList(),
|
siteUrl, dataListUrl, matched.Select(r => r.TicketId).Distinct().ToList(),
|
||||||
cancellationToken);
|
cancellationToken);
|
||||||
|
|
||||||
return matched
|
return matched
|
||||||
.Select(r => ToUserRow(
|
.Select(r => ToUserRow(
|
||||||
r, requestType, siteUrl, dataList.ServerRelativeUrl, approvalList.Title,
|
r, requestType, siteUrl, dataListUrl, approvalTitle,
|
||||||
dataById.GetValueOrDefault(r.TicketId)))
|
dataById.GetValueOrDefault(r.TicketId)))
|
||||||
.ToList();
|
.ToList();
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user