Добрый день,

Задал фильтр по Дате = Текущая неделя.
Смотрю что в БД по фильтру в CustContractFolder
Запрос такой:

SELECT
        [CustContract].[Id] [Id]
FROM
        [dbo].[CustContract] [CustContract]
WHERE
        ([CustContract].[Number] = N'92319851'
        AND ([CustContract].[ModifiedOn] >= CONVERT(DATETIME, '2017-06-25 21:00:00.000', 121)
        AND [CustContract].[ModifiedOn] CONVERT(DATETIME, '2017-07-02 21:00:00.000', 121)))

Почему время до 21:00 только?
Подскажите это настраивается?

Нравится

15 комментариев

Укажите пожалуйста версию продукат.

Время до 21 — из-за того, что на сервере время по Гринвичу. Когда у них 21:00 — у Вас полночь и конец недели.

Возможно, настраивается путём смены времени на сервере, но реально текущая реализация должна фильтровать верно. Нужно только помнить о расхождении при написании напрямую SQL-запросов.

Спасибо. С временем понятно.

Заметили еще такую странность при фильтре по дате: даты в БД не обновляются.
Например сейчас хоть фильтр стоит в GUI пред. неделя, а даты по прежнему старые

AND ([CustContract].[ModifiedOn] >= CONVERT(DATETIME, '2017-06-25 21:00:00.000', 121)
AND [CustContract].[ModifiedOn] < CONVERT(DATETIME, '2017-07-02 21:00:00.000', 121)))

Это стандартное поведение фильтров по датам?

Антон, в смысле, не обновляется?
Может, страница раздела не перезагружалась с прошлой недели?

Страница раздела была обновлена, был новый вход. Открыт фильтр http://www.community.terrasoft.ru/system/files/2017-06-30_1531.png, условия фильтра не менялись, не сохранялись.

В БД же запрос прежний и даты прежние как 30.06

AND ([CustContract].[ModifiedOn] >= CONVERT(DATETIME, '2017-06-25 21:00:00.000', 121)
AND [CustContract].[ModifiedOn] < CONVERT(DATETIME, '2017-07-02 21:00:00.000', 121)))

я ожидал что будет вида '2017-07-02 21:00:00.000' по '2017-07-09 21:00:00.000', т.е. как в GUI предыдущая неделя.

После того как в фильтре нажал сохранить, в бд запрос обновился и стал отбирать как ожидается. Можно как то программно через БД инициировать "сохранить" по всем группам?

Фильтр должен быть по текущей неделе, никаких дополнительных действий не требуется.
Возможно, в системе что-то закешировалось и нужно очистить Redis.

IIS APP остановил, редис почистил.
Все равно в БД по прежнему старый запрос.
В ГУИ BPMOnline фильтр работает верно, но в БД по другому.
Если нажимаю сохранить в фильтре, то в БД запрос обновляется на корректный.

"Антон Сидоров" написал:В ГУИ BPMOnline фильтр работает верно

В таком случае ничего менять не нужно.

Проблема в том, что у нас реализован функционал генерации активностей по группам договоров на уровне БД (делали Вы(Террасофт) при внедрении проекта), т.е. из за этого по не верным договорам создаются активности.
Бизнес смотрит в ГУИ и ожидает, что по займам будут активности, в реальности оказывается фильтр берется из БД по другим фильтрам дат.

Поэтому и интересует вопрос это нормальное поведение BPMOnline?
Можно как то программно через БД инициировать "сохранить" по всем группам, для актуализации запросов и в БД?

Если есть какие-то доработки, то дело может быть в них. Лучше связаться с авторами проекта.

По фильтру Текущая неделя еще вопрос:
В БД записывается такой запрос при создании сегодня.

SELECT
	[CustContract].[Id] [Id]
FROM
	[dbo].[CustContract] [CustContract]
WHERE
	([CustContract].[Number] = N'92319851'
	AND ([CustContract].[ModifiedOn] >= CONVERT(DATETIME, '2017-07-23 21:00:00.000', 121)
	AND [CustContract].[ModifiedOn] < CONVERT(DATETIME, '2017-07-30 21:00:00.000', 121)))

т.е. в БД все верно с учетом часового пояса сервера +3.
Если ставлю дату на сервере 30.07.17 13:41.
Через интерфейс BPM не отображается (см. вложение), в БД - ок.

30.07.17 ещё не настало. У Вас часы идут неправильно.

Я время вперед перевел на сервере специально, чтобы наступление Воскресенья сэмулировать.

Вероятно, логика системы не рассчитана на такое необычное поведение часов.

Показать все комментарии

