Коллеги, добрый вечер!

Мы реализовали действие в разделе Юр. лиц, которое инициирует загрузку данных из сервиса СПАРК и записывает их в базу с помощью хранимой процедуры. Возникла проблема, связанная с тем, что по загруженным Юр. лицам не запускаются процессы (стартовые события процессов - сигнал добавление/изменение).

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

Нравится

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

Небольшое дополнение - в действии используется метод showBodyMask (this.showBodyMask();) для отображения анимации загрузки. Если это важно.

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

Стартовые сигналы не реагируют на прямые запросы к БД (добавление/изменение/удаление записей).
Сигналы срабатывают если запрос выполняется через EntitySchemaQuery - https://academy.terrasoft.ua/documents/technic-sdk/7-9/rabota-s-dannymi
Вы можете решить вашу задачи с помощью триггеров в БД или создать процесс, который будет периодически запускаться с помощью планировщика и обрабатывать интересующие записи.

Поясните, пожалуйста, ваш ответ. EntitySchemaQuery используется для чтения данных.

У нас также реализована загрузка данных через конфигурационный сервис с помощью механизма - https://academy.terrasoft.ua/documents/technic-sdk/7-9/postroenie-zapro….

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

В конфигурационном сервисе тоже нужна дополнительная логика?

Сергей, здравствуйте!

Классы Insert, Update, Delete не вызывают срабатывания сигналов, поскольку запись не ведется на уровне ESQ.

Таким образом процессы запущены не будут.

Пример работы с ESQ можно найти в схеме ImapClient метод SaveActivityParticipants. При таком создании записей процессы будут запущены.

Коллеги, а триггеры в БД имеется в виду на добавление/изменение?

Если у нас будет обновление поля через ESQ и одновременно будет создан триггер на изменение этого поля в БД, не будет ли двойного срабатывания стартового события одного и того же процесса?

И какая логика должна выполняться после срабатывания триггера в БД?

Сергей, здравствуйте!

"Сергей Фролов КРОК" написал:

Коллеги, а триггеры в БД имеется в виду на добавление/изменение?

Если у нас будет обновление поля через ESQ и одновременно будет создан триггер на изменение этого поля в БД, не будет ли двойного срабатывания стартового события одного и того же процесса?

Как было сказано ранее - если операции происходит на уровне сервера БД (процедуры, триггеры, прямые запросы в БД), то процессы срабатывать не будут. По этой причине процесс сработает только по запросу ESQ - триггеры не запустят второй экземпляр процесса.

Спасибо за информацию!

Подскажите, а как должен выглядеть триггер в БД, инициирующий запуск процессов?

"Сергей Фролов КРОК" написал:Подскажите, а как должен выглядеть триггер в БД, инициирующий запуск процессов?

Я надеюсь вопрос не про кварц тригеры? Механизм который позволяет запускать процессы по расписанию.
https://academy.terrasoft.ru/documents/technic-sdk/7-4-0/zapusk-process…

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

var entitySchemaManager = _userConnection.GetSchemaManager("EntitySchemaManager") as EntitySchemaManager;
var activityParticipantSchema = entitySchemaManager.GetInstanceByName("ActivityParticipant");
var activityParticipant = activityParticipantSchema.CreateEntity(_userConnection) as ActivityParticipant;
activityParticipant.SetDefColumnValues();
activityParticipant.ActivityId = _currentEmailActivityId;
activityParticipant.ParticipantId = contactId;
activityParticipant.RoleId = roleId;
activityParticipant.Save();

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

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

Подскажите пожалуйста, можно ли в bpm настроить интервал синхронизации с почтой? Например, подключено несколько почтовых ящиков (ящик1@mail.ru, ящик2@mail.ru). Мне нужно, чтобы письма с ящика ящик1@mail.ru синхронизировались в течении 1 минуты, а ящик2@mail.ru - 60 минут.
Присутствует системная настройка "Интервал синхронизации с почтовым ящиком", но эта настройка применяется, как я понимаю, для всех ящиков.

Нравится

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

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

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

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

Доброго времени суток, коллеги.
Клиент TerrasoftCRM 3.3.2.245
Такая проблема: на основании данного форума я сделал сервис SelectQuery:

SELECT
        1 AS [a] INTO #tmp
DROP TABLE #tmp

EXEC GetMissingDocuments
/*  AS [FakeHeader],
         AS [DocNumber],
         AS [TaskID],
        */

IF 1=0
SELECT 1 AS [FakeFooter]
FROM
        [dbo].[tbl_DatabaseInfo] AS [tbl_DatabaseInfo]

