====== Интеграция ADVANTA с Analytic Workspace ====== [[https://analyticworkspace.ru|Analytic Workspace]] — российская BI-система, позволяющая обрабатывать данные из разных источников и визуализировать их при помощи широкого набора встроенных инструментов. Благодаря интеграции возможно использование инструментария Analytic Workspace для построения дашбордов на основе данных из ADVANTA. Это дает дополнительные возможности для анализа данных и последующего формирования управленческих решений. Ниже приведена подробная пошаговая инструкция по организации процесса обмена данными между двумя системами. Для реализации обмена у вас должен быть доступ к по крайней мере к демо-версиям данных продуктов. ==== 1) Сформировать в ADVANTA LINQ-запросы ==== Интеграция с Analytic Workspace организована с использованием [[corporative:integration:linq|LINQ-запросов]] и [[product:api:start|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().OrderByDescending(o => o.Date).FirstOrDefault().Date, StatusReport_Chto_sdelano_problemi_riski = p.GetChildren().OrderByDescending(o => o.Date).FirstOrDefault().Chto_sdelano_problemi_riski_4a11b8, StatusReport_Prichina_problemi = p.GetChildren().OrderByDescending(o => o.Date).FirstOrDefault().Prichina_problemi_a3e564.Name, StatusReport_StatusName = p.GetChildren().OrderByDescending(o => o.Date).FirstOrDefault().Status_e05ba3.Name, BudjetSum = p.GetChildren().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(false).Where(p => p is IT_proekt_d46b6d || p is Organizacionnij_proekt_a3e2fb).FirstOrDefault().Id, // ProjectName = p.GetParentHierarchy(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().OrderByDescending(o => o.Date).FirstOrDefault().Date, StatusReport_Chto_sdelano_problemi_riski = p.GetChildren().OrderByDescending(o => o.Date).FirstOrDefault().Chto_sdelano_problemi_riski_4a11b8, StatusReport_Prichina_problemi = p.GetChildren().OrderByDescending(o => o.Date).FirstOrDefault().Prichina_problemi_a3e564.Name, StatusReport_StatusName = p.GetChildren().OrderByDescending(o => o.Date).FirstOrDefault().Status_e05ba3.Name }); return projects; Данный код запросов приведен в качестве примера. На вашей инсталяции необходимо будет указать наименования сущностей, объектов, справочников, реквизитов, соответствующих сформированному контексту LINQ-запросов. \\ ==== 2) Создать шаблоны таблиц данных в формате .xlsx ==== Данные шаблоны необходимы для формирования структуры хранения данных в AW в соответствии со структурой получаемых их ADVANTA данных. Для создания шаблона необходимо **выполнить созданный LINQ-запрос** в ADVANTA, скопировать шапку полученной таблицы в Excel и сохранить файл в формате .xlsx. {{ :product:api:integration_examples:без_имени.jpg?800 |}} \\ === Пример шаблона для источника данных по проектам === {{ :product:api:integration_examples:снимок_экрана_2024-04-22_002808.png?600 |}} \\ === Пример шаблона для источника данных по контрольным точкам === {{ :product:api:integration_examples:снимок_экрана_2024-04-22_002843.png?600 |}} \\ Загрузите данные шаблоны в Analytic Workspace, в раздел «Источники данных» — здесь необходимо **создать источник, выбрать формат «Файл» и загрузить сформированный шаблон**. {{ :product:api:integration_examples:снимок_экрана_2024-04-22_003003.png?250 |}} \\ ==== 3) Создать модель в Analytic Workspace и сформировать скрипт в ETL-редакторе ==== После создания источника необходимо в соответствующем разделе Analytic Workspace **создать модель**, которая и будет служить витриной данных для созданного источника. Необходимо создать столько же моделей, сколько предполагается использовать LINQ-запросов. {{ :product:api:integration_examples:снимок_экрана_2024-04-22_003125.png?400 |}} \\ Сразу после создания необходимо перейти в режим редактирования модели и зайти в **ETL-редактор**. {{ :product:api:integration_examples:без_имени1.jpg?800 |}} \\ В открывшемся редакторе необходимо ввести скрипт для обработки получаемых из 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 автоматически загрузятся в модель. \\ === Пример модели === {{ :product:api:integration_examples:снимок_экрана_2024-04-03_165120.png?800 |}} \\ ==== 4) Создать виджеты для отображения данных и дашборды из виджетов ==== Для реализации этих шагов необходимо ознакомиться с возможностями системы Analytic Workspace. В этом вам помогут [[https://webhelp.analyticworkspace.ru|база знаний]], [[https://analyticworkspace.ru/datacourse|обучающий курс]] и специалисты, контакты которых вы можете найти на сайте [[https://analyticworkspace.ru|Analytic Workspace]]. === Пример дашборда «Здоровье портфеля» в Analytic Workspace на основе данных, полученных из ADVANTA === {{ :product:api:integration_examples:снимок_экрана_2024-04-22_004043.png?800 |}} \\ [[https://promo.advanta-group.ru/a2nta_presentation?utm_source=wiki&utm_medium=link&utm_campaign=integrations|Оставить заявку на демонстрацию или внедрение ADVANTA]] [[https://analyticworkspace.ru|Узнать подробнее о системе Analytic Workspace]]