Всем привет!

Хочу вам кратко рассказать о продукте от Atlassian: JIRA Service Desk
Точнее, о некоторых хитростях, которые сильно улучшают удобство использования продукта, т.к. про сам плагин сейчас уже многие в курсе.

Для хитростей необходимо использовать скрипты в постфункциях, в данном случае это sil-скрипты плагина JJupin, и уметь написать и выполнить (в т.ч. из скрипта) sql-запросы к БД, где JIRA хранит свои данные. По использованию плагина кратко в другой статье: «Atlassian JIRA: настройка процесса обработки заявок с помощью плагина JJUPIN».


JIRA Service Desk


По названию вроде оно и так понятно, для чего этот плагин — для того, чтобы в JIRA реализовать функциональность службы Service Desk. Но, на мой взгляд, самое главное — это прием заявок от пользователей в более удобном и красивом дизайне, с использованием отдельного портала под конкретный проект. И неважно, службу сервисдеск вы хотите организовать или просто прием заявок в какой-то проект.

Если же выражаться точнее и шире, то плагин добавляет в JIRA следующую функциональность:
  • сам пользовательский портал, где пользователи могут создавать заявки, видеть список уже поданных заявок с краткой информацией по ним и статусами;
  • настройка пользовательского портала;
  • возможность установки значений уровней SLA на заявки с указанием условий через jql-запрос;
  • отчетность по указанным SLA;
  • очереди заявок с указанием условий отбора через jql-запрос;
  • возможность прикрутить Базу Знаний к порталу.

Использовать эту функциональность вы можете как хотите: в полной мере, для реализации приема и обработки заявок службой Service Desk, либо например только выставление уровней SLA, чтобы контролировать своевременность выполнения заявок, поданных обычными способами, либо будете использовать очереди заявок, либо просто удобство портала по приему заявок

По поводу лицензий на JSD есть тонкости: сейчас они требуются только на тех пользователей, кто будет обрабатывать заявки в проектах, в которых включен Service Desk (их называют агентами), без ограничения по количеству подающих заявки. Раньше было по количеству лицензий в JIRA и те и те.

С одной стороны, если у вас всего 2-3 человека обрабатывают заявки, поданные через портал, то это экономно. Но если у вас заявки обрабатывают много пользователей — ну например в режиме, когда все проекты подключены к JSD, принимаются заявки через портал, а обрабатывают их соответственно пользователи этих проектов/отделов, то здесь уже печаль: цена на количество агентов от 15 и выше быстро уходят в космос. Мы успели купить по старой схеме, поэтому проблем нет.

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


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

Многообразие полей информации


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

