Коллеги всем доброго времени суток! Подскажите как сгенерировать Terrasoft.Exception.

Необходимо преред добавлением записи проверять заполнение детали если пусто выкидывать Exception и сообщение, что заполните деталь

Terrasoft.sdk.Model.setModelEventHandler("Contact", 
	Terrasoft.ModelEvents[Terrasoft.ModelEventKinds.Before].insert,
	function(config, operation) {
		debugger;
		var record = config.scope.eventConfig.records[0];
		window.console.log(config);
		window.console.log(record);
		var addresses = record.ContactAddressDetailV2EmbeddedDetailStore.getData();
		if(addresses.all.length === 0) {
			var exceptionConfig = {
				message: "Сообщение",
			};		
			Ext.callback(config.failure,config.scope,Terrasoft.Exception(exceptionConfig);
		} else {
			Ext.callback(config.success, config.scope, [true]);
		}		
});

Как реализовать что бы работало, может кто то сталкивался?

Вылазит следующие ошибки  -http://prntscr.com/ocnz86

не читает - http://prntscr.com/ocnzgz

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

Нравится

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

разобрался

Terrasoft.sdk.Model.setModelEventHandler("Contact", 
	Terrasoft.ModelEvents[Terrasoft.ModelEventKinds.Before].insert,
	function(config, operation) {
		debugger;
		var record = config.scope.eventConfig.records[0];
		window.console.log(config);
		window.console.log(record);
		var addresses = record.ContactAddressDetailV2EmbeddedDetailStore.getData();
		if(addresses.all.length === 0) {
			var exception = new Terrasoft.Exception();
			exception.config.message = "Сообщение";
 
			Ext.callback(config.succes, config.scope, [false]);
		} else {
			Ext.callback(config.success, config.scope, [true]);
		}
		Ext.callback(config.success, config.scope, [true]);
});

 

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

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

Решил действовать через встроенные БП на событие "Перед сохранением".

БП получился простым,

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

но почему то процесс сохранения не прерывается.

Если условие выполняется, то генерится сигнал тот же самый, который был на входе (UsrParametersOfContractsSaving), по умолчанию - останов (TerminateEvent).

Условие элементарное

Entity.GetTypedColumnValue("UsrStartDate") < Entity.GetTypedColumnValue("UsrEndDate").

Отладка как то не проясняет ситуацию. Может кто сталкивался с данной ситуацией?

Нравится

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

Павел, добрый день! Для решения указанной задачи ПРАВИЛЬНЕЕ использовать не встроенные процессы, а клиентский код. Пример можно посмотреть на странице активности (там проверяется, что завершение не может быть меньше начала). Серверный код не стоит использовать, если в результате проверки необходимо запретить клиенту сохранить запись.

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

Юлия, спасибо за ответ. Действительно, я рассматривал вариант отмены на клиенте. С редактируемым реестром более менее работать научился. Но здесь проблема в том, что это справочник. То есть страница редактирования не персональная, а общая. Поэтому и выбрал встроенные БП. Но там, похоже ничего не получится... А задача действительно - запретить изменение полей, а не делать промежуточные вычисления.

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

Сформулирую как я понял задачу:

На странице есть поле. Поле ссылается на справочник. В справочнике есть следующие поля:

  • Название (то, что будет отображаться на странице)
  • Дата начала
  • Дата завершения

На странице есть также поле с типом "Дата" (назовем его "Валидатор"). Необходимо, чтобы выполнялась проверка находится ли значение, указанное в поле "Валидатор" в интервале ["Дата начала", "Дата завершения"].

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

Есть два решения задачи:

Алексей, здравствуйте.

Задача в следующем. Есть справочник, в котором есть поля Название, Дата начала, Дата окончания. Справочник редактируется в разделе Дизайнер системы - справочники. В этом справочнике необходимо контролировать, чтобы дата окончания не была меньше даты начала. Чтобы при попытке сохранить запись справочника производилась проверка и запись справочника не сохранялась бы при невыполнении условия.

"Для решения указанной задачи ПРАВИЛЬНЕЕ использовать не встроенные процессы, а клиентский код."



- я извиняюсь, а почему это "ПРАВИЛЬНЕЕ"? Потому, что заморачиваться не хочется? А если мне нужно обезопасить данные, чтобы сотрудник не "нахимичил"? Ваша валидация, которая "ПРАВИЛЬНЕЕ", обходится средствами браузера на раз-два. И действительно "ПРАВИЛЬНЕЕ" было бы организовать валидацию на стороне сервера перед сохранением.

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

* Во первых, сообщение ошибки вылезет пользователю на экран в информационном окошке , так что можете сообщить, что не так.

* Во вторых, сохранения точно не произойдёт.

* В третьих, такую проверку пользователь точно не обойдёт.

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

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

Нравится

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

Какая цель использовать sandbox в рамках одной схемы? Это нельзя, и в этом нет смысла. Используйте колбеки.

Ну юзкейс у такого положения вещей есть:
Уже "притчей во-языцах" становится извечная проблема открытия карточек в Combined и Separated режимах, и добавлением какого либо функционала в верхнее горизонтальное меню.
Приходится описывать свою бизнес-логику как для секции так и для карточки, причем логика в сути идентичная, кроме способа получения данных самой карточки (для секции это отдельные трудности, так как прямого доступа к модели карточки не имеется, разве что через "GridData"), так же секцию выделяет то что там необходимо реагировать на отдельные события инициализации карточки.
Вообщем все это порождает офигенный оверхед по коду.
Решение было найдено через Миксин-модуль и события.
Таким образом специально сконфигурированный миксин можно подключать и к карточке и к схеме - логика описана в едином месте, в едином виде, в сути все происходит в карточке, а секция просто соответствующим образом реагирует и подписывается на ряд событий.
Так вот сейчас приходится разделять Миксин-модуль | Модуль экспортирующий публикации | Модуль экспортирующий подписки.
Ну и проскочила мысль, что сами messages можно в рамках одной схемы объявить (одного миксина) а уже подписываться/публиковать по ситуации в схемах куда миксин подключен.

"Севостьянов Илья Сергеевич" написал:Вообщем все это порождает офигенный оверхед по коду.

Именно поэтому мы используем прямой переход из секции в карточку (банально window.open) по клику на запись в реестре. Ибо дублировать логику/пилить кучу сообщений из секции в карточку тупо не хватает терпения. Ууууух. Руку бы пожал тому человеку, который додумался до combined-режима))

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

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

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

