Кейс следующий: сделать правило дедубликации в разделе лиды по похожим контрагентам с проверкой ТОЛЬКО по телефону. Базовое правило не подходит, поскольку проверяет по названию И телефону.

Добавил правило в DuplicatesRule, добавил процедуру поиска с помощью SQL запроса (см. AccountPhoneRuleUsr). Ничего не выходит. Что интересно, если убрать из базового правила (phoneAndAccountNameRule) упоминание поиска по названию, то он тоже перестаёт отрабатывать в принципе. Такое ощущение, что где-то прописано, что поиск по телефону работает только в паре с каким-то совпадением.

Кто-нибудь сталкивался с данной задачкой?

IF(OBJECT_ID('dbo.tsp_FindAccountSimilarRecords','P')) IS NOT NULL
	DROP PROCEDURE dbo.tsp_FindAccountSimilarRecords
GO
 
CREATE PROCEDURE tsp_FindAccountSimilarRecords (@primaryColumnValue uniqueidentifier, @rawXMLConfig nvarchar(MAX), @offsetLimit int = 200)
AS 
 
 
DECLARE @parsedConfig TABLE (
	SchemaName nvarchar(128),
	ParentShemaName nvarchar(128) NULL,
	ColumnName nvarchar(128),
	ColumnValue nvarchar(4000),
	ColumnValueTypeId nvarchar(128)
 );
 
DECLARE @accountRulesConfig TABLE (
	RuleId uniqueidentifier, 
	SchemaName sysname,
	ParentSchemaName sysname NULL,
	ColumnName sysname, 
	NormalizeFnPattern nvarchar(4000),
	CleanDataSchemaName sysname NULL);
 
DECLARE @xmlBody xml;
 
DECLARE @webAndAccountNameRule uniqueidentifier = 'd3607fd4-8303-40ae-b66e-000000000013'	,
		@phoneAndAccountNameRule uniqueidentifier = 'd3607fd4-8303-40ae-b66e-000000000014'	,
		@cityAndAccountNameRule uniqueidentifier = 'd3607fd4-8303-40ae-b66e-000000000015'	,
		@countryAndAccountNameRule uniqueidentifier = 'd3607fd4-8303-40ae-b66e-000000000016'	,
		@AccountNameRule uniqueidentifier = 'd3607fd4-8303-40ae-b66e-000000000017'	,
		@AccountPhoneRuleUsr uniqueidentifier = '778e768d-3941-4461-8954-59702c1f1fab'	,
		@AccountInnRule uniqueidentifier = '1470da34-31ae-4da5-b6c8-9410751133a4'	;
 
DECLARE @leadSchemaUId uniqueidentifier = '41AF89E9-750B-4EBB-8CAC-FF39B64841EC' ;
 
DECLARE @accountSchemaName sysname = 'Account',
		@accountCleanDataSchemaName sysname = 'VwAccountCleanDataValues',
		@accountCommunicationSchemaName sysname = 'AccountCommunication',
		@accountCommunicationCleanDataSchemaName sysname = 'VwAccountCommunicationCleanDataValues',
		@accountAddressSchemaName sysname = 'AccountAddress';
 
DECLARE @accountNameColumn sysname = 'Name',
		@accountInnColumn sysname = 'UsrINN',
		@accountCommunicationColumn sysname = 'Number',
		@accountCommunicationPhoneColumn sysname = 'SearchNumber',
		@accountCountryColumn sysname = 'CountryId',
		@accountCityColumn sysname = 'CityId',
		@communicationTypeIdColumn sysname = 'CommunicationTypeId';
 
DECLARE @resultIdsTable TABLE (Id uniqueidentifier);
 
DECLARE @phoneCommunicationTypeTable TABLE (Id uniqueidentifier);
 
DECLARE @preStmtValues TABLE (
	ColumnName sysname NOT NULL,
	ColumnValue nvarchar (4000) NULL,
	SchemaName sysname NOT NULL,
	ColumnValueTypeId NVARCHAR(128)
);
 
 
DECLARE @emailNormalizePattern nvarchar(50) = N'0-9a-zа-я@_.',
		@nameNormalizePattern nvarchar(50) = N'0-9a-zа-я',
		@normalizedFnSelectStmt nvarchar(250),
		@innNormalizePattern nvarchar(12) = N'0-9',
		@normalizedFnValueStmt nvarchar(250);
 
DECLARE @execStmt nvarchar(MAX),
		@baseNormalizeFn sysname = 'dbo.fn_NormalizeString',
		@phoneNormalizeFn sysname = 'dbo.fn_ExtractDigitLimitFromNumber',
		@webNormalizeFn sysname = 'dbo.fn_ExtractDomainFromUrl';
 
DECLARE @ruleId uniqueidentifier,
		@countDetailValues int = 0;
 
DECLARE @inQueryConditions nvarchar(MAX),
		@equalQueryConditions nvarchar(MAX),
		@schemaName sysname,
		@queryColumnName nvarchar(128);
 
