Сценарий процесса пример

Данная статья поможет молодым специалистам легко начать работу со сценариями использования.

Данная статья поможет молодым специалистам легко начать работу со сценариями использования.

Сценарии использования- это сценарий взаимодействия пользователя (или пользователей) с программным продуктом для достижения конкретной цели.

Цель: моделирование и проектирование взаимодействия пользователя с системой в рамках выполнения одного сценария. Пошаговое подробное взаимодействие пользователя с системой. 

Документирование: таблица с описанием действий актора и реагирование системы на определенные шаги пользователя. 

Один сценарий использования имеет несколько потоков: основной и альтернативные. 

Выделение сценариев 

Один сценарий использования должен описывать действия пользователя, которые приведут к одному большому действию- функционалу пользователя. Например, авторизоваться, добавить товар в корзину и тд. 

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

Каждый основной сценарий использования должен быть независимым от другого основного. Если есть определенные условия выполнения- указываем в “Предусловия”

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

Уровни описания и степени детализации

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

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

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

Степень формализма выполняемого проекта и стадия, на которой он находится, прямо влияют на степень детальности и проработанности вариантов использования. Определяют следующие степени детальности при написании вариантов использования:

  1. Краткий (brief) вариант использования состоит (помимо названия) из одного-двух описательных предложений. Он хорош при сведении функциональных требований в таблицу при планировании приоритетности, технической сложности, номера версии продукта и т. д.

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

  1. Детальный (detailed) вариант использования – это формальный документ с предопределённой структурой разделов; это, собственно, и есть Use case в его традиционном понимании.

Детальный уровень описания применяют при написании ТЗ. Преимущественно, при написании ТЗ все кейсы необходимо описывать на детальной степени; обязательно применять детальную степень и системный уровень при описании кейсов  с высоким уровнем риска. 

Структура сценария использования

Сценарии использования включают в себя следующие разделы: 

  1. Название. Краткое, максимально понятное. Описывающее общее действие пользователя.

 Пример: 

UC-1. Регистрация в личном кабинете 

UC-2. Регистрация в программе лояльности

UC-3. Добавление товара в корзину 

  1. Предусловие. Формулировка условий, при которых данный вариант использования может быть инициирован. Условие, помимо прочего, может быть упоминанием о выполнении других вариантов использования. Также в предусловии необходимо указывать, в какой части системы находится пользователь, кратко- какие действия уже выполнил.

Пример: пользователь находится в “Корзине”, в “Корзине” добавлено 2 товара”. 

Данное предусловие мы можем указать для описания кейса работы пользователя в “Корзине”. Если мы описываем кейс “Добавление товара в корзину” или “Оформление заказа”, где необходимо указать всю цепочку шагов пользователя- то данное предусловие не подойдет.

  1. Основной сценарий. Сценарий – это последовательность шагов, описывающая процесс решения задачи, которой посвящен вариант использования. Шаги удобно последовательно нумеровать.

  2. Альтернативные сценарии, в которых процесс развития событий на каком-либо шаге чем-либо заметно отличается от основного, то есть имеет место ветвление.

Сценарий использования должен отвечать на вопрос “Что делает пользователь?” “Что делает система?”

При описании сценария использования важно соблюдать пошаговый план действий пользователя,  указывая физическое действие пользователя. 

Например, формулировка  “добавил товар в корзину” неверная. 

Правильно:  “нажимает на кнопку “Добавить товар в корзину” и далее-  реакцию системы на действия пользователя. 

Пользователь

Система

Какое физическое действие произвел пользователь? 

Как отреагировала система?

Нажимает “Добавить в корзину”

Система добавляет выбранный товар в корзину. В иконке “Корзина” система выводит маркер- кол-во добавленного товара в корзину. 

Изменяет кнопку “Добавить в корзину” у выбранного товара на кнопку “Перейти в корзину”

Пользователь нажимает “перейти в корзину”

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

Альтернативные сценарии 

При проработке основного сценария, все варианты действий пользователя и поведения системы, отличных от основного сценария необходимо выносить в альтернативный сценарий. То есть, везде, где можно указать “если”- это и будет альтернативный сценарий. 

Важно! Альтернативный сценарий должен ссылаться только на один успешный сценарий. Недопустимо прописывать альтернативный сценарий для альтернативного сценария. 

Рассмотрим на примере авторизации

Предусловие: неавторизованный пользователь находится на странице авторизации и регистрации

Пользователь

Система

Какое физическое действие произвел пользователь? 

Как отреагировала система?

Пользователь нажал кнопку “Зарегистрироваться” 

Система вывела форму регистрации, поле “email”

Пользователь вводит данные в поле “email”

3. Система производит проверку введенных данных на валидацию. Данные проходят по условиям валидации

Если данные не прошли проверку валидации, запускается альтернативный сценарий №1. 

Система производит поиск введенных данных “email”  по учетным записям в системе. 

Учетных записей с такими данными “email” не найдено. 

Если в системе найдена учетная запись с таким логином, запускается альтернативный сценарий №2

Система отправляет пользователю код подтверждения на email

Система выводит пользователю поле “код подтверждения”

Сценарий “ввод кода подтверждения” вынесен в отдельный сценарий. — обязательно указываем, если какой-либо функционал выносим в отдельный кейс, более подробный. 

Пользователь вводит корректный код подтверждения в поле “код подтверждения” 

Система производит проверку кода подтверждения. Код введен верно. 

Пользователь зарегистрирован. 

Альтернативный сценарий с неверным кодом подтверждения выносим в сценарий “Ввод кода подтверждения” 

Пример альтернативного сценария 

Альтернативный сценарий №1 

На шаге №3 успешного сценария, введенные данные не прошли проверку валидации. 

  1. Система выводит информер  с указанием запрещенных символов.

  2. Пользователь вводит корректные данные в поле “email”.

Далее сценарий продолжается от шага №3 успешного сценария.

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

Когда-то я уже упоминал одно из правил, которым руководствуется команда ПланФикса в своей работе: “Работать должны роботы”. Это не значит, что мы не хотим работать – просто мы любим перекладывать на плечи автоматов рутинную работу, которую можно описать понятными правилами, вроде этой:

Работать должны роботы - а сценарии в ПланФиксе помогут вам организовать их работу
Сегодня мы анонсируем Процессы и Сценарии, которые помогут всем нам избавиться от солидной порции такой работы – и одновременно сделают ПланФикс еще более гибким и управляемым.

Попробую для начала объяснить все простыми словами.

Что такое Процесс? Это жизненный цикл задачи, ее путь от создания до завершения. До этого момента процесс в ПланФиксе описывался набором статусов, которые могла принимать задача на этом пути. Теперь к этому набору статусов добавляется новая сущность – Сценарии.

Сценарий – это выполняемая автоматически последовательность операций.

Звучит как определение из учебника, конечно, и вряд дли это облегчает понимание… Ну давайте попробую чуть по-другому. Представьте, что теперь вы можете задавать в ПланФиксе правила, вроде “Если поле “Доставка” содержит значение “Да”, то подключить к задаче в качестве исполнителя группу “Отдел доставки” или “Когда задача перейдет в статус “Выполненная”, отправить клиенту письмо по шаблону “Уведомление клиента о выполнении”. Вот это и есть сценарии – наборы правил, которыми вы “оживляете” задачу, заставляете систему работать автоматически, перекладывая на нее операции, которые раньше делали вручную.

Наборы статусов и Сценарии теперь объединены в Процессы. Это отражено в том числе и в измененном интерфейсе раздела “Кастомизация” (update от 24.06.2016: теперь он перенесен в “Управление аккаунтом”):

Процесс в ПланФиксе состоит из Набора статусов и Автоматических сценариев
Если представить процесс как линию автоматической сборки, то набор статусов – это конвейер, “хребет” процесса, а сценарии – это программы для роботов-манипуляторов, которые включаются в момент нахождения очередной задачи в определенной точке на конвейере и отрабатывают заданную последовательность действий. Достаточно один раз правильно настроить эту линию, чтобы она начала печь пирожки, собирать автомобили или паковать овощи. Вот об этой настройке мы сейчас и поговорим.

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

Новый интерфейс настройки набора статусов в ПланФиксе
В каждой строке теперь перечислены статусы, в который задача может перейти из текущего статуса:

Настройка переходов из статуса в статус в ПланФиксе
Тут же добавляется возможность перевода в другой статус:

ПланФикс - добавление возможности перехода задачи в другой статус
Удалить переход в определенный статус или настроить его параметры можно, кликнув на название этого статуса в списке:

ПланФикс: настройка поведения системы при переходе в определенный статус
Тут есть всякие новинки и интересности, но пока я останавливаться на них не буду, чтобы не раздувать эту заметку, лучше перейдем к настройкам сценариев для этого же процесса. Изначально список сценариев процесса пуст, можно только добавить новый:

Добавление нового сценария в ПланФиксе
Окно добавления нового сценария имеет стандартный для ПланФикса конструктив, который, скорее всего, не вызовет у вас особых вопросов:

ПланФикс: Окно добавления нового процесса
Для примера, давайте настроем простенький сценарий, о котором я упоминал выше: когда задача переведена в статус “Выполненная”, будем отправлять уведомление об этом клиенту. Предположим, что в настраиваемом процессе задачи от клиентов мы получаем по почте, соответственно, клиент в таких задачах автоматически становится постановщиком – его и будем уведомлять.

Начинаем, традиционно, с придумывания говорящего названия для нашего сценария. Если этого не сделать, то разобраться в будущем, что делает тот или иной сценарий, будет намного сложнее:

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

Сценарии в ПланФиксе: выбор события, при котором сработает сценарий
С первым и последним все ясно – это события создания и удаления задачи – а вот в чем разница между двумя событиями, связанными с ее изменением?

Разница в том, что первый из них – это событие, которое сработает в тот момент, когда изменение задачи приведет к выполнению заданных условий (то есть, изменится один из параметров, участвующий в этих условиях). Именно он нам и нужен – когда у задачи изменится статус на “Выполненная”, сработает нужное нам событие:
Сценарии в ПланФиксе: совершение действия при изменении задачиВторой вариант указывает на событие, которое будет срабатывать каждый раз, когда задача будет изменена и условие будет выполняться, даже если изменялись другие параметры задачи, которые не описаны в этом условии. Если бы мы выбрали этот вариант в нашем примере, то скорее всего получили бы ложные срабатывания: ведь если задача находится в статусе “Выполненная” и уведомление клиенту уже отправлено, а в это время кто-то решил бы изменить у задачи исполнителя или значение какого-либо поля, то событие сработало бы опять и клиент получил бы повторное напоминание.

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

Идем дальше – указываем условие, при выполнении которого сработает наш сценарий. Оно в нашем примере очень простое и состоит из одной строки:

Сценарии в ПланФиксе - задание условий срабатывания сценария
Тут используется стандартный для ПланФикса конструктор условий, поэтому я не буду останавливаться на нем подробно.

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

Сценарии в ПланФиксе: установка времени задержки
Теперь нам осталось последнее – определить, что же именно мы хотим сделать в момент наступления описанного события. Сейчас в вариантах действий только два пункта: изменить эту задачу и отправить письмо. Мы выбираем второй:

Сценарии в ПланФиксе: выбор действия, которое необходимо совершить
и настраиваем параметры отправки:

Сценарии в ПланФиксе: настройка отправки письма при срабатывании события
Недавно я рассказывал о шаблонах писем, которые вы теперь можете конструировать самостоятельно, и говорил, что они пригодятся для работы автоматических сценариев – вот это как раз один из таких случаев.

В нашем сценарии будет только одно действие, поэтому мы игнорируем предложение добавить другие и сохраняем сценарий:

Сценарии в ПланФиксе: выбор дополнительных действий и сохранение сценарияВсе, сценарий готов и уже работает – так что как только любая задача, созданная по шаблону со стандартным процессом, будет переведена в статус “Выполненная”, ее постановщик получит уведомление об этом. Вот как выглядит наш сценарий в списке:

Готовый сценарий в процессах ПланФикса
Лампочка слева от названия позволяет временно отключить сценарий, если это понадобится для отладки или в ходе изменения процесса работы.

Вот и все, что касается настройки. Но это такое дело, конечно, что пока сам не попробуешь, не поймешь, так что пробуйте 🙂

