Резолв: Директор Tansu исключает совпавшего Директора компании
Директор Tansu (HeadType.DirectorTansu) нередко совпадает с директором ОДНОЙ из компаний инициатора (HeadType.CompanyDirectors) — обычно ТОО TANSU Construction. Раньше такое совпадение попадало в обычное схлопывание по email (CollapseByExecutorEmail) и утреннее исправление трактовало его как конфликт PositionCode (Chief/DirectionHead и т.п.) — с предупреждением и произвольным выбором одной из строк. Для этой конкретной пары это не конфликт, а один и тот же человек, увиденный с двух сторон: теперь строка CompanyDirectors с email, совпавшим с одним из DirectorTansu, убирается из результата ДО схлопывания — без предупреждения. Шаг DirectorTansu в маршруте обычно идёт последним, поэтому итоговый список не теряет исполнителя, просто перестаёт дублировать его через CompanyDirectors. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
@@ -221,11 +221,42 @@ public sealed class TemplateRouteService(
|
||||
HasUnevaluatableManagerCondition(step, positionMissing) ? PositionMissingWarning : null,
|
||||
cancellationToken)));
|
||||
|
||||
var collapsedSteps = CollapseByExecutorEmail(stepResults.SelectMany(x => x).ToList());
|
||||
var flattenedSteps = RemoveCompanyDirectorsDuplicatedByDirectorTansu(stepResults.SelectMany(x => x).ToList());
|
||||
var collapsedSteps = CollapseByExecutorEmail(flattenedSteps);
|
||||
|
||||
return Result.Ok(new ResolveTemplateRouteResultDto(route.Id, route.RequiresControl, collapsedSteps));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Директор Tansu (HeadType.DirectorTansu) сплошь и рядом совпадает с директором
|
||||
/// ОДНОЙ из компаний инициатора (HeadType.CompanyDirectors) — обычно с ТОО TANSU
|
||||
/// Construction. Оба шага в маршруте законны сами по себе, но если так, из
|
||||
/// CompanyDirectors нужно убрать именно ЭТУ строку — не смешивать её с шагом
|
||||
/// DirectorTansu через обычное схлопывание по email (см. CollapseByExecutorEmail):
|
||||
/// тот считает разные PositionCode у одного email конфликтом и пишет
|
||||
/// предупреждение, а здесь это не конфликт, а одно и то же лицо, просто
|
||||
/// увиденное с двух сторон. Шаг DirectorTansu в маршруте обычно идёт последним
|
||||
/// (после всех CompanyDirectors), поэтому удаление дубликата из CompanyDirectors
|
||||
/// оставляет его на своём месте — в конце.
|
||||
/// </summary>
|
||||
private static IReadOnlyList<ResolvedRouteStepDto> RemoveCompanyDirectorsDuplicatedByDirectorTansu(
|
||||
IReadOnlyList<ResolvedRouteStepDto> steps)
|
||||
{
|
||||
var directorTansuEmails = steps
|
||||
.Where(s => s.PositionCode == HeadType.DirectorTansu && !string.IsNullOrWhiteSpace(s.ExecutorEmail))
|
||||
.Select(s => s.ExecutorEmail!)
|
||||
.ToHashSet(StringComparer.OrdinalIgnoreCase);
|
||||
|
||||
if (directorTansuEmails.Count == 0)
|
||||
return steps;
|
||||
|
||||
return steps
|
||||
.Where(s => s.PositionCode != HeadType.CompanyDirectors
|
||||
|| string.IsNullOrWhiteSpace(s.ExecutorEmail)
|
||||
|| !directorTansuEmails.Contains(s.ExecutorEmail))
|
||||
.ToList();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Маршрут для компании/отдела инициатора с фолбэком по отделу: сначала точное
|
||||
/// совпадение отдела, если такого маршрута нет — запасной маршрут без отдела
|
||||
|
||||
Reference in New Issue
Block a user