BEGIN
 
 
	SET @xmlBody  = CAST(@rawXMLConfig AS XML);
 
	INSERT INTO @phoneCommunicationTypeTable
	VALUES('0DA6A26B-D7BC-DF11-B00F-001D60E938C6') ,
		('3DDDB3CC-53EE-49C4-A71F-E9E257F59E49') ,
		('D4A2DC80-30CA-DF11-9B2A-001D60E938C6') ,
		('2B387201-67CC-DF11-9B2A-001D60E938C6') ,
		('6A3FB10C-67CC-DF11-9B2A-001D60E938C6') ,
		('E9D91E45-8D92-4E38-95A0-EF8AA28C9E7A') 
 
 
	INSERT INTO @accountRulesConfig (RuleId, SchemaName, ParentSchemaName, ColumnName, NormalizeFnPattern, CleanDataSchemaName)
	VALUES 	(@webAndAccountNameRule, @accountCommunicationSchemaName, @accountSchemaName, @accountCommunicationColumn,  @webNormalizeFn + '(N##VALUE##)', @accountCommunicationCleanDataSchemaName),
			(@webAndAccountNameRule, @accountSchemaName, NULL, @accountNameColumn,  @baseNormalizeFn + '(N##VALUE##,N''' + @nameNormalizePattern + ''')',  @accountCleanDataSchemaName),
			(@phoneAndAccountNameRule, @accountCommunicationSchemaName, @accountSchemaName, @accountCommunicationPhoneColumn,  @phoneNormalizeFn + '(##VALUE##)', @accountCommunicationCleanDataSchemaName),
			(@phoneAndAccountNameRule, @accountSchemaName, NULL, @accountNameColumn,  @baseNormalizeFn + '(N##VALUE##,N''' + @nameNormalizePattern + ''')', @accountCleanDataSchemaName),
			(@cityAndAccountNameRule, @accountAddressSchemaName, @accountSchemaName, @accountCityColumn, NULL, NULL),
			(@cityAndAccountNameRule, @accountSchemaName, NULL, @accountNameColumn, @baseNormalizeFn + '(N##VALUE##,N''' + @nameNormalizePattern + ''')', @accountCleanDataSchemaName),
			(@countryAndAccountNameRule, @accountAddressSchemaName, @accountSchemaName, @accountCountryColumn, NULL,NULL),
			(@countryAndAccountNameRule, @accountSchemaName, NULL, @accountNameColumn, @baseNormalizeFn + '(N##VALUE##,N''' + @nameNormalizePattern + ''')', @accountCleanDataSchemaName),
			(@AccountInnRule, @accountSchemaName, NULL, @accountInnColumn, @baseNormalizeFn + '(N##VALUE##,N''' + @innNormalizePattern + ''')', NULL),
			(@AccountPhoneRuleUsr, @accountCommunicationSchemaName, @accountSchemaName, @accountCommunicationPhoneColumn,  @phoneNormalizeFn + '(##VALUE##)', NULL),
			(@AccountNameRule, @accountSchemaName, NULL, @accountNameColumn, @baseNormalizeFn + '(N##VALUE##,N''' + @nameNormalizePattern + ''')', @accountCleanDataSchemaName);
 
	INSERT INTO @parsedConfig
	SELECT NULLIF(p.value('(./schemaName)[1]', 'VARCHAR(128)'),'') AS SchemaName,
		NULLIF(p.value('(./parentSchemaName)[1]', 'VARCHAR(128)'),'') AS ParentSchemaName,
		NULLIF(p.value('(./columnName)[1]', 'NVARCHAR(128)'),'') AS ColumnName,
		NULLIF(p.value('(./columnValue)[1]', 'NVARCHAR(4000)'),'') AS ColumnValue,
		NULLIF(p.value('(./typeId)[1]', 'NVARCHAR(128)'),'') AS ColumnValueTypeId
		FROM @xmlBody.nodes('/columns/item') t(p)
 
	UPDATE	@parsedConfig 
	SET ColumnValue = dbo.fn_GetPhoneNumberSearchForm(ColumnValue)
	WHERE ColumnName = @accountCommunicationPhoneColumn
 
	DECLARE activeRuleList CURSOR
	FOR SELECT Id from DuplicatesRule
		WHERE ObjectId = @leadSchemaUId
		AND Id IN (SELECT RuleId FROM @accountRulesConfig)
		AND isActive = 1;
 
	OPEN activeRuleList
	FETCH NEXT
		FROM activeRuleList INTO @ruleId 
 
	WHILE @@FETCH_STATUS = 0
	BEGIN
 
		SET @execStmt = NULL;
		SET @countDetailValues = 0;
		SET @equalQueryConditions = NULL;
		SET @inQueryConditions = NULL;
 
 
		IF EXISTS (SELECT NULL
			FROM @accountRulesConfig config
			LEFT JOIN @parsedConfig parsed
			ON config.ColumnName = parsed.ColumnName
			AND config.SchemaName = parsed.SchemaName
			WHERE parsed.ColumnName IS NULL 
			AND config.RuleId = @ruleId)
		BEGIN 
			FETCH NEXT
			FROM activeRuleList INTO @ruleId
			CONTINUE
		END
		ELSE
		BEGIN	
			IF EXISTS (
				SELECT NULL
					FROM @parsedConfig parsed, @accountRulesConfig config
					WHERE parsed.ColumnName =config.ColumnName
					AND parsed.SchemaName = config.SchemaName
					AND config.ParentSchemaName IS NULL
					AND parsed.ColumnValue IS NULL
					AND config.RuleId = @ruleId)
			BEGIN
				FETCH NEXT
					FROM activeRuleList INTO @ruleId
				CONTINUE
			END
			ELSE
			BEGIN
				DELETE FROM @preStmtValues
				INSERT INTO @preStmtValues (ColumnName, ColumnValue, SchemaName)
				SELECT ISNULL(rulesCfg.CleanDataSchemaName, rulesCfg.SchemaName)+'.'+rulesCfg.ColumnName,
						CASE WHEN NormalizeFnPattern IS NOT NULL THEN 
							REPLACE(NormalizeFnPattern, '##VALUE##', QUOTENAME(parsedCfg.ColumnValue, ''''))
						ELSE QUOTENAME(parsedCfg.ColumnValue, '''') END ColumnValue, 
						ISNULL(rulesCfg.CleanDataSchemaName, rulesCfg.SchemaName)
					FROM @accountRulesConfig rulesCfg, 
						 @parsedConfig parsedCfg
					WHERE rulesCfg.ColumnName = parsedCfg.ColumnName
					AND rulesCfg.SchemaName = parsedCfg.SchemaName
					AND rulesCfg.ParentSchemaName IS NULL
					AND RuleId = @ruleId
 
				SET @queryColumnName = 'Id';
 
				SELECT TOP 1 @schemaName = SchemaName FROM @preStmtValues 
 
				SELECT DISTINCT @inQueryConditions = 
					' AND ' + ColumnName + ' IN (' + STUFF((SELECT ',' + ColumnValue FROM @preStmtValues f 
					WHERE f.ColumnName = t.ColumnName AND f.ColumnName IN (
						SELECT t.ColumnName 
							FROM @preStmtValues t 
						GROUP BY ColumnName HAVING COUNT(*) > 1)
					FOR XML PATH(''), TYPE).value('(./text())[1]','nvarchar(max)'), 1,1, '') +')' FROM @preStmtValues t
 
				SELECT DISTINCT @equalQueryConditions = 
					STUFF((SELECT ' AND ' 
							+ ColumnName + ' LIKE ' 
							+ ColumnValue FROM @preStmtValues f
					WHERE f.ColumnName IN (
						SELECT t.ColumnName 
							FROM @preStmtValues t 
						GROUP BY ColumnName HAVING COUNT(*) = 1) 
					FOR XML PATH(''), TYPE).value('(./text())[1]','nvarchar(max)'), 1,1, '')
 
				SET @execStmt = 
					N'SELECT TOP '+CAST(@offsetLimit as NVARCHAR)+' '+@queryColumnName + CHAR(10) + 
					'FROM '+ CHAR(10) +
					@schemaName + CHAR(10) +
					'WITH (NOLOCK) ' + CHAR(10) +
					'WHERE 1=1'+ CHAR(10);
 
				IF @equalQueryConditions IS NOT NULL
				BEGIN
					SET @execStmt = @execStmt + CHAR(10) + 
					@equalQueryConditions
				END
 
				IF @inQueryConditions IS NOT NULL
				BEGIN
					SET @execStmt = @execStmt + CHAR(10) + 
					@inQueryConditions
				END
 
 
				IF EXISTS (SELECT NULL FROM @accountRulesConfig 
								WHERE RuleId = @ruleId
								AND ParentSchemaName IS NOT NULL)
				BEGIN
					IF EXISTS (
						SELECT NULL
						 FROM @parsedConfig parsed, @accountRulesConfig config
							WHERE parsed.ColumnName =config.ColumnName
								AND parsed.SchemaName = config.SchemaName
								AND parsed.ParentShemaName = config.ParentSchemaName
								AND parsed.ColumnValue IS NOT NULL
								AND config.RuleId = @ruleId)
					BEGIN
 
						DELETE FROM @preStmtValues
						INSERT INTO @preStmtValues (ColumnName, ColumnValue, SchemaName, ColumnValueTypeId)
						SELECT ISNULL(rulesCfg.CleanDataSchemaName, rulesCfg.SchemaName)+'.'+rulesCfg.ColumnName, 
							CASE WHEN NormalizeFnPattern IS NOT NULL THEN 
							REPLACE(NormalizeFnPattern, '##VALUE##', QUOTENAME(parsedCfg.ColumnValue, ''''))
							ELSE QUOTENAME(parsedCfg.ColumnValue, '''') END ColumnValue, 
							ISNULL(rulesCfg.CleanDataSchemaName, rulesCfg.SchemaName),
							ColumnValueTypeId
							FROM @accountRulesConfig rulesCfg, 
								 @parsedConfig parsedCfg
							WHERE rulesCfg.ColumnName = parsedCfg.ColumnName
							AND rulesCfg.ParentSchemaName = parsedCfg.ParentShemaName
							AND rulesCfg.SchemaName = parsedCfg.SchemaName
							AND RuleId = @ruleId
 
 
						SET @queryColumnName = 'AccountId';
 
						IF EXISTS (
							SELECT NULL 
								FROM @phoneCommunicationTypeTable 
								WHERE Id in (SELECT ColumnValueTypeId FROM @preStmtValues f))
						BEGIN 
							INSERT INTO @preStmtValues (ColumnName, ColumnValue, SchemaName)
							SELECT @communicationTypeIdColumn, 
							'''' + CAST(Id AS NVARCHAR(50)) + '''', 
							(SELECT TOP 1 SchemaName FROM @preStmtValues)
							FROM @phoneCommunicationTypeTable
						END
						ELSE 
						BEGIN
							INSERT INTO @preStmtValues (ColumnName, ColumnValue, SchemaName)
							SELECT @communicationTypeIdColumn, 
							'''' + ColumnValueTypeId + '''',
							SchemaName FROM @preStmtValues
							WHERE ColumnValueTypeId IS NOT NULL
						END	
 
						SELECT TOP 1 @schemaName = SchemaName FROM @preStmtValues 
 
						SELECT DISTINCT @inQueryConditions = 
							' AND ' + ColumnName + ' IN (' + STUFF((SELECT ',' + ColumnValue FROM @preStmtValues f 
							WHERE f.ColumnName = t.ColumnName AND f.ColumnName IN (
								SELECT t.ColumnName 
									FROM @preStmtValues t 
								GROUP BY ColumnName HAVING COUNT(*) > 1)
							FOR XML PATH(''), TYPE).value('(./text())[1]','nvarchar(max)'), 1,1, '') +')' FROM @preStmtValues t
 
						SELECT DISTINCT @equalQueryConditions = 
							STUFF((SELECT ' AND ' 
									+ ColumnName + ' LIKE ' 
									+ ColumnValue FROM @preStmtValues f
							WHERE f.ColumnName IN (
								SELECT t.ColumnName 
									FROM @preStmtValues t 
								GROUP BY ColumnName HAVING COUNT(*) = 1) 
							FOR XML PATH(''), TYPE).value('(./text())[1]','nvarchar(max)'), 1,1, '')
 
						IF @execStmt IS NOT NULL
						BEGIN
							SET @execStmt = 
							N'SELECT TOP '+CAST(@offsetLimit as NVARCHAR)+' '+@queryColumnName + CHAR(10) + 
							'FROM ' + CHAR(10) + 
							@schemaName + CHAR(10) +
							'WITH (NOLOCK) ' + CHAR(10) +
							'WHERE '+ @queryColumnName + CHAR(10) + 
							' IN ('	+ @execStmt + ')';
 
							IF @equalQueryConditions IS NOT NULL
							BEGIN
								SET @execStmt = @execStmt + CHAR(10) + 
								@equalQueryConditions;
							END	
 
							IF @inQueryConditions IS NOT NULL
							BEGIN
								SET @execStmt = @execStmt + CHAR(10) + 
								@inQueryConditions;
							END	
 
							INSERT INTO @resultIdsTable
							EXEC sp_executesql @execStmt;
						END
					END
				END
				ELSE
				BEGIN
					INSERT INTO @resultIdsTable
					EXEC sp_executesql @execStmt;
				END
			END
		END
 
	FETCH NEXT
		FROM activeRuleList INTO @ruleId
	END
	CLOSE activeRuleList
	DEALLOCATE activeRuleList
 
	DELETE
		FROM @resultIdsTable
		WHERE Id = @primaryColumnValue
 
	SELECT DISTINCT TOP (@offsetLimit) Id 
		FROM @resultIdsTable
 
END

 

Нравится

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

Здравствуйте, Данил!

Кастомизация правил поиска похожих лидов осуществляется по инструкции ниже.

1. Необходимо добавить скриптом новое правило в таблицу DuplicatesRule.

Пример скрипта:

insert into DuplicatesRule

(Name, IsActive, ObjectId)

values

('Имя правила', 1, '41AF89E9-750B-4EBB-8CAC-FF39B64841EC')

 

2. Заместить хранимую процедуру tsp_FindAccountSimilarRecordsMSSQL (для примера поиска по контрагентам, по контактам соответственно tsp_FindContactSimilarRecordsMSSQL). Для этого необходимо скопировать весь код из tsp_FindAccountSimilarRecordsMSSQL и дублировать его в новый SQL Script.

3. Объявить своё правилj в блоке с остальными правилами, где указать id добавленного правила с пункта 1 (из таблицы DuplicatesRule) http://prntscr.com/e2m5wz

4. Аналогично существующим правилам, добавить и своё в @accountRulesConfig http://prntscr.com/e2m72y

Например, если правило только для Телефона, копируем выделенную строчку на скриншоте и заменяем название правила на кастомное: http://prntscr.com/i5yogj 

5. Сохранить хранимую процедуру и выполнить установку в БД.

Если привязаться к Вашему коду, то ошибка вероятнее всего в п. 4. , т.к. правило определено неправильно: http://prntscr.com/i5yppg

 

Приятной работы

 

Пробовал и полностью скопировав это правило (если вы про отсутствие @accountCleanDataSchemaName в конце) - не работает.

Что интересно, если я прописываю правило с поиском по ИНН+Телефон, то поиск отрабатывает корректно - проверяет совпадение в обоих полях. Но как только пробую оставить ТОЛЬКО по телефону, то такая дедубликация не работает.

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

Правила поиска дублей для похожих контрагентов/контактов в лиде сделаны таким образом, что нет возможности обращаться отдельно к таблице средств связи, по которой и происходит поиск только по телефону. Логика хранимых процедур была написана с учётом базовых правил, которые предполагают поиск похожих контактов/контрагентов только по правилам, которые включают поиск в таблице Account/Contact плюс таблица средств связи. А обращение только к таблице средств связи в текущей реализации хранимой процедуры не предусмотрено.

Для работы своего правила только по телефону или любого другого средства связи, необходимо внести изменения в хранимую процедуру tsp_FindAccountSimilarRecords, а именно вместо блока "IF @execStmt IS NOT NULL..."  (http://prntscr.com/ibe672) добавить код ниже:



               SET @detailsSelectQuery = N'SELECT TOP '+ CAST(@offsetLimit as NVARCHAR) +

                ' ' + @queryColumnName + CHAR(10) + 

                'FROM ' + CHAR(10) + @schemaName + CHAR(10) +

                'WITH (NOLOCK) ' + CHAR(10) +

                'WHERE 1=1 ';



                IF @execStmt IS NOT NULL

                BEGIN

                    SET @detailsSelectQuery = 

                    @detailsSelectQuery + CHAR(10) + 'AND' + CHAR(10) + @queryColumnName + CHAR(10) + ' IN ('    + @execStmt + ')';

                END



                IF @equalQueryConditions IS NOT NULL

                BEGIN

                    SET @detailsSelectQuery = @detailsSelectQuery + CHAR(10) + 

                    @equalQueryConditions;

                END



                IF @inQueryConditions IS NOT NULL

                BEGIN

                    SET @detailsSelectQuery = @detailsSelectQuery + CHAR(10) + @inQueryConditions;

                END



                IF @detailsSelectQuery IS NOT NULL

                BEGIN

                    INSERT INTO @resultIdsTable

                    EXEC sp_executesql @detailsSelectQuery;

                END

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

При выборе в заказе дополнительную единицу измерения (например, упак = 10 шт, шт - базовая ед.измерения), то цена остается за базовую единицу, а сумма считается с учетом коэффициента. Сумма считается верно, а вот цена остается за базовую единицу. В печатной форме выводятся недостоверные данные. 

Например, 

 Товар1 стоит 5 руб. за шт.

В заказе 1 упак ( упак = 10 шт)

Сумма = 5*1*10 = 50 руб, все верно. В печатной же форме заказе получается так 5*1=50

 

Как быть в такой ситуации? 

Нравится

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

Добрый день, Ильмир!

Печатная форма только отображает значения из тех полей, которые вытянули в нее. На данный момент в базовом функционале системы просто нет возможности выводить агрегированные колонки в редактируемом реестре (к которым и относиться продукт в заказе/счете, график поставок и оплат и т.д.). В данном случае Вы можете реализовать обработчик на поле "Цена", в котором записывать значение = Базовая цена продукта * Количество единиц измерения из детали "Единицы измерения" в продукте. С примерами добавления расчетных полей можно ознакомиться здесь: https://academy.terrasoft.ua/documents/technic-sdk/7-11/dobavlenie-vych…;

 

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

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

Новые данные беру из базы.

Вот код метода:

IsKeyContact: function() {
				var isKeyContact = this.get("UsrIsKeyContact");
				var self = this;
				var oldLoyality = self.get("UsrContactLoyality");
 
				var esq = Ext.create("Terrasoft.EntitySchemaQuery", { rootSchemaName: "UsrContactLoyality"});
				esq.addColumn("Name");
				if (isKeyContact)
				{
					esq.filters.add("Name", Terrasoft.createColumnFilterWithParameter(
						Terrasoft.ComparisonType.EQUAL, "Name", "Лояльный"));
					esq.getEntityCollection(function(result) {
						if (result.success) {
							Terrasoft.each(result.collection.getItems(), function(item) {
								self.log(item.values);
								self.set("UsrContactLoyality", item.values);
							});
						}
					});
				}
				else
				{
					esq.filters.add("Name", Terrasoft.createColumnFilterWithParameter(
						Terrasoft.ComparisonType.EQUAL, "Name", "Неопределенна"));
					esq.getEntityCollection(function(result) {
						if (result.success) {
							Terrasoft.each(result.collection.getItems(), function(item) {
								self.log(item.values);
								self.set("UsrContactLoyality", item.values);
							});
						}
					});
				}
			}

 

Нравится

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

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

Подскажите может я не так делаю что.

При изменении значения получаю ошибку в консоли:

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

 

define("ContactPageV2", [], function() {
	return {
		entitySchemaName: "Contact",
		details: /**SCHEMA_DETAILS*/{}/**SCHEMA_DETAILS*/,
		attributes: {
			"UsrContactLoyality": {
				"dataValueType": Terrasoft.DataValueType.LOOKUP,
				"dependencies": [
					{
						"columns": ["UsrIsKeyContact"],
						"methodName": "IsKeyContact"
					}
				]
			}
		},
		modules: /**SCHEMA_MODULES*/{
			IsKeyContact: function() {
				var isKeyContact = this.get("UsrIsKeyContact");
				this.log(isKeyContact);
			}
 
		}/**SCHEMA_MODULES*/,
		diff: /**SCHEMA_DIFF*/[
			{
				"operation": "merge",
				"name": "PhotoTimeZoneContainer",
				"values": {
					"layout": {
						"colSpan": 24,
						"rowSpan": 1,
						"column": 0,
						"row": 0
					}
				}
			},
			{
				"operation": "merge",
				"name": "AccountName",
				"values": {
					"layout": {
						"colSpan": 24,
						"rowSpan": 1,
						"column": 0,
						"row": 1
					}
				}
			},
			{
				"operation": "merge",
				"name": "JobTitleProfile",
				"values": {
					"layout": {
						"colSpan": 24,
						"rowSpan": 1,
						"column": 0,
						"row": 2
					}
				}
			},
			{
				"operation": "merge",
				"name": "AccountMobilePhone",
				"values": {
					"layout": {
						"colSpan": 24,
						"rowSpan": 1,
						"column": 0,
						"row": 3
					}
				}
			},
			{
				"operation": "merge",
				"name": "AccountPhone",
				"values": {
					"layout": {
						"colSpan": 24,
						"rowSpan": 1,
						"column": 0,
						"row": 4
					}
				}
			},
			{
				"operation": "merge",
				"name": "AccountEmail",
				"values": {
					"layout": {
						"colSpan": 24,
						"rowSpan": 1,
						"column": 0,
						"row": 5
					}
				}
			},
			{
				"operation": "merge",
				"name": "Type",
				"values": {
					"layout": {
						"colSpan": 12,
						"rowSpan": 1,
						"column": 0,
						"row": 0
					}
				}
			},
			{
				"operation": "merge",
				"name": "Owner",
				"values": {
					"layout": {
						"colSpan": 12,
						"rowSpan": 1,
						"column": 12,
						"row": 0
					}
				}
			},
			{
				"operation": "merge",
				"name": "SalutationType",
				"values": {
					"layout": {
						"colSpan": 12,
						"rowSpan": 1,
						"column": 0,
						"row": 1
					}
				}
			},
			{
				"operation": "merge",
				"name": "Gender",
				"values": {
					"layout": {
						"colSpan": 12,
						"rowSpan": 1,
						"column": 12,
						"row": 1
					}
				}
			},
			{
				"operation": "merge",
				"name": "Language",
				"values": {
					"layout": {
						"colSpan": 12,
						"rowSpan": 1,
						"column": 12,
						"row": 2
					}
				}
			},
			{
				"operation": "insert",
				"name": "GeneralInfoTabGroup226c48fc",
				"values": {
					"caption": {
						"bindTo": "Resources.Strings.GeneralInfoTabGroup226c48fcGroupCaption"
					},
					"itemType": 15,
					"markerValue": "added-group",
					"items": []
				},
				"parentName": "GeneralInfoTab",
				"propertyName": "items",
				"index": 5
			},
			{
				"operation": "insert",
				"name": "GeneralInfoTabGridLayout1e39f378",
				"values": {
					"itemType": 0,
					"items": []
				},
				"parentName": "GeneralInfoTabGroup226c48fc",
				"propertyName": "items",
				"index": 0
			},
			{
				"operation": "insert",
				"name": "UsrIsKeyContactb6f672ab-d08b-41ef-9f88-33af0ac7f901",
				"values": {
					"layout": {
						"colSpan": 12,
						"rowSpan": 1,
						"column": 0,
						"row": 0,
						"layoutName": "GeneralInfoTabGridLayout1e39f378"
					},
					"bindTo": "UsrIsKeyContact"
				},
				"parentName": "GeneralInfoTabGridLayout1e39f378",
				"propertyName": "items",
				"index": 0
			},
			{
				"operation": "insert",
				"name": "UsrContactLoyalityd61aa5f3-dda2-413b-8e76-ea6a0cc95c03",
				"values": {
					"layout": {
						"colSpan": 12,
						"rowSpan": 1,
						"column": 12,
						"row": 0,
						"layoutName": "GeneralInfoTabGridLayout1e39f378"
					},
					"bindTo": "UsrContactLoyality"
				},
				"parentName": "GeneralInfoTabGridLayout1e39f378",
				"propertyName": "items",
				"index": 1
			},
			{
				"operation": "merge",
				"name": "Job",
				"values": {
					"layout": {
						"colSpan": 12,
						"rowSpan": 1,
						"column": 0,
						"row": 0
					}
				}
			},
			{
				"operation": "merge",
				"name": "JobTitle",
				"values": {
					"layout": {
						"colSpan": 12,
						"rowSpan": 1,
						"column": 12,
						"row": 0
					}
				}
			},
			{
				"operation": "merge",
				"name": "Department",
				"values": {
					"layout": {
						"colSpan": 12,
						"rowSpan": 1,
						"column": 0,
						"row": 1
					}
				}
			},
			{
				"operation": "merge",
				"name": "DecisionRole",
				"values": {
					"layout": {
						"colSpan": 12,
						"rowSpan": 1,
						"column": 12,
						"row": 1
					}
				}
			}
		]/**SCHEMA_DIFF*/,
		methods: {},
		rules: {},
		businessRules: /**SCHEMA_BUSINESS_RULES*/{}/**SCHEMA_BUSINESS_RULES*/
	};
});

 

Нравится

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

Добрый день

У вас метод IsKeyContact находится в секции modules, а должен в methods

Артем Гура,

И правда, спасибо большое.

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

Добрый день, ситуация такова: в разделе "лиды" есть 2 страницы для редактирования. На одной из них присутствуют AccountProfile и ContactProfile. Нужно добавить их и на другую страницу, скажите пожалуйста можно ли это сделать и как?

Нравится

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

Добрый день, Вячеслав!

Когда в мастере разделов вы добавили еще одну страницу редактирования, она была сгенерирована и добавленна в конфигурацию.

Для того, что бы добавить страницы редактирования AccountProfile и ContactProfile на новую страницу необходимо в конфигурации внести изменения в код этой страницы, либо создать замещающую страницу.

Пример добавления AccountProfile на страницу ContactPageV2.

define("ContactPageV2", ["BaseFiltersGenerateModule", "BusinessRuleModule", "ContactPageV2Resources",           
"ConfigurationConstants", "ContactCareer", "DuplicatesSearchUtilitiesV2"], 
function (BaseFiltersGenerateModule, BusinessRuleModule, resources, ConfigurationConstants, ContactCareer) {    
	return {        
		entitySchemaName: "Contact",        
		// Используемые модули.          
		modules: /**SCHEMA_MODULES*/{            
			// Модуль профиля контрагента.            
			"AccountProfile": {                
				// Конфигурация профиля.                
				"config": {                    
					// Название схемы.                    
					"schemaName": "AccountProfileSchema",                    
					// Признак, сообщающий о том, что конфигурация схемы проинициализирована.                    
					"isSchemaConfigInitialized": true,                   
					// Признак, сообщающий о том, что не используется HistoryState.                    
					"useHistoryState": false,                    
					// Параметры профиля.                    
					"parameters": {                       
						// Конфигурация модели представления.                        
						"viewModelConfig": {                            
							// Название колонки связанной сущности.                            
							masterColumnName: "Account"                        
 
						}                    
 
					}                
 
				}            
 
			}        
 
		}/**SCHEMA_MODULES*/,
		// Массив модификаций.        
		diff: /**SCHEMA_DIFF*/[            
			{                
				"operation": "insert",                
				"parentName": "LeftModulesContainer",                
				"propertyName": "items",               
				// Название профиля.                
				"name": "AccountProfile",                
				// Значения.                
				"values": {                  
					// Тип элемента — модуль.                    
					"itemType": Terrasoft.ViewItemType.MODULE              
					}           
					}    
					]/**SCHEMA_DIFF*/    
 
	}; 
 
});

 

Также Вы можете открыть в конфигурации LeadPageV2 и ознакомиться с реализацией добавления AccountProfile и ContactProfile.

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

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

Код установки значения:

 

 Terrasoft.Core.Configuration.SysSettings.SetDefValue(_userConnection, "CRMTMessagesOffset", _messageOffset);
_userConnection.ResetSettingsCache("CRMTMessagesOffset");

 

Нравится

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

Дмитрий, 

Следующий код работает:

//Установить значение системной настройки
Terrasoft.Core.Configuration.SysSettings.SetValue(UserConnection, "SysSettingsName","SysSettingsValue");
 
//Установить значение системной настройки без учета прав
Terrasoft.Core.Configuration.SysSettings.SetValue(UserConnection, UserConnection.RootAdminUnitGroupId, "SysSettingsName", "SysSettingsValue");



                                        

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

Добрый день.

Посчитали "совмещенный" режим не самым полезным для пользователя. Да и повторять логику отображения и доступности кнопок из Page в Section с помощью месседжей - не самый удобный вариант. В связи с этим решили открывать карточку объекта только в Page режиме, минуя совмещенный с реестром. Т.е. чтобы при нажатии на кнопку открыть в реестре, объект открывался только в режиме редактирования. Каким образом это реализовать? Может кто-то уже сталкивался с подобным кейсом?

Нравится

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

самый простой вариант (как мне кажется) переопределить метод

editRecord: function(primaryColumnValue) {
	var activeRow = this.getActiveRow();
	var typeColumnValue = this.getTypeColumnValue(activeRow);
	var schemaName = this.getEditPageSchemaName(typeColumnValue);
	this.set("ShowCloseButton", true);
	this.openCard(schemaName, ConfigurationEnums.CardStateV2.EDIT, primaryColumnValue);
},

в BaseSectionV2 и открывать карточку через window.open()

А можете привести пример синтаксиса использования windows.open()?

editRecord: function(primaryColumnValue) {
	var activeRow = this.getActiveRow();
	var typeColumnValue = this.getTypeColumnValue(activeRow);
	var schemaName = this.getEditPageSchemaName(typeColumnValue);
	this.set("ShowCloseButton", true);
	window.open(Terrasoft.combinePath(Terrasoft.workspaceBaseUrl,"Nui/ViewModule.aspx#CardModuleV2",schemaName, ConfigurationEnums.CardStateV2.EDIT, primaryColumnValue));
	//this.openCard(schemaName, ConfigurationEnums.CardStateV2.EDIT, primaryColumnValue);
}

 

вот еще пример метода как Из карточки детали выполняется открытие счета сразу на редактирование:

 

openInvoicePage: function(invoiceId) {
   var config = {
         schemaName: "InvoicePageV2",
         operation: enums.CardStateV2.EDIT,
         id: invoiceId,
         moduleId: this.getInviocePageSandboxId()
   };
   this.sandbox.publish("OpenCard", config, [this.sandbox.id]);
},

 

Это же можно повторить и для Схем Реестров, Вызов Метода осуществляете предварительно получив Id сущности, что хотите открыть на редактирование из реестра.

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

Добрый день!

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

Нравится

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

Здравствуйте, Александр!

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

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

Приветствую Александр.

у меня данная задача уже решалась в рамках одного из проектов. Постучитесь ко мне с напоминанием после 01 февраля я с вами поделюсь примером реализации. Только реализовывалось у меня в рамках конфигурации BPMOnline Sales Enterprise. Но поидее функционал Дашбоардов стандартный, должно заработать и на других конфигурациях.

Власов Михаил Викторович, добрый день!

Спасибо за предложение! Обязательно напишем. 

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

Добрый день!

Возник вопрос в организации работы менеджера - можно ли сделать отображение дашборда в определенное время (например один дашборд доступен с 8 до 13, а второй дашборд с 14 до 17) и если можно, то как реализовать (быть может через процесс ограничения прав доступа)?

Нравится

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

Интересная задача, но должна решаться стандартным БП, который запускается с определенной регулярностью, и в зависимости от времени перераспределяет права на dashboard

Я бы решил данную задачу создав Константные временные рамки. Привязал бы данный справочник к Сущности Дашбоард и далее При отображении Дашбоардов фильтровал какие показывать какие нет. Создание 1 нового Справочника, Создание ссылки. Доработка страниц по отрисовки и отображению Дашбоардов. Все. Более я не вижу других идей как быстрее сделать. Так как идти в сторону Прав это интересно. Но это больше времени по доработкам.

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

Добрый день!

На маркетплэйсе в данный момент существует только одно решение по интеграции скриптов телефонных продаж в CRM (коннектор скриптдизайнер).

Скажите пожалуйста, быть может кто-то пробовал реализовывать скрипты продаж своими способами (может даже внутренними средствами bpm: через бизнес-процессы)?

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

Нравится

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

Здравствуйте, Александр!

Для решения вашей бизнес цели Вы можете использовать базовый функционал bpm'online, например, создать бизнес процесс, который будет запускаться по сигналу Звонок. После чего будет выполнять переход по созданным страницам (элемент "Автогенерируемая страница"). 

Альтернативный вариант, чтобы не нагружать систему по "сигналу Звонок" Вы можете назначить операторам организационную роль "Оператор КЦ", тогда на CTI - панели будут отображаться бизнес процессы которые можно запускать во время звонка. Указываются в справочнике "Действия cti панели".

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