Проблематика
В своей работе я столкнулся с необходимостью организации задач сотрудников департамента аналитики в едином окне и построения прозрачной схемы оценки их загруженности.
Какие есть варианты?
Сравнивая различные инструменты и таскменеджеры, выбор пал на одного из популярных игроков рынка - Trello. Однако, сразу после выбора программы, возникло новое препятствие. В бесплатной версии этого приложения отсутствовала возможность синхронизации досок нескольких сотрудников воедино без сторонних сервисов, типа Zapier, где для большого проекта тоже нужна лицензия.
В чем смысл объединения?
Заходить в 5 досок и просматривать отдельно каждого, просто не хватит времени и сил.
Если не синхронизировать доски на одном экране, будет крайне сложно сравнить одного сотрудника с другим по уровню текущей нагрузки.
Сотрудники хотят понимать нагрузку каждого из членов команды, а для этого нужно опять же как то сводить все воедино.
Подобный функционал синхронизации бесплатно доступен у некоторых конкурентов, которые специализируются на agile таскменеджерах, но трелло просто был роднее, тк для личного контроля задач использую его уже несколько лет. Таким образом, для внедрения общего командного таскменеджера в работу департамента осталось решить всего одну проблему:
Как синхронизировать доски 5 сотрудников в одной доске "дашборде" и при этом не оплачивать лицензию в Трелло или передаточных сервисах типа Zapier?
Решение задачи:
К счастью для работы с досками trello уже создан полноценный пакет на языке R, который позволяет подключаться к API таскменеджера, и именно им я и решил воспользоваться для решения всех задач.
Ход решения:
Сначала получим ключи и секретный код для работы с API https://trello.com/app-key (предварительно необходимо авторизоваться под своей учеткой в Trello и открыть себе доски сотрудников с правами администратора)
![](https://habrastorage.org/getpro/habr/upload_files/7a2/6f8/dff/7a26f8dff00a2af442bb50950009baf9.png)
Сохраняем ключ и токен, который можно найти внизу этой же страницы
![](https://habrastorage.org/getpro/habr/upload_files/8c2/6e8/a72/8c26e8a72cea331fdb9102131ff7b4e6.png)
Далее установим сам язык R. Для его подключения нужно скачать и установить инсталляторы. Также для комфортной работы с R рекомендую использовать бесплатную среду разработки RStudio.
Для решения вышеописанной задачи нам потребуется установить пакеты для:
работы с API Trello — «trelloR»
работы со временем и временными периодами — «lubridate»
работы с таблицами и агрегации данных — «dplyr»
Чтобы установить пакеты из основного репозитория CRAN примените базовую функцию install.packages, а для загрузки пакетов с github функцию install_github:
remotes::install_github("jchrom/trelloR")
install.packages("lubridate", dependencies = TRUE)
install.packages("dplyr ", dependencies = TRUE)
Подключаемся к API и получаем токен:
# Указываем путь к папке куда будет сохранен полученный token
setwd("C:\\*********\\R_script\\trello")
# Получаем token
my_token = get_token("my_app", key = "", secret = "",
expiration = c( "never"))
Полученные данные применяем для того, чтобы отправить первый запрос, и пишем функцию, которая поможет упростить наш код:
trelloadd <- function(delcard = NULL,
addcard = NULL,
nlista = NULL){
# Находим исходный лист сотрудника в Трелло откуда будем брать карточки
для записи в дашборд
ishod_tab <- get_list_cards(addcard)
# Определяем доску куда пишем новые карточки
bid = get_id_board(delcard)
# Получаем все списки с листами на доске дашборда
lid <- get_board_lists(bid)$id[nlista]
# Получаем все карточки в необходимом листе куда пишем
cid<-get_list_cards(lid)
# Удаляем карточки, которые уже есть в листе сотрудника на дашборде
if (length(cid$id)>0) {
for (i in 1:length(cid$id)) {
delete_resource(resource = "card", id = cid$id[i])
}
}else{
print("no-del")
}
# Находим дату создания карточки в исходном листе
dateList<- data.frame(dateadd = NA)
for (i in 1:length(ishod_tab$id)) {
cardID <- ishod_tab$id[i]
dateList[i,1] <- strtoi(strtrim(cardID, 8), 16L)
}
dateList$dateadd <-as.POSIXct(dateList$dateadd, origin = "1970-01-01")
# Циклом собираем лист записи и создаем карточку для переноса в дашборд
if (length(ishod_tab$name)>0) {
for (i in 1:length(ishod_tab$name)) {
payload = list(
idList = lid,
name = ishod_tab$name[i],
desc = paste0(ishod_tab$desc[i],"Date Add: " ,dateList$dateadd[i], "
В работе уже ", floor(as.vector(difftime(today(),dateList$dateadd[i], units='days'))), " день"),
start = ishod_tab$start [i],
due = ishod_tab$due [i],
pos = "bottom"
)
r <- create_resource("card", body = payload)
}
}else{
print("Ok")
}
if (nrow(bind_rows(ishod_tab$labels[]))>0) {
# Добавляем лейблы (метки)
bid = get_id_board(delcard)
lid <- get_board_lists(bid)$id[nlista]
cid <-get_list_cards(lid)
# Находим карточки без меток
nlab <- which( lapply(ishod_tab$labels, length)!=0 %in% T)
for (i in nlab) {
labl <- ishod_tab$labels[[i]]
for (xi in 1:nrow(labl)) {
r <- add_label(cid$id[i], color = ishod_tab$labels[[i]][xi,4],
name = ishod_tab$labels[[i]][xi,3] )
}
}
}else{
print("no_lable")
}
}
В функции необходимо будет только заполнять переменные:
delcard - Это id дашборда в который будет записываться информация из досок сотрудников
addcard - Это id листа из которого будут браться карточки для переноса в дашборд
nlista - номер листа в дашборде в который будут заноситься карточки
Получаем delcard
Для получения id дашборда куда будем писать общие карточки, сначала необходимо создать эту доску в самом Трелло, а затем из поисковой строки браузера скопировать необходимый нам id
![Пример ссылки: https://trello.com/b/*********/общие-задачи - где значения ****** это будет Id конкретной доски Пример ссылки: https://trello.com/b/*********/общие-задачи - где значения ****** это будет Id конкретной доски](https://habrastorage.org/getpro/habr/upload_files/ffe/5b1/89e/ffe5b189ed04d914b5ae21bdf79e49fc.png)
Получаем addcard
Для того чтобы получить лист откуда будут браться исходные данные, мы точно также как с delcard копируем ссылку на доску, только теперь забираем всю ссылку целиком и используя готовую функцию извлекаем все листы на исходной доске:
get_board_lists("https://trello.com/b/*****/сотрудник1",
query = list(customFieldItems = "true")
)
В результате выполнения функции, прямо в консоли R мы получим перечень всех листов на доске и по названию листа можем выбрать необходимый нам id для получения карточек
![](https://habrastorage.org/getpro/habr/upload_files/553/b9a/554/553b9a55442219c97745a6f8d190e8aa.png)
Данную процедуру мы проделываем для досок всех наших сотрудников из досок которых мы планируем забирать карточки для переноса на дашборд.
Далее проходим доски всех сотрудников и перезаписываем их на общий дашборд используя функцию созданную выше:
# Сотрудник1 ####
trelloadd(delcard = "od*****W",
addcard = "600**********04",
nlista = 2)
# Сотрудник2 ####
trelloadd(delcard = "od*****W",
addcard = "5fc4********24",
nlista = 3)
# Сотрудник3 ####
trelloadd(delcard = "od*****W",
addcard = "5e94*********8ce",
nlista = 4)
# Сотрудник4 ####
trelloadd(delcard = "od*****W",
addcard = "5faa*********c522",
nlista = 5)
# Сотрудник5 ####
trelloadd(delcard = "od*****W",
addcard = "60744*******3394",
nlista = 6)
# Сотрудник6 ####
trelloadd(delcard = "od*****W",
addcard = "5e73******b07",
nlista = 7)
Так же я продумал вопрос, связанный с тем, чтобы получать в карточки дашборда информацию о том, когда была создана исходная карточка, чтобы можно было оценить, как долго уже решается та или иная задача (ведь дедлайны можно менять). Дата привязывается к моменту создания исходной карточки. Далее настраиваем автоматический запуск скрипта для актуализации дашборда и задаём нужное количество раз обновлений в день.
![Готовый дашборд Готовый дашборд](https://habrastorage.org/getpro/habr/upload_files/28c/7d5/bae/28c7d5bae640fbca2b4d1c763c56e1ed.jpeg)
В итоге:
Мы получили полноценную синхронизацию всех досок любого числа сотрудников в trello
Решили проблему с тем, чтобы наглядно иметь доступ к дате создания каждой задачи
Имеем фундамент для анализа продуктивности сотрудников в любых разрезах, благодаря возможности добавлять в код новые различные улучшения расширяя код на основе Api от Trello, на основе бизнес логики вашей компании и возможностей языка R.
teamfighter
Интересно, сколько человекочасов вы потратили на это решение, сколько человекочасов потратите на его поддержку и сколько бы сэкономил работодатель, если бы купил лицензию jira?
Риторический вопрос, но посчитайте как-нибудь)
ip63 Автор
1. Я дольше статью эту писал чем код для нее =)
2. Поддержка не требуется кроме случаев новых релизов APi но если и будут изменения внести правки в одну функцию не долго
3. Работодатель не потратил ни рубля на эту реализацию тк я её выполнял вне рабочего времени «интереса ради». Учитывая функционал возможных доработок на основе api, скорее всего Jira не даст такой аналитики, которую можно настроить самим.