ADVANTA — российская информационная система управления портфелями, программами, проектами, мероприятиями и задачами. Готовая проектная ERP-система, которая покрывает все процессы проектного управления, автоматизирует работу всех участников проектной деятельности, позволяет планировать и контролировать ресурсы проектов.
Интеграция ADVANTA с Analytic Workspace открывает новые горизонты для анализа данных и принятия решений. Синергия 2 систем позволяет строить дашборды в AW BI на основе данных из ADVANTA.
Важно! Для реализации обмена у вас должен быть доступ, по крайней мере, к демо-версиям данных продуктов.
Подробно расскажем, как организовать обмен данными между ADVANTA и Analytic Workspace.
1) Сформировать в ADVANTA LINQ-запросы
Интеграция с Analytic Workspace организована с использование LINQ-запросов и Web-API ADVANTA. Таким образом, для того, чтобы загрузить данные в BI-систему, необходимо предварительно сформировать LINQ-запросы внутри ADVANTA для получения тех данных, которые в дальнейшем будут визуализированы.
Пример LINQ-запроса данных по проектам
Интеграция ADVANTA с Analytic Workspace открывает новые горизонты для анализа данных и принятия решений. Синергия 2 систем позволяет строить дашборды в AW BI на основе данных из ADVANTA.
Важно! Для реализации обмена у вас должен быть доступ, по крайней мере, к демо-версиям данных продуктов.
Подробно расскажем, как организовать обмен данными между ADVANTA и Analytic Workspace.
1) Сформировать в ADVANTA LINQ-запросы
Интеграция с Analytic Workspace организована с использование LINQ-запросов и Web-API ADVANTA. Таким образом, для того, чтобы загрузить данные в BI-систему, необходимо предварительно сформировать LINQ-запросы внутри ADVANTA для получения тех данных, которые в дальнейшем будут визуализированы.
Пример LINQ-запроса данных по проектам
/* 1. перечень всех проектов (2 типа объектов - ИТ-проект и Организационный проект)
с UID и всеми системными реквизитами (сроки начала/завершения - план, факт, ответственные (ФИО), статус (текстом), последний базовый план)
- объект-родитель (название)
и пользовательскими реквизитами:
- жизненный цикл проекта
- описание
- масштаб проекта (текстовое значение)
- эффект
- последняя запись из справочника "Отчет о статусе" - все поля
- активная запись из справочника "Бюджет проекта" - только поле "Бюджет (план)"
*/
var projects = dataContext.Projects
.Where(p => p is IT_proekt_d46b6d || p is Organizacionnij_proekt_a3e2fb)
.OrderBy(p => p.CreationDate)
.Select(p => new { p.Id,
p.Name, ParentName = p.Parent.Name,
LifeCycleName = p.Fields.Zhiznennij_cikl_proekta_b07f57.Name,
p.SystemStartDate, p.SystemEndDate, p.ActualStartDate, p.ActualEndDate,
p.BaselinePlanStartDate, p.BaselinePlanEndDate,
BossFIO = String.Concat( p.Owner.LastName, " ", p.Owner.FirstName), RPFIO = String.Concat( p.Responsible.LastName, " ", p.Responsible.FirstName),
Description = p.Fields.Opisanie_caaaaa,
ProjectScaleName = p.Fields.Masshtab_proekta_04412f.Name,
ProjectGainName = p.Fields.Effekt_b6c145.Name,
StatusReport_Date = p.GetChildren<Otchet_o_statuse_440616>().OrderByDescending(o => o.Date).FirstOrDefault().Date,
StatusReport_Chto_sdelano_problemi_riski = p.GetChildren<Otchet_o_statuse_440616>().OrderByDescending(o => o.Date).FirstOrDefault().Chto_sdelano_problemi_riski_4a11b8,
StatusReport_Prichina_problemi = p.GetChildren<Otchet_o_statuse_440616>().OrderByDescending(o => o.Date).FirstOrDefault().Prichina_problemi_a3e564.Name,
StatusReport_StatusName = p.GetChildren<Otchet_o_statuse_440616>().OrderByDescending(o => o.Date).FirstOrDefault().Status_e05ba3.Name,
BudjetSum = p.GetChildren<Byudzhet_plan_e5bee7>().Where(b => b.Aktivnostj_versii_281a38.Id == Classifier_Aktivnostj_versii_625508.Aktivnaya_4f5ba775_Id).Sum(b => b.Summa_06ff93)
});
return projects;
Пример LINQ-запроса данных по контрольным точкам
/*
2. перечень всех контрольных точек (1 тип объекта - КТ0)
с UID и всеми системными реквизитами (как и у проекта),
- UID - проекта-родителя (непрямой родитель)
и пользовательские поля:
- описание (текст)
- результат (текст)
- последняя запись из справочника "Отчет о мероприятии" - все поля
*/
var projects = dataContext.KT0_1ff431_List
.Select(p => new {
p.Id,
p.Name,
ProjectId = (Guid?)p.GetParentHierarchy<Project>(false).Where(p => p is IT_proekt_d46b6d || p is Organizacionnij_proekt_a3e2fb).FirstOrDefault().Id,
// ProjectName = p.GetParentHierarchy<Project>(false).Where(p => p is IT_proekt_d46b6d || p is Organizacionnij_proekt_a3e2fb).FirstOrDefault().Name,
p.SystemStartDate, p.SystemEndDate, p.ActualStartDate, p.ActualEndDate,
p.BaselinePlanStartDate, p.BaselinePlanEndDate,
BossFIO = String.Concat( p.Owner.LastName, " ", p.Owner.FirstName), RPFIO = String.Concat( p.Responsible.LastName, " ", p.Responsible.FirstName),
Description = p.Opisanie_caaaaa,
Result = p.Rezuljtat_8e716f,
StatusReport_Date = p.GetChildren<Otchet_o_statuse_meropriyatiya_2bc942>().OrderByDescending(o => o.Date).FirstOrDefault().Date,
StatusReport_Chto_sdelano_problemi_riski = p.GetChildren<Otchet_o_statuse_meropriyatiya_2bc942>().OrderByDescending(o => o.Date).FirstOrDefault().Chto_sdelano_problemi_riski_4a11b8,
StatusReport_Prichina_problemi = p.GetChildren<Otchet_o_statuse_meropriyatiya_2bc942>().OrderByDescending(o => o.Date).FirstOrDefault().Prichina_problemi_a3e564.Name,
StatusReport_StatusName = p.GetChildren<Otchet_o_statuse_meropriyatiya_2bc942>().OrderByDescending(o => o.Date).FirstOrDefault().Status_e05ba3.Name
});
return projects;
Данный код запросов приведен в качестве примера. На вашей инсталляции необходимо будет указать наименования сущностей, объектов, справочников, реквизитов, соответствующих сформированному контексту LINQ-запросов.
2) Создать шаблоны таблиц данных в формате .xlsx
Данные шаблоны необходимы для формирования структуры хранения данных в AW BI в соответствии со структурой получаемых их ADVANTA данных.
Для создания шаблона необходимо выполнить созданный LINQ-запрос в ADVANTA, скопировать шапку полученной таблицы в Excel и сохранить файл в формате .xlsx.
Данные шаблоны необходимы для формирования структуры хранения данных в AW BI в соответствии со структурой получаемых их ADVANTA данных.
Для создания шаблона необходимо выполнить созданный LINQ-запрос в ADVANTA, скопировать шапку полученной таблицы в Excel и сохранить файл в формате .xlsx.
Пример шаблона для источника данных по проектам
Пример шаблона для источника данных по контрольным точкам
Загрузите данные шаблоны в Analytic Workspace, в раздел «Источники данных» — здесь необходимо создать источник, выбрать формат «Файл» и загрузить сформированный шаблон.
3) Создать модель в Analytic Workspace и сформировать скрипт в ETL-редакторе
После создания источника необходимо в соответствующем разделе Analytic Workspace создать модель, которая и будет служить витриной данных для созданного источника. Необходимо создать столько же моделей, сколько предполагается использовать LINQ-запросов.
После создания источника необходимо в соответствующем разделе Analytic Workspace создать модель, которая и будет служить витриной данных для созданного источника. Необходимо создать столько же моделей, сколько предполагается использовать LINQ-запросов.
Сразу после создания необходимо перейти в режим редактирования модели и зайти в ETL-редактор.
В открывшемся редакторе необходимо ввести скрипт для обработки получаемых из ADVANTA данных. Скрипт написан на Python.
Пример скрипта для проектов
Пример скрипта для проектов
# -----------------------------------------------------------------------------------
# Cкрипт для обработки модели * * *
# -----------------------------------------------------------------------------------
import requests
import datetime
from pyspark.sql import Row
# python - m pip install requests, matplotlib, pandas
from pandas import json_normalize
def after_all(df, spark, app, *args, **kwargs):
print(df.schema)
LOGIN = '* * *'
PASSWORD = '* * *'
DOMAIN = 'https://* * *.ru'
AUTH = {
'Login': LOGIN,
'Password': PASSWORD,
}
session = requests.Session()
# cookies = session.cookies.get_dict() # {}
# авторизация
response = session.post(url=DOMAIN+'/api/auth/login', json=AUTH, verify=False)
cookies = session.cookies.get_dict()
# print(cookies)
# получение LINQ-запроса
LINQ = {
'DataSourceKey': 'BI_projects',
# нужен другой запрос для перечня проектов в модель list1
# 'DataSourceKey': 'BI_projects',
# и еще один для перечня КТ из этих проектов в модель list1_ywrq
# 'DataSourceKey': 'BI_milestones',
'PageSize': 100,
}
r = session.post(url=DOMAIN+'/api/queries/get', cookies=cookies, json=LINQ, verify=False)
if not r.ok:
raise Exception(f'Ошибка в {r.url}. HTTP {r.status_code}: {r.text}')
data = r.json()
#Создадим список, который послужит основной для создания DataFrame
rows = []
for line in data:
rows.append(Row(
id=line['Id'],
name=line['Name'],
parentname=line['ParentName'],
lifecyclename=line['LifeCycleName'],
# systemstartdate=str(datetime.datetime.fromisoformat(line['SystemStartDate']).replace(tzinfo=datetime.timezone.utc)),
# systemenddate=str(datetime.datetime.fromisoformat(line['SystemEndDate']).replace(tzinfo=datetime.timezone.utc)),
# actualstartdate=str(datetime.datetime.fromisoformat(line['ActualStartDate']).replace(tzinfo=datetime.timezone.utc)),
# actualenddate=str(datetime.datetime.fromisoformat(line['ActualEndDate']).replace(tzinfo=datetime.timezone.utc)),
# baselineplanstartdate=str(datetime.datetime.fromisoformat(line['BaselinePlanStartDate']).replace(tzinfo=datetime.timezone.utc)),
# baselineplanenddate=str(datetime.datetime.fromisoformat(line['BaselinePlanEndDate']).replace(tzinfo=datetime.timezone.utc)),
systemstartdate=line['SystemStartDate'],
systemenddate=line['SystemEndDate'],
actualstartdate=line['ActualStartDate'],
actualenddate=line['ActualEndDate'],
baselineplanstartdate=line['BaselinePlanStartDate'],
baselineplanenddate=line['BaselinePlanEndDate'],
bossfio=line['BossFIO'],
rpfio=line['RPFIO'],
description=line['Description'],
projectscalename=line['ProjectScaleName'],
projectgainname=line['ProjectGainName'],
# statusreport_date=str(datetime.datetime.fromisoformat(line['StatusReport_Date']).replace(tzinfo=datetime.timezone.utc)),
statusreport_date=line['StatusReport_Date'],
statusreport_chto_sdelano_problemi_riski=line['StatusReport_Chto_sdelano_problemi_riski'],
statusreport_prichina_problemi=line['StatusReport_Prichina_problemi'],
statusreport_statusname=line['StatusReport_StatusName'],
budjetsum=line['BudjetSum']
))
return spark.createDataFrame(rows)
Пример скрипта для контрольных точек
# # -----------------------------------------------------------------------------------
# Cкрипт для обработки модели * * *
# -----------------------------------------------------------------------------------
import requests
import datetime
from pyspark.sql import Row
from pandas import json_normalize
def after_all(df, spark, app, *args, **kwargs):
LOGIN = '* * *'
PASSWORD = '* * *'
DOMAIN = 'https://* * *.ru'
AUTH = {
'Login': LOGIN,
'Password': PASSWORD,
}
session = requests.Session()
# cookies = session.cookies.get_dict() # {}
# авторизация
response = session.post(url=DOMAIN+'/api/auth/login', json=AUTH, verify=False)
cookies = session.cookies.get_dict()
# print(cookies)
# получение LINQ-запроса
LINQ = {
'DataSourceKey': 'BI_milestones',
'PageSize': 1000,
}
r = session.post(url=DOMAIN+'/api/queries/get', cookies=cookies, json=LINQ, verify=False)
if not r.ok:
raise Exception(f'Ошибка в {r.url}. HTTP {r.status_code}: {r.text}')
data = r.json()
#Создадим список, который послужит основной для создания DataFrame
rows = []
for line in data:
print(line)
rows.append(Row(
id=line['Id'],
name=line['Name'],
projectid=line['ProjectId'],
systemstartdate=line['SystemStartDate'],
systemenddate=line['SystemEndDate'],
actualstartdate=line['ActualStartDate'],
actualenddate=line['ActualEndDate'],
baselineplanstartdate=line['BaselinePlanStartDate'],
baselineplanenddate=line['BaselinePlanEndDate'],
bossfio=line['BossFIO'],
rpfio=line['RPFIO'],
description=line['Description'],
result=line['Result'],
statusreport_date=line['StatusReport_Date'],
statusreport_chto_sdelano_problemi_riski=line['StatusReport_Chto_sdelano_problemi_riski'],
statusreport_prichina_problemi=line['StatusReport_Prichina_problemi'],
statusreport_statusname=line['StatusReport_StatusName']
))
return spark.createDataFrame(rows)
Символами * * * в примерах скриптов обозначены автоматически формируемые данные (например, номер модели) или данные, имеющие отношение к конкретной учетной записи в ADVANTA (например, логин, пароль и домен).
Затем необходимо опубликовать скрипт и обновить модель. После обновления данные из ADVANTA автоматически загрузятся в модель.
Пример модели
Пример модели
4) Создать виджеты для отображения данных и дашборды из виджетов
Если у вас остались вопросы по реализации данного процесса или любые другие, вы можете задать их в нашем Telegram-сообществе AW.community.
Пример дашборда «Здоровье портфеля» в Analytic Workspace на основе данных, полученных из ADVANTA.
Если у вас остались вопросы по реализации данного процесса или любые другие, вы можете задать их в нашем Telegram-сообществе AW.community.
Пример дашборда «Здоровье портфеля» в Analytic Workspace на основе данных, полученных из ADVANTA.