1.3.2.3. Настройка этапа

Основная логика проекта настраивается в этапах проекта. Этапы - это состояния, в которых находится объект бизнесс процесса. Документ может переходить с этапа на этап линейно, пропускать этапы или двигаться по разным этапам в зависимости от его параметров. Инструменты настройки этапов позволяют максимально точно настроить бизнесс процесс и автоматизировать управление передачи и изменения данных в БП.

Примечание

В данном разделе используются валиаторы, которым посвещена отдельная статья. Возможно, было бы полезно вначале ознакомится с этим понятием тут Валидаторы этапа и переходов

Файлы конфигурации этапов представляют из себя XML-документы и находится папке workflow корневой директории проекта: ..bps/projects/<ИМЯ_ПРОЕКТА>/workflow/ state1.xml, state2.xml…

Создайте в папке /workflow для своего проекта необходимое количество xml файлов, с названиями эквивалентными системному названию этапа и расширением «.xml»

Рассмотрим по порядку структуру такого файла и его содержимое. Сам файл представляет собой XML-документ с корневым тэгом «xml», внутри которого содержаться дочерние узлы

<xml>
    ...
</xml>

1.3.2.3.1. Валидаторы этапа

Проверяют карточку, которая находится на этом этапе. Если проверка не выполнена, то в верхней части страницы с документом в блоке «Обратите внимание» выводятся сообщения о не пройденных проверках. Если проверяется параметр документа, который выводится в форме, то он подсвечивается желтым цветом с сообщением не выполненной проверке.

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

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

Блоков валидатора может быть несколько для того, чтобы некоторым из них можно было задавать области применимости через skip_if_invalid (см Валидаторы этапа и переходов)

Предупреждение

Модификатор валидатора hide_if_invalid в валидаторе этапа не допускается.

<xml>

    <validator>
      <field1 rule="equal">120</field1>
      <field2 rule="not_equal">200</field2>
    </validator>

    <validator>
      <field3 rule="equal">120</field1>
      <field4 rule="not_equal">200</field2>
    </validator>

</xml>

При открытии карточки, находящейся на этом этапе, система проверит что поля

  • field1 == 120

  • field2 != 200

  • field3 == 120

  • field4 != 200

Если это не так, то выполнит поиск этих параметров в полях карточки и возьмет названия этих полей. Выведет в блоке «Обратите внимание» сообщения о том, что требуется выполнить эти условия, чтобы можно было отправить документы на следующие этапы. Если эти поля будут выведены в форме документа, они будут подсвечены желтым цветом с сообщениями о не выполненных проверках

1.3.2.3.2. Настройка доступа к полям

Для настройки видимости и доступа к полям документа в конфигурационном файле создайте блок <field_access></field_access> (блок доступа к полям).

Для управления доступом к полям в блоке field_access могут находиться два блока <read></read> (поля с доступом на чтение) и <edit></edit> (поля с доступом на редактирование). Пример структуры блока field_access:

<xml>
    <field_access>
        <edit>field_1, field_2</edit>
        <read>field_3, field_4</read>
    </field_access>
</xml>

В данном примере показана настройка разрешения на чтение для всех пользователей полей field_3 и field_4 и доступа на редактирование для всех пользователей полей field_1 и field_2, остальные поля документа (если таковые есть) будут скрыты. Блоков field_access в конфигурационном файле этапа может быть несколько, и они могут переопределять доступ к полям.

Для более точной настройки доступа к полям можно использовать Валидаторы:

<xml>
    <field_access>
        <edit>field_3</edit>
        <validator>
            <field_1 rule="equal">True</object_type>
        </validator>
    </field_access>
</xml>

Блок валидатор добавляет условие применения блока <field_access>. В данном примере поле field_3 будет доступно на редактирование только в случае сли поле документа field_1 содержит значение True. Валидаторы могут использовать для проверки не только поля документа, но и например роль текущего оператора или даже автоматически генерируемое значение. ПОдробнее о валидаторах можно узнать в разделе «Валидаторы»