возник вопрос, как отслеживать изменения в текстовом поле карточки.
а именно, в зависимости от введенного [Числа] в определенное текстовое поле нужно изменять значение справочного поля. подобные изменения необходимо выполнять каждый раз, когда [Число] изменяется.
подскажите, как привязать к текстовому полю событие onChange (если таковое имеется), или каким образом вообще можно решить эту задачу.

заранее благодарен

Нравится

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

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

Есть два варианта решения:
1) На странице редактирования
2) На стороне сервера по событию изменения записи бизнес-процессом

Пример реализации на стороне страницы редактирования Вы можете посмотреть в схеме OrderProductPageV2:

"PrimaryPrice": {
	dependencies: [
		{
			columns: ["Price", "Amount", "DiscountAmount", "TaxAmount", "TotalAmount"],
			methodName: "calculatePrimaryValues"
		}
	]
}

Значение поля PrimaryPrice изменяется методом calculatePrimaryValues при изменении полей "Price", "Amount", "DiscountAmount", "TaxAmount", "TotalAmount".

Что касается бизнес-процесса, то реализуйте изменение записи элементом "Изменить данные". Процесс будет запускаться по событию "Изменение данных" в Вашем объекте. Обязательно укажите, какие поля должны быть изменены.

благодарю за ответ. попробую сделать так.

Сделал по первому способу. Поля устанавливаются, но при нажатии на "Сохранить" значения остаются прежними. Если устанавливать значение справочного поля вручную, то все сохраняется.

Беда, как говорится, не приходит одна.

Приведу примерный механизм изменения данных:

var UsrL = this.get("UsrL");

далее идет поиск нужного значения справочника и установка этого значения в справочное поле

var n =  item.get("Name");
var t = {
	displayValue: n,
	value: UsrLoial.value
};
this.set("UsrL", t);

Для справочника есть следующий метод для установки значения:

this.loadLookupDisplayValue("ИмяСправочника", значение);

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

Коллеги, приветствую.

Хотел бы поинтересоваться относительно возможности инициирования бизнес- процессов событиями страницы.

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

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

Существует- ли какое- либо релевантное событие страницы (onchange на выпадающем списке, например), которое могло бы инициировать бизнес- процесс?

Спасибо.

--
С уважением, Алексей Быков

Нравится

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

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

Ну, наверное, пересчет через процесс - ресурсоемкое удовольствие.

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

Данная реализация подойдет?:smile:

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

Отлично, спасибо большое за ответ - да, подойдет.

Относительно ресурсоемкости согласен.

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

Спасибо!

--
С уважением, Алексей Быков.

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

В процессе администрирования базы данных возникла необходимость определить причину возникновения ошибки. Определенный объём информации импортируется в базу данных, с которым далее пользователи работают. В процессе заполнения определенного набора полей автоматически высчитывалась итоговая сумма в поле «Итого». Но в определённый промежуток времени использования продукта начали появляться ошибки, связанные с несоответствием значения поля «Итого» сумме полей из которых оно вычисляется («Сумма покупки», «Наценка», «Сбор» и т.д.). Так как ошибку не получалось явно повторить, необходимо было разработать механизм для решения данной проблемы.

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

В основу решения было положено создание двух таблиц в базе данных для ведения логов, что происходят с записью набора данных. Первая таблица WindowLog, а вторая TriggerLog.

Первая таблица WindowLog включает в себя поля «Дата создания»(CreatedOn), «Идентификатор записи» (RecordID), «Ответственный» (WindowsUser), «Имя поля породившего событие»(FieldName), «Итого» и поля из которых оно вычисляется («Сумма покупки», «Наценка», «Сбор» и т.д.). Для наполнения таблицы было использованы события невизуального компонента окна dlData: dlDataOnDatasetDataChange, dlDataOnDatasetBeforePost и dlDataOnDatasetAfterPost. В скрипте в событиях была создана функция, которая формировала SQL запрос к таблице WindowLog базы данных с фиксацией информации по указанным полям на момент срабатывания события.

