Первый шаг – пересоздать контекст.
Операция должна выполняется для обновления внутреннего словаря объектов и их свойств, для использования в запросах изменений в настройках объектной модели системы. В противном случае новые объекты, реквизиты и изменение ранее созданных не будут доступны для запросов.
Если контекст еще никогда не создавался, то необходимо его пересоздать обязательно, иначе во внутреннем словаре данные об объектах системы будут полностью отсутствовать.
При пересоздании контекста, страница списка запросов закрашивается цветом, означающим недоступность действий и отображаются «шары ожидания».
По окончании перестроения, снимается блокировка недоступности окна, а справа вверху отображается дата и время последнего перестроения, равная текущему времени завершения операции.
Далее вы можете создать новые запросы и/или импортировать уже существующие.
Кнопка «Новый источник данных» и ссылка «Изменить» для имеющихся запросов, открывают одно и то же окно редактирования запроса.
При создании нового запроса по умолчанию подставляется шаблонный запрос. Он полезен для тех, кто редко пишет запросы, в нем определена базовая структура запроса, которую необходимо поменять для конкретного случая.
//A query sample var projects = dataContext.Projects .Where(p => p.Name != null) .OrderBy(p => p.CreationDate) .Select(p => new { p.Id, p.Name}); return projects;
Каждый запрос имеет свой UID, видимый в окне редактирования. Данный UID используется в методе API и как источник в отчетах "Электронная таблица".
Текст запроса составляется по правилам языка C#. Ввозвращаемое значение должно быть последовательностью объектов типа IQueryable, либо приводиться к нему.
Кнопка «Сделать запрос» выполняет обращение в базу и формирует запрос к СУБД, после чего отображать результат запроса в виде таблицы, представленной страницами данных, а также общее число возвращаемых строк. Справа над таблицей отображается время выполнения запроса.
В каждой колонке отображается значение из запроса.
Вернуться на страницу со списком запросов можно по ссылке «Вернуться к списку».
Составление запроса требует понимания структуры настроек базы ADVANTA, а также понимание того, как делаются запросы в LINQ.
Больше информации можно найти в открытых источниках и документации по C#.
В запросах всегда доступны 3 переменные:
dataContext
– доступ к наборам объектовparameters
– доступ к параметрам, переданным из вне, для параметризованного запросаQueryParameters.Common.BaseUrl
содержащий адрес системы. Доступ к ней возможен например по обращению parameters.GetValue<string>(QueryParameters.Common.BaseUrl)
QueryParameters.Common.PersonId
, содержащий GUID текущего пользователя, от которого выполняется запрос. Он может быть полезен, при создании отчетов типа «Я исполнитель», «Я … кто в объекте», для определения кто этот «Я». Доступ к нему возможен, например parameters.GetValue<Guid>(QueryParameters.Common.PersonId)
workCalendars
– через нее можно получить календарь объекта, или календарь по умолчанию.workCalendars.GetDefaultCalendar()
– возвращает объект Календарь по умолчаниюworkCalendars.GetWorkCalendar(projectId)
– возвращает календарь переданного объекта
Через переменную dataContext
доступны объекты:
Zadacha_c88ec2_List
;Kontakti_e15d5d_List
;Начиная с версии системы 3.29
в объект Projects добавлено новое поле, отображающее значение плановых трудозатрат (PlannedCost
) объекта иерархии.
Для действий с реквизитами, в частности типа DateTime
можно использовать библиотеку DbFunctions
.
Доступны классификаторы:
ProjectStatus
, для вывода и фильтрации объектов по статусу;ProjectMemberRole
.Рабочий календарь содержит следующие методы:
string Id
– ид календаряstring Name
– имя календаряbool IsDefault
– является ли календарь по умолчанию double WorkHoursInDay
– количество часов в рабочем дне double WorkHoursInWeek
– количество часов в неделеdouble WorkDaysInMonth
– количество рабочих дней в месяцеdouble WorkDaysInYear
– количество рабочих дней в годуDateTime AddDuration(DateTime dateTime, TimeSpan duration);
– добавить длительность к дате с учетом рабочего календаряDateTime GetDayEnd(DateTime day);
– получить конец рабочего дняDateTime GetDayStart(DateTime day);
– получить начало рабочего дняdouble GetWorktimeHours(DateTime start, DateTime end);
– получить количество часов между 2 датами с учетом рабочего календаряdouble GetWorktimeDays(DateTime start, DateTime end);
– получить количество дней между 2 датами с учетом рабочего календаря TimeSpan GetWorktimeSpan(DateTime start, DateTime end);
– получить длительность между 2 датами с учетом рабочего календаря. bool IsWorkDay(DateTime day);
– проверить является ли день рабочимКроме 3х переменных, доступны все используемые в системе классификаторы, которые генерируются как статические объекты и имеют наименования типа «Classifier_…», в котором доступны все пункты, в классификаторе, и они могут использоваться в запросах к объектам системы.
Например:
var Negotiation = dataContext.Negotiations .Where(n => n.Tip_soglasovaniya_6ecd7b.Id == Classifier_Tip_soglasovaniya_9a469d.Drugoj_57e6ea78_Id)
Перечень объектов, доступный для запросов, генерируется или обновляется при пересоздании контекста.
Для объекта общего типа Project (а также для частных), реализованы дополнительные методы для получения данных о иерархии.
public ICollection<TCustomType> GetChildren<TCustomType>()
– получение детей проекта без учета иерархииpublic TCustomType GetParent<TCustomType>()
– получение родителя, если родитель не TCustomType, то вернется nullpublic ICollection<TCustomType> GetChildrenHierarchy<TCustomType>(bool includeRoot)
– получение детей с учетом иерархии, если includeRoot, то сам проект тоже попадет в коллекцию, если он соответствующего типаpublic ICollection<TCustomType> GetParentHierarchy<TCustomType>(bool includeRoot)
– получение родителей с учетом иерархииРезультаты LINQ-запроса можно вывести в отчёт "Электронная таблица" как один из источников данных.
При выборе источников для отчёта вы также можете выбрать «linq-источник» – указать его идентификатор.
Можно указать несколько linq-источников. Каждый из них будет выгружаться на отдельный лист таблицы.
После сохранения источников данных, в табличном отчете появляются (по количеству запросов) закладки с данными из запросов. «Query1», «Query2» и т.д. по числу источников-запросов.
Дальнейшая работа отчета «Электронная таблица» никак не отличается от имеющегося функционала.
В случае, если запрос вызывается для отчета из типа объекта, то в него передаются дополнительные параметры:
QueryParameters.SpreadsheetReport.StartDate
– параметр равный началу периода в табличном отчете. Пример его использования может выглядеть примерно так: parameters.GetValueOrDefault<DateTime?>(QueryParameters.SpreadsheetReport.StartDate, DateTime.Now.AddMonths(-1));
QueryParameters.SpreadsheetReport.EndDate
– параметр равный окончанию периода в табличном отчете.QueryParameters.SpreadsheetReport.ProjectId
– параметр равный идентификатору объекта, из которого вызывается отчет. Пример его использования: parameters.GetValueOrDefault<Guid?>(QueryParameters.SpreadsheetReport.ProjectId, new Guid("ac04eda3-6940-46ae-8c8b-5c43c67a43a8"));
Готовый пример, как вписать параметры в LINQ-запрос:
var objectID = parameters.GetValueOrDefault<Guid>("RootProjectId", new Guid("27b97e72-5ffb-48bf-a405-bad7625eecc7")); var strParam = parameters.GetValueOrDefault<string>("request", ""); var projectID = parameters.GetValueOrDefault<Guid?>(QueryParameters.SpreadsheetReport.ProjectId, new Guid("27b97e72-5ffb-48bf-a405-bad7625eecc7")); var dStart = parameters.GetValueOrDefault<DateTime>(QueryParameters.SpreadsheetReport.StartDate, DateTime.Now.AddMonths(-1));
Также можно посмотреть, какие параметры были переданы (для отладки):
var paramsAsString = string.Join(", ", parameters.Select(kv => $"{kv.Key}:{kv.Value}"));
Получение Linq-запросов может выполняться от имени любого пользователя с учетом его прав. Нужно использовать CookieContainer для сохранения cookies и уже с ним делать последующие запросы к API.
Linq вызывается через стандартный интерфейс WebApi. Для этого, например в .NET, можно использовать класс HttpClient. Тело POST запросов передается в формате JSON в фигурных скобках.
Первым шагом необходимо авторизоваться, передав запрос с реквизитами подключения Пользователя системы АДВАНТА по ссылке: http://localhost/Master/api/auth/login
POST http://localhost/api/auth/login { Login:"admin", Password:"123456" }
Альтернативный способ авторизации - используя токен пользователя (для версии системы ADVANTA 3.26 и выше)
POST http://localhost/api/auth/login { tokenValue:"kjhfwi327yr92hjrhfbyugs8r384ygrhf8rifh" }
localhost
- адрес системы.
После авторизации отправляется запрос непосредственно к Linq, используя ключ источника (DataSourceKey
)
POST http://localhost/api/queries/get { DataSourceKey: "Key_of_Query", Parameters: { A: 123, B: "321" }, PageSize: 5 }
или Id LINQ-запроса (DataSourceId
)
POST http://localhost/api/queries/get { DataSourceId: "54d198c3-bbd9-4812-9143-76c632a80e44", Parameters: { A: 123, B: "321" }, PageSize: 20 }
Parameters
- передаваемые в LINQ-запрос параметры (необязательное), а PageSize
- максимальное количество первых по порядку возвращаемых из запроса записей (необязательное, но если не указано - всегда возвращаются только первые 10 записей из результатов выполнения запроса).
Обращение к данным системы с текстом LINQ-запроса (Text
) непосредственно в вызове метода
POST http://localhost/api/queries/get { Text: 'var a = (long)parameters["A"]; var b = parameters.GetValue<string>("B"); return dataContext.Zadacha_2b33fa_List .Select(z => new { z.Name });', Parameters: { A: 123, B: "321" }, PageSize: 100 }
$baseAddress = New-Object -TypeName Uri -ArgumentList $urlA2 $cookieContainer = New-Object -TypeName System.Net.CookieContainer $handler = New-Object -TypeName System.Net.Http.HttpClientHandler $handler.CookieContainer = $cookieContainer $client = New-Object -TypeName System.Net.Http.HttpClient -ArgumentList $handler $client.BaseAddress = $baseAddress $encoding = [System.Text.Encoding]::GetEncoding("utf-8") # Авторизация $auth = @{ 'Login' = $login; 'Password' = $password) } | ConvertTo-Json $authResponse = $client.PostAsync( [string]::Join('/', $urlA2, "api/auth/login"), (New-Object -TypeName System.Net.Http.StringContent -ArgumentList $auth, $encoding,"application/json")) # Запрос $query = @{ 'DataSourceId' = $DataSourceId 'PageSize' = 1000 } | ConvertTo-Json $queryResponse = $client.PostAsync( [string]::Join('/', $urlA2, "api/queries/get"), (New-Object -TypeName System.Net.Http.StringContent -ArgumentList $query, $encoding,"application/json")) $queryResponseResult = $queryResponse.Result.Content.ReadAsStringAsync() # Результат Linq запроса $result = $queryResponseResult.Result | ConvertFrom-Json
в файле Python-скрипта обязательно используйте utf-8 кодировку!
import requests # укажите свои параметры авторизации и адрес размещения системы LOGIN = 'xxxxx' PASSWORD = 'xxxxx' # используйте либо логин-пароль, либо токен # TOKEN = 'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx' # при необходимости, указывайте протокол https в строке с реальным адресом домена системы. # после адреса домена может быть указан еще и каталог размещения системы на домене (например, https://domain.example.ru/Master ) DOMAIN = 'http://xxxxx' session = requests.Session() # авторизация response = session.post( url = DOMAIN + '/api/auth/login', json = { 'Login': LOGIN, 'Password': PASSWORD, }, ) # либо авторизуйтесь, используя токен доступа # response = session.post( # url = DOMAIN + '/api/auth/login', # json = { # 'tokenValue': TOKEN, # }, # ) # сохранение полученных после авторизации cookies для последующих запросов cookies = session.cookies.get_dict() # параметры для обращения к LINQ-запросу (может быть больше, см. выше) LINQ = { 'DataSourceId': "6b7c0388-a249-4d39-9cb6-xxxxxxxxxxx", # id LINQ-запроса в системе ADVANTA 'PageSize': 100, # максимальное количество возвращаемых записей } # получение данных из LINQ-запроса response = session.post( url = DOMAIN + '/api/queries/get', cookies = cookies, json = LINQ, ) data = response.json()