From 2eccd304bb324780699e3fcc1b9bcfc66aa7059e Mon Sep 17 00:00:00 2001 From: "gorbenko.pavel" Date: Fri, 16 Oct 2026 10:44:21 +0500 Subject: [PATCH] =?UTF-8?q?=D0=9A=D1=80=D0=B0=D1=82=D0=BA=D0=B8=D0=B5=20?= =?UTF-8?q?=D1=82=D0=B5=D0=BA=D1=81=D1=82=D1=8B=20=D0=BF=D1=80=D0=B5=D0=B4?= =?UTF-8?q?=D1=83=D0=BF=D1=80=D0=B5=D0=B6=D0=B4=D0=B5=D0=BD=D0=B8=D0=B9:?= =?UTF-8?q?=20=C2=AB=D0=9D=D0=B5=20=D0=BD=D0=B0=D0=B9=D0=B4=D0=B5=D0=BD=20?= =?UTF-8?q?=D1=80=D1=83=D0=BA=D0=BE=D0=B2=D0=BE=D0=B4=D0=B8=D1=82=D0=B5?= =?UTF-8?q?=D0=BB=D1=8C=20=D0=BD=D0=B0=D0=BF=D1=80=D0=B0=D0=B2=D0=BB=D0=B5?= =?UTF-8?q?=D0=BD=D0=B8=D1=8F=C2=BB?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Вместо длинных пояснений — короткие фразы: «Не найден руководитель направления.», «В проекте не найден руководитель проекта.», «Не проставлен директор Tansu.». Для роли «Безопасность» — «сотрудник службы безопасности», чтобы не получилось «найден безопасность». Co-Authored-By: Claude Sonnet 5.5 --- .../Common/StepLabels.cs | 12 ++++++++++++ .../TemplateRoutes/TemplateRouteService.cs | 8 ++++---- .../ApplicationServices/TemplateRouteServiceTests.cs | 4 ++-- 3 files changed, 18 insertions(+), 6 deletions(-) diff --git a/backend/Tnsu.ApprovalRoute.Application/Common/StepLabels.cs b/backend/Tnsu.ApprovalRoute.Application/Common/StepLabels.cs index 5e92a8f..8eb2b8b 100644 --- a/backend/Tnsu.ApprovalRoute.Application/Common/StepLabels.cs +++ b/backend/Tnsu.ApprovalRoute.Application/Common/StepLabels.cs @@ -20,6 +20,18 @@ public static class StepLabels _ => headType.ToString() }; + /// Название с маленькой буквы — для середины фразы («Не найден руководитель направления»). + public static string InSentence(HeadType headType) => Lower(Of(headType)); + + /// + /// Все названия мужского рода («найден руководитель проекта»), кроме «Безопасность» — + /// для неё нужна отдельная формулировка, иначе выйдет «найден безопасность». + /// + public static string InSentence(ProjectRole projectRole) => + projectRole == ProjectRole.Security ? "сотрудник службы безопасности" : Lower(Of(projectRole)); + + private static string Lower(string label) => char.ToLowerInvariant(label[0]) + label[1..]; + public static string Of(ProjectRole projectRole) => projectRole switch { ProjectRole.ProjectManager => "Руководитель проекта", diff --git a/backend/Tnsu.ApprovalRoute.Application/TemplateRoutes/TemplateRouteService.cs b/backend/Tnsu.ApprovalRoute.Application/TemplateRoutes/TemplateRouteService.cs index 16c686b..3b3895f 100644 --- a/backend/Tnsu.ApprovalRoute.Application/TemplateRoutes/TemplateRouteService.cs +++ b/backend/Tnsu.ApprovalRoute.Application/TemplateRoutes/TemplateRouteService.cs @@ -438,7 +438,7 @@ public sealed class TemplateRouteService( { resolvedEmail = projectExecutors.FirstOrDefault(e => e.ProjectRole == step.ProjectRole)?.Email; if (string.IsNullOrWhiteSpace(resolvedEmail)) - warning = $"Не найден исполнитель с ролью в проекте «{StepLabels.Of(step.ProjectRole.Value)}»."; + warning = $"В проекте не найден {StepLabels.InSentence(step.ProjectRole.Value)}."; } // DepartmentHead — единственный HeadType, который резолвится НЕ по цепочке // подчинённости инициатора, а по отделу, переданному явно в запросе (см. @@ -471,12 +471,12 @@ public sealed class TemplateRouteService( }; if (string.IsNullOrWhiteSpace(resolvedEmail)) { - var headLabel = StepLabels.Of(step.HeadType.Value); + var headLabel = StepLabels.InSentence(step.HeadType.Value); // Директор Tansu и управляющий директор берутся из настроек сервиса, а не из // справочника сотрудников — там email не «не найден», а «не проставлен». warning = step.HeadType is HeadType.DirectorTansu or HeadType.ManagingDirectorTansu - ? $"Не проставлен «{headLabel}»: email не задан в настройках сервиса." - : $"Не найден руководитель «{headLabel}»: не указан у инициатора в справочнике сотрудников."; + ? $"Не проставлен {headLabel}." + : $"Не найден {headLabel}."; } } else diff --git a/backend/tests/Tnsu.ApprovalRoute.IntegrationTests/ApplicationServices/TemplateRouteServiceTests.cs b/backend/tests/Tnsu.ApprovalRoute.IntegrationTests/ApplicationServices/TemplateRouteServiceTests.cs index 8b7c2af..4ef4b38 100644 --- a/backend/tests/Tnsu.ApprovalRoute.IntegrationTests/ApplicationServices/TemplateRouteServiceTests.cs +++ b/backend/tests/Tnsu.ApprovalRoute.IntegrationTests/ApplicationServices/TemplateRouteServiceTests.cs @@ -1051,7 +1051,7 @@ public sealed class TemplateRouteServiceTests : IClassFixture