бизнес-процесс
веб-сервис
7.11
sales

Запускаю из сервиса БП, в котором нет никаких ожиданий.

UserConnection 	userConnection	= HttpContext.Current.Session["UserConnection"] as UserConnection;
var 			manager 		= userConnection.ProcessSchemaManager;
var 			processSchema 	= manager.GetInstanceByName("UsrProcess");
var 			process 		= processSchema.CreateProcess(userConnection);

process.SetPropertyValue("ExternalCall", true);
process.Execute(userConnection);

Подскажите, как дождаться завершения БП и прочитать параметры, которые мы имеем в конце выполнения?

Нравится

8 комментариев
Лучший ответ

Добрый день!

Данное действие синхронно, т.е. после завершения операции process.Execute(userConnection); уже можно забирать параметры.

Забирать их следующим образом (пример):

res.Success = process.GetPropertyValue("RpSuccess") != null ? (bool)process.GetPropertyValue("RpSuccess") : false;
res.ErrorDescription = process.GetPropertyValue("RpReturnMsg") != null ? (string)process.GetPropertyValue("RpReturnMsg") : "";

 

Добрый день!

Данное действие синхронно, т.е. после завершения операции process.Execute(userConnection); уже можно забирать параметры.

Забирать их следующим образом (пример):

res.Success = process.GetPropertyValue("RpSuccess") != null ? (bool)process.GetPropertyValue("RpSuccess") : false;
res.ErrorDescription = process.GetPropertyValue("RpReturnMsg") != null ? (string)process.GetPropertyValue("RpReturnMsg") : "";

 

Я бы еще добавил проверку что БП завершен а не свалилися например с ошибкой или еще выполняется, примерно так. 

if (process.Status != ProcessStatus.Running && process.Status != ProcessStatus.Error)

or

if (process.Status == Terrasoft.Core.Process.ProcessStatus.Done)

Как выяснилось, мне нужен интерпретируемый процесс, а там все немного по-другому, а именно

UserConnection 	userConnection	= HttpContext.Current.Session["UserConnection"] as UserConnection;
var manager 		= userConnection.ProcessSchemaManager;
var processSchema 	= manager.GetInstanceByName("UsrPreCreateDealProcess");
var flowEngine 		= new Terrasoft.Core.Process.FlowEngine(userConnection);
Dictionary<string, object> parameter = new Dictionary<string, object>();
parameter.Add("CarId", car_id);
Terrasoft.Core.Process.ProcessDescriptor pd = flowEngine.RunProcess(processSchema, parameter);
if (pd.ProcessStatus == Terrasoft.Core.Process.ProcessStatus.Done)
{
	?????
}

Как вытащить параметры в конце выполнения здесь?

Есть предположение, что копать стоит в сторону FlowEngineStateService, у него есть метод FindProcessComponentSet(Guid processUId), который возвращает инфу о процессе. И там уже забрать параметры

Сидоров Александр В.,

я нашел этот класс, у него есть метод GetParameterValue, но он стабильно возвращает, что параметр не найден по данному пути и возникает (философский) вопрос, что есть Путь? Видимо, это не просто имя. Но товарищи из Террасофта не догадались описать этот момент нигде ни разу.

перепробовал всё с FlowEngineStateService - ничего не работает, написал в ТП

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

ТП ответила, что решения в 7.11 нет. Я так и знал :)) и заранее сделал обходной путь через БД. Заодно полезное для отладки логирование получилось

Показать все комментарии
sandbox
подписка
7.13_()
sales

Доброго времени суток. Имеется раздел "Аукцион" , создал действие "Заполнить участников", при нажатии на кнопку добавляются в детали "Участники" записи определенным отбором. Дело в том что уже заполненный реестра детали отображается только при обновлении страницы. Похоже нужно использовать механизм сообщений  ? Подскажите пожалуйста как сделать так, чтобы без  без обновления страницы данные сразу высвечивались?

Нравится

2 комментария
Лучший ответ

Добрый день!

Деталь можно обновить следующим кодом:

this.updateDetail({detail: "DetailName"});

 

Добрый день!

Деталь можно обновить следующим кодом:

this.updateDetail({detail: "DetailName"});

 

Сидоров Александр В.,

Спасибо, добавил reloadAll: true и заработало)

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

Доброго времени суток, подскажите пожалуйста, как можно задать время выполнения веб-сервиса со сторона JavaScript?



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

Вызываю обычный сервис так:

ServiceHelper.callService("ServiceName", "ServiceMethodPost", function(response) {
	window.console.log(response);
}, serviceData, this);

 