Добрый день,
Можете подсказать назначение параметра appSettings RequestTimeout в web.config?
На что он влияет?

Нравится

2 комментария

Здравствуйте, Антон.

Данный параметр содержит значение времени ожидания ответа от сервера Active Directory при синхронизации с LDAP. При отправке запроса от bpm'online на сервер AD по умолчанию время ожидания ответа составляет 120 секунд.

Спасибо!

Показать все комментарии

Добрый день
В карточке е-мейл-активности есть поле Контакт.Активность. Подскажите, пожста, как "вытащить" значение поля Е-мейл из карточки этого Контакта? Заранее спасибо

Нравится

1 комментарий

Добрый день, Татьяна!

Для получения емейла можно воспользоваться механизмом esq:
https://academy.terrasoft.ru/documents/technic-sdk/7-9/ispolzovanie-ent…
Вам необходимо выбрать Email у Contact, отфильтров по Id контакта.

Показать все комментарии

Добрый день.
В БП по сигналу мне бы хотелось, чтобы открывалась страница реестра Взаимосвязей.
Каким образом мне правильно сделать, чтобы туда передавался контакт в ContactAId и я могла создавать там новые записи при нажатии на кнопку "Добавить"?

Нравится

9 комментариев

Здравствуйте!

Для решения необходимо использовать элемент "Преднастроенная страница". Элемент описан по ссылке:
http://www.community.terrasoft.ru/img/video/lms/28/story.html

Также данная тема обсуждалась в других ветках:
http://www.community.terrasoft.ru/forum/topic/25237

Здравствуйте.
Элемент бизнес-процесса "Преднастроенная страница" есть в 7ке, у нас же 5ка и такого элемента для работы с БП нет. Нужна другая реализация данной задачи.

Антонина, в 5.Х есть возможность добавить в процесс элемент-действие, в действии указать «Открыть страницу». Нужные значения передать в параметрах, а их обработку написать в процессе самой страницы.

Я так и пытаюсь сделать. Меня интересует в каком именно параметре нужно передавать значение ContactAId.
вот пример кода:

var ReportSchemaUId = "56a4f892-df6b-4dac-99ad-762f56553035";//Базовая страница реестра взаимосвязей
var EntitySchemaUId = "8409eced-ba37-4a6a-a031-671fcb7be3e2";
 
Guid ContactId = ReadDataUserTask2.ResultEntity.GetTypedColumnValue<Guid>("ContactId");
RelationUserTask.OpenerInstanceId = InstanceUId;
RelationUserTask.PageUId =  new Guid("56a4f892-df6b-4dac-99ad-762f56553035");
var parameters =  
      new Dictionary<string, string> {
            {"ContactAId", ContactId.ToString()},
			{"DataSourceUId", EntitySchemaUId.ToString()},
			{"TreeGridId", EntitySchemaUId.ToString()}//,
      };
 
RelationUserTask.PageParameters = parameters;
 
RelationUserTask.Centered = true;
RelationUserTask.CloseOpenerOnLoad = false;
 
var SelectedActiveRows = new List<Guid>();
SelectedActiveRows.Add(new Guid(DocumentId.ToString()));
 
var selectedRows = new Dictionary<string, object>();
selectedRows.Add("Item1", "Contact");
selectedRows.Add("Item2", "Id");
selectedRows.Add("Item3", SelectedActiveRows);
UserConnection.SessionData[EntitySchemaUId.ToString() + "_SelectedActiveRows"] = selectedRows;

В каком угодно, это зависит от реализации.
Главное, внутри его потом вычитать и использовать в логике страницы.
Для примера посмотрите, как из AccountEditPage в DuplicatesSearchResultModulePage передаются DuplicateSchemaId и ещё несколько параметров.