Примечание

Если в этапе нет разрешения для доступа к параметру, то этот параметр не выводится в форме и не доступен пользователю. Однако, в модели документа есть метод change_field_access(self, field_access), принимающий разрешения о доступе к параметрам. Он на вход принимает словарь разрешений и может модифицировать доступы к параметрам, используя любые способы настройки (через систему администрирования, через web-сервисы другой системы). Имейте это ввиду, когда видите поведение системы, которое отличается от ожидаемого. Иногда бывают ситуации, когда доступом можно управлять со стороны javaScript, в котором поля можно принудительно менять на readonly отображение (но это крайне не приветствуется и считается грязным подходом)

Примечание

Если у секции field_access несколько валидаторов, то они объединяются по условию «ИЛИ», то есть, если проверку прошел один из блоков валидатора, то блок field_access в целом считается применимым. Однако, если в тэге field_access есть аттрибут tags со значением check_all_validators, то он меняет объединение валидаторов на оператор «И», то есть, в этом случае, требуется чтобы проверку прошли все блоки валидатора.

1.3.2.3.3. Настройка доступа к таблицам

Выполняет тоже самое, что и настроку доступа к полям, только применяется к полям табличного типа. Настройка этих полей более сложная, так как у таблицы есть несколько строк и поля в каждой строке можно настривать по разному. Также есть отдельный настройки на право удалять существующие строки или создавать новые.

Можно доступ к табличным полям выполнять и через field_access. В этом случае, при указании поля в edit, пользователю одинаково доступен полный функционал работы с таблицей. Редактирование любого поля в любой строке, добавление или удаление поля. Этот метод настройки используется только если вам нужне больше точности в управлении доступом, когда вы хотите управлять доступом к отдельной строке, к каждому полю. Когда вы хотите разрешать удалять только некоторые строки.

В случае, если в настройках этапа система встретит настройку доступа к табличному полю в field_access и в table_access, то доступы, описанные в field_access полностью игнорируются. Если взялись настраивать доступ точно, то делайте это полностью.

Представляет собой узлы «table_access» следующего вида, которые находятся непосредственно в корневом узле

<xml>
    <table_access field_name="table_name">
        <read>field1, field2, field3</read>
        <edit>field4, field5</edit>
        <access>create, existing, delete</access>
        <validator>
            <is_responsible rule="equal">True</is_responsible>
            <has_role rule="call" argument="assistance_vzr">True</has_role>
            <ins_type rule="equal">kasko</ins_type>
        </validator>
    </table_access>
</xml>

Опишем эти свойства

  • field_name - Системное название табличного поля, к которому настраивается доступ

  • read - Список полей таблицы, доступных пользователю на просмотр

  • edit - Список полей таблицы, доступных пользователю на редактирование

  • access - Описывает, на какую часть таблицы распространяется разрешение table_access

    • create - блок разрешений применим к созданию новой строки. Если этого доступа нет, пользователь не может добавить строку в таблице

    • existing - Доступ распространяется на существующие строки

    • delete - право на удаление строки

  • validator - Опциональный параметр. Выполняет работу точно также, как и валидаторы блоков field_access, отличаясь только способом поиска параметров. В field_access система ищем параметры в документе. Здесь вначале ищется аттрибут в строке, которая валидируется. Если такой параметр не находится в строке, поиск выполняется в карточке документа. Это позволяет валидатору проверять в первую очередь, валидируемую строку, а во вторую очередь уже, карточку документа

Примечание

Если у секции table_access несколько валидаторов, то они объединяются по условию «ИЛИ», то есть, если проверку прошел один из блоков валидатора, то блок table_access в целом считается применимым. Однако, если в тэге table_access есть аттрибут tags со значением check_all_validators, то он меняет объединение валидаторов на оператор «И», то есть, в этом случае, требуется чтобы проверку прошли все блоки валидатора.

1.3.2.3.4. Настройка переходов

