Использование динамической зоны ответственности
Динамические зоны ответственности – это очень мощный инструмент, который позволяет создавать гибкие процессы. Предположим, что существует некая организация с несколькими юридическими лицами. В бухгалтерии каждый сотрудник отвечает за свое юридическое лицо. Рассмотрим процесс согласования входящих договоров бухгалтерией.
Создадим справочник Наша организация со свойствами Наименование и Бухгалтер и процесс согласования договора с Динамической зоной ответственности согласующего.
Для того, чтобы определять Зону ответственности с помощью сценария, необходимо поменять Зону ответственности на Динамическую.
При смене типа Дизайнер предложит создать переменную для хранения пользователя.
Необходимо обратить внимание, что есть два вида динамической зоны ответственности: Динамическая (выбор из списка) и Динамическая (определяется сценарием). Использовать можно любую, однако тип Динамическая (определяется сценарием) позволяет хранить в себе сценарий для вычисления значения переменной. Можно разместить блок Сценарий перед переходом на необходимую зону ответственности, как на этом изображении.
Но чтобы не "захламлять" карту процесса и не дезориентировать пользователей системы, предпочтительней "прятать" сценарии. Здесь сценарий находится в зоне ответственности, и никого не "смущает".
Однако бывают ситуации, когда необходимо вычислить исполнителя до перехода в произвольном месте бизнес-процесса, например, чтобы инициатор согласования мог увидеть исполнителя до назначения задачи.
- Выбрать согласующего бухгалтера вручную.
- Поставить задачу согласования бухгалтеру, ответственному за данное юридическое лицо.
- Поставить задачу согласования главному бухгалтеру, если сумма договора больше N (в данном примере больше миллиона).
- Поставить задачу согласования главному бухгалтеру, если бухгалтер, отвечающий за выбранное юридическое лицо, не справляется с объемом (в данном примере более трех активных задач согласования).
Пример сценария с использованием PublicAPI
Текст сценария:
//если автор задачи не выбрал согласующего вручную, начинаем определять его сценарием if (context.Soglasuschiy == null) { var runningStatus = PublicAPI.Enums.Workflow.WorkflowInstanceStatus.Running; //создаем фильтр для нахождения активных экземпляров процесса var filter = PublicAPI.Processes.WorkflowInstance.Filter() .Statuses(runningStatus) .TaskName("Согласование договора").Filter; var count = PublicAPI.Processes.WorkflowInstance.Count(filter); //если запущенно более трех экземпляров, или сумма договора более миллиона, ставим задачу Главному бухгалтеру if (count > 3 || context.SummaDogovora >= 1000000) { //для этого определяем руководителя бухгалтера привязанного к выбранной организации var chiefs = context.Organizaciya.Buhgalter.OrganizationItems.ToArray() .Union(context.Organizaciya.Buhgalter.OrganizationGroups) .Select(organizationItem => { var parentOrganizationItem = organizationItem.ParentItem; while (parentOrganizationItem != null && parentOrganizationItem.User == null) parentOrganizationItem = parentOrganizationItem.ParentItem; return parentOrganizationItem != null ? parentOrganizationItem.User : null; }) .Where(u => u != null); var chief = chiefs.First(); //ставим руководителя в зону ответственности context.Soglasuschiy = chief; } //иначе ставим задачу обычному бухгалтеру привязанному к данной организации else { context.Soglasuschiy = context.Organizaciya.Buhgalter; } }
Пространства имен:
using EleWise.ELMA.API; using EleWise.ELMA.Workflow.Models;
Текст сценария:
//если автор задачи не выбрал согласующего вручную, начинаем определять его сценарием if(context.Soglasuschiy == null) { //создаем фильтр для нахождения активных экземпляров процесса var filter = InterfaceActivator.Create<WorkflowInstanceFilter>(); filter.Statuses = new List<WorkflowInstanceStatus>(); //только активные filter.Statuses.Add(WorkflowInstanceStatus.Running); //только задача согласующего filter.TaskName = "Согласование договора"; //получаем количество активных экземпляров процесса по фильтру var count = WorkflowInstanceManager.Instance.Count(filter); //если запущенно более трех экземпляров, или сумма договора более миллиона, ставим задачу Главному бухгалтеру if(count > 3 || context.SummaDogovora >= 1000000) { //для этого определяем руководителя бухгалтера привязанного к выбранной организации var chiefs = context.Organizaciya.Buhgalter.OrganizationItems.ToArray() .Union(context.Organizaciya.Buhgalter.OrganizationGroups) .Select(organizationItem => { var parentOrganizationItem = organizationItem.ParentItem; while (parentOrganizationItem != null && parentOrganizationItem.User == null) parentOrganizationItem = parentOrganizationItem.ParentItem; return parentOrganizationItem != null ? parentOrganizationItem.User : null; }) .Where(u => u != null); var chief = chiefs.First(); //ставим руководителя в зону ответственности context.Soglasuschiy = chief; } //иначе ставим задачу обычному бухгалтеру привязанному к данной организации else { context.Soglasuschiy = context.Organizaciya.Buhgalter; }
Пример сценария без использования PublicAPI
Пространства имен:using EleWise.ELMA.Model.Services; using EleWise.ELMA.Workflow.Models; using EleWise.ELMA.Workflow.Managers;
Текст сценария:
//если автор задачи не выбрал согласующего вручную, начинаем определять его сценарием if(context.Soglasuschiy == null) { //создаем фильтр для нахождения активных экземпляров процесса var filter = InterfaceActivator.Create<WorkflowInstanceFilter>(); filter.Statuses = new List<WorkflowInstanceStatus>(); //только активные filter.Statuses.Add(WorkflowInstanceStatus.Running); //только задача согласующего filter.TaskName = "Согласование договора"; //получаем количество активных экземпляров процесса по фильтру var count = WorkflowInstanceManager.Instance.Count(filter); //если запущенно более трех экземпляров, или сумма договора более миллиона, ставим задачу Главному бухгалтеру if(count > 3 || context.SummaDogovora >= 1000000) { //для этого определяем руководителя бухгалтера привязанного к выбранной организации var chiefs = context.Organizaciya.Buhgalter.OrganizationItems.ToArray() .Union(context.Organizaciya.Buhgalter.OrganizationGroups) .Select(organizationItem => { var parentOrganizationItem = organizationItem.ParentItem; while (parentOrganizationItem != null && parentOrganizationItem.User == null) parentOrganizationItem = parentOrganizationItem.ParentItem; return parentOrganizationItem != null ? parentOrganizationItem.User : null; }) .Where(u => u != null); var chief = chiefs.First(); //ставим руководителя в зону ответственности context.Soglasuschiy = chief; } //иначе ставим задачу обычному бухгалтеру привязанному к данной организации else { context.Soglasuschiy = context.Organizaciya.Buhgalter; }