Нравится

5 комментариев
Лучший ответ

Сериков Асхат Кайратович,

Данный вариант правильный

var config = {
		serviceName: "ServiceName",
		timeout: 100000
	};
var serviceData = {
	phoneNumber: phoneNumber ? phoneNumber : "",
	userName: contact.displayValue,
	email: email ? email : ""
};
ServiceHelper.callService(config, "ServiceMethodPost",  function(response) {
	window.console.log(response);
}, serviceData, this);

Логика ServiceHelper выглядит так:

define("ServiceHelper", ["ext-base", "terrasoft"], function(Ext, Terrasoft) {

	/**
	 * ######## ##### ###-#######.
	 * @param {String|Object} config ### ####### ### ######### ###### #######.
	 * @param {String} methodName ### ######.
	 * @param {Function} callback (optional) ####### ######### ######.
	 * @param {Object} data (optional) ###### # ####### #######.
	 * @param {Object} scope (optional) ######## ######.
	 * @return {Object} ######### #######.
	 */
	function internalCallService(config, methodName, callback, data, scope) {
		var serviceName;
		if (config && Ext.isObject(config)) {
			serviceName = config.serviceName;
			methodName = config.methodName;
			callback = config.callback;
			data = config.data;
			scope = config.scope;
		} else {
			serviceName = config;
		}
		var dataSend = data || {};
		var workspaceBaseUrl = Terrasoft.utils.uri.getConfigurationWebServiceBaseUrl();
		var requestUrl = workspaceBaseUrl + "/rest/" + serviceName + "/" + methodName;
		var requestConfig = {
			url: requestUrl,
			headers: {
				"Accept": "application/json",
				"Content-Type": "application/json"
			},
			method: "POST",
			jsonData: Ext.encode(dataSend),
			callback: function(request, success, response) {
				if (!callback) {
					return;
				}
				var responseObject = response;
				if (success) {
					responseObject = Terrasoft.decode(response.responseText);
				}
				callback.call(this, responseObject, success);
			},
			scope: scope || this
		};
		if (config && config.timeout) {
			requestConfig.timeout = config.timeout;
		}
		return Terrasoft.AjaxProvider.request(requestConfig);
	}

	return {
		callService: internalCallService
	};
});

 

Добрый день!

Timeout указывается в конфиге вызова сервиса (параметр timeout).

В вашем случае будет так:

var config = {
		serviceName: "ServiceName",
		timeout: 100000
	};
ServiceHelper.callService(config, "ServiceMethodPost",  function(response) {
	window.console.log(response);
}, serviceData, this);

 

Сидоров Александр В.,

Спасибо

var serviceData = {
	phoneNumber: phoneNumber ? phoneNumber : "",
	userName: contact.displayValue,
	email: email ? email : ""
};
ServiceHelper.callService("ServiceName", "MethodName", function(response) {
	window.console.log(response);
}, serviceData, this);

В моем случае в serviceData есть другие параметры веб сервиса, их нужно будет в отдельный объект выложить? Не совсем понимаю как БПМ определит что является обычным параметром, а что конфигурационным

Сериков Асхат Кайратович,

Данный вариант правильный

var config = {
		serviceName: "ServiceName",
		timeout: 100000
	};
var serviceData = {
	phoneNumber: phoneNumber ? phoneNumber : "",
	userName: contact.displayValue,
	email: email ? email : ""
};
ServiceHelper.callService(config, "ServiceMethodPost",  function(response) {
	window.console.log(response);
}, serviceData, this);

Логика ServiceHelper выглядит так:

define("ServiceHelper", ["ext-base", "terrasoft"], function(Ext, Terrasoft) {

	/**
	 * ######## ##### ###-#######.
	 * @param {String|Object} config ### ####### ### ######### ###### #######.
	 * @param {String} methodName ### ######.
	 * @param {Function} callback (optional) ####### ######### ######.
	 * @param {Object} data (optional) ###### # ####### #######.
	 * @param {Object} scope (optional) ######## ######.
	 * @return {Object} ######### #######.
	 */
	function internalCallService(config, methodName, callback, data, scope) {
		var serviceName;
		if (config && Ext.isObject(config)) {
			serviceName = config.serviceName;
			methodName = config.methodName;
			callback = config.callback;
			data = config.data;
			scope = config.scope;
		} else {
			serviceName = config;
		}
		var dataSend = data || {};
		var workspaceBaseUrl = Terrasoft.utils.uri.getConfigurationWebServiceBaseUrl();
		var requestUrl = workspaceBaseUrl + "/rest/" + serviceName + "/" + methodName;
		var requestConfig = {
			url: requestUrl,
			headers: {
				"Accept": "application/json",
				"Content-Type": "application/json"
			},
			method: "POST",
			jsonData: Ext.encode(dataSend),
			callback: function(request, success, response) {
				if (!callback) {
					return;
				}
				var responseObject = response;
				if (success) {
					responseObject = Terrasoft.decode(response.responseText);
				}
				callback.call(this, responseObject, success);
			},
			scope: scope || this
		};
		if (config && config.timeout) {
			requestConfig.timeout = config.timeout;
		}
		return Terrasoft.AjaxProvider.request(requestConfig);
	}

	return {
		callService: internalCallService
	};
});

 

