using System.Text.RegularExpressions; namespace Tnsu.ApprovalRoute.Infrastructure.SharePoint; /// /// Конвенция имён списков заявок: «<Форма> <N> — данные» и парный ему /// «<Форма> <N> — согласование». /// /// Третья копия одного и того же соглашения — оно же в провижинере request-portal /// (provisioning/Provision-Lists.ps1, Get-NumberedListTitle) и в самом портале /// (shared/listTitles.ts). Держать в одном месте не получается: три разных runtime. /// Меняя здесь, менять и там. /// /// Номер стоит ПЕРЕД суффиксом, потому что имя списка согласования и портал, и /// админка выводят из имени списка данных регексом, привязанным к концу строки. /// internal static class ListTitleConvention { private const string DataSuffix = "данные"; private const string ApprovalSuffix = "согласование"; private static readonly Regex TitlePattern = new( @"^(?.+?)\s*—\s*(?данные|согласование)\s*$", RegexOptions.Compiled); private static readonly Regex TrailingNumber = new(@"\s+\d+$", RegexOptions.Compiled); /// /// Имя того же списка с номером . Уже имеющийся номер /// заменяется, а не дописывается вторым. /// public static string WithNumber(string title, int number) { var match = TitlePattern.Match(title); if (!match.Success) throw new InvalidOperationException( $"Имя списка «{title}» не по конвенции «<Форма> — данные|согласование» — номер поставить некуда."); var baseName = TrailingNumber.Replace(match.Groups["base"].Value, string.Empty); return $"{baseName} {number} — {match.Groups["suffix"].Value}"; } /// /// Имя парного списка согласования по имени списка данных (номер сохраняется). /// null — имя не по конвенции либо это не список данных. /// public static string? ToApprovalTitle(string dataListTitle) { var match = TitlePattern.Match(dataListTitle); if (!match.Success || match.Groups["suffix"].Value != DataSuffix) return null; return $"{match.Groups["base"].Value} — {ApprovalSuffix}"; } }