Хочу предзаполнять поля добавляемой записи в детали с редактируемым реестром значениями, вычисленными в коде. Т.е. я не могу в объекте их заполнить системной переменной или константой. Но выглядеть внешне это должно также.

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

Как это сделать?

Нравится

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

Добрый день.

 

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

 

Более подробную информацию Вы сможете найти в этом обсуждении.

Добрый день! Есть 2 варианта.

1) Можете реализовать через бизнес-процесс со стартовым сигналом после добавления/изменения записи, либо же  через событийный слой (перед добавлением/сохранение/изменением)

Нигрескул Алексей,

мне нужно заполнить данные до сохранения. БП не поможет

тогда через событийный слой

Нигрескул Алексей пишет:

тогда через событийный слой

Ссылка: https://academy.terrasoft.ru/documents/technic-sdk/7-13/sobytiynyy-sloy-entity 

Причем тут событийный слой? В момент когда я нажимаю +, в базе ничего не происходит, всё происходит на клиенте и на клиенте же надо вставить нужные мне значения, чтобы пользователь мог их изменить или сохранить, если всё верно посчитано.

Алексей-Карягин,

Добрый день! Если внимательно почитать то на событийном слое переопределяете метод OnSaving(), OnUpdating(), OnInserting() при этом подписавшись на события нужного Вам объекта. В данных методах реализуете свою логику в зависимости от потребности, и отработка данных методов происходит ДО сохранения данных в БД, если в результате обработки сохранять не нужно, то просто генерируете throw new Exception("Exception Message"), на клиент Вам

выведется сообщение из Exception и данные в БД не сохраняться.

У меня задача на клиенте показать вместо пустых значений - вычисленные, до сохранения. Как работаю значения по умолчанию в объекте.

попробуйте подписаться на событие onchange:Field

Добрый день.

 

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

 

Более подробную информацию Вы сможете найти в этом обсуждении.

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

Подскажите как сделать валидацию номера для "Средства связи"? Читал статью https://community.terrasoft.ru/questions/validacia-zapolnenia-telefona-v-detali-sredstva-svazi но this.addColumnValidator("Number", newItem.validateField, newItem); что бы в детали сделать замену валидации нужно полностью переписать то что в "BaseCommunicationViewModel" но это модуль и его нельзя замещать.

Нравится

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

Александр, Ваш вопрос связан не с валидацией, а с замещением модулей, которое запрещено и нужны обходные решения. Это обсуждалось неоднократно, например, тут. А когда писался вопрос по приведенной Вами ссылке, замещать ещё было можно, но в комментариях осуждали уже тогда.

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

 

Вот потому то и спрашиваю так как эти способы не работают, как можно сделать валидацию другим способом, пока в голову не пришло идеи не какой, может подскажите?

Не работает именно валидация или замещение? Если второе — то по ссылке выше приводил, как делать обходным способом. По сути, переопределять все стандартные схемы, которые используются для работы со средствами связи на свои аналоги.

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

Ну создать полностью свой модуль с такой же логикой. А можно что бы не переписывать полностью модуль, обойтись малой кровью?

Там не переписывание всего текста модулей, а дополнение своим при помощи override. Но потом и замена всех упоминаний стандартного модуля на свой аналог.

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

Спасибо, получилось как описано в статье.

Сделал замещение BaseCommunicationDetail

 

define("BaseCommunicationDetail", ["KtValidBaseCommunicationViewModel"],
	function() {
		return {
			attributes: {},
			messages: {},
			methods: {},
			diff: /**SCHEMA_DIFF*/[]/**SCHEMA_DIFF*/
		};
	});

и BaseCommunicationViewModel