Переходы предназначены для изменения параметров документа Этап, Ответственный То есть, переход представляет собой ребра направленного графа бизнес-процесса. В конфигурационном файле этапа размещатся переходы, которые выходят с этого этапа. Не допускается иметь несколько переходов с одинаковым системным именем, которые выходят с одного этапа, однако, допускается иметь несколько переходов с одним системным названием, которые выходят с разных этапов. Таким образом, переход уникально идентифицируется этапом, с которого он выходит и системным именем перехода.

Переходы объединяются в группы по смыслу, подходящему для данного процесса и описываются следующим образом

<events>
    <!--
    Переходы, которые не меняют этап (обратите внимание на отсутствие аттрибута state),
    но меняют ответственного. Переходы этой группы игнорируют проверки этапа
    с помощью использования признака uncondition_state и данный переход становится доступен,
    даже если работа на этапе не выполнена.

    Валидатор открывает переход, если у пользователя есть хотябы одна роль доступа из списка admin, clerk_manager
    -->
    <change_responsible title="Передать">
        <change_responsible direction="user" direction_roles="clerk" title="Другому исполнителю" tags="uncondition_state">
            <validator>
                <has_role argument="admin, clerk_manager" rule="call" message="Для Администратора или руководителя делопроизводства">True</has_role>
            </validator>
        </change_responsible>
    </change_responsible>

    <!--
    В случае, если в карточке есть какая-то ошибка, то нужно иметь возможность вернуть карточку на
    предыдущий этап. Такие переходы тоже можно выполнить тогда, когда проверки на данном этапе еще не выполнены.

    -->
    <return title="Вернуть">
        <to_appeal direction="roles" direction_roles="clerk, clerk_manager" state="appeal" title='На этап Обращение' tags="uncondition_state">
            <validator hide_if_invalid="has_role">
                <has_role argument="clerk" message="только Специалист делопроизводства" rule="call">True</has_role>
                <is_responsible message="Вы должны быть ответственным" rule="equal">True</is_responsible>
            </validator>
            <validator hide_if_invalid="has_role">
                <has_role argument="admin, senior_group" message="только для Администратор, Старший группы" rule="call">True</has_role>
            </validator>
        </to_appeal>
    </return>

    <!--
    Данные переходы отправляют карточку дальше по процессу.
    И для этих переходов важно, чтобы работа по карточке на этом этапе была выполнена.
    -->
    <forward title="Далее">
        <to_archive direction="calculate" state="archive" title="На Архивное хранение">
            <validator hide_if_invalid="has_role">
                <has_role rule="call" argument="admin, senior_group" message="Вы не Администратор или Старший группы">True</has_role>
                <decision rule="equal">canceled</decision>
            </validator>
            <validator hide_if_invalid="has_role">
                <has_role rule="call" argument="claim_damage_request_registrator,clerk">True</has_role>
                <is_responsible message="Вы должны быть ответственным" rule="equal">True</is_responsible>
                <decision rule="equal">canceled</decision>
            </validator>
        </to_archive>
        <!--
        Обратите внимание на модификатор check_all_validators
        он меняет условие объединения валидаторов между собой с "ИЛИ" на "И". То есть, чтобы открылся переход,
        требуется выполнение ВСЕХ блоков validator в этом перехода.
        Это имеет смысл для работы вместе с skip_if_invalid, который отключает некоторые валидаторы,
        если они не относятся к области применимости к карточке
        -->
        <to_request_send state="request_send" title="Отправить заявку в ИС ПВУ" direction="unchanged" tags="check_all_validators">
            <!-- Если у оператора нет нужных родей доступа, то переход просто не покажется в списке доступных -->
            <validator hide_if_invalid="has_role">
                <has_role rule="call" argument="admin, claim_damage_request_registrator">True</has_role>
                <is_responsible message="Вы должны быть ответственным" rule="equal">True</is_responsible>
            </validator>
            <!-- Эти проверки выполняются для всех карточек -->
            <validator>
                <d_event rule="required"/>
                <police_issued rule="required"/>
                <address_fias_in_event rule="required"/>
                <type_event rule="required"/>
            </validator>
            <!--
            Эта проверка применяется только для карточек, у которых str(document.is_applicant) == 'No'
            Иначе этот блок проверки пропускается
            -->
            <validator skip_if_invalid="is_applicant">
                <!-- Если -->
                <is_applicant rule="equal">No</is_applicant>
                <!-- То проверить что -->
                <app_fias_address rule="required"/>
                <app_str_address rule="required"/>
                <app_owner_type rule="required"/>
                <app_country rule="required"/>
            </validator>
            <!--
            Эта проверка применяется только для карточек, у которых str(document.vehicle_vin) == 'None'
            Иначе этот блок проверки пропускается
            -->
            <validator skip_if_invalid="vehicle_vin">
                <!-- Если -->
                <vehicle_vin rule="equal">None</vehicle_vin>
                <!-- То проверить что -->
                <chassis_num rule="required"/>
            </validator>
            <!--
            Эта проверка применяется только для карточек, у которых str(document.police_issued) == 'False'
            Иначе этот блок проверки пропускается
            -->
            <validator skip_if_invalid="police_issued">
                <!-- Если -->
                <police_issued rule="equal">False</police_issued>
                <!-- То проверить что -->
                <participants_disagreements rule="required"/>
            </validator>
        </to_request_send>
    </forward>