и вызывал через него хранимую процедуру. Вызывал так:
[js]
var SelectQuery = GetSingleItemByCode('sq_GetMissingDocuments', 'GetMissingDocumentsTasks');
var Result = SelectQuery.Open();
[/js]
Пока база работала на MS SQL Server 2005 все было нормально. После перехода на SQL Server 2008 R2 при вызове SelectQuery.Open() получаю ошибку "Ошибка открытия источника данных "".
Оригинальное сообщение об ошибке: Неопознанная ошибка". Причем если выполнить этот запрос в SSMS, то он выполняется корректно. В SQL Server Profiler ошибок тоже нет. На клиентском компьютере установлена версия SQL Native Client 2008 R2. Куда еще можно копнуть?

Нравится

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

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

"Зверев Александр" написал:Можно переделать логику чисто на скрипт, без сервиса.

Моя хранимая процедура возвращает таблицу. Ее можно завернуть в выходной параметр хранимой процедуры?

Можно процедуру в функцию переделать, с функциями в 2008 проблем не было. Также см. обсуждение, там тоже под новую версию переделывали.

"Зверев Александр" написал:Можно процедуру в функцию переделать

Попробую конечно, но все равно не понятно. У меня в базе есть еще одна аналогичная конструкция. Отличается тем, что ХП в ней получает параметры и результат достается через Dataset и отображается на форме. И она прекрасно работает.

Подобные способы использования что процедуры, что функции являются «хаком» и обходом стандартного поведения сервиса sq, их работа всегда и везде не гарантируется. Возможно, в 2008 что-то изменилось в движке работы с БД.

"Riptor" написал:И она прекрасно работает.

Это хорошо.:cool:

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

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

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

Нравится

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

Здравствуйте, Илья.

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

Более подробно с процессом обновления пакета из SVN выможете ознакомиться по ссылке: https://academy.terrasoft.ru/documents/technic-sdk/7-9/obnovlenie-paket….

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

В типовом окне выбора как и положено у модальных окон - присутствует элемент управления модальным окном "закрыть".
:smile: в простонародии: "крестик"

Вопрос: Существует ли какая либо конфигурационная настройка на этот счет для вызова окна через openLookup(config)
Т.к. в нашем случае бизнес-логика в идеале предусматривает безусловную реакцию пользователя на предложенный выбор, хотелось бы вместо обработки результатов, просто исключить у пользователя "далее-далее-крестик-крестик-готовщика" возможность закрыть это окно.

PS: Отключение кнопки закрытия окна, тоже не silver bullet т.к. пользователь просто может нажать "выбрать" - ничего на самом деле не выделив. И как сопутствующий вопрос - можно ли регулировать это поведение в типовом окне выбора, таким образом чтобы кнопка "Выбрать" например была не активной пока пользователь не произведет выбор, или например генерировала уведомление об обязательности выбора значения ?

Нравится

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

Здравствуйте,
Вы конечно можете написать глобальный css стиль который скроет крестик, или переписать LookupPageViewGenerator для блокировки кнопки выбор. Но логичнее наверно прописать обязательность заполнения лукапного поля, на странице, на которой данный лукап и выбирается. Безусловно или по условию: https://academy.terrasoft.ru/documents/technic-sdk/7-8/pravilo-bindpara…

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

В типовом окне выбора как и положено у модальных окон - присутствует элемент управления модальным окном "закрыть".
:smile: в простонародии: "крестик"

Вопрос: Существует ли какая либо конфигурационная настройка на этот счет для вызова окна через openLookup(config)
Т.к. в нашем случае бизнес-логика в идеале предусматривает безусловную реакцию пользователя на предложенный выбор, хотелось бы вместо обработки результатов, просто исключить у пользователя "далее-далее-крестик-крестик-готовщика" возможность закрыть это окно.

PS: Отключение кнопки закрытия окна, тоже не silver bullet т.к. пользователь просто может нажать "выбрать" - ничего на самом деле не выделив. И как сопутствующий вопрос - можно ли регулировать это поведение в типовом окне выбора, таким образом чтобы кнопка "Выбрать" например была не активной пока пользователь не произведет выбор, или например генерировала уведомление об обязательности выбора значения ?

Нравится

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

Здравствуйте,
Вы конечно можете написать глобальный css стиль который скроет крестик, или переписать LookupPageViewGenerator для блокировки кнопки выбор. Но логичнее наверно прописать обязательность заполнения лукапного поля, на странице, на которой данный лукап и выбирается. Безусловно или по условию: https://academy.terrasoft.ru/documents/technic-sdk/7-8/pravilo-bindpara…