define("KtValidBaseCommunicationViewModel", ["terrasoft", "BaseCommunicationViewModel"],
	function(Terrasoft) {
		Ext.define("Terrasoft.KtValidBaseCommunicationViewModelOverrided", {
			override: "Terrasoft.BaseCommunicationViewModel",
			/**
			 * @override
			 * ######### ######### ###### ########.
			 * @param {String} value ########### ########.
			 * @return {Boolean} true #### ###### ######## ##### ########.
			 */
 
			isPhoneNumber: function(value) {
				//Terrasoft.SysSettings.querySysSettingsItem("CommunicationPhoneRegExpValid", function(phoneRegExp) {
				//	var phonePattern = new RegExp(this.get("PhoneRegExp"));
				//	return phonePattern.test(value);
				//}, this);
				var phonePattern = /^\98(\(\d{3}\)\d{3}\-\d{2}\-\d{2})$/;
				return phonePattern.test(value);
			},
		});
	}
);

Все отлично работает если вшить регулярное выражение.

А как можно получить из системной настройки его? Получение значение в ней асинхронное и нужно сделать через callback, но не как не выходит. Помогите в реализации такого callback, пожалуйста.

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

Понимаю конечно, что с SAPом сравнивать не очень хорошая идея, но все же. При работе с SAP дл переноса обновлений можно выставить всем пользователям уведомление через систему о планируемых работах, а на период работы выгнать из системы и заблокировать на вход в систему всех пользователей (кроме ИТ). Очень удобная вещь, позволяет перенести обновление без риска потери данных за период сессии у пользователя и практически убирает весь негатив польхователей на тормоза в системе на период её компиляции.

Попробовал в Creatio заблокировать всех пользователей на вход, но такого функционала просто нет - можно решить БП. Уведомления тоже можно сделать БП, Закрытие активной сессии по идее тоже не проблема. 

Собственно вопрос - кто как работает и оповещает пользователей о технических работах в системе?

Нравится

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

Ну помимо предложенного способа с Бп, есть таблицы в базе данных. Можете подсоединится, вытянуть активных пользователей и уже как-то уведомить их письмом на почту, в мессенджер и т.д Сделать это можно прямо на сервере где развернут IIS простой консолькой на c#, запуск консольки делать планировщиком Windows по таймеру или триггеру

Ну помимо предложенного способа с Бп, есть таблицы в базе данных. Можете подсоединится, вытянуть активных пользователей и уже как-то уведомить их письмом на почту, в мессенджер и т.д Сделать это можно прямо на сервере где развернут IIS простой консолькой на c#, запуск консольки делать планировщиком Windows по таймеру или триггеру

Мы рассматриваем вариант возможной реализации подобной функциональности в базовой логике наших продуктов.

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

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

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

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

Опытным путем установлено, что если удалить пакет с диска по пути defPackagesWorkingCopyPath из ConnectionzStrings.config, то он проходит и так с каждым пакетом. Т.е. чтобы обновиться из хранилища надо предварительно удалить всю рабочую копию.

Как то не очень радует такой режим работы. Кто сталкивался и как можно решить?

 

Нравится

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

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

Читал это, но не смог никак к себе применить. 

Но два дня безуспешных попыток решить вопрос дали свой результат. Причина в URL хранилища. По каким то причинам не нравится адрес по ip, нужен адрес с именем. После того как сменил IP на имя все заработало. Хотя в адресе по IP ничего, что противоречило бы UTF-8 я не вижу.

Судя по сообщению об ошибке, проблема к доступу по пути :)

Навскидку, могу посоветовать проверить наличие русских символов в пути и права IIS на чтение / запись к папке с приложением

Alex Kalnitskiy,

