воскресенье, 7 апреля 2019 г.

Суммирование времени из подзадач и его конвертация в 8-часовой рабочий день

Попробую описать задачу, которую мне довелось решать. 
Допустим, у нас есть какая-то "главная задача". Которая подразумевает в себе наличие подзадач и дополнительно - другие связанные задачи, которые тоже будут считаться "дочерними". 
Примерная структура будет выглядеть так: 
Главная задача (User Story) →
--------------------------------- Other task
--------------------------------- BA Sub-task
--------------------------------- BA2 Sub-task
--------------------------------- UI Sub-task
--------------------------------- DEV Sub-task
В каждой из этих задач и подзадач планируется время. Что подразумевает наличие: Original Estimate \ Remaining Estimate \ Time Spent
А моя задача состоит в том, чтобы это время суммировать и выводить в кастомные поля на экране главной задачи US
Поскольку мне требовались расчеты реального времени - я решил использовать аддон от CPRIME: PCFU (Power Custom Field Premium) и производить расчеты средствами SIL
Но столкнулся с некоторыми сложностями, о которых ниже.


Если кто-то не знаком с этим аддоном, то в двух словах я объясню принцип. 
Вы создаете поле PCFU - SIL которое выглядит как обычный Custom field - только значение вы заполняете SIL скриптом. Возвращая нужное вам значение. Значение может быть любым доступной переменной (строка\число\интервал\дата\булевое выражение)
И тут начинается самое интересное...
В полях Original Estimate \ Remaining Estimate \ Time Spent содержатся миллисекунды, которые в последствии, конвертируются внутренними средствами JIRA и приводятся в указанный вами формат рабочего времени. 
Например, если вы укажете, что у вас 8-ми часовой рабочий день, то фактические 16 часов времени - у вас будут отображаться как 2d 
А если получить значение этого поля в скрипте - вы увидите миллисекунды. В данном случае: 57600000 (это 16h)
И вот когда мы соберем с необходимых задач\подзадач это время - мы получим X-миллисекунд. И вернув это в интервальное значение - получим визуальное отображение, которое нам совсем не подходит. Таким образом, 57600000 у нас будут отображаться, как 16h. Но мы ведь понимаем, что такого в нашей компании быть не может. У нас 8ми часовой рабочий день. Поэтому нам необходимо, чтобы отображалось как 2d. Вот как это сделать - мы разберем чуть ниже. А пока я покажу пример того, как собрать все время из необходимых подзадач.

Суммируем время из подзадач

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
//Получаем список подзадач в текущей US
string [] sUS = subtasks(key); // общий массив подзадач
//необходимо разделить подзадачи на BA DEV UI
string [] sUSBA;
for(string it in sUS)
    {
        //runnerLog("Тип задачи: " + %it%.issueType);
        //runnerLog(it);
        if(%it%.issueType == "BA task")
            {
                sUSBA = addElement(sUSBA, it);
            }
    }
//Суммируем необходимые значения подзадач BA US
interval BAsummSusOE; //Original Estimate
for(string bas in sUSBA)
    {
        BAsummSusOE += %bas%.originalEstimate;
    }
//Суммируем US + BA
interval summUSBAoe;
summUSBAoe += %key%.originalEstimate + BAsummSusOE;
//Вернем в поле полученные мс (реальные)
return summUSBAoe;
В примере выше - я суммировал время для подзадач issueType: BA task и "главной задачей" User Story. 
И на выходе (в поле, которое я закрепил на экране View у типа задачи User Story - мы увидим интервальный тип времени. Который будет отображаться в виде: 1d15h30m (для примера)
А теперь возвращаемся к тому вопросу, что в нашем рабочем времени не может быть 15h. Да и 1d (как на примере выше) - это 24h - а 24h в нашем рабочем времени - это 3d а не 1d. 
Как же привести это в нужный вид, с учетом нашего рабочего времени. 

Конвертация времени в 8 часовой рабочий день

Для этого напишем функцию, в отдельный файл, следующего содержания: 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
//Функция предназначена для преобразования реального времени в 8-часовой формат и дальнейшей его конвертации в 24 часа, для корректного отображения
function convertTime (interval ri)
    {
        number n = ri;
        n = n / 1000;
         
        number w = n / (5*8*60*60);
        //округляем полученное значение до целого числа. исключаем то, что после запятой следующей функцией:
        w = floor(w, 1);
        number d = n % (5*8*60*60) / (8*60*60);
        d = floor(d, 1);
        number h = n % (8*60*60) / (60*60);
        h = floor(h, 1);
        number m = n % (60*60) / 60;
        m = floor(m, 1);
        //а теперь умножаем полученные данные на реальные значения обычных 24-часовых суток
        //1w = 604800000ms
        //1d =  86400000ms
        //1h =   3600000ms
        //1m =     60000ms
        interval need = (w*604800000)+(d*86400000)+(h*3600000)+(m*60000);
        return need;
    }
Обращаясь в  эту функцию - мы будем получать нужное нам кол-во мс, для отображения времени в нашем 8ми часовом формате рабочего дня. 
Для этого, скорректируем наши поля следующим образом
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
include "functions/convertRealTimeto8hworkday.sil";
//Получаем список подзадач в текущей US
string [] sUS = subtasks(key); // общий массив подзадач
//необходимо разделить подзадачи на BA DEV UI
string [] sUSBA;
for(string it in sUS)
    {
        //runnerLog("Тип задачи: " + %it%.issueType);
        //runnerLog(it);
        if(%it%.issueType == "BA task")
            {
                sUSBA = addElement(sUSBA, it);
            }
    }
//Суммируем необходимые значения подзадач BA US
interval BAsummSusOE; //Original Estimate
for(string bas in sUSBA)
    {
        BAsummSusOE += %bas%.originalEstimate;
    }
//Суммируем US + BA
interval summUSBAoe;
summUSBAoe += %key%.originalEstimate + BAsummSusOE;
/*
//рабочий вариант получения кол-ва часов
number n = summUSBAoe / 1000;
number h = n % (5*8*60*60) / (60*60);
string sh = h;
sh += "h";
return sh;
*/
interval ri = convertTime(summUSBAoe);
return ri;
Т.е. нам первой строкой необходимо было подключить нашу функцию. А в конце файла - обратиться к ней и вернуть в поле уже конвертированное значение
Важно!

Важно понимать. Что по факту, в поле будет находится большое, несоответствующее реальности кол-во мс. И сделано это лишь для того, чтобы мы видели корректное отображение. То, которое нам требуется. 
Поэтому, в дальнейшем, с этими цифрами работать нельзя. Они созданы ТОЛЬКО ДЛЯ ВИЗУАЛЬНОГО ПРЕДСТАВЛЕНИЯ!

Комментариев нет:

Отправить комментарий