Несколько важных замечаний в завершение:

  • Механизм сценариев достаточно сложен и глубоко интегрирован в ПланФикс, поэтому наверняка в первое время вы будете сталкиваться с какими-то вопросами, ошибками или непонятными ситуациями – прошу сразу сообщать об этом нашей Службе поддержки, мы будем оперативно отвечать и/или править систему.
  • В шаблонах задач теперь устанавливается не набор статусов, по которому будет перемещаться эта задача, а процесс целиком, который включает и набор статусов, и автоматические сценарии к нему. Все существующие наборы статусов стали частью одноименных процессов, поэтому в ваших шаблонах уже проставлены эти процессы.
  • Сейчас мы запустили минимальный набор возможностей для автоматических сценариев – в основном для того, чтобы отладить сам механизм их работы. Но сразу после обработки первой волны ваших обращений, мы начнем увеличивать эти возможности. Развитие пойдет по трем основным направлениям:
    • добавление новых событий, при которых будут срабатывать сценарии (например “добавление нового действия”, “создание контакта” и т.п.);
    • добавление типов действий (в частности, в сценарии появится возможность изменять не только текущую, но и другие задачи);
    • добавление видов операций изменения (в нашем примере мы до них не добрались, так как пошли по ветке отправки письма, а не изменения задачи – так что можете самостоятельно оценить варианты изменений задачи, доступные на текущий момент).
  • Глубокая интеграция механизма сценариев в ПланФикс приводит в том числе и к тому, что вы можете заменить некоторые стандартные процессы системы своими. В рассмотренном выше примере вы увидели, как можно сделать свою систему уведомлений в ПланФиксе – соответственно, вы можете полностью или частично “переписать” логику работы системы в различных ситуациях, заставить свою логику работать вместо или вместе со стандартной. И это касается не только уведомлений.
  • Обычно в системах управления бизнес-процессы и автоматические сценарии доступны только на старших тарифах, но мы решили сделать процессы и сценарии доступными для всех тарифов без ограничений. Даже в бесплатной версии ПланФикса мы даем возможность добавить один автоматический сценарий, чтобы все пользователи смогли оценить мощь этого механизма. Для новых аккаунтов в ходе пробного периода использование сценариев доступно без ограничений, как в любом платном пакете.
  • Нам интересны как сценарии, которые у вас получилось реализовать при помощи нового механизма, так и сценарии, для запуска которых в ПланФиксе пока не хватает возможностей – делитесь ими с нами, пожалуйста, это поможет нам не сбиваться с курса и добавлять важные для вас функции.

Дмитрий Гончаренко Команда ПланФикса

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

Анна Вичугова | Анна Гасраталиева

Алгоритм описания функциональных требований к системе в формате Use Case

Существуют разные формы представления функциональных требований: пользовательская история (user story), каноническая форма с привязкой к CRUDL-операциям и модели данных (классический формат описания требований), а также описание сценариев использования (Use Case).

Use Case до сих пор является одной из самых популярных форм представления функциональных требований как среди российских компаний, так и за рубежом. Поэтому именно о них и пойдет речь в нашей статье.

В официальной литературе на русский язык Use Case принято переводить как вариант использования (сокращённо ВИ), хотя в разговорной речи и проектных документах достаточно часто употребляется ещё и транслитерация термина Use Case, то есть говорят и пишут юскейс.

В связке с понятием варианта использования идёт термин Use case scenario, который переводится как сценарий варианта использования или пользовательский сценарий.

Технически, разница есть, то есть Use case это не тоже самое, что Use case scenario. Например, «Купить Товар» — Use case, и у него есть Use case scenario (пошаговое описание того, как именно купить товар: 1. Выбрать товар, 2. Добавить в корзину, 3. Оплатить).

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

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

Итак, Use case (UC) — это популярная форма представления функциональных требований к ПО в виде пошагового сценария взаимодействия актора (пользователя или внешнего сервиса) с проектируемой системой, включая описание метаданных этого взаимодействия: области применения, предусловия, триггеры, постусловия, релевантные бизнес-правила и пр.

Давайте рассмотрим на примере, как описать UC и избежать ошибок в работе с этим методом.

Алгоритм описания функциональных требований к системе

Типовую последовательность разработки функциональных требований в форме UC можно представить следующим образом:

  1. Определить Акторов — тех, кто взаимодействует с системой
  2. Выявить и составить список UC — задач, которые стейкхолдеры смогут решить с помощью системы
  3. Для каждого юскейса определить приоритет — важность UC по отношению к другим вариантам использования
  4. Для каждого важного юскейса определить контекст применения, конечную цель и результат
  5. Описать основной поток каждого UC с высоким приоритетом в виде последовательности шагов, которая приведёт к достижению его цели — пользовательского сценария (use case scenario)
  6. Дополнить основной поток расширениями, исключениями и циклами
  7. Собрать воедино результаты шагов 4−6, детально описав каждый юскейс с высоким приоритетом как алгоритм взаимодействия пользователя с системой

Теперь давайте рассмотрим каждый шаг поподробнее.

1. Определить акторов, которые взаимодействуют с системой

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

Например, если рассматривать мобильный телефон как систему, то актором будет человек — пользователь мобильного телефона. Результат этого шага можно оформить в виде таблицы или диаграммы ролей.

2. Для каждого актора составить список задач, которые он сможет решить с помощью системы

Мы советуем делать это в виде реестра юскейсов — единой таблицы, показывающей распределение юскейсов по акторам.

Рекомендуем называть UC в формате «Инфинитив + Объект», где «Инфинитив» — это инфинитив глагол в совершенного вида с большой буквы, а «Объект» — это существительное, обозначающее объект управления с большой буквы.

Из названия вариант использования должно быть сразу понятно, какую именно задачу пользователя он решает. Например, «Подписать Документ», «Оформить Заказ», «Оплатить Товар», «Сделать Звонок» и так далее.

Для повышения наглядности можно сделать это в табличном виде или UML-диаграммы вариантов использования (она же Use case diagram, диаграмма прецедентов).

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

Для B2B-продуктов и проектов исходными данными для юскейсов, как правило, являются отраслевые и корпоративные регламенты, описание бизнес-процессов и запросы стейкхолдеров.

Давайте сформируем реестр юскейсов. Например, ранее для пользователя мобильного телефона мы определи функциональные возможности «Сделать звоноки» и «Отправить СМС». Они реализуют единую пользовательскую потребность: «Связаться с другим человеком», поэтому их можно объединить в один юскейс.