Сидоров Александр В.,

Понял, пойду попробую спасибо,

Сидоров Александр В.,

В целом все так как вы и сказали, только раз присутствует конфиг, то все остальные параметры(данные, scope, callback) нужно так же перенести в него, иначе они перезатрутся при вызове. Спасибо!

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

Здравствуйте, подскажите, как в версии 7.13.0 можно отключить минимизацию и сборку скриптов в all-combined.js. 

Установка параметра "SeparatedJsFiles" в true в web.config в этой версии не помогает

 

Нравится

2 комментария
Лучший ответ

Добрый день!

Данная тема обсуждалась тут

Добрый день!

Данная тема обсуждалась тут

Такой возможности в нынешних версиях нет, минимум пару месяцев ситуация будет такой же.

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

Добрый день. После обновления до версии 7.13.3 при компиляции получаю ошибку:

The type or namespace name 'Http' does not exist in the namespace 'System.Net' (are you missing an assembly reference?) FILE <Название пользовательского Web сервиса>

Данное пространство имён есть в .NetFramework 4.7.

Кто с таким сталкивался?

Нравится

4 комментария
Лучший ответ

Попробовал добавить библиотеку во внешние сборки, система скомпилировалась без проблем

Добавьте в ваш пользовательский сервис

using System.Net.Http;

Григорий Чех,

На эту строчку и ругается компилятор.

Коновалов Игорь,

В 7.13 правда не нахожу библиотеки System.Net.Http.

Могу посоветовать скачать ее и добавить во внешние сборки

Попробовал добавить библиотеку во внешние сборки, система скомпилировалась без проблем

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

в карточке контрагента при выстраивании взаимосвязей в виде диаграммы система выдает ошибку SqlException

Из-за чего может быть такое поведение?

Изображение удалено.

Нравится

5 комментариев
Лучший ответ

Сегодня обнаружил такую же проблему в своей базе. 

Как выяснилось, у контрагента в поле Parent был внесён его собственный идентификатор, в результате запрос иерархии взаимосвязей вызывал исключение: "Выполнение инструкции прервано. Максимальная рекурсия 100 была использована до завершения инструкции."

Для исправления ошибки достаточно удалить ссылку на родителя в контрагенте (подставить свой Id):

update Account
  set ParentId = null
  where Id = N'665E1BDF-54FA-4231-BE2D-9D4305D91BE3'

 

Добрый день!

Без логов и информации в консоли трудно что то понять.

Определенно что то не то происходит в RelationshipDiagramService. Далее можно отследить, в каком месте происходит ошибка

Используйте профилировщик sql запросов для нахождения причины SqlException и ее устранения

Обратитесь в службу поддержки Террасофт, это базовый функционал - они помогут Вам разобраться.

Сегодня обнаружил такую же проблему в своей базе. 

Как выяснилось, у контрагента в поле Parent был внесён его собственный идентификатор, в результате запрос иерархии взаимосвязей вызывал исключение: "Выполнение инструкции прервано. Максимальная рекурсия 100 была использована до завершения инструкции."

Для исправления ошибки достаточно удалить ссылку на родителя в контрагенте (подставить свой Id):

update Account
  set ParentId = null
  where Id = N'665E1BDF-54FA-4231-BE2D-9D4305D91BE3'

 

Да, это решило проблему. Спасибо.

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

Добрый день, Коллеги!

Подскажите, пожалуйста, как в раздел продажи вынести быстрый фильтр по датам (как в активности с - по), который будет фильтровать по полю дата создания ИСТОРИИ СТАДИИ в карточке продажи. 

Как настроить такой фильтр по полю дата в самом разделе знаю, но как именно по полю дата в детали этого раздела.