Обязательность поля для заполнения в данном случае не очень подходит, вернее базовая логика обработки "не заполненности" обязательных полей- т.к. в случае обязательности поля - пользователю выводится сообщение о том, что не заполнено одно или несколько обязательных полей, перечисляются их наименования, и сохранение карточки прерывается, после чего карточка остается в режиме ввода данных т.е. подразумевается что пользователь найдет указанные в сообщении поля, заполнит их и нажмет "Сохранить".
Во-первых работать с карточкой невозможно пока не закроешь оповещение в котором указаны поля для заполнения. (А стало быть пользователю надо их запомнить или записать :cry: в идеале такие уведомления надо делать интегрированными в UI а не модальной нотификацией, так как сделаны предупреждения и ошибки в конфигураторе например, текст которых остается видимым и с интерфейсом можно продолжить работу)
Во-вторых в некоторых карточках очень перегруженный интерфейс и поиск самого поля которое необходимо заполнить во множестве вкладок и т.д. - отнимает время у сотрудника (если это горячая линия, то эти 10-20 секунд в конечном итоге превращаются в минуты которые никому из клиентов ждать не хочется)
В третьих, если у Вас бизнес-логика подразумевает фиксацию совершения какого либо действия во времени, то в данном случае Вам потребуется вводить дополнительную проверку в логику сохранения карточки (т.к. фактически заполнение произойдет когда-то потом а не по нажаию кнопки) а не совершения какого либо действия чтобы отметить время совершения.
Ну и в конце концов - это просто удобно для пользователя, чтобы система предлагала ему выбор автоматически, если он что-то забыл.

Добрый день.

Магической системной настройки, убирающей отображение кнопки "закрыть" нету, необходимо переписывать логику самого модального окна. Вам стоит обратить внимание на 3 схемы: LookupPage, LookupPageViewGenerator и LookupPageViewModelGenerator. Для удаления кнопки закрыть - Вам стоит смотреть в сторону удаления кода генерации closeIconContainer в LookupPageViewGenerator. Для изменения логики кнопки "Выбрать" - переопределить конфиг для SelectButton в LookupPageViewGenerator, а также добавить логику в LookupPageViewModelGenerator.

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

Добрый день!

Доводилось ли кому реализовывать функционал для сложных взаимосвязей в холдинге?

Конкретно, несколько задач:
1) У одной компании может быть несколько "материнских компаний" - акционеров.
2) Между компаниями могут быть дополнительные взаимосвязи
3) В итоге на связях должны и присутствовать контакты - бенефициары
4) На схеме необходимо отображать и другие типы связей, а не только "holding - affiliate)

Думаю, что для банков такое должны были делать.

connected to

Нравится

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

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

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

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

Доброго времени суток!
Требует помощь с пониманием как работает TimezoneContainer у контакта, для того чтобы по аналогии сделать её для контрагента. Кто с таким сталкивался, прошу помощи.

Нравится

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

уууух. пришло время костылей

define("AccountPageV2", ["TimezoneGenerator", "TimezoneMixin"], function() {
	return {
	entitySchemaName: "Account",
	mixins: {
		TimezoneMixin: "Terrasoft.TimezoneMixin"
	},
	methods: {
		onEntityInitialized: function() {
			this.callParent(arguments);
			this.mixins.TimezoneMixin.init.call(this);
		},
		onDetailChanged: function(detail) {
			this.callParent(arguments);
			if (detail.schemaName === "AccountAddressDetailV2") {
				this.updateTimezone();
			}
		},
		updateTimezone: function() {
			this.mixins.TimezoneMixin.init.call(this);
		},
		setContactTimeConfig: function(accId, callback, scope) { //метод из TimeZoneMixin, его надо расковырять
			var func = function(contactTimeConfig) {
				var isValid = this.isConfigValid(contactTimeConfig);
				if (isValid) {
					this.set("ContactTimeConfig", contactTimeConfig);
					if (callback && this.Ext.isFunction(callback)) {
						callback.call(scope);
					}
				} else {
					this.log(Resources.localizableStrings.ContactTimeConfigInvalidFormatException,
							Terrasoft.LogMessageType.WARNING);
				}
			};
			this.getAccountTimeZone(func, accId);
		},
		getAccountTimeZone: function(callback, accId) {
			var esq = Ext.create("Terrasoft.EntitySchemaQuery", { rootSchemaName: "AccountAddress"});
			esq.addColumn("City.TimeZone.Name", "TZName");
			esq.addColumn("City.TimeZone.Offset", "Offset");
			esq.addColumn("City.Name", "CityName");
			esq.filters.addItem(esq.createColumnFilterWithParameter(3, "Account", accId));
			esq.getEntityCollection(function (result) {
				var info = result.collection.collection.items[0].values; //По-идее нужно лезть в кучу миксинов/утилит/хелперов с сервисами, но можно и так вытащить инфу по городу. Тут я беру 1 попавшийся из AccountAddress. Можно дополнить фильтрами
				var offset = info.Offset === "GMT" ? 0 : parseInt(info.Offset.split("GMT")[1].split(":")[0]);
				var time = new Date(new Date().getUTCFullYear(), new Date().getUTCMonth(), new Date().getUTCDate(), new Date().getUTCHours(), new Date().getUTCMinutes(), new Date().getUTCSeconds());
				time.setUTCHours(time.getUTCHours() + offset);
				var contactTimeConfig = {
					equals: true,
					location: info.CityName,
					minutesOffset: offset*60,
					time: time,
					timeZone: info.TZName
				};
				this.callback.call(this.scope, contactTimeConfig);
			}.bind({callback: callback, scope: this}));
		}
	},
	diff: [
		{
			"operation": "insert",
			"name": "TimeZoneContainer",
			"parentName": "AccountPhotoContainer",
			"propertyName": "items",
			"values": {
				"itemType": Terrasoft.ViewItemType.CONTAINER,
				"generator": "TimezoneGenerator.generateTimeZone",
				"wrapClass": ["timezone-container"],
				"visible": true,
				"timeZoneCaption": {"bindTo": "TimeZoneCaption"},
				"timeZoneCity": {"bindTo": "TimeZoneCity"},
				"tips": []
			}
		}
	]};
});