Юскейсы «Поиграть в казуальную Игру» и «Посмотреть фотографии» относятся к потребности «Скоротать время».

Таким образом, для данного примера с мобильным телефоном реестр юскейсов может выглядеть следующим образом:

3. Для каждого UC определить его приоритет

Реализация юскейсов в коде — трудоёмкая работа, поэтому надо понимать, с каких лучше начать в первую очередь, а до каких очередь может не дойти никогда.

Реестр юскейсов может использоваться для приоритизации пользовательских функциональных требований с целью их ранжирования по степени важности, которая определяет порядок реализации.

Самым простым методом приоритизации, который часто применяется на практике, считается метод MoSCoW. Он получил своё название не в честь российской столицы, а как сокращение следующих 4 категорий:

  • Must — то, что необходимо сделать в любом случае. Считается, что без реализации этих требований решение не будет работать или при отсутствии этих фич продукт не будет нужен потребителям. Чаще всего этот приоритет называется 1-я очередь и обозначается цифрой 1
  • Should — требования 2-ой очереди, которые должны быть реализованы после тех, что отнесены к группе Must. Это приоритет номер 2
  • Could — желательные требования, которые можно сделать, если останется время и будут ресурсы. Это приоритет номер 3
  • Would — требования, которые хотелось бы реализовать, но пока их можно проигнорировать или перенести на следующие итерации без вреда для продукта. Это приоритет номер 4

В нашем примере с мобильным телефоном приоритизировать юскейсы можно так, как показано в таблице 2.

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

Впрочем, тема трассировки и приоритизации требований достаточно обширна и заслуживает отдельной статьи.

4. Для каждого высокоприоритетного (Must или Should) UC определить контекст применения, конечную цель и результат

Это можно оформить в виде списка или таблицы, например в Notion:

5. Раскрыть содержание основного потока каждого юскейса высокого приоритета в виде пользовательского сценария

Напомним, что пользовательский сценарий — это последовательность шагов, которая приведёт к достижению конечной цели юскейса, получению нужного актору результата.

Основную часть пользовательского сценария составляет так называемый happy path (основной поток), который представляет собой пошаговый алгоритм выполнения сценария без логических операторов XOR (исключающее или), используемых для ветвления потока управления в результате проверки каких-либо условий.

Как может выглядеть черновик сценария основного потока юскейса:

1. Пользователь даёт команду совершить звонок
2. Система запрашивает номер телефона вызываемого абонента
3. Пользователь сообщает номер абонента
4. Система убеждается в корректности указанного номера телефона
5. Система вызывает абонента с указанным номером телефона
6. Система убеждается, что звонок начался
7. Система передаёт голос собеседников в ходе разговора

Для наглядности можно нарисовать эту линейную последовательность шагов в виде простого процесса в нотациях EPC, BPMN (рис.1), UML activity или sequence, а также блок-схемы алгоритма по ГОСТ 19.701−90.

Последовательность шагов в виде BPMN-диаграммы

На практике подавляющая часть сценариев описывается только текстовым описанием. Пример такого описания мы разберём с вами ниже.

6. Дополнить линейную последовательность основного потока в описании UC расширениями, исключениями и циклами

На этом этапе аналитик усложняет ранее полученный happy path, включая в схему различные ветвления с помощью логического оператора XOR.

Вместо BPMN для отображения логики сценария нашего юскейса можно использовать любую другую нотацию (EPC, UML activity diagram, IDEF3 или даже простого текстового алгоритма).

Расширенная BPMN-диаграмма юскейса с исключениями и альтернативными потоками

7. Собрать воедино результаты выполнения трёх предыдущих шагов, детально описав каждый UC как алгоритм взаимодействия пользователя с системой

На этом этапе у каждого юскейса появляется описание, структура которого всегда примерно такая:

  • Имя
  • Приоритет
  • Область действия
  • Контекст
  • Актор
  • Цель
  • Предусловия
  • Результат (постусловие)
  • Основной поток
  • Расширения или альтернативные потоки
  • Бизнес-правила

Давайте разберем каждый элемент этой структуры поподробнее.

Эту структуру можно представить в текстовом виде или, для наглядности, в виде таблицы. Давайте завершим описание этого юскейса так, как мы делаем это на реальных проектах, то есть полностью опишем happy path и альтернативные сценарии.

Пример 1. UC «Сделать Звонок»

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

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

Как структурировать UC из набора
исходных ФТ

Задача:
Рассмотрим пример информационной системы, которая позволяет клиенту выбрать один или несколько обучающих курсов, заключить договор на участие в них и оплатить сумму через онлайн-оплату.

Если у клиента есть промо-код на скидку по конкретному курсу, сумма в договоре будет снижена на размер скидки.

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

  • FRQ1 Система должна предоставить пользователю с ролью «Клиент» возможность заключить договор на участие в одном или нескольких обучающих курсах
  • FRQ2 Система должна предоставить пользователю с ролью «Клиент» возможность добавить курсы к договору
  • FRQ2 Система должна предоставить пользователю с ролью «Клиент» возможность удалить курсы из договора
  • FRQ4 Система должна предоставить пользователю с ролью «Клиент» оплатить сумму по заключенному договору через шлюз онлайн-оплаты
  • FRQ5 Система должна предоставить пользователю с ролью «Клиент» снизить сумму по заключенному договору с применением промо-кода на скидку

Формируем описание в формате UC, применяя алгоритм:

Шаг 1. Определяем акторов. Судя по требованиям, с системой взаимодействует клиент и шлюз оплаты.

Шаг 2. Сформируем реестр юскейсов. Для этого мы можем, например, представить имеющийся набор функциональных требований в виде UML-диаграммы вариантов использования (UML Use case diagram).

Исходная UML-диаграмма use case

Чтобы составить реестр юскейсов, давайте выделим из ранее представленных юскейсов именно те, что имеют бизнес-ценность для пользователя без привязки к системе.

Упрощённая UML-диаграмма use case

Давайте также сопоставим получившиеся юскейсы и функциональные требования в таблице ниже.

При формировании реестра юскейсов для пользователя мобильного телефона мы можем выделить такие функциональные возможности как «Сделать Звонок» и «Отправить СМС». Оба этих юскейса отражают непосредственное взаимодействие актора с системой, направленное на достижение определённой бизнес-цели, это системный юскейс.