Как бы я хотел написать "Спасибо за помощь, проблема решена", но увы и ах! Кириллицы в пути нет, у пользователя IIS Full control на папку и все вложенное в неё, а ошибка остается :(

Ошибка
При работе с хранилищем произошла ошибка
Target path '/branches/development/EPMPortal/branches/1.0.0' does not exist
SvnErrorCode: SVN_ERR_FS_PATH_SYNTAX

 

70% - Авторизация в SVN закончилась.

Олександр Цируль пишет:

70% - Авторизация в SVN закончилась

Если про Creatio то нет. Авторизовался перед выполнение данной операцией. + заливку в SVN я могу выполнять. а вот обновить из хранилища без ошибки не могу. Обновляется только если удаляю рабочую копию.

Судя по старым обсуждениям на других сайтах, дело может быть всё же в особенностях пути к файлу (например, символах переноса либо отсутствии прав на доступ к этой папке), также там советуют перезапуск и отвязку-привязку.

 

А тут больше о том, какой должен быть формат пути:

Directory entry names and directory paths.

Here are the rules for directory entry names, and directory paths:

A directory entry name is a Unicode string encoded in UTF-8, and may not contain the NULL character (U+0000). The name should be in Unicode canonical decomposition and ordering. No directory entry may be named '.', '..', or the empty string. Given a directory entry name which fails to meet these requirements, a filesystem function returns an SVN_ERR_FS_PATH_SYNTAX error.

A directory path is a sequence of zero or more directory entry names, separated by slash characters (U+002f), and possibly ending with slash characters. Sequences of two or more consecutive slash characters are treated as if they were a single slash. If a path ends with a slash, it refers to the same node it would without the slash, but that node must be a directory, or else the function returns an SVN_ERR_FS_NOT_DIRECTORY error.

A path consisting of the empty string, or a string containing only slashes, refers to the root directory.

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

Читал это, но не смог никак к себе применить. 

Но два дня безуспешных попыток решить вопрос дали свой результат. Причина в URL хранилища. По каким то причинам не нравится адрес по ip, нужен адрес с именем. После того как сменил IP на имя все заработало. Хотя в адресе по IP ничего, что противоречило бы UTF-8 я не вижу.

Ну хоть теперь все в Гугле найдут по коду ошибки и эту причину. Странно, что движок SVN выдавал в ошибке именно путь к папке, а не весь адрес с IP.

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

Как можно сделать что бы карточка при создании записи не закрывалась?

Пробовал два метода описанные тут https://community.terrasoft.ua/questions/zakrytie-zapisi-pri-sohranenii и https://community.terrasoft.ua/questions/thissave-prervat-zakrytie-kartocki-vozvrat-k-predydusei-kartocke-v-shain тут, но не один из них не помог

Нравится

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

Александр, обратите ещё внимание на более новую статью по теме:

«Как сохранять, не закрывая, открытую бизнес-процессом страницу редактирования».

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

Видел статью, пробовал, не работает. Видимо что-то не туда пишу

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

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

Добрый день!

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

В секции обьявил данный метод который публикует фильтры в другой модуль.

....
afterFiltersUpdated: function() {
				this.callParent(arguments);
				debugger;
				var previousDate = new Date();
				previousDate.setDate(previousDate.getDate() - 1);
 
				var StartDate = "";
				var StopDate = "";
 
				var fixedFilters = this.get("SectionFiltersValue").collection.get("FixedFilters");
				var customFilters = this.get("SectionFiltersValue").collection.get("CustomFilters");
				StartDate = fixedFilters.PeriodFilter.startDate === null ? 
					Ext.Date.format(previousDate, "Y-m-d") :
					typeof (fixedFilters.PeriodFilter.startDate) === "string" ? 
					Ext.Date.format(new Date((new Date(fixedFilters.PeriodFilter.startDate.substr(0, 10))))) : 
					Ext.Date.format(new Date(), "Y-m-d");
				StopDate = fixedFilters.PeriodFilter.dueDate === null ? 
					Ext.Date.format(previousDate, "Y-m-d") :
					typeof (fixedFilters.PeriodFilter.dueDate) === "string" ? 
					Ext.Date.format(new Date((new Date(fixedFilters.PeriodFilter.dueDate.substr(0, 10))))) : 
					Ext.Date.format(new Date(), "Y-m-d");
 
					var dataSend = {
						StartDate: StartDate,
						StopDate: StopDate
					};
 
					this.sandbox.publish("UpdateInsurerAnalyticWidget", dataSend, ["AbInsurerAnalyticWidgetUpdated"]);
			},
....

 

define("AbInsurerAnalyticByZoneModule", ["ext-base", "terrasoft", "sandbox", "BaseFiltersGenerateModule", "AbInsurerAnalyticByZoneModuleResources", "ChartModuleHelper", "css!AbInsurerAnalyticByZoneModuleCSS", "ServiceHelper"],
	function(Ext, Terrasoft, sandbox, BaseFiltersGenerateModule, resources, ChartModuleHelper, css, ServiceHelper, ConfigurationConstants) {
		function getViewModel() {
			return Ext.create("Terrasoft.BaseViewModel", {
				entitySchema: "AbInsurance",
				methods: {
					init: function() {},
					getChart: function(key) {
						sandbox.publish("GenerateChart", key);
 
					},
					load: function() {}
				}
			});
		}
		var result = "";
		function generateMainView(renderTo) {
 
			var resultConfig = Ext.create("Terrasoft.Container", {
				id: "tableInsurerAnalyticByZoneParamContainer",
				selectors: {
					wrapEl: "#tableInsurerAnalyticByZoneParamContainer"
				},
				renderTo: renderTo
			});
			return resultConfig;
		};
		function getAnalyticByZone(parameters) {
			var serviceData = {
				startDate: parameters[0].toString(),
				stopDate: parameters[1].toString()
			};
 
			ServiceHelper.callService("AnalyticsProcessingService", "GetAnalyticDashboardData",
				function (response) {
					debugger;
					var htmlAdded = resources.localizableStrings.HeaderTable;
					if (response.status === 404 || response.status === 500 || response.status === 400) {
						Terrasoft.showErrorMessage("\t Error: \n" + response.message);
					}
					else if(response.GetAnalyticDashboardDataResult.length > 0){
						result = response.GetAnalyticDashboardDataResult;
						for(var i = 0; i < result.length; i++){
							var segment = result[i].Segment;
							var avgRevenue = result[i].AvgRevenue;
							var salesCount = result[i].SalesCount;
							var cpa = result[i].Cpa;
							var sumCtr = result[i].SumCtr;
							var cr = result[i].Cr;
							var roas = result[i].Roas;
							var tableBody = resources.localizableStrings.TableBody;
							htmlAdded += Ext.String.format(tableBody,segment,avgRevenue,salesCount,cpa,sumCtr,cr,roas);
						}
					} else {
						result = null;
					}
					htmlAdded += "</table>";
					Ext.get("tableInsurerAnalyticByZoneParamContainer").setHTML(htmlAdded);
				}, serviceData, this);
		}
		function getReplaceString(str, separator){
		var arSt = str.split(separator);
			var res = arSt[2] + separator + arSt[1] + separator + arSt[0];
			while(res.indexOf(separator) > 0){
				res = res.replace(separator,"-");
			}
			return res;
		}
 
		var render = function(renderTo) {
			var viewConfig = generateMainView(renderTo);
			var viewModel = getViewModel();
			var getStartD = Ext.get("fixedFilterCreatedAtView-wrap").dom.innerText;
			var getEndD = Ext.get("fixedFilterCreatedAtDueView-wrap").dom.innerText;
			var date = new Date();
			var startD = getStartD.indexOf("Начало") > 0 ? Ext.Date.format(date, "Y-m-d") : getReplaceString(getStartD, ".");
			var endD = getEndD.indexOf("Завершение") > 0 ? Ext.Date.format(date, "Y-m-d") : getReplaceString(getEndD, ".");
			var ar = [];
			ar.push(startD);
			ar.push(endD);
			getAnalyticByZone(ar);
			viewConfig.bind(viewModel);
		};
		return {
			schema: "AbInsurance",
			mesages: {
				"UpdateInsurerAnalyticWidget": {
				mode: Terrasoft.MessageMode.PTP,
				direction: Terrasoft.MessageDirectionType.SUBSCRIBE
			},
			},
			methods: {
 
			},
			userCode: function() {},
			init: function() {
				debugger;
				sandbox.subscribe("UpdateInsurerAnalyticWidget", function(arg) {
 
					var arArg = [];
					arArg.push(arg.StartDate);
					arArg.push(arg.StopDate);
					getAnalyticByZone(arArg);
				}, this, ["AbInsurerAnalyticWidgetUpdated"]);
			},
			render: render
		};
	}
);

в данном модуле в init сделал подписку, но она не отрабатывает при изменении фильтров.

Кто нибудь сталкивался с такой проблемой?

Нравится

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

Алексей, не вижу в примерах кода вызова sandbox.registerMessages(messageConfig) для регистрации сообщений модуля. Проверьте, всё ли правильно в Ваших разработках, ориентируясь на инструкцию «Обмен сообщениями между модулями» в академии.

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

Добрый день!

Установил расширение https://marketplace.terrasoft.ru/template/email-extension-creatio. Осваиваю его функционал, обнаружил одну особенность - все письма отображаются в одном списке. Захотел навести порядок - создать динамические группы в которых группировались бы входящие и исходящие сообщения по пользователю, подумал руками делать не совсем правильно, решил через БП. Но, не могу в списке объектов найти объекты этого пакета. Например, "Группа Email":

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

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

Приложение компилировал.

В чем может быть дело?

 

Нравится

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

Руслан, возможно, тот пакет, где Вы ведёте доработку, находится в иерархии пакетов не ниже, чем пакет дополнения, а сбоку или выше.

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

Спасибо за рекомендацию, буду разбираться.

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

Всем доброго времени суток. Кто нибудь сталкивался с разработкой пользовательского виджета в аналитике. Не могу разобраться, как реализовать в виде списка? У меня есть ХП которая возвращает нужный результат. 

Можете скинуть пару примеров?

Заранее благодарю.

Нравится

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

Добрый вечер, Алексей.

 

Результат хранимой процедуры возвращайте в представление, например:

 

CREATE FUNCTION [dbo].[tsf_PathReportData]()
RETURNS @ExaminationBlocksByObject TABLE (
		[Number] nvarchar(50),
		[ExaminationId] uniqueidentifier,
		[ObjectId] uniqueidentifier,
		[MacroscopicDescription] nvarchar(max),
		[BlocksDescription] nvarchar(max))
AS
BEGIN
 
	DECLARE
		@Number nvarchar(50),
		@ExaminationId uniqueidentifier,
		@ObjectId uniqueidentifier,
		@MacroscopicDescription nvarchar(max),
		@BlocksDescription nvarchar(max)
 
	DECLARE ExaminationDetailCursor CURSOR STATIC LOCAL FOR
	SELECT
			O.Number,
			O.MacroscopicDescription,
			O.ExaminationId,
			O.Id as ObjectId
	FROM ABExaminationObject O
 
	OPEN ExaminationDetailCursor
 
	FETCH NEXT FROM ExaminationDetailCursor INTO @Number, @MacroscopicDescription, @ExaminationId, @ObjectId
 
	WHILE @@FETCH_STATUS = 0 BEGIN
 
		SET @BlocksDescription = ''
 
		SELECT @BlocksDescription = @BlocksDescription + B.Number + ' ' + B.[Description] + CHAR(13) + CHAR(10)
		FROM ABExaminationBlock B
		WHERE B.ExaminationObjectId = @ObjectId
 
		INSERT INTO @ExaminationBlocksByObject (
			Number,
			ExaminationId,
			ObjectId,
			MacroscopicDescription,
			BlocksDescription
		)
		VALUES (
			@Number,
			@ExaminationId,
			@ObjectId,
			@MacroscopicDescription,
			@BlocksDescription)
 
		FETCH NEXT FROM ExaminationDetailCursor INTO @Number, @MacroscopicDescription, @ExaminationId, @ObjectId
 
	END 
 
	CLOSE ExaminationDetailCursor 
	DEALLOCATE ExaminationDetailCursor
 
	RETURN
 
END
 
 
create view VwExaminationReport
as
select
	newid() as Id,
	Number as Number,
	MacroscopicDescription as MacroscopicDescription,
	ExaminationId as Examination,
	BlocksDescription as BlocksDescription
from [tsf_PathReportData]()

На основании этого представления создайте схему таблицы-представления в конфигурации и используйте этот объект в стандартном элементе итогов 'Список'.

Алла Савельева,

добрый! Мне в ХП нужно передавать параметры даты из фильтров, на сколько я знаю, то представление нельзя сделать с принимаемыми параметрами.

CREATE PROCEDURE [dbo].[absp_GetProductAnalyticByZone] @startDate varchar(10), @stopDate varchar(10)
AS
SELECT 
	T.Segment [Segment], 
	ROUND(SUM(T.[AvgRevenue]), 2, 1) [AvgRevenue],
	SUM(T.[SalesCount]) [SalesCount],	
	ROUND(SUM(T.[CPA]), 2, 1) [CPA],	
	SUM(T.[SumCtr]) [SumCtr],	
	ROUND(SUM(T.[ROAS]), 2, 1) [ROAS]
FROM
	(SELECT 
		[IABZ].[Date],
		[IABZ].ZoneId,
		[IZ].Segment,
		SUM([IABZ].Ctr) [SumCtr],
		SALES_QUERY.SalesCount [SalesCount],
		SALES_QUERY.AvgRevenue [AvgRevenue],
		IIF(SALES_QUERY.SalesCount = 0 , 0,([CpcCost].[AdsCost]/SALES_QUERY.SalesCount))[CPA],
		(SALES_QUERY.SalesCount * SALES_QUERY.AvgRevenue / [CpcCost].[AdsCost]) * 100 [ROAS],
		[CpcCost].[AdsCost]
 
	FROM [InsurerAnalyticByZone] [IABZ] WITH(NOLOCK)
	LEFT OUTER JOIN [InsurerZone] [IZ] WITH(NOLOCK) ON [IABZ].ZoneId = [IZ].Id
	INNER JOIN [CpcCost] [CpcCost] WITH(NOLOCK) ON [IABZ].[Date] = [CpcCost].[Date]
	OUTER APPLY (SELECT COUNT([I].[Id]) [SalesCount],
						AVG([I].[Revenue]) [AvgRevenue]
					FROM [AbInsurance] [I] WITH(NOLOCK) 
					INNER JOIN [CityByEwa] [CBE] WITH(NOLOCK) ON [I].EwaCityId = [CBE].Id
					WHERE [I].StatusId = '195CD1AD-37B3-4F0A-B4FC-70E2BF0B3F06' 
					AND [CBE].ZoneCode = [IZ].Code 
					AND CONVERT(varchar(10), [I].CreatedAt, 120) = [IABZ].[Date]
				) SALES_QUERY
	GROUP BY [IABZ].ZoneId, [IZ].Segment, [IABZ].[Date],  [IZ].Code, [CpcCost].AdsCost, SALES_QUERY.SalesCount, SALES_QUERY.AvgRevenue	
	) AS T
WHERE T.[Date] BETWEEN @startDate AND @stopDate
GROUP BY T.ZoneId, T.Segment
 
UNION ALL 
 
SELECT 
[CBE].[Name] [Segment],
[R].[AvgRevenue] [AvgRevenue],
COUNT([I].[Id]) [SalesCount],
SUM(IIF(R.[Count] = 0, 0, [CpcCost].[AdsCost]/R.[Count])) [CPA],
 0 [SumCtr],
ROUND(SUM((R.[Count] * R.[AvgRevenue]) / [CpcCost].[AdsCost]) * 100, 2, 1) [ROAS]
FROM [AbInsurance] [I] WITH(NOLOCK) 
INNER JOIN [CityByEwa] [CBE] WITH(NOLOCK) ON [I].EwaCityId = [CBE].Id AND [CBE].Id = '9a008f3a-f865-4e74-b1f2-530f54711f2b'
INNER JOIN [CpcCost] [CpcCost] WITH(NOLOCK) ON CONVERT(varchar(10), [I].CreatedAt, 120) = [CpcCost].[Date]
OUTER APPLY ( SELECT COUNT([I].Id) [Count],
						AVG([I].[Revenue]) [AvgRevenue]
				FROM [AbInsurance] [I] WITH(NOLOCK) 
				INNER JOIN [CityByEwa] [CBE] WITH(NOLOCK) ON [I].EwaCityId = [CBE].Id AND [CBE].Id = '9a008f3a-f865-4e74-b1f2-530f54711f2b'
				INNER JOIN [CpcCost] [CpcCost] WITH(NOLOCK) ON CONVERT(varchar(10), [I].CreatedAt, 120) = [CpcCost].[Date]
				WHERE [I].StatusId = '195CD1AD-37B3-4F0A-B4FC-70E2BF0B3F06' AND CONVERT(varchar(10), [I].CreatedAt, 120) BETWEEN @startDate AND @stopDate
) R
WHERE [I].StatusId = '195CD1AD-37B3-4F0A-B4FC-70E2BF0B3F06' AND CONVERT(varchar(10), [I].CreatedAt, 120) BETWEEN @startDate AND @stopDate
GROUP BY [CBE].[Name], [R].[AvgRevenue]

вот моя ХП, возвращает мне нужную информацию

Нигрескул Алексей,

А если попробовать реализовать Ваш виджет, как наследник от базового списка итогов?

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

Добрый день!

 

У нас стоит Oktell Call-Centre и стандартный коннектор Oktell от террасофт. 

У нас есть сотрудники, которые используют и стац. телефоны и отдельно софтверный телефон Oktell. 

Но софтфон Oktell не позволяет переносить звонки в bpm. 

Каким образом это можно сделать с помощью других sip-телефонов Microsip, 3CX и др. SIP-телефоны?

Нравится

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

Так в сценарии пост-обработки звонка ложите его в базу bpm! Если надо будет помощь, напишите в скайп dima-tashohlo

Так в сценарии пост-обработки звонка ложите его в базу bpm! Если надо будет помощь, напишите в скайп dima-tashohlo

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

Добрый день!

При запуске команды ExecuteScript, утилита отваливается с ошибкой «Не удается найти файл».

Команда RebuildWorkspace выполняется успешно:

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

В мониторе процессов видно что не удается найти файл Terrasoft.Tools.Common.resources.dll:

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

Кто нибудь сталкивался с такой проблемой? В чем может быть дело? Спасибо!

Нравится

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

Добрый день!

Лично мне помогла следующая строка в IExecutor-классе:



userConnection.Workspace.WorkspaceAssembly = Assembly.Load("Terrasoft.Configuration");



Еще дополнительно можно попробовать обновить папку DesktopBin\WorkspaceConsole данными из папки Terrasoft.Configuration\bin после полной компиляции приложения

Добрый день!

Лично мне помогла следующая строка в IExecutor-классе:



userConnection.Workspace.WorkspaceAssembly = Assembly.Load("Terrasoft.Configuration");



Еще дополнительно можно попробовать обновить папку DesktopBin\WorkspaceConsole данными из папки Terrasoft.Configuration\bin после полной компиляции приложения

Alex Kalnitskiy, добрый день!

Вы мой спаситель, помогло следующее - скопировал из папки Terrasoft.Configuration\bin  файл Terrasoft.Configuration.dll и на всякий случай Terrasoft.Configuration.pdb. И вуаля, все заработало. Тех поддержка не смогла предоставить решение.

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