Ну и ещё надо навесить немного стилей (пр. убрать часы под контейнер с обогащение данных). Но мне лень)

Варфоломеев Данила, благодарю)
Дальше разберусь что да как.

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

Добрый день.
В договоре сделал бизнес правило для блокировки всех полей в заголовке если поле "Состояние" выбрано: Подписан.
1F703F42-F7E8-4E3F-9B54-2B85F62EA507 - это id состояния "Подписан"
В общем поля блокируются в любом случае даже если выбрано другое состояние, а мне надо, блокировать поля в случае если выбрано только значение "Подписан".

Как исправить?

rules: {
        "Number": {
                // Правило зависимости доступности поля [Рабочий телефон] от значения в поле [Мобильный телефон].
                "BindParameterDisabledNumber": {
                        // Тип правила BINDPARAMETER.
                        "ruleType": BusinessRuleModule.enums.RuleType.BINDPARAMETER,
                        // Правило регулирует свойство ENABLED.
                        "property": BusinessRuleModule.enums.Property.ENABLED,
                        // Массив условий, при выполнении которых отрабатывает правило. В данном
                        // случае массив содержит одно условие для определения, установлено ли значение.
                        "conditions": [{
                                // Выражение левой части условия.
                                "leftExpression": {
                                        // Тип выражения ATTRIBUTE указывает на то, что в качестве выражения выступает
                                        // атрибут (колонка) модели представления.
                                        "type": BusinessRuleModule.enums.ValueType.ATTRIBUTE,
                                        // Название колонки модели представления, значение которой сравнивается в выражении.
                                        "attribute": "State"
                                },
                                // Тип операции сравнения.
                                "comparisonType": Terrasoft.ComparisonType.EQUAL,
                                // Выражение правой части условия.
                                "rightExpression": {
                                        // Тип выражения CONSTANT указывает на то, что в качестве значения выражения выступает
                                        // константное значение.
                                        "type": BusinessRuleModule.enums.ValueType.CONSTANT,
                                        // Значение, с которым сравнивается выражение левой части.
                                        "value": "1F703F42-F7E8-4E3F-9B54-2B85F62EA507"
                                }
                        }]
                }
        },
        "Owner": {
                // Правило зависимости доступности поля [Рабочий телефон] от значения в поле [Мобильный телефон].
                "BindParameterEnabledOwnerr": {
                        // Тип правила BINDPARAMETER.
                        "ruleType": BusinessRuleModule.enums.RuleType.BINDPARAMETER,
                        // Правило регулирует свойство ENABLED.
                        "property": BusinessRuleModule.enums.Property.ENABLED,
                        // Массив условий, при выполнении которых отрабатывает правило. В данном
                        // случае массив содержит одно условие для определения, установлено ли значение.
                        "conditions": [{
                                // Выражение левой части условия.
                                "leftExpression": {
                                        // Тип выражения ATTRIBUTE указывает на то, что в качестве выражения выступает
                                        // атрибут (колонка) модели представления.
                                        "type": BusinessRuleModule.enums.ValueType.ATTRIBUTE,
                                        // Название колонки модели представления, значение которой сравнивается в выражении.
                                        "attribute": "State"
                                },
                                // Тип операции сравнения — не равно.
                                "comparisonType": Terrasoft.ComparisonType.EQUAL,
                                // Выражение правой части условия.
                                "rightExpression": {
                                        // Тип выражения CONSTANT указывает на то, что в качестве значения выражения выступает
                                        // константное значение.
                                        "type": BusinessRuleModule.enums.ValueType.CONSTANT,
                                        // Значение, с которым сравнивается выражение левой части.
                                        "value": "1F703F42-F7E8-4E3F-9B54-2B85F62EA507"
                                }
                        }]
                }
        },
        "Type": {
                // Правило зависимости доступности поля [Рабочий телефон] от значения в поле [Мобильный телефон].
                "BindParameterEnabledType": {
                        // Тип правила BINDPARAMETER.
                        "ruleType": BusinessRuleModule.enums.RuleType.BINDPARAMETER,
                        // Правило регулирует свойство ENABLED.
                        "property": BusinessRuleModule.enums.Property.ENABLED,
                        // Массив условий, при выполнении которых отрабатывает правило. В данном
                        // случае массив содержит одно условие для определения, установлено ли значение.
                        "conditions": [{
                                // Выражение левой части условия.
                                "leftExpression": {
                                        // Тип выражения ATTRIBUTE указывает на то, что в качестве выражения выступает
                                        // атрибут (колонка) модели представления.
                                        "type": BusinessRuleModule.enums.ValueType.ATTRIBUTE,
                                        // Название колонки модели представления, значение которой сравнивается в выражении.
                                        "attribute": "State"
                                },
                                // Тип операции сравнения.
                                "comparisonType": Terrasoft.ComparisonType.EQUAL,
                                // Выражение правой части условия.
                                "rightExpression": {
                                        // Тип выражения CONSTANT указывает на то, что в качестве значения выражения выступает
                                        // константное значение.
                                        "type": BusinessRuleModule.enums.ValueType.CONSTANT,
                                        // Значение, с которым сравнивается выражение левой части.
                                        "value": "1F703F42-F7E8-4E3F-9B54-2B85F62EA507"
                                }
                        }]
                }
        },
        "StartDate": {
                // Правило зависимости доступности поля [Рабочий телефон] от значения в поле [Мобильный телефон].
                "BindParameterEnabledStartDater": {
                        // Тип правила BINDPARAMETER.
                        "ruleType": BusinessRuleModule.enums.RuleType.BINDPARAMETER,
                        // Правило регулирует свойство ENABLED.
                        "property": BusinessRuleModule.enums.Property.ENABLED,
                        // Массив условий, при выполнении которых отрабатывает правило. В данном
                        // случае массив содержит одно условие для определения, установлено ли значение.
                        "conditions": [{
                                // Выражение левой части условия.
                                "leftExpression": {
                                        // Тип выражения ATTRIBUTE указывает на то, что в качестве выражения выступает
                                        // атрибут (колонка) модели представления.
                                        "type": BusinessRuleModule.enums.ValueType.ATTRIBUTE,
                                        // Название колонки модели представления, значение которой сравнивается в выражении.
                                        "attribute": "State"
                                },
                                // Тип операции сравнения.
                                "comparisonType": Terrasoft.ComparisonType.EQUAL,
                                // Выражение правой части условия.
                                "rightExpression": {
                                        // Тип выражения CONSTANT указывает на то, что в качестве значения выражения выступает
                                        // константное значение.
                                        "type": BusinessRuleModule.enums.ValueType.CONSTANT,
                                        // Значение, с которым сравнивается выражение левой части.
                                        "value": "1F703F42-F7E8-4E3F-9B54-2B85F62EA507"
                                }
                        }]
                }
        },
        "EndDate": {
                // Правило зависимости доступности поля [Рабочий телефон] от значения в поле [Мобильный телефон].
                "BindParameterEnabledEndDate": {
                        // Тип правила BINDPARAMETER.
                        "ruleType": BusinessRuleModule.enums.RuleType.BINDPARAMETER,
                        // Правило регулирует свойство ENABLED.
                        "property": BusinessRuleModule.enums.Property.ENABLED,
                        // Массив условий, при выполнении которых отрабатывает правило. В данном
                        // случае массив содержит одно условие для определения, установлено ли значение.
                        "conditions": [{
                                // Выражение левой части условия.
                                "leftExpression": {
                                        // Тип выражения ATTRIBUTE указывает на то, что в качестве выражения выступает
                                        // атрибут (колонка) модели представления.
                                        "type": BusinessRuleModule.enums.ValueType.ATTRIBUTE,
                                        // Название колонки модели представления, значение которой сравнивается в выражении.
                                        "attribute": "State"
                                },
                                // Тип операции сравнения.
                                "comparisonType": Terrasoft.ComparisonType.EQUAL,
                                // Выражение правой части условия.
                                "rightExpression": {
                                        // Тип выражения CONSTANT указывает на то, что в качестве значения выражения выступает
                                        // константное значение.
                                        "type": BusinessRuleModule.enums.ValueType.CONSTANT,
                                        // Значение, с которым сравнивается выражение левой части.
                                        "value": "1F703F42-F7E8-4E3F-9B54-2B85F62EA507"
                                }
                        }]
                }
        },
        "qrtOrderPaymentList": {
                // Правило зависимости доступности поля [Рабочий телефон] от значения в поле [Мобильный телефон].
                "BindParameterEnabledqrtOrderPaymentList": {
                        // Тип правила BINDPARAMETER.
                        "ruleType": BusinessRuleModule.enums.RuleType.BINDPARAMETER,
                        // Правило регулирует свойство ENABLED.
                        "property": BusinessRuleModule.enums.Property.ENABLED,
                        // Массив условий, при выполнении которых отрабатывает правило. В данном
                        // случае массив содержит одно условие для определения, установлено ли значение.
                        "conditions": [{
                                // Выражение левой части условия.
                                "leftExpression": {
                                        // Тип выражения ATTRIBUTE указывает на то, что в качестве выражения выступает
                                        // атрибут (колонка) модели представления.
                                        "type": BusinessRuleModule.enums.ValueType.ATTRIBUTE,
                                        // Название колонки модели представления, значение которой сравнивается в выражении.
                                        "attribute": "State"
                                },
                                // Тип операции сравнения.
                                "comparisonType": Terrasoft.ComparisonType.EQUAL,
                                // Выражение правой части условия.
                                "rightExpression": {
                                        // Тип выражения CONSTANT указывает на то, что в качестве значения выражения выступает
                                        // константное значение.
                                        "type": BusinessRuleModule.enums.ValueType.CONSTANT,
                                        // Значение, с которым сравнивается выражение левой части.
                                        "value": "1F703F42-F7E8-4E3F-9B54-2B85F62EA507"
                                }
                        }]
                }
        },
        "qrtOriginalDoc": {
                // Правило зависимости доступности поля [Рабочий телефон] от значения в поле [Мобильный телефон].
                "BindParameterEnabledqrtOriginalDoc": {
                        // Тип правила BINDPARAMETER.
                        "ruleType": BusinessRuleModule.enums.RuleType.BINDPARAMETER,
                        // Правило регулирует свойство ENABLED.
                        "property": BusinessRuleModule.enums.Property.ENABLED,
                        // Массив условий, при выполнении которых отрабатывает правило. В данном
                        // случае массив содержит одно условие для определения, установлено ли значение.
                        "conditions": [{
                                // Выражение левой части условия.
                                "leftExpression": {
                                        // Тип выражения ATTRIBUTE указывает на то, что в качестве выражения выступает
                                        // атрибут (колонка) модели представления.
                                        "type": BusinessRuleModule.enums.ValueType.ATTRIBUTE,
                                        // Название колонки модели представления, значение которой сравнивается в выражении.
                                        "attribute": "State"
                                },
                                // Тип операции сравнения.
                                "comparisonType": Terrasoft.ComparisonType.EQUAL,
                                // Выражение правой части условия.
                                "rightExpression": {
                                        // Тип выражения CONSTANT указывает на то, что в качестве значения выражения выступает
                                        // константное значение.
                                        "type": BusinessRuleModule.enums.ValueType.CONSTANT,
                                        // Значение, с которым сравнивается выражение левой части.
                                        "value": "1F703F42-F7E8-4E3F-9B54-2B85F62EA507"
                                }
                        }]
                }
        }
}