Функциональные возможности «Сделать звонок» и «Отправить СМС» относятся к одной потребности пользователя «связаться с другим человеком», которая будет состоять из двух системных юскейсов: «Позвонить Человеку» и «Отправить СМС». Показать эту трассировку (связь) можно с помощью реестра вариантов использования.

Реестр вариантов использования:

Шаг 3. Определить приоритеты системных юскейсов

Поскольку юскейсы в рассматриваемой части системы тесно связаны между собой, ранее рассмотренный метод приоритизации MoSCow не совсем подходит для этого случая. Здесь целесообразнее расставить приоритеты с точки зрения технических зависимостей данных юскейсов между собой: сперва должны быть реализованы требования относительно возможности заключить договор, чтобы потом проводить оплату по заключённому договору.

Шаги 4−7. Эти шаги (описать основной поток и расширения для каждого из приоритетных юскейсов) мы представим в виде примера описания одного из юскейсов (UC «Оплатить Договор», см. ниже). По аналогии будет описан и UC «Заключить Договор».

Пример 2. UC «Оплатить Договор»

Для нашего примера вариант использования «Оплатить Договор» может выглядеть так:

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

Такой формат хорошо подходит для реализации, если в юскейсе описана конкретная привязка к модели данных, указаны сущности и атрибуты, над которыми выполняются операции.

Рассмотренная табличная форма описания UC является не единственной возможной. Бывают ещё и другие форматы, например, таблица в две колонки, юскейс в стиле RUP и так далее.

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

Пример 3. UC «Обновить Анкету»

Достоинства и недостатки UC как формы представления требований

Основными преимуществами UC являются следующие:

  • Нисходящая и восходящая трассировка (от системного уровня к бизнесу) улучшает понятность требований для Заказчика и команды реализации: UC несёт конечную бизнес-ценность, детально описывает структуры данных и бизнес-логику их обработки, позволяет убедиться в реализации
  • Вариант использования можно использовать как единицу поставки при планировании, реализации, тестировании и приёмке работ;
  • Набор связанных друг с другом вариантов использования позволяет обеспечить полноту функциональных требований, следующих из потребностей пользователей
  • Детальный шаблон представления UC позволяет полностью описать взаимодействие актора с системой, включая контекст, предшествующие, сопутствующие и результирующие события, а также ссылки к бизнес-правилам и нефункциональным требованиям (ограничения и некоторые атрибуты качества)
  • UC — отличная база для формирования тестовых сценариев (test cases) для проверки того, работает ли реализованная система как ожидалось

Обратной стороной этих достоинств являются следующие недостатки:

  • Плохо подходят для документирования требований, основанных не на взаимодействии с системой, а на выполнении расчётов и преобразованиях уже имеющихся в системе данных. Например, построение графиков и отчётов, вычисления, описание математических алгоритмов
  • Субъективность: качество изложения как самого UC, так и их реестра (ширина, глубина детализации уровней абстракции) зависит от навыков аналитика
  • На детальную проработку каждого UC уходит много времени. Например, у меня это занимает в среднем от 30 минут; добиться существенного повышения скорости работы можно за счёт повторного использования типовых юскейсов (опытный аналитик или отдел могут создать библиотеку своих юскейсов)
  • Проектирование системы только по UC исключает другие потенциально ценные методики документирования и анализа требований, такие как каноническая форма представления функциональных требований с привязкой с CRUD-операциям или популярная в Agile-проектах форма User Story по INVEST с критериям приёмки (Acceptance Criteria)

Откуда взялся такой формат как Use Case

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

Исторически функциональные требования, представляющие поведение системы, описывались в виде отдельных функций. Например, так:

  • FRQ1 Система должна предоставить пользователю с ролью «Клиент» возможность заключить договор на участие в одном или нескольких обучающих курсах
  • FRQ2 Система должна предоставить пользователю с ролью «Клиент» возможность добавить курсы к договору

В 1986 году Ивар Якобсон (шведский учёный, который вместе с Гради Бучем и Джеймсом Рамбо стоял у истоков ООП и UML) предложил альтернативную форму представления функциональных возможностей системы. Вместо описания функциональных требований к системе в виде отдельных функций Якобсон предложил объединить их по контексту, а затем превратить в набор вариантов использования (ВИ), который будет обеспечивать полноту и неизбыточность требований.

Якобсон обнаружил, что отдельные системные ФТ обычно не представляют большой самостоятельной ценности для заказчика, менеджера, пользователя, так как являются слишком мелкими единицами функциональности. Подход Якобсона позволил вместо сотен-тысяч системных функций применять единицы-десятки юскейсов, что гораздо удобнее в целях управления, планирования и сдачи ИТ-продукта/системы. Кроме того, он хорошо стыкуется с задачами тестирования и создания пользовательской документации. Подробнее об этом см в статье.

В 2001 году Алистер Коберн, эксперт в разработке ПО, расширил и уточнил идеи Якобсона, выпустив книгу «Современные методы описания функциональных требований к системам» (Writing Effective Use Cases). Книга получилась достаточно подробной, содержащей множество примеров. Помимо техник описания самих UC, работа Коберна включает также связанные вопросы о контексте, границах и основных компонентах проектируемой системы, то есть так называемый scope системы.

Эти и другие аспекты работы с требованиями были изложены в книге ещё одного автора, широко известного в системном и бизнес-анализе. В 2003 году Карл Вигерс (Karl Wiegers) написал 2-е издание своей книги «Разработка требований к программному обеспечению» (Software Requirements), где рассмотрены не только техники разработки требований, но и вопросы управления ими, включая сбор, документирование, трассировку, работу с изменениями и анализ рисков. Эта книга почти вдвое объёмнее труда Коберна и больше подходит для начинающих аналитиков.

UC рассматривает проектируемое ПО как «чёрный ящик», описывая взаимодействие с системой с точки зрения внешнего наблюдателя: ЧТО система должна сделать, чтобы актор достиг своей цели, а НЕ КАК это должно быть сделано.

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

Несмотря на повсеместное распространение гибких методологий разработки ПО, UC как подход к описанию функциональных требований очень активно применяется на практике. В отличие от пользовательских историй (User Story), другой популярной формы представления требований, UC охотно принимают в реализацию — в основном благодаря структурированному формату и детальной проработке бизнес-логики с привязкой к модели данных.