Запрос:

INSERT INTO WindowLog (*набор полей*)
SELECT (*набор полей*) -- Dataset('поле1'), Dataset('поле2'), Dataset('поле2')

Вторая таблица TriggerLog включает в себя поля «Дата создания»(CreatedOn), «Идентификатор записи» (RecordID), «Состояние» (до изменения записи и после), «SystemUser», «Итого» и поля из которых оно вычисляется («Сумма покупки», «Наценка», «Сбор» и т.д.). Для заполнения данной таблицы был создан триггер на инструкцию UPDATE проблемной таблицы с двумя запросами вставки значений в таблицу. В одном запросе вставлялись значения до изменений, а во втором после.

Запрос №1:

INSERT INTO TriggerLog (*набор полей*)       
SELECT (*набор полей*)
FROM deleted

Запрос №2:

INSERT INTO TriggerLog (*набор полей*)       
SELECT (*набор полей*)
FROM inserted

Результатом использования данного решения на основе анализа таблицы WindowLog было установлено, что срабатывают все события окна редактирования, влияющие на вычисление значения поля «Итого». В процессе использования окна редактирования и после сохранения записи значения поля «Итого» были корректны.

Проанализировав записи в таблице TriggerLog было установлено, что в результате выполнения инструкции UPDATE было внесено некорректное значение. Сопоставив даты создания записей в таблице TriggerLog и WindowLog было установлено, что инструкция UPDATE была вызвана не в результате манипуляций с окном редактирования, а иным источником. На основании поля «SystemUser» таблицы TriggerLog было установлено что изменения были внесены с помощью импортера данных.

Таблицу TriggerLog возможно расширить, добавив в нее поля, которые помогут ускорить процесс обнаружение источника изменений записи базы данных. Список дополнительных полей может выгладять следующим образом: ApplicationName, LoginName, HostName.

PS: Принимаю предложения на доработку вашей конфигурации!!! Для более детальной информации можно связаться по следующему e-mail адресу: providnui@ukr.net !!!

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

Всем удачи в этом не легком процессе!!!

Нравится

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

Доброго времени суток!

Есть задача: на карточке редактирования добавить свою логику сохранения записи, при которой нужно выводить в messagePanel сообщение подобное "Поле {0} обязательно для заполнения" и не давать сохранять запись.

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

Нравится

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

Здравствуйте Constantine!
Это просто.
У карточки редактирования есть метод: "AreConditionsCorrect". Переопределив его и добавив свою логику (установив Page.[EditControl].Required = true [данный метод установит свойство поле обязательно для заполнения] и панель сообщений сама Вам выведет указанное в описании сообщение со ссылкой на поле) или Вы можете вернуть значение "false" из метода перед этим заполнив MessagePanel, и базовая логика сохранения не отработает.
А лучше, если Вы будете устанавливать свойство обязательности в своей логике, например при смене значения другого поля.
И наконец, почему бы Вам просто не изменить свойство в объекте, установив значение "Обязательно для заполнения на уровне приложения"?

Спасибо за совет, Андрей!
Я видимо не совсем правильно сформулировал саму задачу. Указанное сообщение я упомянул для примера, а логика разрешения/запрета сохранения записи не касается обязательных для заполнения полей.
Буду копать в сторону этого метода

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

Використовую версію 3.3.2.205
В деталі контрагента здійснюю вилучення елемента. Коли елемент є основним для контрагента, то перед вилученням в карточці контрагента намагаюсь прописати значення null, але в карточку значення не прописується.

Доступ до набору даних здійснюю наступним чином:

BaseGridArea.WorkspaceDataset = GetAttribute(Window, 'WorkspaceDataset');

Значення прописую так:

var AccountDataset = BaseGridArea.WorkspaceDataset;
AccountDataset.Edit();
AccountDataset.Values('LegalPersonID') = null;
AccountDataset.Post();

Виявив відсутність реакції на операцію:

AccountDataset.Post();

Наступні функції нічого не видають

function dlDataOnDatasetBeforePost(Dataset) {
        MessageBox("scr_AccountsGridArea : dlDataOnDatasetBeforePost");
}

function dlDataOnDatasetAfterPost(Dataset) {
        MessageBox("scr_AccountsGridArea : dlDataOnDatasetAfterPost");
}

На

AccountDataset.Edit();
реакція є

Подія OnDatasetDataChange також спрацьовує.

В чому може бути справа ?

Нравится

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

Игорь, возможно, какая-то логика заложена в скрипте датасета контрагента, посмотрите в сервисах
- ds_Account
- scr_Account
события on OnDatasetDataChange, OnDatasetBeforePost, OnDatasetAfterPost.

А таки ж логіка в OnDatasetDataChange в scr_Account.

Здравствуйте Игорь, проблема решена ?

Можливо причина ось у цьому параметрі:
Account.IsUpdating = true;

Загалом проблема знята.
Тільки ще не розібрався в чому власне воня полягала :)

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