Нравится

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

у меня такое правило вроде отрабатывает

"Number": {
    "BindParameterDisabledNumber": {
        "ruleType": BusinessRuleModule.enums.RuleType.BINDPARAMETER,
        "property": BusinessRuleModule.enums.Property.ENABLED,
        "conditions": [{
            "leftExpression": {
                    "type": BusinessRuleModule.enums.ValueType.ATTRIBUTE,
                    "attribute": "State"
            },
            "comparisonType": Terrasoft.ComparisonType.NOT_EQUAL,
            "rightExpression": {
                    "type": BusinessRuleModule.enums.ValueType.CONSTANT,
                    "value": "1f703f42-f7e8-4e3f-9b54-2b85f62ea507"
            }
        }]
    }
}

ВИдимо вы напутали с comparisonType

Добрый день, Максим.

Скорей всего, Вам стоит поменять comparisonType на Terrasoft.ComparisonType.NOT_EQUAL.

Также рекомендую Вам заменить бизнес правила на атрибут отвечающий за активность поля и менять его значение при изменении поля "Состояние". Это сделает код более читабельным и менее громоздким.

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

Добрый день.
Версия 7.9.0

Пробую добавить валидацию полей в редактируемую деталь с реестром и вычислаемы полями по примеру
https://academy.terrasoft.ru/documents/technic-sdk/7-9/dobavlenie-valida...

