Служба технической поддержки
Пример реализации проекта обработки входящих заявок службы технической поддержки.
Постановка задачи
Допустим, мы получили подобные требования:
Наша компания столкнулась с необходимостью модернизировать работу службы технической поддержки. В настоящее время обращения клиентов обрабатываются вручную через почту и чаты, что приводит к потере запросов, задержкам в ответах и сложностям в анализе работы специалистов.
Нам нужна система, которая позволит автоматизировать обработку обращений, начиная от момента их регистрации и до полного решения. Важно, чтобы система поддерживала создание тикетов с возможностью приоритезации, категоризации и назначения ответственных. Также необходимо ведение истории обращений по каждому клиенту для более персонализированного обслуживания.
Ключевые ожидания от системы:
- автоматическая маршрутизация заявок в зависимости от темы и загрузки специалистов;
- уведомления клиентов о статусе их запросов;
- база знаний для быстрого поиска решений типовых проблем;
- инструменты аналитики для оценки эффективности работы поддержки;
- интеграция с нашими текущими CRM и мессенджерами.
Особое внимание стоит уделить удобному интерфейсу для операторов и возможности масштабирования системы по мере роста компании.
Подготовка решения
Перед нами интересная задача. Давайте разберёмся, как мы можем реализовать подобную систему с помощью нашего фреймворка.
Для начала, создадим папку для нашего решения и перейдём в неё:
mkdir technical-support-system
cd technical-support-system
Находясь в папке, создадим решение через Docker-контейнер report.ms/app:
docker run --rm -v "${PWD}:/app" report.ms/app create Техническая поддержка
После создания в папке мы увидим структуру файлов:
/technical-support-system
├── .vscode
│ ├── launch.json
│ └── tasks.json
├── imgs
│ ├── app-login-bg.png
│ └── favicon.ico
├── scripts
│ └── set_password.py
├── .gitignore
├── app.rms
├── site.rms
├── docker-compose.yml
└── README.md
Файл app.rms содержит описание структуры приложения, а site.rms - описание сайта. Для нашего примера мы будем использовать только app.rms, так как сайт нам не нужен. Удалим файл site.rms:
rm site.rms
Откроем папку в VS Code и запустим решение, нажав на F5. После запуска автоматически откроется браузер с адресом http://localhost:<СЛУЧАЙНЫЙ_ПОРТ>.
На открывшейся странице мы увидим:
- название решения
- форму авторизации
- ссылку для открытия формы восстановления пароля
- изображение фона.
Откроем файл app.rms и посмотрим, что в нём есть. В нём описана структура приложения, включая справочники, роли, страницы и действия. Мы можем редактировать этот файл, чтобы настроить приложение под наши требования.
###############################
# Report.ms app yml #
###############################
lang: ru
Проект:
Название: Техническая поддержка
FavIcon: imgs/favicon.ico
Пароль администратора: '123'
Мастер пароль: 'qwerty'
Фон страницы логина: imgs/app-login-bg.jpg
Роли:
- Администратор:
Доступен профиль: Да
Страницы:
- Пользователи:
Тип страницы: Справочник
Справочник: Пользователи
Может создавать: Да
Может открывать окно редактирования: Да
Может сортировать по колонкам: Да
Может фильтровать по колонкам: Да
Справочники:
- Пользователи:
Наименование единицы справочника: Пользователь
Иконка: users
Ширина окна создания-редактирования: Мелкое
Поле для отображения как аватара: Аватар
Поле для отображения всей сущности: Имя
Поля:
- Аватар:
Тип поля: Файл
Тип файла: Аватар
- Email:
Заполнитель при пустом значении: Укажите почту...
Размер: 8
Обязательно при создании: Да
Обязательно при обновлении: Да
- Имя:
Заполнитель при пустом значении: Имя пользователя...
Размер: 8
Обязательно при создании: Да
Обязательно при обновлении: Да
- Роль:
Тип поля: Выбор роли
Заполнитель при пустом значении: Выберите роль...
Обязательно при создании: Да
Обязательно при обновлении: Да
- Пароль:
Тип поля: Сохранённый пароль
Скрыто в списке: Да
Скрыто на форме: Да
Действия:
- Установить пароль:
Описание: Установить пароль для пользователя
Иконка действия: key
Условие доступности: "Текущий пользователь: Роль" = "Роль: Администратор"
Параметры:
- Новый пароль:
Тип поля: Сохранённый пароль
Python код: scripts/set_password.py
Давайте добавим небольшое изменение в файл app.rms, а именно добавим Описание в секцию Проект
...
Проект:
Название: Техническая поддержка
Описание: Система обработки входящих заявок службы технической поддержки
FavIcon: imgs/favicon.ico
Пароль администратора: '123'
Мастер пароль: 'qwerty'
Фон страницы логина: imgs/app-login-bg.jpg
...
После сохранения изменений в файле app.rms мы увидим, что страница в браузере обновилась. На странице авторизации помимо названия решения мы увидим также описание, которое мы добавили в секцию Проект/Описание.
Ваше приложение будет автоматически обновляться при изменении файла app.rms. Вам не нужно перезапускать приложение, чтобы увидеть изменения. Это позволяет быстро вносить изменения в структуру приложения и сразу видеть результат.
Авторизация
Вводим логин admin и пароль 123. Пароль указан в файле app.rms в разделе Проект/Пароль администратора.
В ваших приложениях будет минимум один пользователь с ролью администратора и логином admin, его нельзя удалить и его пароль всегда будет соответствовать тому, который указан в файле app.rms в разделе Проект/Пароль администратора.
После авторизации мы попадаем на страницу Пользователи, где видим список пользователей, имеем возможность создавать новых и редактировать существующих.
Справочник "Заявки"
Создание
Давайте создадим справочник "Заявки", который будет хранить информацию о входящих запросах от клиентов. Для этого откроем файл app.rms и добавим новый справочник в раздел Справочники и укажем Наименование единицы справочника:
...
Справочники:
- Пользователи:
Наименование единицы справочника: Пользователь
Иконка: users
Ширина окна создания-редактирования: Мелкое
Поле для отображения как аватара: Аватар
Поле для отображения всей сущности: Имя
Поля:
- Аватар:
Тип поля: Файл
Тип файла: Аватар
- Email:
Заполнитель при пустом значении: Укажите почту...
Размер: 8
Обязательно при создании: Да
Обязательно при обновлении: Да
- Имя:
Заполнитель при пустом значении: Имя пользователя...
Размер: 8
Обязательно при создании: Да
Обязательно при обновлении: Да
- Роль:
Тип поля: Выбор роли
Заполнитель при пустом значении: Выберите роль...
Обязательно при создании: Да
Обязательно при обновлении: Да
- Пароль:
Тип поля: Сохранённый пароль
Скрыто в списке: Да
Скрыто на форме: Да
Действия:
- Установить пароль:
Описание: Установить пароль для пользователя
Иконка действия: key
Условие доступности: "Текущий пользователь: Роль" = "Роль: Администратор"
Параметры:
- Новый пароль:
Тип поля: Сохранённый пароль
Python код: scripts/set_password.py
- Заявки:
Наименование единицы справочника: Заявка
Мы добавили новый справочник "Заявки" в раздел Справочники, но на странице в браузере мы его пока не видим.
Некоторые атрибуты справочников, такие как Иконка, Ширина окна создания-редактирования, Поле для отображения как аватара, Поле для отображения всей сущности и многие другие не обязательны. Если они не указаны, будут использоваться значения по умолчанию.
Но некоторые атрибуты, такие как Наименование единицы справочника, обязательны и должны быть указаны. Если они не указаны, приложение не сможет корректно работать и будет выдавать ошибку. Вы можете видеть ошибки в VS Code в окне Problems.
О том, какие атрибуты доступны для справочников, вы можете узнать в документации в разделе Справочники.
Также вы можете нажать Ctrl + Space в VS Code, находясь в файле app.rms, чтобы увидеть список доступных атрибутов для справочников.
Отображение страницы
Давайте добавим страницу для этого справочника в раздел Роли/Администратор/Страницы:
...
Роли:
- Администратор:
Доступен профиль: Да
Страницы:
- Пользователи:
Тип страницы: Справочник
Справочник: Пользователи
Может создавать: Да
Может открывать окно редактирования: Да
Может сортировать по колонкам: Да
Может фильтровать по колонкам: Да
- Заявки:
Тип страницы: Справочник
Справочник: Заявки
Может создавать: Да
Может открывать окно редактирования: Да
...
Теперь другое дело. После сохранения изменений в файле app.rms мы увидим на странице в браузере новую страницу "Заявки", где мы можем видеть список заявок, создавать новые и редактировать существующие.
Создание полей
Но окно создания-редактирования пустое, так как мы не добавили поля в справочник "Заявки". Давайте добавим поля в справочник "Заявки" в разделе Справочники/Заявки/Поля:
...
Справочники:
...
- Заявки:
Наименование единицы справочника: Заявка
Поля:
- Заголовок:
- Описание:
- Статус:
- Приоритет:
Мы сильно упростили поля для справочника "Заявки", но этого достаточно для старта. После сохранения изменений в файле app.rms в браузере мы увидим:
- в списке заявок колонки "Заголовок", "Описание", "Статус" и "Приоритет"
- в окне создания-редактирования появились поля "Заголовок", "Описание", "Статус" и "Приоритет". Каждое поле занимает целую строку формы создания-редактирования и является текстовым элементом ввода в одну строку. Мы можем создавать новые заявки и редактировать существующие.
Тип поля "Текст"
Отлично! Теперь мы можем создавать и редактировать заявки. Сразу бросается в глаза, что в поле "Описание" мы можем внести текст только в одну строку, что не всегда удобно. Давайте изменим тип поля "Описание" на "Текст":
Справочники:
...
- Заявки:
Наименование единицы справочника: Заявка
Поля:
- Заголовок:
- Описание:
Тип поля: Текст
- Статус:
- Приоритет:
После сохранения изменений в файле app.rms мы увидим:
- в окне создания-редактирования поле "Описание" стало многострочным
- в списке заявок поле "Описание" стало вести себя немного по-другому. Если текста много, появляется кнопка "Показать полностью".
Обязательные поля
Стоит учесть, что сейчас можно создать заявку с пустыми полями. Это не очень правильно, поэтому давайте сделаем обязательным поле "Заголовок". Для этого надо в разделе Справочники/Заявки/Поля/Заголовок выставить параметр Обязательно при создании в значение Да. А при редактировании мы тоже хотим, чтобы поле нельзя было оставить пустым. Поэтому выставим значение Да в параметр Обязательно при обновлении:
Справочники:
...
- Заявки:
Наименование единицы справочника: Заявка
Поля:
- Заголовок:
Обязательно при создании: Да
Обязательно при обновлении: Да
- Описание:
Тип поля: Текст
- Статус:
- Приоритет:
Мы видим, что у поля "Заголовок" на форме создания-редактирования появился индикатор обязательности, который сообщает, что поле должно иметь непустое значение. Он выглядит как знак красной звёздочки (*) рядом с названием поля.
Теперь при попытке создать заявку с пустым полем "Заголовок" мы увидим предупреждение о том, что это поле обязательно должно иметь непустое значение.
Если у поля не задан атрибут Тип поля, по умолчанию используется тип Строка.
Тип поля "Значение перечисления"
Обратим внимание на поле "Статус". Это поле также является строкой. Это не очень удобно.
Давайте сделаем его выпадающим списком из статичного списка значений. Для этого поменяем тип поля на "Значение перечисления".
Справочники:
...
- Заявки:
Наименование единицы справочника: Заявка
Поля:
- Заголовок:
Обязательно при создании: Да
Обязательно при обновлении: Да
- Описание:
Тип поля: Текст
- Статус:
Тип поля: Значение перечисления
- Приоритет:
В VS Code мы видим ошибку: Не указано обязательное поле "Перечисление" для строки "Статус". Поле "Перечисление" обязательно, если мы указываем тип поля "Значение перечисления".
Поле "Перечисление" должно содержать одно из перечислений, заданных в файле app.rms. Давайте создадим перечисление в разделе Перечисления, зададим ему несколько значений и укажем его название в атрибуте Перечисление:
###############################
# Report.ms app yml #
###############################
lang: ru
Проект:
Название: Техническая поддержка
FavIcon: imgs/favicon.ico
Пароль администратора: '123'
Мастер пароль: 'qwerty'
Фон страницы логина: imgs/app-login-bg.jpg
Роли:
- Администратор:
Доступен профиль: Да
Страницы:
- Пользователи:
Тип страницы: Справочник
Справочник: Пользователи
Может создавать: Да
Может открывать окно редактирования: Да
Может сортировать по колонкам: Да
Может фильтровать по колонкам: Да
- Заявки:
Тип страницы: Справочник
Справочник: Заявки
Может создавать: Да
Может открывать окно редактирования: Да
Справочники:
- Пользователи:
Наименование единицы справочника: Пользователь
Иконка: users
Ширина окна создания-редактирования: Мелкое
Поле для отображения как аватара: Аватар
Поле для отображения всей сущности: Имя
Поля:
- Аватар:
Тип поля: Файл
Тип файла: Аватар
- Email:
Заполнитель при пустом значении: Укажите почту...
Размер: 8
Обязательно при создании: Да
Обязательно при обновлении: Да
- Имя:
Заполнитель при пустом значении: Имя пользователя...
Размер: 8
Обязательно при создании: Да
Обязательно при обновлении: Да
- Роль:
Тип поля: Выбор роли
Заполнитель при пустом значении: Выберите роль...
Обязательно при создании: Да
Обязательно при обновлении: Да
- Пароль:
Тип поля: Сохранённый пароль
Скрыто в списке: Да
Скрыто на форме: Да
Действия:
- Установить пароль:
Описание: Установить пароль для пользователя
Иконка действия: key
Условие доступности: "Текущий пользователь: Роль" = "Роль: Администратор"
Параметры:
- Новый пароль:
Тип поля: Сохранённый пароль
Python код: scripts/set_password.py
- Заявки:
Наименование единицы справочника: Заявка
Поля:
- Заголовок:
Обязательно при создании: Да
Обязательно при обновлении: Да
- Описание:
Тип поля: Текст
- Статус:
Тип поля: Значение перечисления
Перечисление: Статусы заявок
- Приоритет:
Перечисления:
- Статусы заявок:
Значения:
- Новая:
- В работе:
- Выполнена:
- Отменена:
Теперь в колонке "Статус" мы видим выпадающий список из четырёх значений.
Мы всегда задаём перечисления в разделе Перечисления, а не для поля отдельно. Это позволяет нам легко добавлять новые значения в перечисления, а также управлять ими в одном месте.
Так же мы можем повторно использовать уже созданные перечисления для полей с типом Значение перечисления.
Заметим, что значения в выпадающем списке поля Статус отображаются в том же порядке, что и в перечислении в секции Перечисления/Статусы заявок/Значения.
Таким образом, мы можем управлять порядком их отображения.
Тип поля "Булево значение"
Мы рассмотрели основные типы полей. Давайте взглянем на поле "Приоритет". Очевидно, заявка для технической поддержки может быть либо приоритетной, либо нет. Мы можем создать перечисление "Приоритеты заявки" с двумя значениями: Не приоритетная и Приоритетная, но в данном случае лучше воспользоваться ещё одним типом поля, а именно Булево значение.
Тип поля Булево значение позволяет нам создать поле, которое будет отображается в виде флажка, который можно установить или снять. Это то, что нам нужно для поля "Приоритет"!
Справочники:
...
- Заявки:
Наименование единицы справочника: Заявка
Поля:
- Заголовок:
Обязательно при создании: Да
Обязательно при обновлении: Да
- Описание:
Тип поля: Текст
- Статус:
Тип поля: Значение перечисления
Перечисление: Статусы заявок
- Приоритет:
Тип поля: Булево значение
...
Теперь на форме создания-редактирования заявки мы увидим элемент ввода в виде галочки, которую мы можем отметить или снять. А в списке заявок мы видим в колонке "Приоритет" галочки у приоритетных заявок.
Мы познакомились с некоторыми типами полей, такими как Строка, Текст, Значение перечисления и Булево значение.
Но это далеко не все типы полей, которые доступны. Подробности о доступных типах полей можно узнать в документации на странице Справочники в секции Поле справочника.
Давайте кратко перечислим возможные типы полей:
СтрокаТекстЗначение перечисленияБулево значениеЭлемент справочника- когда поле ссылается на другой справочник.Дата и времяДатаВремяВыбор ролиВычислимое полеМассив- при задании этого поля мы можем выбирать несколько значений из списка перечисления или справочника, в зависимости от того, что указано в поле Содержание массива.ПрогрессПродолжительностьСохранённый парольТаблицаФайлЧисло
Далее мы познакомимся со многими типами поля из этого списка.
Компоновка полей
Статус и Приоритет очень важные поля, но на форме они занимают гораздо больше места, чем могли бы. Каждое из этих полей занимает целую строчку на форме создания-редактирования, при этом содержание поля не доходит даже и до половины строки формы.
Атрибут Размер может быть задан как число от 1 до 16. По умолчанию размер поля равен 16 — то есть оно занимает всю ширину формы.
Если несколько полей, которые идут подряд и имеют в сумме размер меньше или равен 16, то они будут расположены на одной строке.
Таким образом, мы можем управлять внешним видом формы создания-редактирования.
Давайте зададим полям Статус и Приоритет атрибут Размер и установим его значение 8 и посмотрим, как это будет выглядеть:
Справочники:
...
- Заявки:
Наименование единицы справочника: Заявка
Поля:
- Заголовок:
Обязательно при создании: Да
Обязательно при обновлении: Да
- Описание:
Тип поля: Текст
- Статус:
Тип поля: Значение перечисления
Перечисление: Статусы заявок
Размер: 8
- Приоритет:
Тип поля: Булево значение
Размер: 8
...
Теперь поля Статус и Приоритет занимают меньше места на форме и расположены в одну строку. Заметим, что вид списка заявок не изменился, так как атрибут Размер не влияет на вид списка, а только на форму создания-редактирования.
Расположим Статус и Приоритет в начале формы создания-редактирования. Для этого достаточно их переместить в начало списка полей:
Справочники:
...
- Заявки:
Наименование единицы справочника: Заявка
Поля:
- Статус:
Тип поля: Значение перечисления
Перечисление: Статусы заявок
Размер: 8
- Приоритет:
Тип поля: Булево значение
Размер: 8
- Заголовок:
Обязательно при создании: Да
Обязательно при обновлении: Да
- Описание:
Тип поля: Текст
...
Теперь форма создания-редактирования выглядит более логично.
Порядок полей в списке полей в файле app.rms влияет на их расположение на форме создания-редактирования.
Также он влияет на вид списка заявок, в нём поля будут расположены в порядке, в котором они указаны в списке полей.
Мы можем переопределить порядок для отображения полей специально для списка, это делается через атрибут Поля для отображения в разделе Страницы для нужной роли, мы вернёмся к этому позже.
Предвыбранные значения
Если подумать, то станет понятно, что при создании пользователь всегда будет выбирать статус заявки "Новая". Для таких случаев мы можем задать атрибут Предвыбрано в значение Да, и тогда при создании заявки статус будет по умолчанию заполнен первым значением перечисления.
Справочники:
...
- Заявки:
Наименование единицы справочника: Заявка
Поля:
- Статус:
Тип поля: Значение перечисления
Перечисление: Статусы заявок
Размер: 8
Предвыбрано: Да
- Приоритет:
Тип поля: Булево значение
Размер: 8
- Заголовок:
Обязательно при создании: Да
Обязательно при обновлении: Да
- Описание:
Тип поля: Текст
...
Атрибут Предвыбрано можно использовать не только для полей с типом Значение перечисления, но и для полей с типом Булево значение. В этом случае галочка будет по умолчанию отмечена.
Поле "Дата создания"
Теперь мы можем создавать и редактировать заявки, менять их статус, а также выставлять или снимать приоритет. Было бы полезно видеть дату и время создания каждой заявки. Мы можем создать поле Дата создания с типом Дата и время и заполнять его вручную текущей датой и временем, но оказывается такое поле уже существует в базе данных, мы можем использовать его. Чтобы увидеть его в списке заявок, нам достаточно установить значение поля Показывать дату и время создания в Да в разделе Роли/Администратор/Страницы/Заявки.
...
Роли:
- Администратор:
Доступен профиль: Да
Страницы:
- Пользователи:
Тип страницы: Справочник
Справочник: Пользователи
Может создавать: Да
Может открывать окно редактирования: Да
Может сортировать по колонкам: Да
Может фильтровать по колонкам: Да
- Заявки:
Тип страницы: Справочник
Справочник: Заявки
Может создавать: Да
Может открывать окно редактирования: Да
Показывать дату и время создания: Да
...
Теперь в списке заявок мы видим дату и время создания заявки.
По умолчанию поле Дата создания не отображается в списке заявок, но мы можем его включить. Этот атрибут относится к секции страницы у ролей.
Мы подробно рассмотрим эти атрибуты в следующих разделах.
Внешний вид
Улучшим внешний вид наших заявок. А именно:
- Зададим заполнитель для поля Заголовок и Описание
- Добавим описание к полю Заголовок и Приоритет
- Добавим текстовое описание и картинку для справочника заявки
- Добавим иконку для заявок в меню
- Добавим иконки и цвета для значений Статуса заявки
Заполнитель
Для добавления заполнителя используется атрибут Заполнитель при пустом значении. Почти во всех типах полей мы можем задать этот атрибут и при пустом значении поля он будет отображаться в качестве заполнителя.
Справочники:
...
- Заявки:
Наименование единицы справочника: Заявка
Поля:
- Статус:
Тип поля: Значение перечисления
Перечисление: Статусы заявок
Размер: 8
Предвыбрано: Да
- Приоритет:
Тип поля: Булево значение
Размер: 8
- Заголовок:
Обязательно при создании: Да
Обязательно при обновлении: Да
Заполнитель при пустом значении: Укажите заголовок...
- Описание:
Тип поля: Текст
Заполнитель при пустом значении: Укажите описание...
...
Такой подход улучшает восприятие.
Обычно текст атрибута Заполнитель при пустом значении побуждает пользователя заполнить поле, но мы можем задать любой текст, и он будет отображаться в качестве заполнителя.
Описание полей
Теперь добавим описание к полю Заголовок и Приоритет. Для этого воспользуемся атрибутом Описание.
Справочники:
...
- Заявки:
Наименование единицы справочника: Заявка
Поля:
- Статус:
Тип поля: Значение перечисления
Перечисление: Статусы заявок
Размер: 8
Предвыбрано: Да
- Приоритет:
Тип поля: Булево значение
Размер: 8
Описание: Приоритетные заявки будут обрабатываться первыми
- Заголовок:
Обязательно при создании: Да
Обязательно при обновлении: Да
Заполнитель при пустом значении: Укажите заголовок...
Описание: Краткое описание сути заявки
- Описание:
Тип поля: Текст
Заполнитель при пустом значении: Укажите описание...
...
Теперь у полей Заголовок и Приоритет есть небольшой значок подсказки рядом с названием поля. При клике на этот значок мы увидим текст из описания поля во всплывающей подсказке.
Текст атрибута Описание у поля объясняет его назначение пользователю. Оно может подсказать какое именно значение в него нужно занести и как это значение будет использоваться.
Описание справочника
Если мы зададим атрибут Описание для справочника "Заявки", то мы увидим текст этого описания в списке заявок.
Если заявок пока нет, вместо пустого списка будет отображаться этот текст. Если заявки уже есть, текст можно увидеть, нажав на кнопку "Информация" в правом верхнем углу.
Справочники:
...
- Заявки:
Наименование единицы справочника: Заявка
Описание: Заявки от пользователей на оказание технической поддержки
Поля:
- Статус:
Тип поля: Значение перечисления
Перечисление: Статусы заявок
Размер: 8
Предвыбрано: Да
- Приоритет:
Тип поля: Булево значение
Размер: 8
Описание: Приоритетные заявки будут обрабатываться первыми
- Заголовок:
Обязательно при создании: Да
Обязательно при обновлении: Да
Заполнитель при пустом значении: Укажите заголовок...
Описание: Краткое описание сути заявки
- Описание:
Тип поля: Текст
Заполнитель при пустом значении: Укажите описание...
...
Текст атрибута Описание у справочника объясняет пользователю как ему работать со справочником и что он из себя представляет.
Изображение в описании
Порой для лучшего понимания сути того или иного справочника помимо текстового описания мы можем задать картинку, которая будет отображаться рядом с этим текстовым описанием. Это делается через атрибут Изображение в описании. В значении этого атрибута мы указываем путь к картинке. Сохраним картинку в каталоге imgs и укажем путь к ней.
Справочники:
...
- Заявки:
Наименование единицы справочника: Заявка
Описание: Заявки от пользователей на оказание технической поддержки
Изображение в описании: imgs/requests-description.svg
Поля:
- Статус:
Тип поля: Значение перечисления
Перечисление: Статусы заявок
Размер: 8
Предвыбрано: Да
- Приоритет:
Тип поля: Булево значение
Размер: 8
Описание: Приоритетные заявки будут обрабатываться первыми
- Заголовок:
Обязательно при создании: Да
Обязательно при обновлении: Да
Заполнитель при пустом значении: Укажите заголовок...
Описание: Краткое описание сути заявки
- Описание:
Тип поля: Текст
Заполнитель при пустом значении: Укажите описание...
...
Теперь рядом с описанием мы увидим изображение. Мы можем использовать любые форматы картинок: векторные и растровые. Хорошо в описании справочников смотрятся монохромные и контрастные изображения.
Удобно хранить все изображения в отдельном каталоге. Таким образом, мы можем быстро находить и менять нужные нам изображения.
Иконка в меню
Если мы зададим атрибут Иконка у справочника, она будет отображаться в меню рядом с названием справочника. Для значения иконки мы можем использовать название иконки из набора Font Awesome или указать путь к картинке. Давайте в этот раз используем название иконки из набора Font Awesome, например, bug. Обычно техническая поддержка чаще получает заявки об ошибках:
Справочники:
...
- Заявки:
Наименование единицы справочника: Заявка
Описание: Заявки от пользователей на оказание технической поддержки
Изображение в описании: imgs/requests-description.svg
Иконка: bug
Поля:
- Статус:
Тип поля: Значение перечисления
Перечисление: Статусы заявок
Размер: 8
Предвыбрано: Да
- Приоритет:
Тип поля: Булево значение
Размер: 8
Описание: Приоритетные заявки будут обрабатываться первыми
- Заголовок:
Обязательно при создании: Да
Обязательно при обновлении: Да
Заполнитель при пустом значении: Укажите заголовок...
Описание: Краткое описание сути заявки
- Описание:
Тип поля: Текст
Заполнитель при пустом значении: Укажите описание...
...
Теперь в меню администратора рядом с названием справочника отображается иконка жука. Выглядит симпатично.
Цвет и иконка перечисления
Иконки можно использовать не только для справочников в меню, но и, например, для значений перечислений.
Для значений перечислений можно указывать цвета, что может быть очень полезно для быстрого распознавания статуса при просмотре.
Для задания цвета у значения перечисления мы можем использовать название цвета из этого набора: Белый, Бирюзовый, Жёлтый, Зелёный, Коричневый, Красный, Оливковый, Оранжевый, Пурпурный, Розовый, Серый, Синий.
Давайте немного украсим наше перечисление Статусы заявок задав значениям цвета и иконки:
...
Перечисления:
- Статусы заявок:
Значения:
- Новая:
Цвет: Оранжевый
Иконка: clock
- В работе:
Цвет: Синий
Иконка: wrench
- Выполнена:
Цвет: Зелёный
Иконка: check
- Отменена:
Цвет: Красный
Иконка: cancel
Теперь на форме создания и редактирования и в списке заявок мы видим новое отображение значений перечисления. Рядом с названиями значений отображаются соответствующие иконки, и они помечены заданным цветом.
Это не все возможности по изменению внешнего вида справочников. Некоторые другие возможности будут рассмотрены в следующих уроках.
Итоги
Давайте посмотрим, как выглядит итоговый файл app.rms:
###############################
# Report.ms app yml #
###############################
lang: ru
Проект:
Название: Техническая поддержка
FavIcon: imgs/favicon.ico
Пароль администратора: '123'
Мастер пароль: 'qwerty'
Фон страницы логина: imgs/app-login-bg.jpg
Роли:
- Администратор:
Доступен профиль: Да
Страницы:
- Пользователи:
Тип страницы: Справочник
Справочник: Пользователи
Может создавать: Да
Может открывать окно редактирования: Да
Может сортировать по колонкам: Да
Может фильтровать по колонкам: Да
- Заявки:
Тип страницы: Справочник
Справочник: Заявки
Может создавать: Да
Может открывать окно редактирования: Да
Показывать дату и время создания: Да
Справочники:
- Пользователи:
Наименование единицы справочника: Пользователь
Иконка: users
Ширина окна создания-редактирования: Мелкое
Поле для отображения как аватара: Аватар
Поле для отображения всей сущности: Имя
Поля:
- Аватар:
Тип поля: Файл
Тип файла: Аватар
- Email:
Заполнитель при пустом значении: Укажите почту...
Размер: 8
Обязательно при создании: Да
Обязательно при обновлении: Да
- Имя:
Заполнитель при пустом значении: Имя пользователя...
Размер: 8
Обязательно при создании: Да
Обязательно при обновлении: Да
- Роль:
Тип поля: Выбор роли
Заполнитель при пустом значении: Выберите роль...
Обязательно при создании: Да
Обязательно при обновлении: Да
- Пароль:
Тип поля: Сохранённый пароль
Скрыто в списке: Да
Скрыто на форме: Да
Действия:
- Установить пароль:
Описание: Установить пароль для пользователя
Иконка действия: key
Условие доступности: "Текущий пользователь: Роль" = "Роль: Администратор"
Параметры:
- Новый пароль:
Тип поля: Сохранённый пароль
Python код: scripts/set_password.py
- Заявки:
Наименование единицы справочника: Заявка
Описание: Заявки от пользователей на оказание технической поддержки
Изображение в описании: imgs/requests-description.svg
Иконка: bug
Поля:
- Статус:
Тип поля: Значение перечисления
Перечисление: Статусы заявок
Размер: 8
Предвыбрано: Да
- Приоритет:
Тип поля: Булево значение
Размер: 8
Описание: Приоритетные заявки будут обрабатываться первыми
- Заголовок:
Обязательно при создании: Да
Обязательно при обновлении: Да
Заполнитель при пустом значении: Укажите заголовок...
Описание: Краткое описание сути заявки
- Описание:
Тип поля: Текст
Заполнитель при пустом значении: Укажите описание...
Перечисления:
- Статусы заявок:
Значения:
- Новая:
Цвет: Оранжевый
Иконка: clock
- В работе:
Цвет: Синий
Иконка: wrench
- Выполнена:
Цвет: Зелёный
Иконка: check
- Отменена:
Цвет: Красный
Иконка: cancel
Что мы сделали:
- Мы можем создавать и редактировать пользователей с правами администратора
- Мы можем создавать и редактировать заявки в техническую поддержку
- Мы можем видеть дату и время создания заявок
- Заявки выглядят хорошо как в списке так и на форме редактирования
- Некоторые поля обязательны при создании и обновлении
- Некоторые поля предвыбраны при создании
- Мы познакомились с некоторыми типам полей
Роль "Специалист"
Сейчас мы создавали и редактировали заявки под администратором, но это некорректно, потому что у роли "Администратора" есть функционал управления пользователями, а сотрудники технической поддержки не должны иметь доступ к этому функционалу; они должны иметь возможность создавать и редактировать заявки. Поэтому создадим ещё одну роль "Специалист", которая будет иметь доступ только к созданию и редактированию заявок.
Создание роли
Добавим новую роль "Специалист" в секцию Роли с одной страницей Заявки, такой же как у роли "Администратор".
...
Роли:
- Администратор:
Доступен профиль: Да
Страницы:
- Пользователи:
Тип страницы: Справочник
Справочник: Пользователи
Может создавать: Да
Может открывать окно редактирования: Да
Может сортировать по колонкам: Да
Может фильтровать по колонкам: Да
- Заявки:
Тип страницы: Справочник
Справочник: Заявки
Может создавать: Да
Может открывать окно редактирования: Да
Показывать дату и время создания: Да
- Специалист:
Доступен профиль: Да
Страницы:
- Заявки:
Тип страницы: Справочник
Справочник: Заявки
Может создавать: Да
Может открывать окно редактирования: Да
Показывать дату и время создания: Да
...
Теперь мы можем создать пользователя с ролью "Специалист". Для этого зайдём в справочник Пользователи, нажмём "Создать", выберем роль "Специалист", укажем Email "test@test.com", Имя "Test" и нажмём Создать.
После создания пользователя откроем его окно редактирования и нажмём кнопку выбора действия в правом нижнем углу формы. Мы увидим список с одним доступным действием - Установить пароль. Нажмём его. В появившейся форме установим пароль "12345678". Нажмём Установить пароль.
Теперь мы можем выйти из пользователя "admin" и войти под пользователем "test@test.com" с паролем "12345678".
Мы могли указать пароль "qwerty", так как этот пароль был установлен в секции Проект/Мастер пароль. Используя Мастер пароль, вы можете зайти под любым пользователем системы.
Это удобно для тестирования приложения.
Держите ваш Мастер пароль в безопасности и периодически меняйте.
Мы видим доступный справочник Заявки, так как для роли "Специалист" доступен только он, и он открывается по умолчанию.
После авторизации мы попадаем на первую страницу, которая указана в секции Страницы для его роли. В нашем случае это страница Заявки.
Страницы приветствия
Иногда полезно, когда пользователь той или иной роли может получить инструкцию по использованию системы сразу после входа без дополнительных кликов.
Для роли "Специалист" это особенно актуально. При первом входе было бы неплохо добавить описание функционала заявок и инструкцию по их использованию.
Чтобы добавить такое описание, мы можем использовать секцию Приветствия в нашей роли. Для каждой страницы приветствия задаются заголовок и текст.
Давайте добавим две страницы приветствия для роли "Специалист":
...
Роли:
...
- Специалист:
Доступен профиль: Да
Приветствия:
- Добро пожаловать!:
Текст: Добро пожаловать в систему технической поддержки! Тут можно управлять заявками пользователей.
- Заявки пользователей:
Текст: Вы можете создавать заявки на странице **Заявки**. Вы можете менять статус и приоритетность заявок.
Страницы:
- Заявки:
Тип страницы: Справочник
Справочник: Заявки
Может создавать: Да
Может открывать окно редактирования: Да
Показывать дату и время создания: Да
...
После сохранения нашего файла app.rms мы увидим, что в браузере у пользователя с ролью "Специалист" отобразится первая из двух страниц приветствия. Заголовок расположен над текстом и выделен. У нас есть возможность навигации по двум страницам приветствия. После ознакомления появляется кнопка "Начать", при нажатии на которую открывается страница заявок.
Система автоматически запоминает, просмотрел ли пользователь приветствия. Повторно они показываться не будут.
Если в приветствиях были внесены изменения, они будут показаны пользователю.
Таким образом можно дополнять информацию об изменениях в системе на страницах приветствия, чтобы пользователи могли ознакомиться и воспользоваться ими.
Изображения на страницах приветствия
Помимо текста, на страницах приветствия можно добавить изображения, которые будут отображаться в браузере пользователю. На этих изображениях могут быть изображения, иллюстрирующие работу системы, или скриншоты экранов. Они помогают пользователям ознакомиться с функционалом системы.
Путь к изображению задаётся через атрибут Ссылка на картинку.
Мы также можем указать атрибут Позиция картинки. Он может принимать значения "Слева" и "Справа", чтобы определить позицию картинки и текста на экране. Часто бывает хорошо, когда позиция картинки на страницах приветствия чередуется.
Давайте добавим изображения для страниц приветствия роли "Специалист":
...
Роли:
...
- Специалист:
Доступен профиль: Да
Приветствия:
- Добро пожаловать!:
Текст: Добро пожаловать в систему технической поддержки! Тут можно управлять заявками пользователей.
Позиция картинки: Справа
Ссылка на картинку: imgs/specialist-intro-1.png
- Заявки пользователей:
Текст: Вы можете создавать заявки на странице **Заявки**. Вы можете менять статус и приоритетность заявок.
Позиция картинки: Слева
Ссылка на картинку: imgs/specialist-intro-2.png
Страницы:
- Заявки:
Тип страницы: Справочник
Справочник: Заявки
Может создавать: Да
Может открывать окно редактирования: Да
Показывать дату и время создания: Да
...
Теперь на страницах приветствия отображаются изображения.
Сортировка заявок
Давайте добавим возможность сортировки, чтобы пользователи могли упорядочить заявки по дате создания или приоритетности. Для этого добавим атрибут Может сортировать по колонкам к странице Заявки у роли Специалист и выставим значение Да:
...
Роли:
...
- Специалист:
Доступен профиль: Да
Приветствия:
- Добро пожаловать!:
Текст: Добро пожаловать в систему технической поддержки! Тут можно управлять заявками пользователей.
Позиция картинки: Справа
Ссылка на картинку: imgs/specialist-intro-1.png
- Заявки пользователей:
Текст: Вы можете создавать заявки на странице **Заявки**. Вы можете менять статус и приоритетность заявок.
Позиция картинки: Слева
Ссылка на картинку: imgs/specialist-intro-2.png
Страницы:
- Заявки:
Тип страницы: Справочник
Справочник: Заявки
Может создавать: Да
Может открывать окно редактирования: Да
Показывать дату и время создания: Да
Может сортировать по колонкам: Да
...
Теперь специалист может упорядочивать заявки по дате создания, приоритетности и даже статусу. Для этого он может навести курсор на заголовок колонки, и появятся кнопки сортировки в виде стрелок вверх и вниз. При нажатии на стрелку он сортирует заявки по соответствующему полю. При повторном нажатии сортировка отменяется.
Поиск и фильтрация заявок
Бывает, нужно найти какую-то конкретную заявку. Для этого добавим атрибут Может фильтровать по колонкам к странице Заявки у роли Специалист и выставим значение Да.
Также мы добавим атрибут Доступен полнотекстовый поиск и поставим ему значение Да. Это позволит нам искать заявки по тексту.
...
Роли:
...
- Специалист:
Доступен профиль: Да
Приветствия:
- Добро пожаловать!:
Текст: Добро пожаловать в систему технической поддержки! Тут можно управлять заявками пользователей.
Позиция картинки: Справа
Ссылка на картинку: imgs/specialist-intro-1.png
- Заявки пользователей:
Текст: Вы можете создавать заявки на странице **Заявки**. Вы можете менять статус и приоритетность заявок.
Позиция картинки: Слева
Ссылка на картинку: imgs/specialist-intro-2.png
Страницы:
- Заявки:
Тип страницы: Справочник
Справочник: Заявки
Может создавать: Да
Может открывать окно редактирования: Да
Показывать дату и время создания: Да
Может сортировать по колонкам: Да
Может фильтровать по колонкам: Да
Доступен полнотекстовый поиск: Да
...
Теперь у роли "Специалист" в верхней части страницы "Заявки" появилось поле полнотекстового поиска. При вводе в него текста выполняется поиск по всем полям среди доступных заявок.
Также заголовки колонок стали интерактивными — при клике открывается фильтр для поиска по этой колонке.
Обратим внимание, что всплывающее окно фильтров для разных полей реализовано по-разному в зависимости от их типа. Например, для поля с типом "Значение перечисления" мы видим все значения с возможностью выбора тех, по которым хотим искать.
Сортировка по умолчанию
Если сортировка по умолчанию не задана, новые элементы справочника добавляются в конец списка.
Мы можем управлять этим поведением с помощью атрибутов Стратегия сортировки, Тип сортировки и Поле для сортировки в секции "Страницы" для "Роли".
Стратегия сортировки принимает одно из двух значений:
По дате создания- сортировка по умолчанию происходит относительно поляДата создания, которая заполняется автоматически при создании элемента справочникаВыбрать поле- сортировка по умолчанию относительно поля, которое задано в атрибутеПоле для сортировки.
Тип сортировки может быть По убыванию или По возрастанию.
Поле для сортировки задаётся только если Стратегия сортировки выставлена в Выбрать поле, и может быть равно одному из полей справочника этой страницы.
Настроим отображение так, чтобы новые заявки по умолчанию были сверху. Для этого выставим Стратегия сортировки в По дате создания, а Тип сортировки в По убыванию:
...
Роли:
...
- Специалист:
Доступен профиль: Да
Приветствия:
...
Страницы:
- Заявки:
Тип страницы: Справочник
Справочник: Заявки
Может создавать: Да
Может открывать окно редактирования: Да
Показывать дату и время создания: Да
Может сортировать по колонкам: Да
Может фильтровать по колонкам: Да
Доступен полнотекстовый поиск: Да
Стратегия сортировки: По дате создания
Тип сортировки: По убыванию
...
Теперь новые заявки отображаются в начале списка.
Часто бывает нужно, чтобы у разных ролей один и тот же справочник по умолчанию сортировался по-разному.
Эти атрибуты (Стратегия сортировки, Тип сортировки и Поле для сортировки) также можно задать на уровне справочника. Тогда на страницах, на которых не заданы эти поля, будут применены настройки из справочника. Если и в справочнике и на странице заданы эти атрибуты, то будут применены те, что заданы в атрибутах страницы.
Итоги
Давайте посмотрим, как выглядит итоговый файл app.rms:
###############################
# Report.ms app yml #
###############################
lang: ru
Проект:
Название: Техническая поддержка
FavIcon: imgs/favicon.ico
Пароль администратора: '123'
Мастер пароль: 'qwerty'
Фон страницы логина: imgs/app-login-bg.jpg
Роли:
- Администратор:
Доступен профиль: Да
Страницы:
- Пользователи:
Тип страницы: Справочник
Справочник: Пользователи
Может создавать: Да
Может открывать окно редактирования: Да
Может сортировать по колонкам: Да
Может фильтровать по колонкам: Да
- Заявки:
Тип страницы: Справочник
Справочник: Заявки
Может создавать: Да
Может открывать окно редактирования: Да
Показывать дату и время создания: Да
- Специалист:
Доступен профиль: Да
Приветствия:
- Добро пожаловать!:
Текст: Добро пожаловать в систему технической поддержки! Тут можно управлять заявками пользователей.
Позиция картинки: Справа
Ссылка на картинку: imgs/specialist-intro-1.png
- Заявки пользователей:
Текст: Вы можете создавать заявки на странице **Заявки**. Вы можете менять статус и приоритетность заявок.
Позиция картинки: Слева
Ссылка на картинку: imgs/specialist-intro-2.png
Страницы:
- Заявки:
Тип страницы: Справочник
Справочник: Заявки
Может создавать: Да
Может открывать окно редактирования: Да
Показывать дату и время создания: Да
Может сортировать по колонкам: Да
Может фильтровать по колонкам: Да
Доступен полнотекстовый поиск: Да
Стратегия сортировки: По дате создания
Тип сортировки: По убыванию
Справочники:
- Пользователи:
Наименование единицы справочника: Пользователь
Иконка: users
Ширина окна создания-редактирования: Мелкое
Поле для отображения как аватара: Аватар
Поле для отображения всей сущности: Имя
Поля:
- Аватар:
Тип поля: Файл
Тип файла: Аватар
- Email:
Заполнитель при пустом значении: Укажите почту...
Размер: 8
Обязательно при создании: Да
Обязательно при обновлении: Да
- Имя:
Заполнитель при пустом значении: Имя пользователя...
Размер: 8
Обязательно при создании: Да
Обязательно при обновлении: Да
- Роль:
Тип поля: Выбор роли
Заполнитель при пустом значении: Выберите роль...
Обязательно при создании: Да
Обязательно при обновлении: Да
- Пароль:
Тип поля: Сохранённый пароль
Скрыто в списке: Да
Скрыто на форме: Да
Действия:
- Установить пароль:
Описание: Установить пароль для пользователя
Иконка действия: key
Условие доступности: "Текущий пользователь: Роль" = "Роль: Администратор"
Параметры:
- Новый пароль:
Тип поля: Сохранённый пароль
Python код: scripts/set_password.py
- Заявки:
Наименование единицы справочника: Заявка
Описание: Заявки от пользователей на оказание технической поддержки
Изображение в описании: imgs/requests-description.svg
Иконка: bug
Поля:
- Статус:
Тип поля: Значение перечисления
Перечисление: Статусы заявок
Размер: 8
Предвыбрано: Да
- Приоритет:
Тип поля: Булево значение
Размер: 8
Описание: Приоритетные заявки будут обрабатываться первыми
- Заголовок:
Обязательно при создании: Да
Обязательно при обновлении: Да
Заполнитель при пустом значении: Укажите заголовок...
Описание: Краткое описание сути заявки
- Описание:
Тип поля: Текст
Заполнитель при пустом значении: Укажите описание...
Перечисления:
- Статусы заявок:
Значения:
- Новая:
Цвет: Оранжевый
Иконка: clock
- В работе:
Цвет: Синий
Иконка: wrench
- Выполнена:
Цвет: Зелёный
Иконка: check
- Отменена:
Цвет: Красный
Иконка: cancel
Что мы сделали:
- Создали роль "Специалист"
- Добавили роли "Специалист" страницы приветствия с текстом и изображениями
- Добавили для роли "Специалист" возможность сортировки на странице "Заявки"
- Добавили для роли "Специалист" возможность фильтрации на странице "Заявки"
- Добавили для роли "Специалист" возможность полнотекстового поиска на странице "Заявки"
- Добавили для роли "Специалист" сортировку по умолчанию на странице "Заявки"
Присвоение номера заявки
Для точной идентификации заявки в системе мы можем использовать номер заявки. Для этого при создании заявки мы будем присваивать ей номер по порядку.
Создание поля
Создадим новое "Порядковый номер" для справочника заявки с типом "Число". Для этого добавим новый узел в Справочники/Заявки/Поля:
...
Справочники:
...
- Заявки:
Наименование единицы справочника: Заявка
Описание: Заявки от пользователей на оказание технической поддержки
Изображение в описании: imgs/requests-description.svg
Иконка: bug
Поля:
- Порядковый номер:
Тип поля: Число
- Статус:
Тип поля: Значение перечисления
Перечисление: Статусы заявок
Размер: 8
Предвыбрано: Да
- Приоритет:
Тип поля: Булево значение
Размер: 8
Описание: Приоритетные заявки будут обрабатываться первыми
- Заголовок:
Обязательно при создании: Да
Обязательно при обновлении: Да
Заполнитель при пустом значении: Укажите заголовок...
Описание: Краткое описание сути заявки
- Описание:
Тип поля: Текст
Заполнитель при пустом значении: Укажите описание...
...
На форме создания-редактирования мы видим новое поле "Порядковый номер" и можем его заполнить. Мы можем внести абсолютно любое число, даже если заявка с таким номером уже существует. Но мы можем использовать механизм событий, чтобы выполнить логику присвоения номера при создании заявки.
Событие создания
Чтобы реализовать автоматическую генерацию номера заявки, создадим скрипт на языке Python. Он будет выполняться при создании заявки.
Создадим файл on_create_ticket.py в директории scripts с таким содержанием:
def run(app):
max_number = app.dictionary('Заявки').max('Порядковый номер')
if max_number is None:
max_number = 0
app.context_object['Порядковый номер'] = max_number + 1
Разберём его по частям:
def run(app):- это функция, которая будет выполнена при создании заявкиapp- это объект приложения, через него мы можем получить доступ к данным приложения и контекстаapp.dictionary('Заявки')- это объект справочника заявкиapp.dictionary('Заявки').max('Порядковый номер')- это максимальное значение поля "Порядковый номер" в справочнике "Заявки", если его нет, то возвращаетсяNoneif max_number is None:- если максимальное значение "Порядковый номер" равноNone, то мы устанавливаем его равным0app.context_object['Порядковый номер'] = max_number + 1- устанавливаем значение поля "Порядковый номер" в контексте заявки равным максимальному значению "Порядковый номер" + 1
Подключим этот скрипт к событию "Создание заявки", для этого добавим новый узел в Справочники/Заявки/События/Создание и укажем атрибут Python код:
...
Справочники:
...
- Заявки:
Наименование единицы справочника: Заявка
Описание: Заявки от пользователей на оказание технической поддержки
Изображение в описании: imgs/requests-description.svg
Иконка: bug
Поля:
...
События:
- Создание:
Python код: scripts/on_create_ticket.py
...
Теперь при создании заявок их порядковые номера будут увеличиваться автоматически.
Запрет изменения
Сейчас пользователи могут изменить порядковый номер заявки вручную, это необходимо запретить, чтобы избежать непредвиденных ошибок и дублирующихся номеров.
Чтобы это сделать, установим значение атрибута Условие редактирования в <ЛОЖЬ> у поля "Порядковый номер" в справочнике "Заявки":
...
Справочники:
...
- Заявки:
Наименование единицы справочника: Заявка
Описание: Заявки от пользователей на оказание технической поддержки
Изображение в описании: imgs/requests-description.svg
Иконка: bug
Поля:
- Порядковый номер:
Тип поля: Число
Условие редактирования: <ЛОЖЬ>
...
...
...
Теперь пользователи не смогут изменить порядковый номер заявки и он будет присвоен только автоматически.
Читаемый вид
В техническое поддержке принят свой стандарт для номеров заявок, согласно которому номер состоит из двух букв в верхнем регистре, потом тире и восемь цифр. Две первые буквы пока будут Т и П(в будущем можно будет добавить другие буквы), а 8 цифр будут номером заявки. То есть номер заявки будет выглядеть так: ТП-00001234.
Поэтому поле "Номер" и будем присваивать ему значение ТП-<Порядковый номер>, сделаем это поле тоже не редактируемым:
...
Справочники:
...
- Заявки:
Наименование единицы справочника: Заявка
Описание: Заявки от пользователей на оказание технической поддержки
Изображение в описании: imgs/requests-description.svg
Иконка: bug
Поля:
- Номер:
Условие редактирования: <ЛОЖЬ>
- Порядковый номер:
Тип поля: Число
Условие редактирования: <ЛОЖЬ>
...
...
...
Модицифицируем скрипт on_create_ticket.py:
def run(app):
max_number = app.dictionary('Заявки').max('Порядковый номер')
if max_number is None:
max_number = 0
app.context_object['Порядковый номер'] = max_number + 1
app.context_object['Номер'] = f"ТП-{str(app.context_object['Порядковый номер']).zfill(8)}"
Теперь номер заявки будет выглядеть так: ТП-00001234.
Мы так же можем вынести этот номер в заголовок формы редактирования заявки. Для этого установим значение атрибута Поле для отображения всей сущности в Номер у справочника "Заявки":
...
Справочники:
...
- Заявки:
Наименование единицы справочника: Заявка
Описание: Заявки от пользователей на оказание технической поддержки
Изображение в описании: imgs/requests-description.svg
Иконка: bug
Поле для отображения всей сущности: Номер
Поля:
- Номер:
Условие редактирования: <ЛОЖЬ>
- Порядковый номер:
Тип поля: Число
Условие редактирования: <ЛОЖЬ>
...
...
...
Теперь в заголовке формы редактирования заявки будет текст вида "Заявка ТП-00001234".
Скрытие полей
Мы можем управлять видимостью полей на форме редактирования заявки и в списке с помощью атрибутов Скрыто на форме и Скрыто в списке соответственно, чтобы скрыть достаточно выставить им значение Да.
Скроем поле "Порядковый номер" и на форме создания-редактирования и в списке, а поле "Номер" - только на форме редактирования (так как оно уже отображается в заголовке формы редактирования):
...
Справочники:
...
- Заявки:
Наименование единицы справочника: Заявка
Описание: Заявки от пользователей на оказание технической поддержки
Изображение в описании: imgs/requests-description.svg
Иконка: bug
Поле для отображения всей сущности: Номер
Поля:
- Номер:
Условие редактирования: <ЛОЖЬ>
Скрыто на форме: Да
- Порядковый номер:
Тип поля: Число
Условие редактирования: <ЛОЖЬ>
Скрыто на форме: Да
Скрыто в списке: Да
...
...
...
Итоги
Давайте посмотрим, как выглядит итоговый файл app.rms:
###############################
# Report.ms app yml #
###############################
lang: ru
Проект:
Название: Техническая поддержка
FavIcon: imgs/favicon.ico
Пароль администратора: '123'
Мастер пароль: 'qwerty'
Фон страницы логина: imgs/app-login-bg.jpg
Роли:
- Администратор:
Доступен профиль: Да
Страницы:
- Пользователи:
Тип страницы: Справочник
Справочник: Пользователи
Может создавать: Да
Может открывать окно редактирования: Да
Может сортировать по колонкам: Да
Может фильтровать по колонкам: Да
- Заявки:
Тип страницы: Справочник
Справочник: Заявки
Может создавать: Да
Может открывать окно редактирования: Да
Показывать дату и время создания: Да
- Специалист:
Доступен профиль: Да
Приветствия:
- Добро пожаловать!:
Текст: Добро пожаловать в систему технической поддержки! Тут можно управлять заявками пользователей.
Позиция картинки: Справа
Ссылка на картинку: imgs/specialist-intro-1.png
- Заявки пользователей:
Текст: Вы можете создавать заявки на странице **Заявки**. Вы можете менять статус и приоритетность заявок.
Позиция картинки: Слева
Ссылка на картинку: imgs/specialist-intro-2.png
Страницы:
- Заявки:
Тип страницы: Справочник
Справочник: Заявки
Может создавать: Да
Может открывать окно редактирования: Да
Показывать дату и время создания: Да
Может сортировать по колонкам: Да
Может фильтровать по колонкам: Да
Доступен полнотекстовый поиск: Да
Стратегия сортировки: По дате создания
Тип сортировки: По убыванию
Справочники:
- Пользователи:
Наименование единицы справочника: Пользователь
Иконка: users
Ширина окна создания-редактирования: Мелкое
Поле для отображения как аватара: Аватар
Поле для отображения всей сущности: Имя
Поля:
- Аватар:
Тип поля: Файл
Тип файла: Аватар
- Email:
Заполнитель при пустом значении: Укажите почту...
Размер: 8
Обязательно при создании: Да
Обязательно при обновлении: Да
- Имя:
Заполнитель при пустом значении: Имя пользователя...
Размер: 8
Обязательно при создании: Да
Обязательно при обновлении: Да
- Роль:
Тип поля: Выбор роли
Заполнитель при пустом значении: Выберите роль...
Обязательно при создании: Да
Обязательно при обновлении: Да
- Пароль:
Тип поля: Сохранённый пароль
Скрыто в списке: Да
Скрыто на форме: Да
Действия:
- Установить пароль:
Описание: Установить пароль для пользователя
Иконка действия: key
Условие доступности: "Текущий пользователь: Роль" = "Роль: Администратор"
Параметры:
- Новый пароль:
Тип поля: Сохранённый пароль
Python код: scripts/set_password.py
- Заявки:
Наименование единицы справочника: Заявка
Описание: Заявки от пользователей на оказание технической поддержки
Изображение в описании: imgs/requests-description.svg
Иконка: bug
Поля:
- Номер:
Условие редактирования: <ЛОЖЬ>
Скрыто на форме: Да
- Порядковый номер:
Тип поля: Число
Условие редактирования: <ЛОЖЬ>
Скрыто на форме: Да
Скрыто в списке: Да
- Статус:
Тип поля: Значение перечисления
Перечисление: Статусы заявок
Размер: 8
Предвыбрано: Да
- Приоритет:
Тип поля: Булево значение
Размер: 8
Описание: Приоритетные заявки будут обрабатываться первыми
- Заголовок:
Обязательно при создании: Да
Обязательно при обновлении: Да
Заполнитель при пустом значении: Укажите заголовок...
Описание: Краткое описание сути заявки
- Описание:
Тип поля: Текст
Заполнитель при пустом значении: Укажите описание...
События:
- Создание:
Python код: scripts/on_create_ticket.py
Перечисления:
- Статусы заявок:
Значения:
- Новая:
Цвет: Оранжевый
Иконка: clock
- В работе:
Цвет: Синий
Иконка: wrench
- Выполнена:
Цвет: Зелёный
Иконка: check
- Отменена:
Цвет: Красный
Иконка: cancel
Мы добавили файл on_create_ticket.py в директорию scripts:
def run(app):
max_number = app.dictionary('Заявки').max('Порядковый номер')
if max_number is None:
max_number = 0
app.context_object['Порядковый номер'] = max_number + 1
app.context_object['Номер'] = f"ТП-{str(app.context_object['Порядковый номер']).zfill(8)}"
Что мы сделали:
- Добавили файл
on_create_ticket.pyв директориюscriptsс кодом, который присваивает номер заявки при её создании - Добавили поле "Порядковый номер" в справочник "Заявки"
- Добавили поле "Номер" в справочник "Заявки"
Роль "Пользователь"
До этого момента заявки могли создавать только сами сотрудники технической поддержки. Давайте создадим роль "Пользователь", чтобы пользователи могли создавать заявки на оказание технической поддержки.
Для этого добавим роль "Пользователи" в секцию Роли и создадим страницу Заявки аналогично как для роли "Специалист", но без возможности сортировки, фильтрации и полнотекстового поиска. Также добавим страницы приветствия для роли "Пользователь":
...
Роли:
- Администратор:
...
- Специалист:
...
- Пользователь:
Доступен профиль: Да
Приветствия:
- Добро пожаловать!:
Текст: Добро пожаловать в систему технической поддержки! Тут можно управлять заявками пользователей.
Позиция картинки: Справа
Ссылка на картинку: imgs/user-intro-1.png
- Заявки пользователей:
Текст: Вы можете создавать заявки на странице **Заявки**. Вы можете менять статус и приоритетность заявок.
Позиция картинки: Слева
Ссылка на картинку: imgs/user-intro-2.png
Страницы:
- Заявки:
Тип страницы: Справочник
Справочник: Заявки
Может создавать: Да
Может открывать окно редактирования: Да
Показывать дату и время создания: Да
Стратегия сортировки: По дате создания
Тип сортировки: По убыванию
...
Теперь пользователи смогут создавать заявки на оказание технической поддержки. Администратор может создавать пользователей с ролью "Пользователь" и предоставлять им доступ к системе.
Запоминаем пользователя
Для того чтобы специалист технической поддержки знал от кого пришла та или иная заявка нам необходимо добавить поле "От кого" с типом поля "Элемент справочника" в справочник "Заявки":
...
Справочники:
...
- Заявки:
Наименование единицы справочника: Заявка
Описание: Заявки от пользователей на оказание технической поддержки
Изображение в описании: imgs/requests-description.svg
Иконка: bug
Поля:
- От кого:
Тип поля: Элемент справочника
Справочник: Пользователи
- Номер:
Условие редактирования: <ЛОЖЬ>
Скрыто на форме: Да
...
События:
- Создание:
Python код: scripts/on_create_ticket.py
...
Так как поле "От кого" имеет тип поля "Элемент справочника", нам необходимо указать справочник на который поле будет ссылаться. В нашем случае это справочник "Пользователи".
Теперь и пользователь, и специалист технической поддержки могут выбирать и видеть от кого пришла заявка в списке заявок.
Для пользователей системы поля с типом поля "Элемент справочника" отображаются как выпадающие списки со значениями из справочника.
Ограничиваем "От кого"
Сейчас в поле "От кого" можно выбрать любого пользователя системы, что не правильно. Нужно чтобы можно было выбрать только пользователей с ролью "Пользователь", так как заявки приходят только от них.
Для этого добавим атрибут Ограничение выборки в поле "От кого":
...
Справочники:
...
- Заявки:
Наименование единицы справочника: Заявка
Описание: Заявки от пользователей на оказание технической поддержки
Изображение в описании: imgs/requests-description.svg
Иконка: bug
Поля:
- От кого:
Тип поля: Элемент справочника
Справочник: Пользователи
Ограничение выборки: "Текущий объект: Роль" = "Роли: Пользователь"
- Номер:
Условие редактирования: <ЛОЖЬ>
Скрыто на форме: Да
...
События:
- Создание:
Python код: scripts/on_create_ticket.py
...
Мы указали такое ограничение "Текущий объект: Роль" = "Роли: Пользователь", что означает что в поле "От кого" будут доступны только пользователи с ролью "Пользователь".
Мы используем суфикс "Текущий объект" и после двоеточия указываем имя поля, в нашем случае это "Роли".
Теперь в поле "От кого" можно выбрать только пользователей с ролью "Пользователь".
Заполняем "От кого"
Сейчас пользователь с ролью "Пользователь" при создании заявки может выбрать любого пользователя системы, что не правильно. Нужно заполнить поле "От кого" текущим пользователем.
Для этого обновим скрипт on_create_ticket.py. Для этого проверим, если пользователь который создаёт заявку является пользователем с ролью "Пользователь", то заполняем это поле текущим пользователем:
def run(app):
max_number = app.dictionary('Заявки').max('Порядковый номер')
if max_number is None:
max_number = 0
app.context_object['Порядковый номер'] = max_number + 1
app.context_object['Номер'] = f"ТП-{str(app.context_object['Порядковый номер']).zfill(8)}"
if app.context_user['Роль'] == app.role('Пользователь'):
app.context_object['От кого'] = app.context_user
Теперь при создании заявки пользователь с ролью "Пользователь" поле "От кого" будет заполняться создателем.
Скрываем "От кого"
Для пользователей с ролью "Пользователь" поле "От кого" можно скрыть, потому что для него оно не информативно. В таких случаях , чтобы скрыть поле для какой то конкретной роли мы используем атрибут Скрыто для ролей, в котором перечисляем роли, которым нужно скрыть поле:
...
Справочники:
...
- Заявки:
Наименование единицы справочника: Заявка
Описание: Заявки от пользователей на оказание технической поддержки
Изображение в описании: imgs/requests-description.svg
Иконка: bug
Поля:
- От кого:
Тип поля: Элемент справочника
Справочник: Пользователи
Ограничение выборки: "Текущий объект: Роль" = "Роли: Пользователь"
Скрыто для ролей: ["Пользователь"]
- Номер:
Условие редактирования: <ЛОЖЬ>
Скрыто на форме: Да
...
События:
- Создание:
Python код: scripts/on_create_ticket.py
...
Теперь пользователь вообще не видит это поле, но его продолжает видеть сотрудники технической поддержки.
Фильтруем по "От кого"
Мы можем обнаружить, что все пользователи с ролью "Пользователь" видят все заявки созданные в системе. Это не правильно, пользователи должны видеть только свои заявки. Для того чтобы это сделать, добавим атрибут Правило выборки на страницу "Заявки" для роли "Пользователь":
...
Роли:
- Администратор:
...
- Специалист:
...
- Пользователь:
Доступен профиль: Да
Приветствия:
...
Страницы:
- Заявки:
Тип страницы: Справочник
Справочник: Заявки
Может создавать: Да
Может открывать окно редактирования: Да
Показывать дату и время создания: Да
Стратегия сортировки: По дате создания
Тип сортировки: По убыванию
Правило выборки: "Текущий объект: От кого" = "Текущий пользователь: Идентификатор"
...
Теперь пользователи с ролью "Пользователь" видят только свои заявки.
Для справнения мы используем поле Текущий пользователь: Идентификатор, оно есть у каждого объекта, хотя мы его и не объявляли.
Ещё одно такое поле, которое мы можем использовать в условиях поле Текущий объект: Дата создания.
Видимость "Статус" и "Приоритет"
Для пользователей с ролью "Пользователь" нам нужно скрыть поле "Статус" и "Приоритет".
При этом поле "Приоритет" нужно скрыть совсем. А поле "Статус" нужно скрыть только при создании.
Для поля "Приоритет" добавим атрибут Скрыто для ролей и установим значение ["Пользователь"] (так же мы делали с полем "От кого"):
...
Справочники:
...
- Заявки:
Наименование единицы справочника: Заявка
Описание: Заявки от пользователей на оказание технической поддержки
Изображение в описании: imgs/requests-description.svg
Иконка: bug
Поля:
Поля:
- От кого:
...
- Номер:
...
- Порядковый номер:
...
- Статус:
Тип поля: Значение перечисления
Перечисление: Статусы заявок
Размер: 8
Предвыбрано: Да
Скрыто для ролей: ["Пользователь"]
- Приоритет:
...
- Заголовок:
...
- Описание:
...
События:
- Создание:
Python код: scripts/on_create_ticket.py
...
Поле "Статус" мы хотим скрыть на форме но только при создании заявки. Для таких ситуаций следует использовать атрибут Условие скрытия и указать что мы скрываем это поле при создании(когда идентификатор текущего объекта пустой) и для пользователя с ролью "Пользователь":
...
Справочники:
...
- Заявки:
Наименование единицы справочника: Заявка
Описание: Заявки от пользователей на оказание технической поддержки
Изображение в описании: imgs/requests-description.svg
Иконка: bug
Поля:
Поля:
- От кого:
...
- Номер:
...
- Порядковый номер:
...
- Статус:
...
Условие скрытия: "Текущий объект: Идентификатор" = <ПУСТО> И "Текущий пользователь: Роль" = "Роли: Пользователь"
- Приоритет:
...
- Заголовок:
...
- Описание:
...
События:
- Создание:
Python код: scripts/on_create_ticket.py
...
Теперь пользователь с ролью "Пользователь" не видит поле "Статус" при создании заявки.
Обновим логику события создания заявки, чтобы заполнять статус заявки автоматически:
def run(app):
max_number = app.dictionary('Заявки').max('Порядковый номер')
if max_number is None:
max_number = 0
app.context_object['Порядковый номер'] = max_number + 1
app.context_object['Номер'] = f"ТП-{str(app.context_object['Порядковый номер']).zfill(8)}"
if app.context_user['Роль'] == app.role('Пользователь'):
app.context_object['От кого'] = app.context_user
app.context_object['Статус'] = app.enum('Статусы заявок', 'Новая')
Для работы с перечислениями в скриптах используется функция app.enum где первым аргументом передаётся имя перечисления, а втором его значение.
Итоги
Давайте посмотрим, как выглядит итоговый файл app.rms:
###############################
# Report.ms app yml #
###############################
lang: ru
Проект:
Название: Техническая поддержка
FavIcon: imgs/favicon.ico
Пароль администратора: '123'
Мастер пароль: 'qwerty'
Фон страницы логина: imgs/app-login-bg.jpg
Роли:
- Администратор:
Доступен профиль: Да
Страницы:
- Пользователи:
Тип страницы: Справочник
Справочник: Пользователи
Может создавать: Да
Может открывать окно редактирования: Да
Может сортировать по колонкам: Да
Может фильтровать по колонкам: Да
- Заявки:
Тип страницы: Справочник
Справочник: Заявки
Может создавать: Да
Может открывать окно редактирования: Да
Показывать дату и время создания: Да
- Специалист:
Доступен профиль: Да
Приветствия:
- Добро пожаловать!:
Текст: Добро пожаловать в систему технической поддержки! Тут можно управлять заявками пользователей.
Позиция картинки: Справа
Ссылка на картинку: imgs/specialist-intro-1.png
- Заявки пользователей:
Текст: Вы можете создавать заявки на странице **Заявки**. Вы можете менять статус и приоритетность заявок.
Позиция картинки: Слева
Ссылка на картинку: imgs/specialist-intro-2.png
Страницы:
- Заявки:
Тип страницы: Справочник
Справочник: Заявки
Может создавать: Да
Может открывать окно редактирования: Да
Показывать дату и время создания: Да
Может сортировать по колонкам: Да
Может фильтровать по колонкам: Да
Доступен полнотекстовый поиск: Да
Стратегия сортировки: По дате создания
Тип сортировки: По убыванию
- Пользователь:
Доступен профиль: Да
Приветствия:
- Добро пожаловать!:
Текст: Добро пожаловать в систему технической поддержки! Тут можно управлять заявками пользователей.
Позиция картинки: Справа
Ссылка на картинку: imgs/user-intro-1.png
- Заявки пользователей:
Текст: Вы можете создавать заявки на странице **Заявки**. Вы можете менять статус и приоритетность заявок.
Позиция картинки: Слева
Ссылка на картинку: imgs/user-intro-2.png
Страницы:
- Заявки:
Тип страницы: Справочник
Справочник: Заявки
Может создавать: Да
Может открывать окно редактирования: Да
Показывать дату и время создания: Да
Стратегия сортировки: По дате создания
Тип сортировки: По убыванию
Справочники:
- Пользователи:
Наименование единицы справочника: Пользователь
Иконка: users
Ширина окна создания-редактирования: Мелкое
Поле для отображения как аватара: Аватар
Поле для отображения всей сущности: Имя
Поля:
- Аватар:
Тип поля: Файл
Тип файла: Аватар
- Email:
Заполнитель при пустом значении: Укажите почту...
Размер: 8
Обязательно при создании: Да
Обязательно при обновлении: Да
- Имя:
Заполнитель при пустом значении: Имя пользователя...
Размер: 8
Обязательно при создании: Да
Обязательно при обновлении: Да
- Роль:
Тип поля: Выбор роли
Заполнитель при пустом значении: Выберите роль...
Обязательно при создании: Да
Обязательно при обновлении: Да
- Пароль:
Тип поля: Сохранённый пароль
Скрыто в списке: Да
Скрыто на форме: Да
Действия:
- Установить пароль:
Описание: Установить пароль для пользователя
Иконка действия: key
Условие доступности: "Текущий пользователь: Роль" = "Роль: Администратор"
Параметры:
- Новый пароль:
Тип поля: Сохранённый пароль
Python код: scripts/set_password.py
- Заявки:
Наименование единицы справочника: Заявка
Описание: Заявки от пользователей на оказание технической поддержки
Изображение в описании: imgs/requests-description.svg
Иконка: bug
Поля:
- От кого:
Тип поля: Элемент справочника
Справочник: Пользователи
Ограничение выборки: "Текущий объект: Роль" = "Роли: Пользователь"
Скрыто для ролей: ["Пользователь"]
- Номер:
Условие редактирования: <ЛОЖЬ>
Скрыто на форме: Да
- Порядковый номер:
Тип поля: Число
Условие редактирования: <ЛОЖЬ>
Скрыто на форме: Да
Скрыто в списке: Да
- Статус:
Тип поля: Значение перечисления
Перечисление: Статусы заявок
Размер: 8
Предвыбрано: Да
Условие скрытия: "Текущий объект: Идентификатор" = <ПУСТО> И "Текущий пользователь: Роль" = "Роли: Пользователь"
- Приоритет:
Тип поля: Булево значение
Размер: 8
Описание: Приоритетные заявки будут обрабатываться первыми
Скрыто для ролей: ["Пользователь"]
- Заголовок:
Обязательно при создании: Да
Обязательно при обновлении: Да
Заполнитель при пустом значении: Укажите заголовок...
Описание: Краткое описание сути заявки
- Описание:
Тип поля: Текст
Заполнитель при пустом значении: Укажите описание...
События:
- Создание:
Python код: scripts/on_create_ticket.py
Перечисления:
- Статусы заявок:
Значения:
- Новая:
Цвет: Оранжевый
Иконка: clock
- В работе:
Цвет: Синий
Иконка: wrench
- Выполнена:
Цвет: Зелёный
Иконка: check
- Отменена:
Цвет: Красный
Иконка: cancel
Файл scripts/on_create_ticket.py:
def run(app):
max_number = app.dictionary('Заявки').max('Порядковый номер')
if max_number is None:
max_number = 0
app.context_object['Порядковый номер'] = max_number + 1
app.context_object['Номер'] = f"ТП-{str(app.context_object['Порядковый номер']).zfill(8)}"
if app.context_user['Роль'] == app.role('Пользователь'):
app.context_object['От кого'] = app.context_user
app.context_object['Статус'] = app.enum('Статусы заявок', 'Новая')
Что мы сделали:
- Добавили поле "От кого" в справочник "Заявки"
- Модифицировали
on_create_ticket.py, поле "От кого" заполняется текущим пользователем, если заявку создаёт "Пользователь" - Ограничили выбор пользователей в поле "От кого" только теми, у которых роль "Пользователь"
- Показываем пользователям с ролью "Пользователь" только их заявки
- Скрыли поля "От кого" и "Приоритет" для пользователя с ролью "Пользователь"
- Скрыли поле "Статус" для пользователя с ролью "Пользователь" при создании заявки
- Автоматически заполняем поле статус при создании заявки пользователем с ролью "Пользователь"