В данной статье я хотел бы изложить опыт работы с задачами, заданиями, уведомлениями в контексте разработки DirectumRX, с небольшими (но, думаю, полезными, сниппетами).
DirectumRX реализован на языке C#, что позволяет использовать функционал объектно-ориентированного программирования, а в частности - наследование. Для любой задачи, и любого задания, уведомления, созданного в прикладной разработке есть общий предок, который реализует базовый интерфейс типа:
Что это дает разработчику - во-первых, возможность использовать репозитории базовых типов. Это используется, например в фоновом процессе рассылки почтовых уведомлений, когда нужно работать со всей массой заданий, как с одним типом. Во-вторых, использовать в качестве параметров функций унифицированный тип, сводя множество if-else в одну функцию, и избегая таким образом дублирования кода.
Как вы знаете, у заданий есть результаты выполнения. Чтобы выполнить задание из кода, нужно вызвать функцию Complete, и передать ей в качестве параметра результат. Для SimpleTask (базовая задача, или простая задача) - это будет null, для других типов же нужно обратиться к классу Result пространства имен задания, для задания на согласование, например, это будет - Sungero.Docflow.ApprovalAssignment.Result. В нем-то и содержатся результаты выполнения.
Допустим, вам нужно найти задачу, в которую вложен определенный документ. Для этого можно воспользоваться свойством AttachmentDetails.
Tasks.GetAll().Any(t => t.AttachmentDetails.Any(d => d.EntityId.Value == anyId))
Данный “трик” позволит получить все задачи, во вложениях которых есть сущность с определенным ИД, если вам нужно конкретизировать тип сущности - можно воспользоваться свойством EntityTypeGuid указав его в фильтре.
Бывает так, что в определенный момент нужно создать уведомление по задаче, но 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.
Иногда мало просто закрыть задачу в автоматическом режиме, задания на согласование и подпись требуют еще и подписания документа. Для подписания в системе предусмотрен репозиторий 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). Два в одном. Остается только повесить вызов клиентской функции в планировщик.
Авторизуйтесь, чтобы написать комментарий