Но пример для страницы редактирования раздела. Может я не в ту схему вставляю методы? Или же я просто не вижу ошибку которую допускаю ? Буду признателен за подсказку

 

define("UsrUsrOrderOnField1Page", [], function() {
        return {
                entitySchemaName: "UsrOrderOnField",
                details: /**SCHEMA_DETAILS*/{}/**SCHEMA_DETAILS*/,
                attributes: {
                        "UsrReservRemains": {
                                dataValueType: Terrasoft.DataValueType.INTEGER,
                                dependencies: [
                                        {
                                                columns: ["UsrQuantity"],
                                                methodName: "calculateUsrReservRemains"
                                        }
                                ]
                        }
                },
                diff: /**SCHEMA_DIFF*/[
                        {
                                "operation": "insert",
                                "name": "UsrQuantityWorkOrdere",
                                "values": {
                                        "layout": {     "colSpan": 12,"rowSpan": 1,"column": 12,"row": 4,"layoutName": "Header"},
                                        "bindTo": "UsrQuantityWorkOrder"
                                },
                                "parentName": "Header",
                                "propertyName": "items",
                                "index": 4
                        },
                        {
                                "operation": "insert",
                                "name": "UsrQuantity",
                                "values": {
                                        "layout": {"colSpan": 12,"rowSpan": 1,"column": 0,"row": 3,"layoutName": "Header"
                                        },
                                        "bindTo": "UsrQuantity"
                                },
                                "parentName": "Header",
                                "propertyName": "items",
                                "index": 5
                        },
                        {
                                "operation": "insert",
                                "name": "UsrReservRemains",
                                "values": {
                                        "layout": {"colSpan": 12,"rowSpan": 1,"column": 0,"row": 4,"layoutName": "Header"
                                        },
                                        "bindTo": "UsrReservRemains"
                                },
                                "parentName": "Header",
                                "propertyName": "items",
                                "index": 6
                        },
                        {
                                "operation": "insert",
                                "name": "UsrToWorkOrder",
                                "values": {
                                        "layout": {"colSpan": 12,"rowSpan": 1,"column": 12,"row": 3,"layoutName": "Header"
                                        },
                                        "bindTo": "UsrToWorkOrder"
                                },
                                "parentName": "Header",
                                "propertyName": "items",
                                "index": 7
                        }
                ]/**SCHEMA_DIFF*/,
                methods: {
                        calculateUsrReservRemains: function() {
                                if (!this.get("UsrLastQuantity")) {
                                        this.set("UsrLastQuantity", 0);
                                }
                                if (!this.get("UsrReservRemains")) {
                                        this.set("UsrReservRemains", 0);
                                }
                                var result = this.get("UsrReservRemains") + this.get("UsrQuantity") - this.get("UsrLastQuantity");
                               
                                this.set("UsrReservRemains", result);
                                this.set("UsrLastQuantity", this.get("UsrQuantity"));
                        },
                        quantityVlidator: function() {
                                var invalidMessage = "";
                                if (this.get("UsrQuantity") this.get("UsrReservRemains")) {
                                        invalidMessage = this.get("Resources.Strings.ValueOfReservGraterThenQuantity");
                                }
                                return {
                                        fullInvalidMessage: invalidMessage
                                        invalidMessage: invalidMessage
                                };
                        },
                        setValidationConfig: function() {
                                this.callParent(arguments);
                                this.addColumnValidator("UsrQuantity", this.quantityVlidator);
                                this.addColumnValidator("UsrReservRemains", this.quantityVlidator);
                        }
                },
                rules: {}
        };
});

 