OpenDuplicatesSearchResultsUserTask.OpenerInstanceId = Page.Process.InstanceUId;
OpenDuplicatesSearchResultsUserTask.PageUId = duplicateSearchResultsPageUId;
OpenDuplicatesSearchResultsUserTask.UseCurrentActivePage = true;
OpenDuplicatesSearchResultsUserTask.PageParameters = new Dictionary<string, string>() {
	{"SchemaId", SearchForDuplicatesUserTask.SchemaId.ToString()},
	{"DuplicateSchemaId", SearchForDuplicatesUserTask.DuplicateSchemaId.ToString()},	
	{"EditPageId", SearchForDuplicatesUserTask.EditPageId.ToString()},
	{"RecordId", SearchForDuplicatesUserTask.RecordId.ToString()},
	{"DataKey", DataKey}
};
OpenDuplicatesSearchResultsUserTask.CloseMessage = "DuplicateResultsPageClosed";
		public virtual bool ChildInitScriptTaskExecute(ProcessExecutingContext context) {
			if (!Ext.IsAjaxRequest) {
	(Page.AspPage as UI.Core.Page).InitializeProfile(new ProfileKeyEventArgs());
	SchemaId = Guid.Parse(Page.GetParameterValue("SchemaId").ToString());
	DuplicateSchemaId = Guid.Parse(Page.GetParameterValue("DuplicateSchemaId").ToString());	
	EditPageId = Guid.Parse(Page.GetParameterValue("EditPageId").ToString());
	RecordId = Guid.Parse(Page.GetParameterValue("RecordId").ToString());
	DataKey = Page.GetParameterValue("DataKey").ToString();	
	Page.Grid.PageInstance.Process.SetPropertyValue("SchemaId", SchemaId);
	Page.Grid.PageInstance.Process.SetPropertyValue("DuplicateSchemaId", DuplicateSchemaId);	
	Page.Grid.PageInstance.Process.SetPropertyValue("EditPageUId", EditPageId);
	Page.Grid.PageInstance.Process.SetPropertyValue("DataKey", DataKey);
	Page.Grid.PageInstance.Process.SetPropertyValue("RecordId", RecordId);
}
return true;
		}

Александр, добрый день.
При нажатии на кнопку запускаю БП.
В БП написала такой код и открываю страницу:

var ReportSchemaUId = "56a4f892-df6b-4dac-99ad-762f56553035";//Базовая страница реестра взаимосвязей
var EntitySchemaUId = "533e9db5-b10c-44a9-bbef-168af653d2d5";//Взаимосвязь
var openerInstanceId = "8409eced-ba37-4a6a-a031-671fcb7be3e2";//Взаимосвязь (представление)
 
var EntitySchema = UserConnection.EntitySchemaManager.GetInstanceByName("Relationship");
Guid ContactId = ReadDataUserTask2.ResultEntity.GetTypedColumnValue<Guid>("ContactId");
 
var parameters = new Dictionary<string, string> {
    {"openerInstanceId", EntitySchemaUId},
	{"contactAId", ContactId.ToString()}
};
RelationUserTask.PageParameters = parameters;
Guid clientDocumentGridPageUId = new Guid("56a4f892-df6b-4dac-99ad-762f56553035");
RelationUserTask.PageUId = clientDocumentGridPageUId;
RelationUserTask.Centered = true;
RelationUserTask.CloseOpenerOnLoad = false;

Далее на Базовой странице реестра взаимосвязей добавила код на событие PageLoadComplete:

			Page.TreeGrid.Clear();
 
				  try
            {
			Guid contactAId = Guid.Parse(Page.Request.QueryString["contactAId"]);
			Guid sysSchemaEntity = Guid.Parse(Page.Request.QueryString["openerInstanceId"]);			
 
			Page.Label1.Caption=contactAId.ToString();
                var opportunityFilter = Page.DataSource.CurrentStructure.CreateIsNullFilter(Page.DataSource.Schema, "ContactA");
                Page.DataSource.CurrentStructure.Filters.Add(opportunityFilter);
                    var applicationFilter = Page.DataSource.CurrentStructure.CreateFilterWithParameters(Page.DataSource.Schema, FilterComparisonType.Equal,
                    "ContactA", contactAId);
                    Page.DataSource.CurrentStructure.Filters.Add(applicationFilter);                          
            }
            catch
            {
 
            }
            Page.DataSource.LoadRows();
           Page.TreeGrid.RefreshData();

Что получилось:
При нажатии на кнопку открывается страница реестра взаимосвязей.
Далее нажимаю на ней на кнопку Добавить - Контакт и тут происходит свал системы.

Exception Message: Object reference not set to an instance of an object.
Exception Type: System.NullReferenceException
Exception Source: TSBpm
 