Полный реестр UC и структурированное описание каждого из них позволяет разработчикам воплотить описанные структуры данных и алгоритмы их обработки. Таким образом, большая трудоемкость при разработке вариантов использования на этапе анализа и спецификации требований окупается сокращением времени на этапе реализации и тестирования. Кроме того, реестр юскейсов можно использовать для оценки трудоёмкости проекта — менеджеры проектов часто приходят к аналитикам и тимлидам с этим вопросом.

В завершение статьи хотелось бы напомнить: если ваш юскейс решает проблемы разработки ПО, то есть создаёт общее понимание требований у заказчика и всей проектной команды, то вы написали хороший юскейс. Следование формату само по себе не самоценно.

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

Анна Вичугова

  • Кандидат технических наук (Системный анализ, управление и обработка информации, 2013)
  • Сертифицированный бизнес-аналитик (CBAP 2020, международная сертификация IIBA)
  • Сертифицированный специалист Business Studio (2010, 2012, 2013, 2018)
  • Сертифицированный специалист и администратор СЭД Directum (2011

Профессиональные интересы: системный анализ, бизнес-анализ, разработка и поддержка СМК, ССП (KPI), анализ и формализация бизнес-процессов (UML, IDEF, BPMN), Data Science, технологии Big Data, разработка технической документации (ТЗ по ГОСТам серии 19.***, 34.***, руководства пользователя и администратора, описание программных продуктов), управление продуктами и проектами.

Анна Гасраталиева

Системный аналитик, выпускающий редактор Systems. Education

Системный аналитик, выпускающий редактор Systems. Education

Профессиональные интересы: телекоммуникации, интеграции, управление задачами, управление людьми, обучения

Введение в написание сценариев

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

С версии 3.2.9.20379 в системе доступен ELMA API. Подробнее…

Начало работы. Ваш первый сценарий

Перейдем сразу к делу. Для успешного обучения лучший метод – это практика.

Работа со сценариями ведется в Дизайнере ELMA. Сами сценарии используются во многих местах системы, наиболее же распространенным является использование их в операциях Сценарий бизнес-процессов.

Создадим наш первый сценарий. Для этого создадим бизнес-процесс и назовем его «Калькулятор». Имя класса для работы с контекстными переменными – P_Calculator. Также желательно задать соотвествующие названия классов для метрик процесса и для экземпляра процесса. Не забывайте, что классам, переменным, методам рекомендуется давать английские названия. Использование транслитерации и названий символов русского языка нежелательно, поэтому лучше сразу приучать себя к использованию английского языка в коде программы.

В созданный процесс добавим следующие сущности:

  • динамическая зона ответственности (так, чтобы все пользователи могли запускать процесс);
  • контекстные переменные:
    • Поле ввода (InputField) – дробное число, не пустое, по умолчанию = 0;
    • Текущий результат (CurrentResult) – дробное число, не пустое, по умолчанию = 0;
  • на диаграмме процесса расположите одну пользовательскую задачу и одну операцию Сценарий. В пользовательской задаче выведите контекстные переменные:
    • Поле ввода – для редактирования;
    • Текущий результат – для чтения.

Рис. 1. Графическая модель процесса «Калькулятор»

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

Для каждого процесса создается отдельный класс, наследующий базовый класс EleWise.ELMA.Workflow.Scripts.ProcessScriptBase<Context> (где Context – это класс контекста процесса, вы можете увидеть строку using Context = EleWise.ELMA.Model.Entities.ProcessContext.P_Calculator). В этом классе методы представляют собой отдельные сценарии. В нашем случае создается пустой метод Calculate, в который передается контекст процесса context:

public void Calculate(Context context)
{

}

Для начала сложим текущее значение и то, что пользователь ввел в поле ввода:

public void Calculate(Context context)
{
context.CurrentResult = context.CurrentResult + context.InputField;
}

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

Таким образом, вы видите, что любые изменения, внесенные в контекст в операции Сценарий сохраняются автоматически.

Но это, конечно, очень простой пример. Он показывает самые базовые операции, и цель его в том, чтобы познакомить пользователя с принципом работы со сценариями.

Второй пример сценария. Работа с объектами

Наиболее интересными, конечно, являются возможности по работе с объектами системы (иногда их называют сущности). Создадим в Дизайнере ELMA свой собственный объект Питомец (Pet) (будем вести учет домашних питомцев наших клиентов) в группе Работа с клиентами. Добавим в объект следующие свойства:

  • Имя (Name) – тип Строка, обязательно для заполнения, является наименованием, отображать в таблице. Рекомендуется добавлять поле с наименованием через добавление стандартных полей в справочнике. Для этого необходимо нажать правой кнопкой мыши в область, где описаны поля объекта, и выберать в контекстном меню пункт Добавить свойства по умолчанию, но в нашем примере сделаем это вручную;
  • Вид (Kind) – тип Выпадающий список: Кошка, Собака, Попугай, Рыбка, Черепаха, Змея;
  • Возраст (Age) – тип Целое число, может иметь пустое значение;
  • Хозяин (Master) – ссылка на объект Контакт, обязательно для заполнения, отображать в таблице.

После этого сохраните и опубликуйте модель данных. Не забудьте перезапустить сервер на вкладке Публикация.

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

Далее создадим процесс, который будет создавать питомца для выбранного контакта, при этом предварительно проверяя, что у контакта еще нет питомца с таким именем. Как видите, тут требуется решить две задачи:

  1. Создание записи объекта в сценарии.
  2. Проверка на наличие записи по определенному условию.

Создание записи объекта

Для выполнения первой части нам необходимо создать процесс «Добавление нового питомца» (NewPetAdding). Создадим для данного процесса следующие контекстные переменные:

  • Контакт (Contact) – ссылка на объект Контакт, является входной;
  • Имя питомца (PetName) – тип Строка;
  • Вид питомца (PetKind) – тип Выпадающий список: Кошка, Собака, Попугай, Рыбка, Черепаха, Змея;
  • Возраст питомца (PetAge) – тип Целое число;
  • Новый питомец (NewPet) – ссылка на объект Питомец;
  • Ошибка заполнения (FillingError) – тип Строка (нужна для вывода ошибки, если не выполнено какое-то условие).

После этого расположим на графической модели процесса 2 пользовательские задачи и один сценарий.

Рис. 2. Графическая модель процесса «Добавление нового питомца»

В задаче «Ввести данные о питомце» добавим на форму задачи переменные Контакт, Имя питомца, Вид питомца, Возраст питомца, доступные для редактирования. В задаче «Проверить» выведем все переменные контекста только для чтения. Обратите внимание, что поле Имя питомца не нужно делать обязательным для заполнения, так как мы проверим его в скрипте (однако при настройке реального приложения нужно проверять обязательность заполнения этого поля еще и на форме).

Теперь перейдем к редактированию сценария. Создайте новый метод CreateNewPet и вставьте туда следуюший код:

public void CreateNewPet(Context context)
{
    //Проверяем, что переменная Контакт выбрана
    if(context.Contact == null)
    {
        context.FillingError = "Не указан Контакт";
        //Выход из скрипта
        return;
    }
    
    //Проверяем, что Имя питомца не пустое
    if(String.IsNullOrWhiteSpace(context.PetName))
    {
        context.FillingError = "Не указано Имя питомца";
        //Выход из скрипта
        return;
    }
    
    //Создаем новую запись для объекта Питомец
    var newPet = EntityManager<Pet>.Create();
    
    //Присваиваем значения из контекста
    newPet.Name = context.PetName;
    newPet.Kind = context.PetKind;
    newPet.Age = context.PetAge;
    newPet.Master = context.Contact;
    
    //Сохраняем новую запись в БД
    newPet.Save();
    
    //Присваиваем новую запись в контекст
    context.NewPet = newPet;
}

Как видите, все достаточно понятно из комментариев. Единственный момент, который нужно прояснить, – это использование класса EntityManager<Pet>.

Менеджер сущности

Существует несколько типов менеджеров сущностей. Подробнее о типах менеджеров сущностей см. в соответствующей статье.

В нашем случае мы использовали статический класс для доступа к базовому типизированному менеджеру сущности. Сам класс EntityManager<T> – типизированный, и для доступа к конкретному менеджеру мы должны указать тип объекта (в нашем случае это как раз Питомец, имя класса у него Pet). После этого можно обратиться к статическому полю Instance, которое вернет объект менеджера сущности, или вызвать статический метод Create, который создаст новый объект указанного типа (в нашем случае Питомец) без записи в базу.

Далее идет присвоение значений свойств нового объекта из контекста процесса и сохранение объекта в БД при помощи метода Save.

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

Попробуйте теперь опубликовать процесс: при этом отобразится сообщение об ошибке:

Тип «EleWise.ELMA.CRM.Models.IContact» определен в сборке, ссылка на которую отсутствует. Следует добавить ссылку на сборку «EleWise.ELMA.CRM, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null».

Давайте теперь добавим ссылку на сборку. Для этого необходимо в окне редактирования сценария справа в панели Настройки нажать кнопку Добавить — Добавить ссылку на сборку.

Рис. 3. Панель настройки. Кнопка «Добавить»

Далее в окне можно отфильтровать по имени сборки, например указать CRM в поле фильтра и после этого выбрать нужную сборку (в нашем случае это EleWise.ELMA.CRM, как указано в тексте ошибки).

Рис. 4. Диалоговое окно добавления ссылок на сборку

Вы можете добавлять ссылки на сборки системы ELMA или на глобальные сборки .NET, зарегистрированные в GAC.

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

Вы можете придумать и свой механизм обработки ошибок сценария, но это выходит за рамки данной статьи

Поиск записи по условию

Далее мы должны рассмотреть возможность поиска записи по условию и обработки результатов. Это нужно нам для проверки, что у контакта уже есть питомец с таким именем. Давайте немного обновим сценарий:

public void CreateNewPet(Context context)
{
    //Проверяем, что переменная Контакт выбрана
    if(context.Contact == null)
    {
        context.FillingError = "Не указан Контакт";
        //Выход из скрипта
        return;
    }
    
    //Проверяем, что Имя питомца не пустое
    if(String.IsNullOrWhiteSpace(context.PetName))
    {
        context.FillingError = "Не указано Имя питомца";
        //Выход из скрипта
        return;
    }
    
    //Получаем список питомцев для указанного контакта и для указанного имени (полное совпадение)
    var pets = EntityManager<Pet>.Instance.Find(p => p.Master == context.Contact && p.Name == context.PetName);
    
    //Проверяем, есть ли в коллекции хоть одна запись
    if(pets.Any())
    {
        context.FillingError = "Уже есть питомец с указанным именем";
        //Выход из скрипта
        return;
    }
    
    //Создаем новую запись для объекта Питомец
    var newPet = EntityManager<Pet>.Create();
    
    //Присваиваем значения из контекста
    newPet.Name = context.PetName;
    newPet.Kind = context.PetKind;
    newPet.Age = context.PetAge;
    newPet.Master = context.Contact;
    
    //Сохраняем новую запись в БД
    newPet.Save();
    
    //Присваиваем новую запись в контекст
    context.NewPet = newPet;
}

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

В нашем случае мы ищем все объекты типа Питомец (Pet), где поле Хозяин (Master) совпадает с переменной Контакт, и поле Имя (Name) равно переменной Имя питомца в контексте процесса. Мы можем использовать поиск по выражению, так как у нас используются только условия сравнения. Далее проверяется наличие записи в результирующей коллекции. В нашем случае, если найдется хоть одна запись удовлетворяющая условию, то нужно вывести сообщение об ошибке.

Как видите, мы решили поставленную задачу по добавлению питомца для выбранного контакта при помощи достаточно простого скрипта. Далее мы рассмотрим более сложный пример.

Третий пример сценария. Редактирование и выпадающие списки

В этом примере мы будем использовать тот же процесс и объект, что и в предыдущем, но теперь при выборе контакта мы будем выводить список питомцев пользователю на форму. Также добавим возможность прямо на форме задаче редактировать данные питомца. Для выбора питомца создадим переменную Питомец (Pet) типа Выпадающий список с возможностью ввода своих вариантов. В этот список мы будем заносить уже существующих питомцев для контакта и давать редактировать возраст, либо сразу дадим добавить питомца.

Чтобы корректно обработать все варианты (ведь процесс может быть запущен с уже указанным контактом на входе), нужно добавить еще один сценарий. Данный сценарий должен быть расположен сразу после стартового события, функцию назовем OnStartProcess:

public void OnStartProcess(Context context)
{
    FillPetDDL(context);
}
private void FillPetDDL(Context context)
{
    //Получаем настройки выпадающего списка для контекстной переменной Питомец
    var settings = (DropDownListSettings) context.GetSettingsFor(c => c.Pet);
    
    //Очищаем все элементы
    settings.Items.Clear();
    
    if(context.Contact == null)
    {
        //Если контакт не выбран - дальше ничего не делаем
        return;
    }
    
    //Находим всех питомцев, для выбранного контакта
    var pets = EntityManager<IPet>.Instance.Find(p => p.Master == context.Contact);
    
    foreach (var pet in pets)
    {
        //Добавляем питомца в выпадающий список
        settings.Items.Add(new DropDownItem(pet.Id.ToString(), pet.Name));
    }
    
    //Сохраняем настройки выпадающего списка
    settings.Save();

     //Обнуляем ранее выбранное значение переменной Питомец
    context.Pet = null;
}

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

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

public void OnPetCreateFormLoad(Context context, EleWise.ELMA.Model.Views.FormViewBuilder<Context> form)
{
    var pet = GetPet(context);
    
    if(pet != null)
    {
        //Устанавливаем признак Только для чтения на форме для свойства Вид питомца
        form.For(c => c.PetKind).ReadOnly(true);
    }
}
private Pet GetPet(Context context)
{
    if(context.Contact == null)
    {
        return null;
    }
    
    var pName = context.Pet.Value;
    if(string.IsNullOrWhiteSpace(pName))
    {
        return null;
    }
    
    var pet = EntityManager<Pet>.Instance.Find(p => p.Master == context.Contact && p.Name == pName).FirstOrDefault();
    
    return pet;
}

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

Далее нам нужно настроить поведение переменных на форме. Для этого зайдем в Настройки задачи и добавим для переменных на форме сценарии при изменении. Для переменной Контакт (функция OnContactSelect):

public void OnContactSelect(Context context, EleWise.ELMA.Model.Views.FormViewBuilder<Context> form)
{
    FillPetDDL(context);
    
    form.For(c => c.PetKind).ReadOnly(false);
    context.PetKind = null;
    context.PetAge = null;
}

и для переменной Питомец (функция OnPetSelect):

public void OnPetSelect(Context context, EleWise.ELMA.Model.Views.FormViewBuilder<Context> form)
{
    if(context.Contace == null)
    {
        return;
    }
    
    //Выбираем питомца
    var pet = GetPet(context);
    
    if(pet != null)
    {
        //Если уже сохранен в справочнике, то заполняем поля контекста
        context.PetName = pet.Name;
        context.PetAge = pet.Age;
        context.PetKind = pet.Kind;
        context.NewPet= (Pet)pet;
        
        //Запрещаем редактирование переменной Вид питомца
        form.For(c => c.PetKind).ReadOnly(true);
    }
    else
    {
        //Иначе сбрасываем на пустые значения и устанавливаем имя из выпадающего списка
        context.PetName = context.Pet.Value;
        context.PetAge = 0;
        context.PetKind = null;
        context.NewPet = null;
        
        //Разрешаем редактирование переменной Вид питомца
        form.For(c => c.PetKind).ReadOnly(false);
    }
}

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

Рис. 5. Форма задачи «Ввести данные о питомце». Автозаполнение полей при выборе питомца из выпадающего списка

Если же ввести в поле Питомец имя, которого еще нет у данного контакта, то поле Вид будет снова доступно для редактирования.

Рис. 6. Форма задачи «Ввести данные о питомце». Добавление нового питомца

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

После всех изменений нам нужно только немного переписать сценарий сохранения питомца:

public void CreateNewPet(Context context)
{
    //Проверяем, что переменная Контакт выбрана
    if(context.Contact == null)
    {
        context.FillingError = "Не указан Контакт";
        //Выход из скрипта
        return;
    }
    
    //Проверяем, что Имя питомца не пустое
    if(String.IsNullOrWhiteSpace(context.PetName))
    {
        context.FillingError = "Не указано Имя питомца";
        //Выход из скрипта
        return;
    }
    
    context.NewPet = null;
    
    //Получаем питомца для указанного контакта и для указанного имени (полное совпадение)
    var pet = GetPet(context);
    
    if(pet != null)
    {
        //Если питомец найден, присваиваем его в контекст
        context.NewPet = pet;
    }
    
    //Проверяем переменную в контексте
    if(context.NewPet == null)
    {
        //Создаем новую запись для объекта Питомец
        var newPet = EntityManager<Pet>.Create();
        
        //Присваиваем значения из контекста
        newPet.Name = context.PetName;
        newPet.Kind = context.PetKind;
        newPet.Age = context.PetAge;
        newPet.Master = context.Contact;
        
        //Сохраняем новую запись в БД
        newPet.Save();
        
        //Присваиваем новую запись в контекст
        context.NewPet = newPet;
    }
    else
    {
        //Обновляем только возраст питомца
        context.NewPet.Age = context.PetAge;
        context.NewPet.Save();
    }
}

Из изменений вы можете заметить, что теперь мы не только создаем нового питомца, но и проверяем, не существует ли уже у данного контакта питомец с таким именем. Если существует, то надо обновить только его возраст.

Что почитать дальше

Изучив эти три примера, вы уже сможете самостоятельно реализовать очень много сценариев в системе. Комбинируя сценарии на форме и сценарии между задачами, можно обрабатывать самые сложные бизнес-задачи.

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

  • Структура модели данных и менеджеры сущностей;
  • Поиск объектов в сценарии;
  • Использование сценариев «при изменении на форме»;
  • Работа с документами в сценариях;
  • Пользовательские расширения;
  • Взаимодействие с модулем CRM в сценариях;
  • Работа с процессами в сценариях.

Понравилась статья? Поделить с друзьями:
  • Сценарий развлекательной программы клоунов
  • Сценарий радуга конкурсно игровой программы
  • Сценарий процесса обработки заказа
  • Сценарий развлекательной программы искатели развлечений
  • Сценарий радуга желаний на день рождения