Т.Е, я хочу в этом фильтре фильтровать записи (продажи) у которых за заданный период есть в истории стадий стадии

Нравится

5 комментариев
Лучший ответ

По идее код должен выглядеть таким образом:

 define("OpportunitySectionV2", ["BaseFiltersGenerateModule"], function(BaseFiltersGenerateModule) {
    return {
        entitySchemaName: "Opportunity",
        methods: {
            initFixedFiltersConfig: function() {
                var fixedFilterConfig = {
                    entitySchema: this.entitySchema,
                    filters: [
                        {
                            name: "PeriodFilter",
                            caption: "",
                            dataValueType: this.Terrasoft.DataValueType.DATE,
                            startDate: {
                                columnName: "[OpportunityInStage:Opportunity:Id].StartDate",
                            },
                            dueDate: {
                                columnName: "[OpportunityInStage:Opportunity:Id].StartDate",
                            }
                        },
                    ]
                };
                this.set("FixedFilterConfig", fixedFilterConfig);
            }
        }
    };
});

Но это не будет работать, так как FixedFilterViewV2 не позволит создать элемент с таким id.

Могу предложить 2 варианта:

1) переопределить FixedFilterViewV2 и исправить этот метод. В 7.13.х переопределять модули сложно, но можно

2) настроить и сохранить расширенный фильтр

Смотрите документацию по применению расширенных фильтров

Григорий Чех,

Тут фильтр на поля самого раздела, вопрос в том как в разделе добавить этот фильтр но фильтровать по записям детали (по полю дата в детали)

Тогда нужно вам писать свой фильтр который будет отбирать записи с иторией стадий попадающий в диапазон дат

Калушка Д.,

Напишите sql-запрос, который будет выбирать нужные значения из таблицы продаж, а потом этот запрос 'переведите' в програмный код понятный bpm'online.

Его потом и пропишите в конфиге для быстрых фильтров.

По идее код должен выглядеть таким образом:

 define("OpportunitySectionV2", ["BaseFiltersGenerateModule"], function(BaseFiltersGenerateModule) {
    return {
        entitySchemaName: "Opportunity",
        methods: {
            initFixedFiltersConfig: function() {
                var fixedFilterConfig = {
                    entitySchema: this.entitySchema,
                    filters: [
                        {
                            name: "PeriodFilter",
                            caption: "",
                            dataValueType: this.Terrasoft.DataValueType.DATE,
                            startDate: {
                                columnName: "[OpportunityInStage:Opportunity:Id].StartDate",
                            },
                            dueDate: {
                                columnName: "[OpportunityInStage:Opportunity:Id].StartDate",
                            }
                        },
                    ]
                };
                this.set("FixedFilterConfig", fixedFilterConfig);
            }
        }
    };
});

Но это не будет работать, так как FixedFilterViewV2 не позволит создать элемент с таким id.

Могу предложить 2 варианта:

1) переопределить FixedFilterViewV2 и исправить этот метод. В 7.13.х переопределять модули сложно, но можно

2) настроить и сохранить расширенный фильтр

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

Добрый день!

 

Работаю в файловом режиме.

После неловких моих движений стала появляться следующая ошибка:

Exception Message: Операция является недопустимой из-за текущего состояния объекта. Exception Type: Terrasoft.Common.TopologicalSorterLoopsException`1[Terrasoft.Core.Packages.Package] Exception Source: Terrasoft.Common Exception Stack Trace: в Terrasoft.Common.ListGraphNodeUtilities.OrderByTopology[T](IList`1 source) в Terrasoft.Core.Packages.WorkspaceUtilities.GetTopologyPackagePositions(UserConnection userConnection, Guid workspaceId) в Terrasoft.Core.SchemaManager`1.GetTopologyPackagePositions(Guid workspaceId) в Terrasoft.Core.SchemaManager`1.InitializeItems(Guid itemUId) в Terrasoft.Core.Entities.EntitySchemaManager.InitializeItems(Guid itemUId) в Terrasoft.Core.SchemaManager`1.InitializeItems() в Terrasoft.Core.Entities.EntitySchemaManager.Initialize(SchemaManagerProvider provider, SchemaManagerProviderConfigurationElement configuration) в Terrasoft.Core.SchemaManagerProvider.InitializeSchemaManager(String managerName) в Terrasoft.Core.SchemaManagerProvider.GetManager(String managerName) в Terrasoft.Core.UserConnection.GetSchemaManager(String schemaManagerName) в Terrasoft.Core.UserConnection.get_EntitySchemaManager() в Terrasoft.Core.DB.DBSecurityEngine.FindEntitySchemaNameByUId(Guid entitySchemaUId) в Terrasoft.Core.DB.DBSecurityEngine.GetEntitySchemaOperationsRightLevels(String schemaName) в Terrasoft.Core.DB.DBSecurityEngine.GetEntitySchemaOperationsRightLevel(String schemaName) в Terrasoft.Core.DB.DBSecurityEngine.GetIsEntitySchemaDeletingAllowed(String schemaName) в Terrasoft.WebApp.WorkspaceExplorerModule.CheckRights() в Terrasoft.WebApp.WorkspaceExplorerModule.Page_Load(Object sender, EventArgs e) в System.Web.Util.CalliEventHandlerDelegateProxy.Callback(Object sender, EventArgs e) в System.Web.UI.Control.OnLoad(EventArgs e) в System.Web.UI.Control.LoadRecursive() в System.Web.UI.Page.ProcessRequestMain(Boolean includeStagesBeforeAsyncPoint, Boolean includeStagesAfterAsyncPoint)

Остановил приложение, затем пул приложений, очистил базу Redis. Запустил все обратно - ошибка не исчезла. Перезапустил службу IIS, то же не помогло. Восстановил резервную копию, так же не помогло. (попробую еще раз)

Служба технической поддержки не оказывает помощь по данному вопросу.

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

Нравится

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

Во второй раз восстановил базу из другой резервной копии. Вышло сообщение о том что рабочее пространство Default не инициализировано. Скомпилировал приложение, пока все работает. 

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

select spd.syspackageid, sp.name, spd.dependonpackageid, sp2.name, spd2.dependonpackageid, sp3.name from SysPackageDependency spd 
inner join syspackage sp on sp.id = spd.syspackageid 
inner join syspackage sp2 on sp2.id = spd.dependonpackageid
inner join SysPackageDependency spd2 on spd2.syspackageid = spd.dependonpackageid
inner join syspackage sp3 on sp3.id = spd2.dependonpackageid where sp.name = 'название менявшегося пакета'

 

Спасибо, Александр, за поддержку! Да, я заметил по логам что компиляция стала уходить в цикл. Решил посмотреть логи продуктовой базы (июнь 2018), нашел там похожее сообщение о том что есть зацикленность в пакетах и успокоился на этом. Но ваш пост пролил свет на путь решения проблемы, буду разбираться дальше.

Показать все комментарии
организационные роли
переименование
7.13_()
sales

Здравствуйте, есть необходимость переименовать организационную роль all emploees во "Все сотрудники" пока переименовал название роли в тестовой системе, новым пользователям роль присваивается, выдается записям. 



Переименовывал кто-то орг. роль all employees? Будут последствия для системы? 

Нравится

1 комментарий
Лучший ответ

Добрый день!

По сути орг. роль - это запись в таблице SysAdminUnit.

И должна быть связка по Id. Так что проблем быть не должно.



PS: поиск по "all emploees" по исходным кодам результата не дает

Добрый день!

По сути орг. роль - это запись в таблице SysAdminUnit.

И должна быть связка по Id. Так что проблем быть не должно.



PS: поиск по "all emploees" по исходным кодам результата не дает

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

Добрый день!

Не удается передать веб-сервису параметры методом POST, БП просто запускается, но не получает параметры. При использовании метода GET ошибок не возникает. использую строку /0/ServiceModel/ProcessEngineService.svc/UsrAddContragentPDZ/RunProcess

 public static void SendData()

        {

            var Request = HttpWebRequest.Create(processServiceUri) as HttpWebRequest;

            Request.Method = "POST";

            Request.Accept = "application/json";

            Request.ContentType = "application/json";

            Request.CookieContainer = AuthCookie;

            CookieCollection cookieCollection = AuthCookie.GetCookies(new Uri(processServiceUri));

            string csrfToken = cookieCollection["BPMCSRF"].Value;

            Request.Headers.Add("BPMCSRF", csrfToken);

            using (var requestStream = Request.GetRequestStream())

            {

                using (var writer = new StreamWriter(requestStream))

                {

                    string json = new JavaScriptSerializer().Serialize(new

                    {

                        BossID = "GBO_048845",

                        StatusPDZString = "007C2385-2EDC-402A-B40A-E74625E0E6DD",

                        PDZString = "4098,56"

                    });

                    writer.Write(json);

                    writer.Flush();

                    writer.Close();

                }

            }

Где может быть ошибка?

Нравится

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