Вернусь к вопросу валидации, который я поднимал ранее...
1. Есть раздел "Подписанты" с полями:
ФиоКонтакта, РазрешеннаяСумма
2. Есть раздел "Договора" с полями
СуммаДоговора
ФиоПодписанта = Подписанты.ФиоКонтакта
Необходимо произвести валидацию полей на схеме раздела "Договора"
СуммаДоговора < Подписанты.РазрешеннаяСумма
где Договор.ФиоПодписанта = Подписанты.ФиоКонтакта
По примерам https://academy.terrasoft.ru/documents/technic-sdk/7-10/postroenie-putey-k-kolonkam-otnositelno-kornevoy-shemy и https://academy.terrasoft.ru/documents/technic-sdk/7-10/poluchenie-rezultata-zaprosa построил свой запрос
methods: { // Метод-валидатор значения SummValidator: function() { var message = ""; // Создаем экземпляр класса Terrasoft.EntitySchemaQuery с корневой схемой [Contact]. var esq = this.Ext.create("Terrasoft.EntitySchemaQuery", { rootSchemaName: "UsrContract1Page" }); // Добавляем колонку esq.addColumn("UsrLimitAmount2.[UsrSignatories1Page:Id:UsrSignatoriesId].UsrLimitAmount", "UsrSignatoriesLimitAmount"); // Получаем одну запись из выборки по [Id] объекта карточки и отображаем ее // в информационном окне. esq.getEntityCollection(function(result) { if (!result.success) { // обработка/логирование ошибки, например this.showInformationDialog("Ошибка запроса данных"); return; } result.collection.each(function(item) { message += item.get("UsrSignatoriesLimitAmount"); }); this.showInformationDialog(message); }, this); }, // Переопределение базовой функции, инициализирующей пользовательские валидаторы. setValidationConfig: function() { // Вызывает инициализацию валидаторов родительской модели представления. this.callParent(arguments); this.addColumnValidator("UsrLimitAmount2", this.SummValidator); this.addColumnValidator("UsrContractAmount", this.SummValidator); } },
Но при проверке работы проваливаюсь в ошибку this.showInformationDialog("Ошибка запроса данных");
Помогите с решением данного кейса
Нравится
getEntityCollection - асинхронный вызов. т.е. ваш метод валидации в сути асинхронный, в то время как обработчик результата валидации addColumnValidator рассчитан на вызов синхронного метода, так что такой подход в принципе не работоспособен.
И это еще не все, далее в вашем методе валидаторе не предусматривается логика возвращение объекта, со строго установленными свойствами
{ fullInvalidMessage: invalidMessage, invalidMessage: invalidMessage };
которые там обязаны быть внимательно ознакомьтесь с примером https://academy.terrasoft.ru/documents/technic-sdk/7-10/dobavlenie-validacii-k-polyu-stranicy
PS: для валидации поля использовать запрос в БД каждый раз - с точки зрения архитектуры и перфоманса не хорошо, подумайте как вы могли бы предварительно подготовить данные необходимые для валидации, заодно и избежите асинхронного вызова.
Севостьянов Илья Сергеевич пишет:
подумайте как вы могли бы предварительно подготовить данные необходимые для валидации, заодно и избежите асинхронного вызова
Есть на схеме Договора поле типа Справочник имеющее ссылку в раздел Подписанты. Но тут скорей отсутствие навыка разработки в BPM - как подставить сумму в это поле в зависимости от выбранного Подписанта? Как-то "костыльно" получится...
как подставить сумму в это поле
в это же поле ? в справочное - никак.
в другое поле - с численным типом, по зависимости, см. dependensies свойство в описании атрибутов
Ответ supporta:
Валидацию вы можете применить только к полям или атрибутам текущей схемы, так что для решения задачи вам понадобится виртуальный атрибут, по которому вы будете валидировать. Атрибуты создаются в блоке attributes: {
Примеры реализаций таких атрибутов множество в базовых схемах, поищите. Используются они как обычные колонки, следовательно их можно будет устанавливать this.set и читать this.get, и, использовать их в валидации.
Вам необходимо создать атрибут для вашей «РазрешеннаяСумма»
Далее данный атрибут нужно будет заполнять как при инициализации карточки, метод, onEntityInitialized: function() {
Так и при изменении лукапов от которых зависит получаемая информация. В вашем случае при изменении лукапа "ФиоПодписанта"
И последнее, как получить данные которыми вы хотите заполнить данный атрибут: Как вы правильно поняли, с помощью esq, ссылку на статью которой вы предоставили второй. Вам достаточно сделать запрос к корневой таблице «Подписанты» с условием ФиоКонтакта = this.get(“ФиоПодписанта”)
Севостьянов Илья Сергеевич,
Последовал совету supporta и вот что у меня получилось:
1. Создал виртуальную колонку в атрибутах
2. В onEntityInitialized вызываю функцию setVirtLimitAmount с использованием EntitySchemaQuery для чтения данных из БД
3. dueSummValidator - проверяю значения и setValidationConfig - вызываю инициализацию валидаторов
4. Все это работает, но я бы сказал через одно место... работает синхронно, а мне бы хотелось асинхронно... По сути для этого мне было бы достаточно, каждый раз при изменении Подписанта (UsrSignatories) вызывать функцию setVirtLimitAmount. Возможно ли отследить изменение поля UsrSignatories? Одного Lookup-а недостаточно.