Голосование в задаче согласования Directum RX в 2027: модификация через low-code
На практике часто возникает необходимость организовать коллегиальное принятие решений — например, при утверждении решений совещания, бюджетов или стратегических инициатив. Стандартные механизмы согласования в Directum RX позволяют настроить маршрут, но не поддерживают полноценное голосование с фиксацией позиций «За», «Против», «Воздержался».
В 2027 году эту задачу можно решить через low-code — без изменения стандартных механизмов системы. В этой статье — как мы реализовали модификацию для голосования в рамках задачи согласования.
Если вы хотите понять, как Directum RX встраивается в общую архитектуру — изучите подробнее о Directum RX. Там описаны технические требования и схемы развёртывания.

Задача: коллегиальное принятие решений
В этой статье — как реализовать модификацию для голосования в рамках задачи согласования, сохранив привычный интерфейс и интегрировав результаты прямо в протокол совещания.
Требования
- Голосование должно быть доступно на любом этапе согласования.
- Участники голосуют по каждому решению: «За», «Против», «Воздержался».
- Нельзя выбрать несколько вариантов.
- Результаты агрегируются в протоколе.
- Голосование — опциональная функция, активируемая при необходимости.
Реализация: ключевые компоненты
Модификация включает несколько компонентов:
- Настройка вида документа «Протокол совещания».
- Создание справочника «Матрицы согласования».
- Доработка задачи согласования.
- Асинхронный обработчик результатов.
- Роль согласования «Участники голосования».
Добавление признака «Требуется голосование»
В перекрытый справочник DocumentKind добавляем логическое свойство:
csharp
/// <summary>
/// Требуется голосование.
/// </summary>
public virtual bool? NeedVoting { get; set; }
На событии Showing формы — показываем только для вида «Протокол совещания»:
csharp
public override void Showing(Sungero.Presentation.FormShowingEventArgs e)
{
base.Showing(e);
var isMinutes = _obj.DocumentType?.DocumentTypeGuid == Constants.MeetingMinutesTypeGuid;
_obj.State.Properties.NeedVoting.IsVisible = isMinutes;
}
Коллекция решений в протоколе
В карточку Minutes добавляем коллекцию Decisions, где каждое решение содержит:
- Текст решения.
- Матрицу голосующих.
- Счётчики голосов.
- Результат.
csharp
public virtual void DecisionsAdded(Sungero.Domain.Shared.CollectionPropertyAddedEventArgs e)
{
var added = e.Added as IMinuteDecision;
added.Number = (_obj.Decisions.Max(d => d.Number) ?? 0) + 1;
added.Result = Resources.NoResults;
}
Кастомный тип этапа «Голосование»
csharp
/// <summary>
/// Тип этапа.
/// </summary>
public virtual CustomStageType? CustomStageType { get; set; }
Фильтруем отображение — «Голосование» доступно только для этапов типа «Задание»:
csharp
public virtual IEnumerable<Enumeration> CustomStageTypeFiltering(IEnumerable<Enumeration> query)
{
if (_obj.StageType != StageType.SimpleAgr || _obj.AllowSendToRework == true)
query = query.Where(q => !Equals(q, CustomStageType.Voting));
return query;
}
Коллекция голосов в задании
В перекрытое задание ApprovalSimpleAssignment добавляем коллекцию Voting, содержащую:
- Decision — текст.
- VoteFor, VoteAgainst, VoteAbstain — выбор.
Обеспечиваем взаимоисключающий выбор:
csharp
public virtual void VotingVoteAgainstValueInput(Sungero.Presentation.BooleanValueInputEventArgs e)
{
if (e.NewValue == true)
{
_obj.VoteFor = false;
_obj.VoteAbstain = false;
}
}
public virtual void VotingVoteForValueInput(Sungero.Presentation.BooleanValueInputEventArgs e)
{
if (e.NewValue == true)
{
_obj.VoteAgainst = false;
_obj.VoteAbstain = false;
}
}
Проверка голосования перед завершением задания
На событии BeforeComplete убеждаемся, что по всем решениям проголосовано:
csharp
public override void BeforeComplete(Sungero.Workflow.Server.BeforeCompleteEventArgs e)
{
base.BeforeComplete(e);
if (_obj.CustomStageType != CustomStageType.Voting)
return;
var emptyVotes = _obj.Voting.Where(v => !v.VoteFor && !v.VoteAgainst && !v.VoteAbstain);
if (emptyVotes.Any())
{
e.AddError("Проголосуйте по всем решениям.");
return;
}
}
Асинхронный обработчик результатов
После завершения задания — агрегируем голоса в протоколе:
csharp
public void AddVotingResults(long assignmentId, long minutesId)
{
var assignment = ApprovalSimpleAssignment.GetAll().Where(a => a.Id == assignmentId).FirstOrDefault();
var minutes = Minutes.GetAll().Where(m => m.Id == minutesId).FirstOrDefault();
if (assignment == null || minutes == null) return;
foreach (var vote in assignment.Voting)
{
var decision = minutes.Decisions.FirstOrDefault(d => d.Id == vote.MinutedDecisionId);
if (decision != null)
{
if (vote.VoteFor) decision.VoteFor = (decision.VoteFor ?? 0) + 1;
if (vote.VoteAgainst) decision.VoteAgainst = (decision.VoteAgainst ?? 0) + 1;
if (vote.VoteAbstain) decision.VoteAbstain = (decision.VoteAbstain ?? 0) + 1;
decision.Result = $"За: {decision.VoteFor}, Против: {decision.VoteAgainst}, Воздержались: {decision.VoteAbstain}";
}
}
minutes.Save();
}
Роль согласования «Участники голосования»
Ограничиваем доступ роли только для протоколов:
csharp
public override List<IDocumentKind> Filter(List<IDocumentKind> kinds)
{
var query = base.Filter(kinds);
if (_obj.Type == RoleType.MinutesVoters)
query = query.Where(k => k.DocumentType.DocumentTypeGuid == Constants.MeetingMinutesTypeGuid);
return query.ToList();
}
Как это связано с автоматизацией договоров
Голосование в задаче согласования — частный случай коллегиального принятия решений. Но тот же подход используется и для согласования договоров, когда нужно собрать визы нескольких участников.
Если хотите понять, как автоматизировать работу с договорами в целом — изучите как автоматизировать работу с договорами. Там разобраны типовые сценарии.
А если нужна настройка маршрутов согласования договоров — посмотрите согласование договоров.
Итог
Модификация позволяет:
- Голосовать прямо в задаче согласования.
- Сохранять результаты в протоколе.
- Гибко настраивать состав голосующих.
- Интегрировать в любые бизнес-процессы.
Решение реализовано через low-code подход, без изменения стандартных механизмов Directum RX, что упрощает сопровождение и обновление.
Что делать дальше
Если нужна помощь с внедрением
Если хотите заказать внедрение Directum RX с подобными доработками — посмотрите заказать внедрение. Мы поможем с настройкой и кастомизацией.
Если нужна техподдержка
Если система уже работает, но нужна помощь с доработками — посмотрите техподдержка Directum. Мы поможем с обновлениями и кастомизацией.
Если хотите посмотреть кейс
Посмотрите кейс: Интеррос — как инвестиционный гигант перешёл на Directum RX за 3 месяца с кастомизацией под свои процессы.
FAQ: частые вопросы
Можно ли реализовать голосование без доработок?
Нет. Стандартные механизмы Directum RX не поддерживают полноценное голосование с фиксацией позиций. Требуется модификация, но её можно реализовать через low-code.
Нужно ли менять стандартные механизмы?
Можно ли интегрировать голосование с другими процессами?
Сколько времени занимает реализация?
Есть ли у ЦВД опыт таких доработок?
25 ноября 2025 г. · 25 мин
22 ноября 2025 г. · 27 мин