Exception Stack Trace:
   at Terrasoft.WebApp.BaseRelationshipEditPageEventsProcess`1.ScriptTask1Execute(ProcessExecutingContext context)
   at Terrasoft.Core.Process.ProcessScriptTask.InternalExecute(ProcessExecutingContext context)
   at Terrasoft.Core.Process.ProcessFlowElement.Execute(ProcessExecutingContext context)

Что я не доделала или сделала не так? Как исправить?

Где-то внутри ScriptTask1Execute в функцию вместо объекта попадает null. Нужно отлаживаться, чтобы понять, где именно.

Я посмотрела не хватает для полноценной работы параметров:

var ParentEntityId = Guid.Parse(Page.Request.QueryString["ParentEntityId"]);
var MainEntitySchemaId = Guid.Parse(Page.Request.QueryString["MainEntitySchemaId"]);
var ParentEntitySchemaId = Guid.Parse(Page.Request.QueryString["ParentEntitySchemaId"]);

В БП я их определила и передаю, на странице реестра взаимосвязей они тоже подхватываются.
А как передать их на страницу редактирования взаимосвязи?

Тоже через параметры. При стандартной логике кнопки «Добавить» и «Изменить» на странице реестра открывают окна-карточки при помощи JS, формируемого в функции GetRegisterAddPageScript и ей подобных.

Показать все комментарии

Использую действие Добавление данных (AddDataUserTask1)
Мне нужно создать активность по клиенту типа SMS (в допустимых действиях только Задача, Звонок и E-mail)

var Body = (string)SysSettings.GetValue(UserConnection, "RKO_OpeningAccount");
Guid SchemaId = new Guid("C449D832-A4CC-4B01-B9D5-8A12C42A9F89");
var DefValues= new Dictionary
        string, object>();
DefValues.Add("Recepient", Phone);
DefValues.Add("MsgSubject", "Информирование об открытии счета");
DefValues.Add("Body", Body);
DefValues.Add("StartDate", DateTime.Now);
DefValues.Add("DueDate", DateTime.Now);
DefValues.Add("OwnerId", "410006E1-CA4E-4502-A9EC-E54D922D2C00");//Петр Петрович Петров
DefValues.Add("AuthorId", "410006E1-CA4E-4502-A9EC-E54D922D2C00");//Петр Петрович Петров
DefValues.Add("StatusId", "4BDBB88F-58E6-DF11-971B-001D60E938C6");//Завершена
DefValues.Add("DetailedResult", "Cмс отправлено");
DefValues.Add("ContactId", Contact);
DefValues.Add("AccountId", Account);
DefValues.Add("EmployeeFolder", Otdelenie);
DefValues.Add("LeadId", LeadId);

AddDataUserTask1.EntitySchemaId = SchemaId;
AddDataUserTask1.RecordDefValues = DefValues;

return true;

Выходит ошибка : Неявное преобразование типа "System.Collections.Generic.Dictionary" в "Terrasoft.Core.Process.EntityColumnMappingValues" невозможно

Нравится

5 комментариев

Если Вы хотите просто создать в скрипте новую активность с нужными значениями полей, а потом сохранить в базу с отработкой всей логики на объекте, то можно воспользоваться методами Entity. См., например, как это сделано:

var communication = new Activity(userConnection);
				communication.SetDefColumnValues();
				if (isEmail) {
					communication.Title = (string)Terrasoft.Core.Configuration.SysSettings.GetValue(userConnection, "EmailTypeCommunicationPrintingFormText");
				} else if (isImmidiateProcessing) {
					communication.StatusId = ActivityConsts.CompletedStatusUId;
					communication.Title = "Коммуникация по обработке на месте" ;
				} else {
					communication.Title = "Коммуникация с письменным ответом";
				}
				communication.Commentary = serviceRequestEntity.GetTypedColumnValue<string>(shortDescColumn.Name);
				if(isEmail) {
					var contactEmail = serviceRequestEntity.GetTypedColumnValue<string>(emailColumnName.Name);
					if (!string.IsNullOrEmpty(contactEmail)) {
						communication.Recepient = string.Format("{0} <{1}>; ", serviceRequestEntity.GetTypedColumnValue<string>(contactNameColumn.Name), contactEmail);
					}
					communication.HtmlBody = communication.Title; 
				} else if(isSms) {
					communication.Recepient = serviceRequestEntity.GetTypedColumnValue<string>(contactPhoneColumn.Name);
				}
				communication.ContactId = serviceRequestEntity.GetTypedColumnValue<Guid>(contactIdColumn.Name);
				communication.TypeId = activityTypeId;
				communication.ActivityCategoryId = ActivityConsts.ToDoCategoryUId;
				communication.MessageTypeId = ActivityConsts.OutgoingEmailtypeUId;
				communication.ServiceCallId = recordUId;
				communication.Save();

Александр, я поступила по-другому - создала новый процесс на добавление данных и передаю туда данные из основного событийного подпроцесса.
Есть вопросы по поводу сериализациии в БД - для чего она нужна и везде ли она нужна?

При добавление в событийный подпроцесс процесса по добавлению данных получена ошибка: Элемент "CreatedSMS" не может быть сериализован в БД, т.к. не сериализуется процесс.
Методом перебора вариантов получилось сохранить страницу только после того, как в процессе по добавлению данных убрала галочку «сериализовать в БД», все сохранилось и работает.
НО! Мне нужно в основной событийный подпроцесс после создания объекта добавить еще один процесс (старый, написан не мной) и опять такая же проблема: Элемент "SendSmsProcess" не может быть сериализован в БД, т.к. не сериализуется процесс.

Сериализация элемента процесса в БД нужна для того, чтобы после перерыва в выполнении процесса (например, пока пользователь не выполнит задачу) в нём хранились те же значения, что и до.

Могу ли я убрать из старого процесса галочку сериализации? Или как мне лучше всего поступить?

Анастасия, это зависит от конкретного процесса.
Уточните у того, кто его делал.

Показать все комментарии

Коллеги, добрый день! На дев площадке добавили колонки в разделы Контрагенты, Конфигурации и Обращения. После добавления разделы отображались корректно. После фиксации изменений, обновления пакета из хранилища на прод площадку и последующей компиляции конфигурации, разделы Конфигурации и Обращения стали отображаться некорректно. В разделе Конфигурации при открытии существующей записи отображается окно новой записи: https://yadi.sk/d/kHsdJtiL3Gg3Wd , в консоли появляются следующие ошибки https://yadi.sk/d/sXIPRxkn3Gg3eF,приложение ругается на новые колонки (Недопустимое имя столбца) В разделе Обращения при открытии записи не отображается номер обращения https://yadi.sk/d/JuO8WvQ63Gg3sq в консоли также появляются аналогичные ошибки из-за созданных колонок https://yadi.sk/d/slVgPRYq3Gg3z3 Есть способ лечения ошибок с помощью удаления этих колонок с помощью мастера раздела и из конфигурации, последующей фиксации изменений в хранилище и переносе обратно на дев площадку, но это неправильно. Также после обновления пакета из хранилища, возникает ошибка для пользовательского бизнес процесса https://yadi.sk/d/gn6EsdX33Gg6zc
Какова природа данной проблемы?

Нравится

6 комментариев

Я, конечно, не разработчик, но в почему всё в пакете Custom? Его же, вроде, нельзя корректно перенести.

"Сидоров Александр Валерьевич" написал:всё в пакете Custom?

Разве? всё вроде как в пакете WS_FirstOfd
"Голикова Елена Евгеньевна" написал:Какова природа данной проблемы?

Вы только компилировали? Или делали все 5 шагов? (генерация-компиляция-данные-скрипты-обновление структур)?

"Варфоломеев Данила" написал:Разве? всё вроде как в пакете WS_FirstOfd

Да, Вы правы. На этом скрине мне показалось, что открыт пакет Custom https://yadi.sk/d/gn6EsdX33Gg6zc

"Варфоломеев Данила" написал:
Сидоров Александр Валерьевич пишет:

всё в пакете Custom?

Разве? всё вроде как в пакете WS_FirstOfd

Голикова Елена Евгеньевна пишет:

Какова природа данной проблемы?

Вы только компилировали? Или делали все 5 шагов? (генерация-компиляция-данные-скрипты-обновление структур)?


Делала обновление структур БД, компиляцию, генерацию всех исходных кодов. Результат тот же. В тех поддержке отклонили обращение по SLA

Здравствуйте!

Ответ на вопрос "Какова природа данной проблемы?" - различие между тестовой средой и продуктовой среда, на прод вносятся изменения на прямую миную тест.

Выполните следующие рекомендации:

  • Убедитесь в корректности зависимостей пакетов и их соответствие между тест и прод средой
  • Откройте все объекты участвующие в разделе, убедитесь, что все поля заполнены корректно, после чего пересохраните и опубликуйте. Все возникшие конфликты устраните
  • Переоткройте каждую схему/модуль раздела и пересохраните/скомпилируйте
  • Откройте процесс и выполните его пересохранение, возникшие ошибки устраните

Не забудьте все исправления внести тестовую среду.

Обратите внимание на системную настройку SchemaNamePrefix на прод среде, она должна совпадать с настройкой на тест среде.

"Терещук Павел" написал:

Здравствуйте!

Ответ на вопрос "Какова природа данной проблемы?" - различие между тестовой средой и продуктовой среда, на прод вносятся изменения на прямую миную тест.

Выполните следующие рекомендации:

  • Убедитесь в корректности зависимостей пакетов и их соответствие между тест и прод средой
  • Откройте все объекты участвующие в разделе, убедитесь, что все поля заполнены корректно, после чего пересохраните и опубликуйте. Все возникшие конфликты устраните
  • Переоткройте каждую схему/модуль раздела и пересохраните/скомпилируйте
  • Откройте процесс и выполните его пересохранение, возникшие ошибки устраните

Не забудьте все исправления внести тестовую среду.

Обратите внимание на системную настройку SchemaNamePrefix на прод среде, она должна совпадать с настройкой на тест среде.


Помогла пошаговая компиляция и сохранение всех объектов и схем. Префиксы названий объектов были настроены на обоих площадках корректно. Спасибо

Показать все комментарии

Может кто сталкивался. Прошу прокомментировать или помочь

5 версия Сервис деск.

В реестре, для всех ролей, кроме "системный администратор" появляются надписи нет доступа>.
На самом деле, доступ к объектам, колонкам и всему, что только возможно - предоставлен группе "Все сотрудники".

Снятие администрирования к колонкам и прочему - ни к чему не приводит. куки и редис - чистили.
Странно, что эта надпись не появляется для полей с типом "справочник". Б
Буду очень благодарна :)

Нравится

15 комментариев

Марина, судя по скриншоту, это какой-то новый или значительно переработанный раздел. Возможно, в нём работа с администрированием по записям не предусматривалась или специально ограничена.
Лучше обратиться к тем, кто его разработали, и уточнить по работе этого механизма для указанного раздела.

Нашла что-то подобное, но предложенный вариант не сработал
http://www.community.terrasoft.ru/forum/topic/9817

В стандартном разделе контактов таких полей нет. Возможно, все эти поля пустые в базе и таким образом отображаются в окне. По ссылке выше дан ряд рекомендаций, в том числе пересоздание колонок и перезапуск пула.

Александр, это не новый раздел.
Это я сама создала новое окно, куда вывела отфильтрованные данные из объекта Контакты
там, где есть значения в карточке раздела КОНТАКТЫ- они отображаются. Если значения отсутствуют, то пишется - нет доступа
Например, Имя и Фамилия - есть в карточках. они отображаются в окне
А поле Отчество - не отображается. Хотя я могу войти в карточку Контакта и внести Отчество.

не поняла: в КОНТАКТАХ нет Фамилия, имя, отчество?

Поля Тип, серия, номер - это поля паспотра - ест старый паспорт и новый(если замуж кто вышел. Я создала эти поля в карточке Контакта (и деталь есть)

Нет, в коробке есть единое поле ФИО. Возможно, новые поля создавались после раздачи прав и для них что-то не раздалось.

Вот как раз у меня вопрос: что не раздалось? если войдя в карточку КОНТАКТЫ, я могу всё редактировать.
Александр, это вот Вы зачем мне написали, что что-то не раздалось, хотя у меня был вопрос: коллеги, что могло не раздаться?

Могли не раздаться права доступа по полям.
Вы можете редактировать, поскольку у системных администраторов есть доступ ко всему.

"Милова Марина Федоровна" написал:На самом деле, доступ к объектам, колонкам и всему, что только возможно - предоставлен группе "Все сотрудники".

Отображаемые значения могут не соответствовать реальности, если колонки добавлялись позже.

так в результате, где искать деффект?

К сожалению, поскольку это окно, колонки и прочее не являются стандартными, по одному скриншоту сложно понять причину такого поведения.
Вы можете провести отладку и посмотреть, что реально находится в полях Entity текущей строки реестра при работе под администратором и под пользователем.

Марина, попробуйте в администрировании объекта КОНТАКТЫ раздать права по данным колонкам для конкретной роли, а также дать полный доступ к записям.

Дмитрий, спасибо.
Всё получилось

Показать все комментарии

Помогите сделать запрос функции SQL из Исходного кода c возможностью записи результата и дальнейшим его использованием.

В sql запрос выглядит так :

SELECT  dbo.fn_dateadd_work ('minute', 20, defValues)

 

Нравится

16 комментариев

Функцию с одним возвращаемым значением можно запустить так:

string number = "12345";
using (DBExecutor dbExecutor = userConnection.EnsureDBConnection()) {
	UserDefinedFunction userDefinedFunction = new UserDefinedFunction(userConnection, "fn_GetPhoneNumberSearchForm")
		.WithParameter("SourcePhoneNumber", number) as UserDefinedFunction;
	userDefinedFunction.PackageName = userConnection.DBEngine.SystemPackageName;
	userDefinedFunction.ReturnType = UserDefinedFunctionReturnType.Scalar;
	searchNumber = userDefinedFunction.ExecuteScalar<string>(dbExecutor);
}

Если же функция возвращает много значений:

using (DBExecutor dbExecutor = userConnection.EnsureDBConnection()) {
				UserDefinedFunction userDefinedFunction = new UserDefinedFunction(userConnection, "fn_GetFreeIntervalsForContactToDeadline")
					.WithParameter("ContactId", ContactId)
					.WithParameter("CalendarId", calendarId)
					.WithParameter("FromDate", userConnection.CurrentUser.GetCurrentDateTime())
					.WithParameter("Deadline", deadLineDate.ToString("yyyy-MM-dd HH:mm:ss"))
					.WithParameter("Offset", userConnection.CurrentUser.TimeZone.BaseUtcOffset.TotalMinutes) as UserDefinedFunction;
 
				userDefinedFunction.PackageName = userConnection.DBEngine.SystemPackageName;
				userDefinedFunction.ReturnType = UserDefinedFunctionReturnType.Table;
				using(IDataReader dataReader = userDefinedFunction.ExecuteReader(dbExecutor)) {
					while (dataReader.Read()) {
						DateTime startDate = dataReader.GetColumnValue<DateTime>("StartDate");
						DateTime endDate = dataReader.GetColumnValue<DateTime>("EndDate");
						//...
					}
				}
			}
string datepart = "day";
var defValues3 = "";
var defValues5 = "";
 
using (DBExecutor dbExecutor = userConnection.EnsureDBConnection()) {
                    UserDefinedFunction userDefinedFunction = new UserDefinedFunction(userConnection, "fn_dateadd_work ")
                            .WithParameter("datepart", datepart) 
            				.WithParameter("number", 3)
            				.WithParameter("date", defValues.StartDate)as UserDefinedFunction;
                    userDefinedFunction.PackageName = userConnection.DBEngine.SystemPackageName;
                    userDefinedFunction.ReturnType = UserDefinedFunctionReturnType.Scalar;
                    defValues3 = userDefinedFunction.ExecuteScalar<string>(dbExecutor);
            }
 

Выдает ошибку:
Exception Message: Не удалось найти столбец "dbo", определяемую пользователем функцию или агрегатную функцию "dbo.fn_dateadd_work ". Также возможно, имя является неоднозначным.
Exception Type: System.Data.SqlClient.SqlException
Exception Source: .Net SqlClient Data Provider

Функция Скалярная

Это значит, что такой функции у Вас в базе нет. Возможно, дело в пробеле в конце.

"Зверев Александр" написал:

Это значит, что такой функции у Вас в базе нет. Возможно, дело в пробеле в конце.

			string datepart = "day";
			var defValues3 = "";
			var defValues5 = "";
            using (DBExecutor dbExecutor = userConnection.EnsureDBConnection()) {
            UserDefinedFunction userDefinedFunction = new UserDefinedFunction(userConnection, "fn_dateadd_work")
                .WithParameter("datepart", datepart) 
				.WithParameter("number", 3)
				.WithParameter("date", defValues.StartDate)as UserDefinedFunction;
            userDefinedFunction.PackageName = userConnection.DBEngine.SystemPackageName;
            userDefinedFunction.ReturnType = UserDefinedFunctionReturnType.Scalar;
            defValues3 = userDefinedFunction.ExecuteScalar<string>(dbExecutor);
			}

Убарала пробел, ошибка та же. Функция в Бд есть.
В инете пишут, что возможно фн табличная и к ней так и нужно обращаться...
http://www.cyberforum.ru/sql-server/thread735489.html

Может, на функцию нет прав на запуск у пользователя, который прописан в конфиге ConnectionStrings.
Посмотрите в SQL-профайлере, какие запросы уходят и попробуйте запустить такие же вручную.

"Зверев Александр" написал:

Может, на функцию нет прав на запуск у пользователя, который прописан в конфиге ConnectionStrings.

Посмотрите в SQL-профайлере, какие запросы уходят и попробуйте запустить такие же вручную.


Спасибо, проблема в правах.

А можно как то в исходном коде реализовать такой вызов функции:

select * from dbo.fn_SomeFunctionName()  where someColumnName>2

Руслан, если через UserDefinedFunction такое нельзя, можно воспользоваться CustomQuery.

Хорошо, а через Select можно? Если да то как?

Пробовал так, не работает.

var select = (Select)new Select(_userConnection)
    .Column("Id")
    .From("fn_GetContactDescendantRoles")
    .Where("level")
    .IsEqual(Column.Parameter(1));
select.Parameters.Add("contact", new Guid("40445C52-FFD1-4DBA-94D8-127A7B29806A"));
select.Parameters.Add("parentRole", new Guid("CFB6F756-B740-44AD-A221-80C5E441EBF4"));

Выходит ошибка:

System.Data.SqlClient.SqlException: "Параметры функции "dbo.fn_GetContactDescendantRoles" не были предоставлены."

Руслан, я имел в виду не Select, а CustomQuery.

В Вашей попытке через Select, вероятно, это получаются параметры не функции, а всего запроса (как при запросе на выборку из обычной таблицы). Проверить можно, сгенерировав перед выполнением текст запроса при помощи GetSqlText().

Зверев Александр,

Я понял что вы имели ввиду, но мне не хочется делать приложение жестко привязанным к базе данных MSSQL. Ожидаю что использование класса Select оставит приложение "кроссплатформенным". Поэтому предположил что можно использовать Select как при обычном обращении к таблице, т.к. функция возвращает таблицу.

Руслан, в справке написано:

Класс Terrasoft.Core.DB.Select предназначен для построения запросов выборки записей из таблиц базы данных. 

Для работы с  функциями используют другой класс, UserDefinedFunction . Для произвольных запросов — CustomQuery.

Зверев Александр,

Это все замечательно. Но в sql существует возможность выполнения такой конструкции:

select * from dbo.fn_SomeFunctionName()  where someColumnName&gt;2

Вы сказали что это не предусмотрено в классе UserDefinedFunction. Конечно моя функция не возвращает +100500 записей и можно было просто пробежаться по нужным в цикле, но я хочу задать условие на стороне сервера, чтобы он вернул только нужные по условию where. Вроде мелочь, но если количество запросов будет большое, то и сетевой трафик вырастет. В общем я за оптимизацию. Есть ли возможность в будущем расширить функционал данного класса?

В SQL можно и drop database выполнить. Возможность есть (но для этого нужно иметь доступ к исходникам ядра системы), больше вопрос, есть ли востребованность. Обходной вариант я предложил. Думаю, написать три строчки вызова для разных БД и получив ConnectionString (например, как тут в комментарии) выбрать нужную проще, чем вносить изменения в классы ядра.

Завёл идею, но не уверен, что до неё скоро доберутся.

Спасибо, Александр, за идею. Согласен что доберутся не скоро, но пусть будет, надеюсь это будет полезно еще кому-нибудь. По поводу получения строки соединения тоже спасибо, интересная возможность. 

Показать все комментарии

Добрый день.
Подскажите пожалуйста как в 5 версии системы отправить письмо с прикрепленными файлами из БП.
Интересует именно как прикрепить к письму файлы?
В БП использую элементы(действия) "Добавление данных", затем "Действие процесса"(Отправить сообщение), в котором указываю Id созданной ранее записи.
Таким образом письмо отправляется на почту. А как туда еще и файлы прикрепить?

Нравится

3 комментария

Антонина, действие «Отправить сообщение» должно уметь отправлять письмо со вложениями. Оно берёт файлы из таблицы детали «ActivityFile», привязанные к этой активности. См. функцию «GetActivityAttachments» внутри действия.

А чтобы прикрепить файлы на эту деталь, нужно выполнить код, аналогичный функции «CopyFiltes» со страницы «EmailEditPage». Ещё один пример, где прикрепляется сгенерированный файл отчёта, приведен здесь, но этот код под 7.Х, могут быть некоторые отличия.

То есть Вы создаёте в БП новую активность типа «email», сохраняете её, добавляете ей на деталь файлы, а затем вызываете действие отправки.

А если мне нужно отправить файлы которые не прикреплены к активности, а прикреплены например к заявкам? Вроде бы как дублировать эти файлы в активности не хотелось бы.

Текущая логика берёт файлы с детали у активности. В принципе, если критично место в базе, можно как-то доработать логику функции «GetActivityAttachments» действия «Отправить сообщение», чтобы оно при определённых условиях брало содержимое файлов из другого места.

Ещё один возможный подход: реально в БД в таблице «ActivityFile» (и ей подобных) хранится только ссылка на активность и ссылка на общую таблицу файлов всех разделов, куда попадают название, размер, содержимое файла. Можно попробовать у записи о файле в другом разделе брать значение «FileId» и подставлять в новую запись о файле активности. Но при этом потребуются переделки в структуре таблицы, подобные тем, что описаны в этой теме, поскольку сейчас Id файла — первичный ключ.

Показать все комментарии

Столкнулся со следующей проблемой в BPMOnline ServiceDesk 5.4:
- Необходимо в Аналитике сделать ПОЧАСОВОЙ график регистрации инцидентов.

Но при настройке графика для поля "Дата/время" предлагается только форматы "Год, Месяц, Неделя, День". Соответственно вопрос каким образом добавить формат "Час"??

Нравится

1 комментарий

Решил проблему сам путем добавления в объект SysDateTimeFormat следующей строчки:

insert into SysDateTimeFormat(Name,Code) values('Час','Hour')

Показать все комментарии