Это все хорошо, конечно: для поля «Размер» я для одного типа заявок напишу «Укажите размер диска», а для другого «Размер экрана», поле у меня будет одно, но никто не запутается при подаче заявки, что там должно быть (это простой пример для понимания.

Но проблема в том, что в конечном итоге таких очень уникальных полей для самой разной информации может быть не один десяток, а то и сотни. И даже если какие-то поля использовать для разных типов заявки, но для похожей информации, количество реальных полей в JIRA не сильно уменьшится. А теперь представьте себе бедного администратора, который должен завести эту кучу полей — причем делать это постоянно, т.к. проекты растут, добавляются и т.д. Не можете представить? Я тоже, лучше и не надо.

Но выход есть!

Он конечно с ограничениями: если вам какие-то поля (желательно большинство таких специфичных) нужны дальше только для информации и вам не надо их редактировать по отдельности (ну подали заявку, где 15 полей описывают какие-то параметры, вы их прочитали, поняли и сделали работу, больше ничего), то мы весело решаем эту проблему. Администратор нам должен до конца жизни, ему останется только изучить плагин jjupin и чуть-чуть sql, и совместно с вами уговорить руководство купить этот плагин.

Решение

  • Понимаем, какое максимальное количество и какого типа уникальных полей может быть одновременно на экране создания заявки (если что, потом добавим). Их будет десяток, ну чуть больше — сравните со списком всех уникальных полей;
  • Добавляем эти поля в JIRA в виде типа UniversalFieldString01, UniversalFieldString02, UniversalFieldMemo01 и т.д.(названия можете дать свои, главное учесть это в скрипте);
  • Добавляем все эти поля на экраны создания заявок в тех проектах, где они будут использоваться (помимо стандартных темы, описания и т.д., чтобы они у нас появились при создании заявки);
  • При настройке экрана заявки на портале добавляем эти поля в необходимом количестве для этого типа заявки (строковых столько, текстовых столько и т.д.);
  • Указываем этим полям те названия и комментарии, которые должны быть у этого типа заявки;
  • Пишем скрипт, который вызываем при создании заявки, и который из этих полей и их введенных значений составляет единый текст в виде «имя поля: значение поля» на каждой строке (ну или как угодно) и добавляет этот текст в описание заявки;
  • Отдыхаем.


Тонкости и проблемы

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

Скрипт
Итак, создаем sil-скрипт указанный ниже и вызываем его при создании заявки (этот код можно поместить в отдельный модуль в качестве функции и использовать ее вызов из других скриптов, чтобы не писать под каждый проект)
У нас JIRA работает на MS SQL Server, sql в скрипте под него, если у вас другая БД, то возможно придется немного поменять синтаксис:

    string[] flist;
    string _portalid = 1; //ID портала Service Desk, его можно найти в таблице ".._VIEWPORT", указать соответствующий проекту
    string sqlq;
    integer qty;
    integer i;
    string s;
    string sf;
    string sv;

// Внимание!!! Найдите в БД таблицу, у которой название содержит "VIEWPORT" и замените в sql-запросе в наименовании всех таблиц значение "AO_54307E_" на то, которое будет у вас

// Пишем запрос, который по указанному ID портала выдает нам все наши универсальные поля в виде списка: название поля "UniversalField..." и название поля на экране

    sqlq = " select PFF.Field_ID, PFF.Label, F.CFName ";
    sqlq = sqlq + " FROM [Jira].[dbo].[AO_54307E_VIEWPORT] P ";
	sqlq = sqlq + " join [Jira].[dbo].[AO_54307E_VIEWPORTFORM] PF on PF.ViewPort_ID = P.ID ";
	sqlq = sqlq + " join [Jira].[dbo].[AO_54307E_VIEWPORTFIELD] PFF on PFF.Form_ID = PF.ID and field_ID like '%custo%' ";
	sqlq = sqlq + " join [Jira].[dbo].[customfield] f on 'customfield_' + cast(f.ID as varchar) = PFF.Field_ID and F.CFName like 'UniversalField%' "; // Здесь мы отбираем только нам нужные поля (UniversalField....)
    sqlq = sqlq + " where P.ID = " + _portalid;
    sqlq = sqlq + " and PF.[Key] = replace('" + customfield_12700 + "', '" + project + "/', '') "; // Вместо customfield_12700 пишем "customfield_" и далее ID поля с названием "Customer Request Type" (смотреть в таблице customfield), в это поле в заявку JIRA записывает название типа экрана при создании заявки, это нам нужно для считывания названий полей, указанных на портале в настройке именно этого экрана
    
    flist = sql("jiraDS", sqlq); // jiraDS - это источник данных (datasource) к БД JIRA, в документации к jjupin есть информация по его созданию

    qty = arraySize(flist);
    i = 0;
    s = "";

    while (qty > i){
        sv = getElement(flist,i); // Берем название поля
        sf = %sv%; // Получаем его значение в заявке
        if ((indexOf(getElement(flist,i+2), "UniversalFieldDate") >= 0)) // Если поле - дата, то форматируем значение поля (название поля даты "Universal..." пишем как завели у себя)
        {
            sf = formatDate(%sv%, "dd.MM.yyyy");
        }
        if (sf != "") // Если значение не пустое, пишем в общий результат в виде "Название поля на экране портала" + перенос строки + "Значение поля" + 2 переноса (для читабельности)
        {
            s = s + getElement(flist,i+1) + ": \n" + sf + "\n\n";
        }
           
        i = i + 3;
    };
    
    if (s != "") // Если у нас хоть что-то записалось в результат, то добавляем его в описание заявки, в данном случае в начале описания, можно в конце, кому как
    {   
        if (desc != "")
        {
            s = s + "========= \n\n";
        }
        desc = s + desc;
    }

Ура, все работает!

Выглядит результат примерно так (это поле «Описание» в заявке):
Название программы:
Антивирус Касперского

Служебная необходимость:
очень надо

Имя компьютера:
komp13

=========

Добрый день!
Коллеги, просьба установить на компьютер антивирус


Честно говоря, это решение нас просто спасло от катастрофы (ну точнее, администраторов).

Все на портал!


Нет, не совсем все работает: мы теперь не хотим, чтобы все, кто угодно, делали заявки прямо через JIRA — их надо отправить на портал, там все красиво, бело и пушисто. Но как это сделать? Пиши, не пиши — обязательно найдется тот, кто будет делать заявку через JIRA и заполнит все не так (точнее, вообще ничего не заполнит, т.к. там одни UniversalField и т.д.)
С другой стороны, себе любимым надо разрешить делать заявки и напрямую, т.к… ну вы понимаете.

Решение
Решаем все тем же sil-скриптом, все там же при создании заявки, но уже используем его в виде валидатора
Дополнительно надо завести некую роль (либо использовать существующую) в проекте, в которой будут те люди, которые имеют право создавать заявки из JIRA:

if (customfield_12700 != "") // Здесь опять же вместо customfield_12700 пишем "customfield_" и далее ID поля с названием "Customer Request Type" (смотреть в таблице customfield), в это поле в заявку JIRA записывает название типа экрана при создании заявки, это нам нужно для понимания, откуда создается заявка: если там есть значение, значит из портала
{
    return true;
}

// Если напрямую из JIRA, то проверяем, содержится ли пользователь в нашей роли, и если он там - все хорошо
if (isUserInRole(currentUser(),project, "Роль для создания заявок"))
{
    return true;
}

// А если не там, то сообщаем, куда ему пойти
string s;
s = "Создание заявок стало возможно только через портал Service Desk! Пожалуйста, перейдите по ссылке: http://.... (ссылку необходимо скопировать и открыть в браузере)";

return false, "", s;


Кое-что по мелочи


Давайте представим, что вам надо завести на портале пару десятков экранов, и все они в основном с одинаковыми полями
Да даже взять один-два новых экрана
Т.е. это… надцать раз добавить по 10 полей, прописать им всем названия, комментарии, выставить порядок и обязательность
Оно конечно, можно вручную их набить от начала и до конца — и мы это делали.

Но есть способ, достаточно ускоряющий этот процесс: запустить sql-запрос, который нам сделает всю черновую работу

Итак, мы сначала создаем нужное количество экранов — со своими названиями, группами и т.д., но в поля не идем
Затем берем один экран и настраиваем на нем все поля, которые у нас будут представлены во всех экранах
Далее нам нужны будут ID этого экрана-шаблона и ID всех остальных экранов, которые мы создали. ID можно увидеть в адресной строке браузера при редактировании полей конкретного экрана.
По очереди подставляем эти ID в скрипт и запускаем. Можно через тот же sql-запрос вытащить все ID экранов и выполнить скрипт поочередно, можно вообще дописать sql-запрос так, чтобы он все сам там делал — это уже неважно. Важен пример, как легко и просто можно оперировать настройками экранов и портала сервисдеска: мы для каждого экрана добавляем в таблицу полей те поля, которые есть в экране-шаблоне и нет в этом экране, и в том порядке, как они там расположены.
Нажмите F5 после запуска запроса — и вы увидите все эти поля прямо сейчас на экране
Далее вам останется донастроить мелочи

Скрипт
Синтаксис MS SQL, также не забываем, что название таблиц плагина у вас может начинаться не на «AO_54307E_», поэтому надо его поменять в запросе
declare @form_id int, @newform_id int
set @form_id = -- подставляем ID экрана-шаблона
set @newform_id = -- подставляем ID каждого экрана, куда надо скопировать поля

INSERT INTO [Jira].[dbo].[AO_54307E_VIEWPORTFIELD]
           ([DESCRIPTION]
           ,[DISPLAYED]
           ,[FIELD_ID]
           ,[FIELD_TYPE]
           ,[FORM_ID]
           ,[LABEL]
           ,[REQUIRED]
           ,[FIELD_ORDER])
select           
           [DESCRIPTION]
           ,[DISPLAYED]
           ,[FIELD_ID]
           ,[FIELD_TYPE]
           ,@newform_id
           ,[LABEL]
           ,[REQUIRED]
           ,[FIELD_ORDER]
from	AO_54307E_VIEWPORTFIELD f
where	FORM_ID = @form_id and not exists(select 1 from AO_54307E_VIEWPORTFIELD f2 where f2.FORM_ID = @newform_id and f2.FIELD_ID = f.FIELD_ID)


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



Ну вот теперь красота!
Ну не совсем правда — картинок нет.

Возможно я что-то забыл — потом дополню.
Вопросы приветствуются, советы тоже.

Комментарии (5)


  1. kuda78
    25.08.2015 19:07
    +1

    «Вашего сына зовут drop table?»


  1. SerCe
    26.08.2015 12:25

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


    1. tygra
      26.08.2015 13:37

      Будем считать приложения Atlassian неприличными


      1. SerCe
        26.08.2015 15:14

        Да нет, для запроса данных в JIRA есть отличный поддерживаемый JQL, который идеть сквозь бизнес логику JIRA, а не лезет напрямую в базу. А через бесплатный ScriptRunner вы вполне могли добиться нужного вам поведения, написав маленьких скриптик на groovy, используя предоставленный API.
        Надежно, переносимо, безопасно.


        1. tygra
          26.08.2015 16:20

          А, понял, про что вы. :)
          Нет, не пойдет: JQL используется только для выборки списка заявок по параметрам. К служебным данным он отношения не имеет
          И боюсь API не сможет выдать данные по параметрам настройки конкретного экрана на портале сервисдеска

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

          И кстати, ScriptRunner становится платным — причем очень платным для количества лицензий начиная от 250 (http://www.adaptavist.com/w/continuing-to-develop-scriptrunner-for-jira/). Дешевле купить все плагины JJUPIN и т.д. от кеплера