Здравствуйте! В схеме карточки редактирования заказа в системном методе setValidationConfig() регистрирую метод-валидатор для одного из полей. Внутри этого метода делаю запрос к таблице заказов с помощью EntitySchemaQuery и провожу проверку на корректность данных. Как известно, запрос на выборку данных запускается с помощью метода EntitySchemaQuery.getEntityCollection(function(result) { ... }). По-видимому, данный метод работает асинхронно, поэтому метод-валидатор заканчивает свою работу, не дожидаясь результата выборки. В итоге, валидация всегда получается успешной вне зависимости от результата проверки.
Как можно решить эту проблему? Есть ли способ выполнить выборку из базы синхронно?
Нравится
Здравствуйте, Дмитрий!
Предоставьте, пожалуйста, полный листинг Вашего кода.
Добрый день Дмитрий!!!
подскажите пожалуйста вам Валидацию когда требуется производить в момент заполнения формы или перед сохранением? если к примеру требуется сделать перед сохранением, то ваша задача решаема. За это отвечает метод asyncValidate
. Если у вас конфигурация Sales, пример можно подсмотреть в схеме ContractPageV2
, там как раз перед сохранением идет проверка Уникальности номера, при проверке выполняется запрос к Базе данных.
для сведения на клиентской стороне все SQL запросы выполняются Асинхронно. И это правильно. Это увеличивает производительность программы. Плюс чтобы вы понимали на клиентской стороне должны быть построены самые элементарные запросы. Если запрос нетривиальный, его требуется строить и выполнять уже на стороне сервера, т.е писать код на C#.
будут вопросы с радостью на них отвечу
Вот код функции, отвечающей за валидацию (упрощенный пример):
actNumberValidator: function() { var invalidMessage = ""; // Получаем список заказов var orderEsq = Ext.create("Terrasoft.EntitySchemaQuery", { rootSchemaName: "Order", isDistinct: true }); orderEsq.addColumn("Number"); orderEsq.addColumn("UsrActNumber", "ActNumber"); orderEsq.getEntityCollection(function(result) { var orderCollection = result.collection.collection; var isActNumberExists = orderCollection.items.some(function(item) { return item.get("ActNumber") === this.get("UsrActNumber"); }, this); if (isActNumberExists) { invalidMessage = "Заказ с таким номером акта уже существует"; return { invalidMessage: invalidMessage, fullInvalidMessage: invalidMessage }; } }, this); return { invalidMessage: invalidMessage, fullInvalidMessage: invalidMessage }; }
Я понимаю, что такой тяжелые запросы к базе лучше не выполнять на клиенте, но валидацию необходимо проводить перед сохранением изменений объекта. Насколько я знаю, сделать это возможно только на клиенте.
Михаил, не могли бы вы объяснить, как работает валидация с использованием метода asyncValidate?
Добрый день Дмитрий!!!
какой минус я вижу сразу в вашем запросе. Это вы делаете запрос к БД и получаете весь список Заказов, и далее перебираете их и сравниваете их. А если в БД будет Миллион записей? то все клиент ваш подвиснет навсегда или надолго. Давайте идти по порядку. Опишите задачу, какое поле проверяем (при Валидации) какой правильно должен отрабатываться запрос к БД и цель этого запроса. и далее я вам помогу составить и запрос и приведу как этот запрос Асинхронный будет работать при валидации полей. И еще пока незабыл данная валидация когда должна работать при Заполнение полей или при сохранение карточки редактирования. Спасибо!!!
Опишу задачу. Для каждого заказа заполняется поле [Номер акта]. Нумерация актов идет отдельно для каждого контрагента, указанного в прикрепленном к заказу договоре в поле [Наша компания]. Соответственно, в контрагенте есть поле [Номер последнего заказа]. При добавлении нового заказа с указанным договором (поле [UsrContract]) запускается процесс для увеличения номера последнего заказа. Поля [Номер акта] и [Номер последнего акта] должны быль редактируемы. Поэтому при заполнении номера акта необходимо проверять его уникальность.
Может быть, предложите другое, более оптимальное решение данной задачи?
"Дмитрий Д." написал:Нумерация актов идет отдельно для каждого контрагента, указанного в прикрепленном к заказу договоре в поле [Наша компания].
Вопрос где хранится данный номер Акта? в отдельной таблице или где? так как по умолчанию в конфигурации Sales Актов выполненных работ нет. Данная сущность создана с нуля? это отдельный раздел и таблица? если так то как Акт и договор связаны, какой связью "1 ко многим"? Далее вопросы как Заказ связан с Актом выполненных работ и для чего это сделано? я просто немного не понял как у вас сейчас это все Дмитрий реализовано. Поясните поподробнее пожалуйста. Я скажу вам свое мнение правильно или нет. И как бы я реализовал. Так как данную задачу в своей конфигурации я уже выполнил. спасибо!!!
Отдельной сущности Акт нет. Акт распечатывается на объекте Заказ и содержит в шапке примерно такой текст: "Акт №<номер_акта> от <дата_окончания_отчетного_периода> выполненных работ и оказанных услуг к Приложению №<номер_приложения> договора №<номер_договора> от <дата_подписания_договора>". Номер акта хранится в кастомном поле Order.UsrActNumber. Сейчас это поле заполняется руками. Нужно, чтобы это поле заполнялось автоматически. Для этого у контрагента было заведено поле Account.UsrActLastNumber для хранения номера последнего акта. При добавлении нового заказа данное поле инкрементируется и заносится в Order.UsrActNumber.
Хорошо Дмитрий если развивать вашу идею, то вам достаточно при сохранение заказа обновлять поле "UsrActLastNumber" в Контрагентах, а при создании (именно при создании) нового Заказа и при выборе Контрагента из БД заполнять поле "UsrActNumber" + 1 и все. Цель Валидации я просто тогда далее не вижу. Или я чего-то не понял. Поясните пожалуйста еще раз спрашиваю Дмитрий для какого поля вы желаете проводить валидацию и в какой момент в момент Заполнения или в момент Сохранения. Спасибо!!!
Поле UsrActNumber доступно для редактирования. При редактировании этого поля хотелось бы проверить его значение на уникальность.
"Дмитрий Д." написал:Сейчас это поле заполняется руками. Нужно, чтобы это поле заполнялось автоматически.
Выше именно это вы Дмитрий писали о поле "UsrActNumber". Т.е. вы желаете чтобы пользователь заполнил номер акта вручную, а программа проверила Равняется или нет введенный новый номер акта ("UsrActNumber") последнему номеру контрагента ("UsrActLastNumber"). И если номера равны выдать предупреждение об этом. Данную задачу вы желаете решить? я правильно вас понял? если до то еще раз повторюсь как вам требуется провести Валидацию в момент ввода или перед сохранением? спасибо!!!
Михаил, давайте подойдем к вопросу с другой стороны. Расскажите, как это реализовано у вас? Как вы работаете с актами?
Дмитрий я к данному вопросу подошел следующим образом. Я разделил сущности Договор на 2 части, хозрасчетные договора, данные договора закрываются реализациями и счет-фактурами. И договоры об оказании услуг, вот данные договора закрываются Актами выполненных работ. все разделено на отдельные сущности. У каждой сущности своя нумерация, свои отчетные документы, свои бизнес-процессы. Это маленькое начало большого айсберка :) А в целом полностью закрыл Складской учет, работа с поставщиками, работа с покупателями, управление денежными потоками. Получилось очень даже неплохо. Вот по какому пути я пошел изначально.
Михаил, насколько я понял, у вас Счет-фактура и Акты являются отдельными сущностями, которые отображаются наряду с такими разделами, как заказы и счета? Есть ли в этом смысл, когда для акта необходимо хранить только лишь его номер?
"Дмитрий Д." написал:Михаил, насколько я понял, у вас Счет-фактура и Акты являются отдельными сущностями, которые отображаются наряду с такими разделами, как заказы и счета?
Добрый день Дмитрий!!!
да все верно Дмитрий вы поняли. Но смысл есть всегда, во первых данные сущности хранятся отдельно чтобы для данной сущности были свои Отчетные формы, свои бизнес-процессы. Так как BPMOnline изначально создавалась и позиционирует себя как система BPMN позволяющая пользователю помощь в работе и недопустить ошибок и увеличить его производительность. Это первая цель. Вторая цель выгрузка результативных документов из BPMOnline в 1С. Так как бухгалтерия работает в 1С. Пока в BPMOnline бухгалтерия не работает. Но и над этим вопросом я сейчас занимаюсь. Я не пытаюсь скопировать и клонировать 1С. Я сейчас проектирую и разрабатываю систему, на платформе BPMOnline которая закроет все вопросы. Но будет гораздо удобнее, быстрее и т.д. Вот моя цель и задача на сегодня.