1.3.2.4. Валидаторы этапа и переходов

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

Использование валидаторов смотрите в разделе Настройка этапа

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

Примечание

Чтобы валидатор считался выполненным, требуется, чтобы все условия валидатора были выполнены. То есть, условия в валидаторе объедины через оператор «И»

Примечание

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

1.3.2.4.1. Аттрибуты валидатора

У тэга <validator> могут быть 2 не обязательных аттрибута

  • skip_if_invalid

    Пропускает данный валидатор, считая что его здесь нет вовсе, если не сработали проверки, системные названия которых перечислены в значении этого аттрибута. Суть опции в том, что через нее настраивается область применимости валидатора. То есть, проверки, которые перечислены в значении этого аттрибута, проверяют не документ, а сам валидатор и отвечают на вопрос «А для этого ли случая валидатор».

    <xml>
        <!--
        Если проверка на ins_type не сработает, то валидатор будет пропущен, как будто его
        и не существовало. То есть, он применим только если document.ins_type == 'osago'
        -->
        <validator skip_if_invalid="ins_type">
            <!-- Если тип страхования osago -->
            <ins_type rule="equal">osago</ins_type>
            <!-- То плановая дата должна быть заполнена -->
            <d_plan rule="required"/>
        </validator>
    </xml>
    
  • hide_if_invalid

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

    <xml>
        <!--
        Переход доступен когда у оператора есть роль администратора и плановая дата заполнена.
        Но если у оператора роли администратора нет, то данный переход оператору не покажется
        вообще в подсказках, что он вообще есть.
        Так как что бы оператор не делал с этой карточкой, если у оператора нет роли администратор,
        она у него не появится все равно. Этот переход не для него. И поэтому показывать его в подсказках
        нет никакого смысла
        -->
        <to_work direction="user" direction_roles="base" state="work" title="В работу">
            <validator hide_if_invalid="has_role">
                <has_role rule="call" argument="admin">True</has_role>
                <d_plan rule="required"/>
            </validator>
        </to_work>
    </xml>
    

1.3.2.4.2. Аттрибуты проверки

Валидатор состоит из списка проверок. Рассмотрим проверку более детально.

Принцип работы проверки очень прост. Она получает аттрибут документа через вызов getattr(document, name, None) и в зависимости от значения rule проверяет его на соответствие.

Если rule == „call“, то полученный аттрибут документа считается методом и вызывается с передачей параметра в виде строки, взятого из аттрибута проверки «arguments»

Параметры проверки:

  • rule Правило проверки значения для принятия решения о результате проверки (обязательный аттрибут)

  • message Сообщение о ошибке для оператора, если проверка не выполнена. Параметр не обязательный. Если отсутствует, система будет пытаться составить сообщение сама, в зависимости от типа проверки

  • arguments Не обязательный аргумент, используется для проверки типа «call» чтобы передать параметр в вызов метода

  • to_attr Прикрепляет сообщение о не прошедшей проверке к конкретному полю документа. Используется, когда требуется проверить какой-то параметр документа кастомным образом и это происходит через property с каким-то названием (отличающимся от названия самого аттрибута)

1.3.2.4.3. Правила проверки

  • Валидатор соответствия и несоответствия

    Проверяет поле или свойство документа на равенство/неравенство заданному значению Валидация пройдет при условии что поле field1 равно 120, а поле field2 не равно 200.

    <validator>
      <field1 rule="equal">120</field1>
      <field2 rule="not_equal">200</field2>
    </validator>
    
  • Валидатор «необходимо заполнить»

    Проверяет поле документа на заполненность

    <validator>
        <field3 rule="required"/>
    </validator>
    

    В примере блок валидации будет применен только в случае наличия данных в поле документа field3.

  • Валидатор проверки вхождения проверяемого элмента в список (или не вхождения)

    Основан на том, что аттрибут документа, одноименный с названием XML-тэга проверки возвращает список, каждый элемент которого приводится к строке и после этого проверяется, входит ли (или не входит) проверяемое значение в этот список

    <validator>
        <field3 rule="in">12</field3>
        <field4 rule="not_in">12</field4>
    </validator>
    

    В примере блок валидации будет применен только в случае наличия «12» в списке значений, возвращаемых field3 и при этом, если «12» не входит в список, возвращаеый аттрибутом документа с именем field4

  • Валидатор, который возвращает уже готовые результаты проверки

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

    <validator>
        <checker rule="check_message"/>
    </validator>
    
    @property
    def checker(self):
        """
        В зависимости от типа страхования проверит заполненность
        различных наборов полей и если какое-то из них пустое,
        то выдаст по всем требование о заполнении полей
        """
        messages = {}
        if self.ins_type == 'osago':
            for name in ['field1', 'field2', 'field3']:
                if not getattr(self, name):
                    messages[name] = 'Заполните'
        else:
            for name in ['field4', 'field5', 'field6']:
                if not getattr(self, name):
                    messages[name] = 'Заполните'
        return messages
    
  • Вызов функции валидации

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

    <validator>
        <has_role rule="call" arguments="admin">True</has_role>
    </validator>
    

    В данном примере валидатор проверяет наличие роли «admin» у оператора системы, который работает с документом.

1.3.2.4.4. Функции проверки, существующие в ядре

  • has_role(name) - Проверяет наличие ролей доступа в ролях оператора. name: Строка с названиями ролей, разделенных запятой (или одной ролью);

  • has_all_roles(name) - Проверяет пересечение всех запрошенных ролей с имеющимися. name: Строка с названиями ролей, разделенных запятой (или одной ролью);

  • has_file(name) - Валидатор проверки наличия хотя бы одного типа файла. name: Список типов файлов, разделенный запятой;

  • has_all_files - Валидатор проверки наличия всех типов файлов. name: Список типов файлов, разделенный запятой;

  • has_any_open_task - Проверка наличия открытых типов задач. name: Список типов задач, разделенный запятой;

  • has_any_closed_task - Проверка наличия закрытых типов задач. name: Список типов задач, разделенный запятой.

Вы можете писать собственные проверки на языке python. Для этого необходимо перегрузить класс DocumentValidatorMixin:

Создайте файл validators.py в директории /<ИМЯ_ПРОЕКТА>/document/ В файле validators.py создайте класс DocumentValidatorMixin. Не забудьте подключить новый класс в основной фаил проекта __init.py__:

from .validator import DocumentValidatorMixin

class DocumentMixin(..., DocumentValidatorMixin,)

Пример validators.py:

from datetime import date

class DocumentValidatorMixin(object):

    @property
    def is_date_in_future(self, date):
        if date > date.today():
            return  True
    return False

В примере объявляется функция is_date_in_future, которая принимает на вход аргумент date. Функция возвращает True если переданная дата больше текущей даты (в будущем), иначе возвращает False. Пример использования в конфигурационном файле этапа:

<validator>
    <is_date_in_future rule="call" arguments="date_plan">True</is_date_in_future>
</validator>

Если значение поля date_plan является датой в будущем блок валидации пройдет проверку.