Нравится

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

"Сергей Джулай" написал:Буду признателен за подсказку

Скрин консоли с ошибкой приложите, пожалуйста

Да дело в том что ошибки в консоли нету. На странице редактирования заказа деталь с редактируемым реестром(21.jpg), и валидация там не работает (но и ошибок нет). Когда же на странице редактирования самой детали работает все отлично(20.jpg).
А нужна валидация, что бы не открывать новую страницу.

А код немного сменил (Упростил)

quantityVlidator: function() {
    var invalidMessage = "";
        if (this.get("UsrQuantity") < 1) {
            nvalidMessage = this.get("Resources.Strings.ValueOfReservGraterThenQuantity");
        }
    return {
        fullInvalidMessage: invalidMessage,
        invalidMessage: invalidMessage
    };
},
setValidationConfig: function() {
    this.callParent(arguments);
    this.addColumnValidator("UsrQuantity", this.quantityVlidator);
}

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

save: function() {
	if (this.get("UsrString").length === 12) {
		this.callParent(arguments);
	} else {
		this.showInformationDialog("Колонка String должна содержать 12 символов!");
	}
}

Спасибо Максим. Я так и реализовал валидацию, но это слабовато, так как в РР если внести неверное значение, то оно все равно сохранится, хоть и выдаст информационное окно с ошибкой. А это уже риск сломать некую логику. Может можно как то реализовать некую валидацию в момент события сохранения в GRIDе ? Например на событие выделения строки, поля которые должны проверяться сохраняются в временные переменные, а по событию save происходит валидация и если она не проходит, то значения возвращаются с временных переменных.