</events>

Если в переходе есть несколько блоков валидаторов, то они объединяются друг с другом по условию «ИЛИ». То есть, чтобы переход стал доступен, достаточно выполнения одного из валидаторов. Но если у перехода есть модификатор «check_all_validators», то он меняет объединение валидаторов на «И»

Опишем аттрибуты и возможные значения для переходов. Узел группы переходов описывать не буду, так как он вполне очевиден.

  • Название тэга - задает системное название перехода

  • direction - способ изменения ответственного оператора после совершения перехода. Если не указано, используется значение «unchanged»

    • unchanged - после выполнения, ответственный за документ не меняется

    • user - при выполнении перехода, оператор явным образом выбирает ответственного из списка. По умолчанию, выводится полный список пользователей. Если используется опция direction_roles, то в списке остаются только те пользователи, у которых есть одна из этих ролей доступа. Если требуется более точное управление, используйте переопределение метода модели документа get_event_responsible_choices(self, event: dict), который принимает словарь с данными события и возвращает список подходящих пользователей в виде [(user_id: int, user_title: str)]

    • roles - При выполнении перехода, ответственный за карточку очищается и равен None. При входе оператора в такую карточку, если у пользователя есть одна из ролей, указанных в опции direction_roles, то у в карточке доступна кнопка «Принять», при нажатии на которую, этот оператор становится ответственным за эту карточку и в таблице переходов заполняется поле d_confirm (штамп времени, когда карточку приняли на себя)

    • calculate - При совершении перехода, система принимает решение о том, кто станет ответственным, самостоятельно через вызов метода модели get_event_responsible(event: dict) и этот метод вернет экземпляр пользователя, который и будет выбран ответственным после совершении этого перехода. Если метод вернет None, то переход не выполнится с сообщением о невозможности определить ответственного

  • direction_roles - описывает список системных названий ролей доступа. Используется в зависимости от параметра direction (см. описание параметра чуть выше)

  • state - Системное название этапа, на который ведет переход. Если отсутствует, система использует системное название текущего этапа

  • title - Название перехода для оператора

  • tags - Модификаторы перехода, меняющие поведение

    • comment_required - Обязательно указание комментария при переходе

    • check_all_validators - Требуется проверка ВСЕХ секций validator чтобы открылся переход (см примеры использования в примере)

    • uncondition_state - Переход доступен даже если валидация этапа не прошла. Разрешает выполнить переход назад по процессу или переход по изменению ответственного, например.