DirectumRX. Задачи, задания, уведомления. Tips&Tricks

36 0

В данной статье я хотел бы изложить опыт работы с задачами, заданиями, уведомлениями в контексте разработки DirectumRX, с небольшими (но, думаю, полезными, сниппетами).

1. Базовые задачи и задания

DirectumRX реализован на языке C#, что позволяет использовать функционал объектно-ориентированного программирования, а в частности - наследование. Для любой задачи, и любого задания, уведомления, созданного в прикладной разработке есть общий предок, который реализует базовый интерфейс типа:

  • Для задачи - Sungero.Workflow.ITask;
  • Для задания - Sungero.Workflow.IAssignmentBase;
  • Для уведомления - Sungero.Workflow.INotice.

Что это дает разработчику - во-первых, возможность использовать репозитории базовых типов. Это используется, например в фоновом процессе рассылки почтовых уведомлений, когда нужно работать со всей массой заданий, как с одним типом. Во-вторых, использовать в качестве параметров функций унифицированный тип, сводя множество if-else в одну функцию, и избегая таким образом дублирования кода.

2. Результаты выполнения

Как вы знаете, у заданий есть результаты выполнения. Чтобы выполнить задание из кода, нужно вызвать функцию Complete, и передать ей в качестве параметра результат. Для SimpleTask (базовая задача, или простая задача) - это будет null, для других типов же нужно обратиться к классу Result пространства имен задания, для задания на согласование, например, это будет - Sungero.Docflow.ApprovalAssignment.Result. В нем-то и содержатся результаты выполнения.

3. Ищем вложение

Допустим, вам нужно найти задачу, в которую вложен определенный документ. Для этого можно воспользоваться свойством  AttachmentDetails.

Tasks.GetAll().Any(t => t.AttachmentDetails.Any(d => d.EntityId.Value == anyId))

Данный “трик” позволит получить все задачи, во вложениях которых есть сущность с определенным ИД, если вам нужно конкретизировать тип сущности - можно воспользоваться свойством EntityTypeGuid указав его в фильтре.

4. Создание уведомления по задаче

Бывает так, что в определенный момент нужно создать уведомление по задаче, но CreateWithNotices не подходит, поскольку не принимает в качестве аргумента базовую задачу.

[Remote]
public void CreateNotification(Sungero.Workflow.IAssignmentBase assignment, IRecipient performer, string subject)
{
  var task = Sungero.Workflow.SimpleTasks.CreateAsSubtask(assignment);
  task.Subject = subject;
  task.AssignmentType = Sungero.Workflow.SimpleTask.AssignmentType.Notice;
  task.RouteSteps.AddNew().Performer = performer;
  task.Start();
}

Тогда остается только сделать всё самому, принудительно указав тип “Уведомление” для задачи типа ISimpleTask.

5. Подписание

Иногда мало просто закрыть задачу в автоматическом режиме, задания на согласование и подпись требуют еще и подписания документа. Для подписания в системе предусмотрен репозиторий Signatures.

Собственно - небольшой кейс. Заказчик пожелал, чтобы просроченные задания на согласование выполнялись автоматически с соответствующей отметкой в задаче и в листе согласования.

Что нам нужно:

  • Найти просроченные задания
  • Подписать вложенные документы
  • Выполнить задания

С п.1 все понятно, нужна серверная функция:

[Remote]
public List<Sungero.Workflow.IAssignmentBase> GetAllApprovalAssignments()
{
     var today = Calendar.Now;
     var assignments = Sungero.Docflow.ApprovalAssignments.GetAll(a => a.Status == Sungero.Docflow.ApprovalAssignment.Status.InProcess && a.Deadline > today).Cast<Sungero.Workflow.IAssignmentBase>();
     var managerAssignments = Sungero.Docflow.ApprovalManagerAssignments.GetAll(a => a.Status == Sungero.Docflow.ApprovalManagerAssignment.Status.InProcess && a.Deadline > today).Cast<Sungero.Workflow.IAssignmentBase>();
     return assignments.ToList().Concat(managerAssignments.ToList()).ToList();
}

С п.2 начинается магия. Дело в том что функции репозитория Signatures - исключительно клиентские, выполнить их на сервере не получится. Но, как всегда, побеждает не самый храбрый, а самый хитрый. Нам на выручку приходит DrxUtil со своей возможностью вызова клиентских функций, (главное, чтобы они были помечены атрибутом Public).

[Public]
public void ExecuteApprovalAssignment(Sungero.Docflow.IApprovalManagerAssignment assignment){
	var document = assignment.DocumentGroup.OfficialDocuments.First();
	if(document.Versions.Count == 0){
		return;
	}
	string comment = "Автоматическое согласование";
	if(Locks.TryLock(document))
	{
		Functions.Module.Remote.CreateSubstitution(assignment.Performer); //Создаем замещение, просто так от имени системы задагние не выполнить
		Signatures.Endorse(document.Versions.Last(),comment,assignment.Performer); //Подписываем документ согласующей подписью
		assignment.Complete(Sungero.Docflow.ApprovalManagerAssignment.Result.Approved); //Завершаем задание
		document.Save();
		assignment.Save();
		Locks.Unlock(document);
		Logger.DebugFormat("Signed document = {0}, performed assignment = {1}",document.Id, assignment.Id);
	}
}

Тут мы и подписываем документ, и выполняем задание (п.3). Два в одном. Остается только повесить вызов клиентской функции в планировщик.

Пока комментариев нет.

Авторизуйтесь, чтобы написать комментарий