Посмотрите в сторону ConfigurationGridUtilities, там есть onActiveRowAction, можете переопределить его, и добавить валидацию там. Переопределять этот метод необходимо на схеме детали, и общатся со схемой карточки через sandbox.

Спасибо Максим. За подсказку - буду дальше размышлять в подсказанном направлении.

Сергей,

Поделитесь, пожалуйста, решением данной задачи.

Добрый день Алла. К сожалению до правильной реализации руки так и не дошли. Сейчас проверки выполнена с помощью предупреждения.

attributes: {
	"UsrQuantityWorkOrder": {
		dataValueType: Terrasoft.DataValueType.INTEGER,
		dependencies: [
			{
				columns: ["UsrQuantityWorkOrder"],
				methodName: "validationUsrQuantityWorkOrdere"
			}
		]
	}
},
methods: {
	validationUsrQuantityWorkOrdere: function() {
		if (this.get("UsrQuantityWorkOrder") > this.get("UsrReservRemains")) {
			this.showInformationDialog("Значение больше чем значиние Остаток в резерве");
		}
	}
}

Сергей, спасибо за информацию.

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

Кстати, интересно реализована ли валидация для редактируемого реестра в версии 7.10?

Кто в курсе?

Да, вы правы, пользователь может внести неверное значение, нужно все таки разобраться с sandbox и ConfigurationGridUtilities.

Как собственно и в обычных деталях и карточках - Ваша задача изучить цепочку вызовов функций сохранения (в каждом случае все немного отличается).
Определите подходящий метод в цепочке вызовов (который вызывается на исполнение до непосредственной записи в БД, обладает необходимым контекстом (this) и т.д.), ну и переопределите его - обогатив своей логикой валидации.
Валидация пройдена - "отпускаем" по this.callParent(arguments) [По естественной ветке]
Не пройдена - прерываем выполнение, и всего делов (показываем наши сообщения, открываем справочники - все что душе угодно)
Если в валидации задействованы асинхронные вызовы - например ESQ запросы.
вам вот сюда "Раcширить логику save, после валидации. Контроль Chain выполнения"

Илья,

в моем кейсе все усложняется тем, что это редактируемый реестр и согласно всему написанному выше не факт, что даже можно напилить свой костыль, чтобы пользователь всё-таки не мог сохранить изменения, если они не валидны. Попробовать, конечно, можно :wink:

Пока решили реализовать только само предупреждение и соответственно планирую создать обращение на support с пожеланием (чем больше будет пожеланий от пользователей, тем выше вероятность реализации базовых механизмов в ближайших релизах)!

Спасибо за то, что поделились опытом!

Советую присмотреться и отладить метод "unSelectRow"
в частности вызываемый им "saveRowChanges" (схема ConfigurationGridUtilities)


Так что замещайте ConfigurationGridUtilities переопределяйте saveRowChanges
Внедряя в нее логику валидации до "row.save"- и будет Вам счастье.

Илья,

спасибо Вам за помощь в поиске подходящего решения :smile:

Добрый день! Коллеги,  в 7.12 до сих пор валидация для редактируемого реестра не реализована(((...сейчас как раз задача есть. В  каких следующих версиях можно ожидать?

 

В анонсе 7,13 єтого нет (не кидайте в меня тапками если не заметил) Так что ждите или программируйте!

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

Думаю, что такой доработки в коробке ещё долго не будет, учитывая дату публикации данного поста и все сложности, которые возникают при малейшей попытке доработки редактируемого реестра в базовой версии crying

Значит или ждать или кастомно делать под себя, (Проверять до сохранения и потом если все ок сохранять )

Григорий Чех пишет:Получается в saveRowChanges изменять условие под себя из ответа Севостьянов Илья Сергеевич?

См. также тут и тут.

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