![](https://habrastorage.org/webt/5a/ye/ur/5ayeuraj68c552yh9l_qczxbpau.jpeg)
Продолжаем рассказывать о том, как мы улучшаем жизнь не только нашим клиентам и партнерам, но и сотрудникам компании. Речь пойдет о внедрении системы согласования. Сознательно не указал согласования “чего”, так как в дальнейшем станет понятно, что чисто теоретически, согласования “всего”.
Размышления о системе согласований
Изначально в нашей компании, как и во многих других, в которых мне пришлось поработать, а также в которых был “гостем” или просто наслышан от своих знакомых, согласование договоров велось (и на момент написания статьи пока еще ведется), посредством обычной переписки в почте. Естественно это устраивает компании с небольшим количеством персонала и контрагентов. Нет особой необходимости придумывать и внедрять системы из-за подписания одного-двух договоров в месяц (а то и год) с единолично принимающим о подписывании решении генеральным директором. Аналогичная ситуация наблюдалась и с оплатой счетов. Каждый сотрудник, который взаимодействует с контрагентами и которому необходимо что-то оплатить, запрашивает счет и по почте отправляет в бухгалтерию с просьбой “оплатить”. При этом, далеко не всегда бухгалтерия оплачивает счета без предварительного согласования оплаты с непосредственным руководителем сотрудника и/или руководством компании. При определенных условиях цепочка согласований может “укорачиваться” или наоборот “удлиняться”.
Пока сотрудников не много и каждый знает всех своих коллег, кто кем является и кто кому руководитель — особых проблем не возникает. В ручном режиме и при определенных условиях заявки на оплату проходят согласования в режиме переписки и оплачиваются (либо отклоняются). Но наша компания растет и с определенного момента мы перешли ту незримую черту, после которой необходимо задуматься об автоматизации данных процессов и о необходимости внедрения чего-то нового.
Наши хотелки
У нас были свои минимальные требования к системе:
- User-friendly интерфейс и крайне желательно web-ориентированный (без надобности установки клиентов)
- Гибкость настройки
- Мы хоть и не клинические, но параноики. Поэтому сервисы, в которых может появляться конфиденциальная информация, хотим держать в нашем закрытом периметре
Первично мы провели анализ продуктов семейства “системы электронного документооборота”, которые есть на рынке. Посмотрели известные системы: 1С: Документооборот, “ДЕЛО”, “ТЕЗИС”. Также смотрели на системы, которые были созданы на заказ для других компаний, а также такие новинки, как Allware.
Не могу сказать, что системы плохие. На самом деле почти все системы позволяют выполнить основные наши “хотелки” и даже больше, чем нам нужно. Но, как обычно, дьявол кроется в деталях.
В первую очередь — интерфейс. Не привыкли мы пользоваться интерфейсом в стиле “1С”. Нам нужен простой, интуитивно-понятный интерфейс, в котором мы будем производить минимум действий для получения максимального результата (а кто же так не хочет?).
Во вторую очередь — цена (одномоментно заплаченная и затем стоимость владения продуктом в целом). Нам далеко не все нужно в системах, которые предлагаются из коробки. Но при этом платить приходится сразу за все. А так как сейчас многие переходят на систему подписки, то платить приходится постоянно и сумма, как обычно, зависит от множества условий (кол-во пользователей/подключений, возможности работы в облаке, дополнительные опции, модули и т.п.). А “соскочить” с системы, если вдруг цена перестала устраивать — проблематично.
В-третьих — нет возможности “управлять” своими «хотелками».
Реализация
Не буду долго расписывать, как и почему в итоге мы остановились на решении “придумать велосипед” и написать свою систему электронного документооборота. Решение принято — нужно делать. Мы уже прошли болезнь попытки реализовать продукт без требований, поэтому первично стартовал процесс написания ТЗ и его согласования. Благо перед глазами у нас были примеры реализаций, поэтому формирование прошло довольно безболезненно.
Единственное, над чем пришлось нам поломать копья — это в процессе разработки архитектуры не поддаться на соблазн удовлетворить требования “как есть”, в ущерб гибкости и дальнейшему удобству эксплуатации. Соблазн был велик, особенно у основного заказчика, так как срок реализации и внедрения сокращался бы в 2 раза. Но нам удалось убедить и руководство, и себя, что “лучше день потерять, потом за 5 минут долететь”. И считаю, что мы сделали правильный выбор.
Лучше день потерять, потом за 5 минут долететь.Стек “стандартный” — .Net Core 2 и EntityFramework, Angular 4, MS SQL, так как имеем в применении инструментария и технологий довольно большой бэкграунд. Хотя СУБД для нас особого значения не имеет по понятным причинам. При необходимости перейдем на какую пожелаем.
В итоге получился продукт, который удовлетворяет важным для нас требованиям:
- Один воркфлоу — разные участники согласования (связан со следующим пунктом)
- Условия пропуска этапа согласования по заданным условиям (любое поле в заявке можно добавить в условие с заданной проверкой и на основании валидности условия определяется необходимость перехода на очередной шаг согласования или его “пропуск”)
- Наш “фирменный” интерфейс
Также были проработаны и реализованы такие удобные и полезные фичи, как:
- Задание дефолтных значений справочников (как пользовательских, так и системных). Пользовательский справочник — это сущность, позволяющая задавать элементы самостоятельно пользователем. Созданные элементы будут доступны только ему. При этом в такой справочник администратор системы может внести общие элементы, которые будут доступны всем пользователям системы
- Определение наиболее часто использующихся элементов справочников для каждого пользователя и формирование списков в интерфейсе исходя из данной статистики (сортировка)
- Полностью настраиваемые из админки схемы (структура и свойства полей для заполнения) и представления (расположение элементов в форме) каждого типа запроса на согласование
- Гибкий ACL
- Настраиваемый каждым пользователем поиск заявок по различным наборам параметров. Параметрами могут быть любые свойства шаблонов заявки с возможностью выбрать условие, которое необходимо наложить на данное поле при фильтрации. При этом можно создать сколько угодно сетов для фильтрации. Удобно для быстрого поиска в разных разрезах
- Проверка на валидность введенных значений на основании заданного шаблона для конкретного поля заявки
Не обошлось конечно и без “курьезов”. В первую очередь речь, идет о конфигурировании воркфлоу. Мы изначально решили, что нам нужна возможность конфигурирования древовидной схемы бизнес-процесса. Чтобы из одной точки (этапа) согласования можно было пойти по разным веткам, в зависимости от выбора пользователя (Согласующего). Логично и гибко. Но уже после того, как мы реализовали данную возможность, и запустили систему в продакшн, нам показалось, что на самом деле не нужно давать пользователю право выбора (возможности задуматься). Для него все должно происходить на уровне “Согласовать”, “Отказать”. В противном случае мы не сможем отойти от принципа понимания сотрудником тонкостей взаимодействия в компании. А для удовлетворения данного условия воркфлоу должен быть линейным.
Не обошлось конечно и без «курьезов».В итоге мы нашли компромисс — архитектуру решения и реализацию воркфлоу оставили древовидной, а вот использование с точки зрения конфигурирования закрепили на уровне “договоренности”. И правильно сделали. Так как уже сейчас, при анализе задач, связанных с запуском новых типов согласований стало ясно, что на некоторых этапах, для специфических типов заявок, нам необходимо предоставить возможность выбора согласующему различных действий.
Теперь немного о нашем “ноу-хау” (по крайней мере мы в это верим). Чтобы добиться линейности и при этом возможности использовать один воркфлоу для одной схемы согласования (под схемой я имею ввиду сущности, для согласования которых требуется вовлеченность и порядок разных ролей — договор, счет на оплату и т.п.), мы продумали и реализовали механизм условий пропуска очередного этапа (-ов) согласования. В формировании условий мы можем использовать любую сущность карточки согласования и сравнить ее с “чем-либо”.
К примеру, есть у нас следующие сущности: Инициатор, Cумма, Валюта, Контрагент. И нам нужно, чтобы при сумме, меньшей 100 000 руб. не проходило согласование через сотрудника A, при валютных платежах, обязательно подключался к согласованию B, а в случае, если инициатором является сотрудник C, необходимо дополнительное согласование сотрудника D. При этом под сотрудниками мы подразумеваем как отдельных лиц, так и определенную группу. Для реализации этих моментов мы добавляем все точки согласования “в линию”. Т.е.: Инициатор->A->B->D->…
Далее формируются условия на “пропуск” перехода в каждую из точек согласования. К примеру на Переход Инициатор->A конфигурируется условие “Сумма < 100 000”, на (Инициатор)A->B – Валюта = “Рубль”, (Инициатор, A, B)->D – Инициатор != C.
Почему указаны в скобках переходы? Потому что условия могут выполняться в комплексе и “под капотом”, если у нас формируется условие на переход в точку согласования, мы автоматически генерируем еще системный переход, который “обходит” данную точку (вот тут нам помогла наша древовидная архитектура воркфлоу и не пришлось ничего “костылить”).
Ну и немного дегтя в бочку меда. У нас не дошли руки до реализации конфигурируемого механизма управления оповещениями. Хотя изначально его закладывали в архитектуру проекта. Как обычно, для ускорения процесса запуска пришлось немного “временно захардкодить”, и на текущий момент данный хардкод остался. А идея была в том, чтобы создать механизм, аналогичный jira, который позволяет создать свою схему нотификаций, в которой можно задавать триггеры(события) и связывать их с группами или конкретными сотрудниками и иметь возможность ее “привязать” к любому типу заявки.
Для ускорения процесса запуска пришлось немного «временно захардкодить».
Интерфейсы
Немного интерфейсов нашей системы, чтобы было понимание, о чем вообще шла речь
Дашборд
![дашборд](https://habrastorage.org/webt/kd/rc/fd/kdrcfdpzq9inrw57fthq_krr09u.jpeg)
Первое, что видит пользователь системы при ее открытии (если не учитывать процесс аутентификации) – это дашборд. В нем отображаются только активные (незавершенные) согласования. При этом заявки разделены на 2 сегмента:
- Заявки, которые требуют согласования пользователем (я исполнитель)
- Заявки, которые были инициированы пользователем (я автор)
Создание новой заявки
![Создание заявки](https://habrastorage.org/webt/fz/vf/hx/fzvfhxn3ayokktbst4ctg78t-fc.jpeg)
Интерфейс создания новой заявки может иметь представление (количество и расположение элементов) совершенно любое. Здесь представлен простой интерфейс, который демонстрирует возможность ввода чисел, выбор из списка, флаг (чек-бокс), дата, аттачи.
Единственное, на что можно обратить внимание, это опция “Создать еще”. При ее активации, после создания текущей заявки, мы попадаем не в дашборд или в карточку только что созданной заявки, а сразу открывается форма создания новой заявки того же типа, что и только что созданная. Реализовано было по просьбе наших сотрудников, которым приходится “пачками” создавать однотипные заявки.
Этап согласования
![Этап согласования](https://habrastorage.org/webt/ii/p7/fe/iip7fe6wcpp8gvc2pwcrrlw0qli.jpeg)
Данный интерфейс не сильно отличается от формы создания заявки. Но имеет ряд принципиальных функциональных особенностей:
- Вместо кнопок создания появляются кнопки, клики на которые переводят заявку в одно из состояний бизнес-процесса. В вырожденном случае, о чем писал выше, это “Отклонить” и “Согласовать”
- Вложения, комментарии и новая сущность журнал (история действий) вынесены в отдельные вкладки
- По умолчанию все поля заявки, кроме комментария – недоступны для редактирования. При этом мы заложили функциональность, позволяющую предоставить на любом конкретном шаге согласования возможность корректировать только заданный набор полей.
- Если вы являетесь инициатором заявки (вы всегда можете зайти в карточку согласования), и у вас появляется опция “Создать дубликат”, при клике на которую открывается форма создания заявки, значения полей которой (за исключением вложений) дублируют значения полей текущей заявки.
Если присмотреться, то можно заметить напротив поля для выбора Контрагента оранжевый элемент с плюсом внутри. Это и есть функциональность управления персональным справочником. При клике на данный элемент открывается форма добавления элемента справочника.
![](https://habrastorage.org/webt/rx/9r/2m/rx9r2msc1ngfb_d33lk7q6gzcfu.jpeg)
Так как в данном случае это Контрагент, то элемент справочника у нас содержит два реквизита – Наименование и ИНН. После создания пользователь может сразу выбрать данный элемент из выпадающего списка.
Поиск
![](https://habrastorage.org/webt/1o/9w/qf/1o9wqfjp9gzx4ogqgon2jvkf2tk.jpeg)
В поиске заявок сверху отображается набор свойств, по значениям которых нужно осуществить выборку. Наборы конфигурируемы каждым пользователем под свои нужды с возможностью быстрого переключения между ними.
Администрирование бизнес-процесса
В рамках управления бизнес-процессом мы можем создавать любое количество точек маршрута и указывать переходы. Вследствие чего формируется граф переходов. И для каждой точки согласования мы можем задавать:
- Кто является согласующим в данной точке
- Разрешения на выполнение действий в заданной точке маршрута
- Условия пропуска данной точки (этапа согласования)
Согласующие
![](https://habrastorage.org/webt/13/tn/tb/13tntbfk4q34ve_y_af9d2rltpu.jpeg)
Во вкладке “Согласующие” можно добавить группы, добавленные пользователи в которые могут осуществлять процесс согласования в данной точке бизнес-процесса.
Разрешения на действия
![](https://habrastorage.org/webt/uv/4c/ma/uv4cmaqi75sv9yrwinhjbez0-ci.jpeg)
На разрешениях можно остановиться чуть подробней. Для ограничения действий согласующими, связанных с изменением значений полей (сущностей) в заявке, введен механизм разрешений. На текущий момент у нас введено 4 разрешения:
- Загрузка вложений
- Просмотр вложений
- Комментирование
- Изменение значений полей заявки
Если с первыми тремя все более-менее понятно, то разрешение на изменение доступных полей нужно прокомментировать. По умолчанию, согласующие не могут менять никакие значения полей в заявке. Доступен только режим просмотра. В случае, если необходимо в конкретной точке согласования разрешить изменять отдельные поля заявки, активируется данная опция и предоставляется возможность выбора из списка полей заявки только те, значения которых можно изменить согласующему.
Хоть и немного притянуто за уши, но к примеру, это может понадобиться в том случае, если у вас существует отдельная позиция “проверяльщик корректности заполнения суммы”, то дать ему возможность менять в заявке только сумму и ничего более.
Условия пропуска
![](https://habrastorage.org/webt/pa/qp/4c/paqp4cg89-far9hzehhuqypzhqk.jpeg)
Условия пропуска я описывал выше. Функциональность нужна для формирования единого линейного бизнес-процесса для всех пользователей системы, и при этом осуществлять движение заявки по маршруту разными путями, в зависимости от заданного условия и без участия пользователя.
На скрине подготавливается настройка, которая позволит пропустить данную точку маршрута в случае, если инициатор находится в определенных группах и при этом Валюта эквивалентна Российскому рублю.
Вместо заключения
На текущий момент в нашей компании запущен всего один тип согласования. Но при гибкости настройки, которая заложена в системе, мы имеем инструментарий, позволяющий осуществить конфигурирование любых карточек заявок, где можно указать любое количество полей, любое представление карточки заявки и любой маршрут согласования с различными условиями.
Единственное, что требуется – это поработать аналитику над сбором требований и затем переложить их в систему посредством интерфейса администрирования. Чем мы сейчас и занимаемся.
Продукт жив, периодически мы вносим изменения по требованию наших сотрудников, в следствие чего его мощь и удобство использования растет, а внедряемые функции выполняют ту задачу, которая стоит перед нашим бизнесом, и мы всегда можем с уверенностью сказать, что запрашиваемая функциональность будет внедрена в случае, если это вообще возможно.