Здравствуйте. Задача была в валидации по полю и системной настройке. Читал статьи по фильтрам в ESQ и по форуму перелистал всё.
Всё работает, кроме одного момента.
Валидация:
Если значение выпадающего списка frequency равно "Ежедневно" и в выпадающем списке active поле = "Да" и количество записей в базе больше чем системной настройке(в данном случае 5) - срабатывает валидация на поле и всплывающее уведомление при попытке сохранения, или изменения записи.
frequency - выпадающий список периодичностей;
active - выпадающий список активности;
ermsg - сообщение ошибки;
maxCount - системная настройка (ранее "MaxAmountofDailyActivities");
response.collection.getCount() - актуальное кол-во записей;
При сохранении записи с полем "Ежедневно" + "Да", если таких записей уже 5 - валидация работает и правильно выдаёт ошибку.
1.Но если любую другую запись, например с полем "Еженедельно" + "Да" изменить на "Ежедневно" + "Да", то ошибка не показывается и запись сохраняется. В данный момент записей становится уже 6.
2.Но если далее создавать записи с "Ежедневно" + "Да" или изменять другие на "Ежедневно" + "Да", ошибка показывается и всё продолжает работать нормально.
код метода прикрепил ниже + скриншоты
methods: { asyncValidate: function(callback, scope) { this.callParent([function(response) { if (!this.validateResponse(response)) { return; } Terrasoft.chain( function(next) { this.validateSwimmingPrograms(function(response) { if (this.validateResponse(response)) { next(); } }, this); }, function(next) { callback.call(scope, response); next(); }, this); }, this]); }, validateSwimmingPrograms: function(callback, scope) { Terrasoft.SysSettings.querySysSettingsItem("MaxAmountofDailyActivities", function(maxCount) { var frequency = ""; var active = ""; var ermsg = this.get("Resources.Strings.ErrorMessage"); var result = {success: true}; if (this.get("UsrFrequency")) { frequency = this.get("UsrFrequency").displayValue; } if (this.get("UsrActive")) { active = this.get("UsrActive").displayValue; } var esq = Ext.create("Terrasoft.EntitySchemaQuery", { rootSchemaName: "UsrSwimmingPrograms" }); esq.addColumn("UsrFrequency.Name", "UsrFrequencyName"); esq.addColumn("UsrActive.Name", "UsrActiveName"); esq.filters.addItem(esq.createColumnFilterWithParameter(Terrasoft.ComparisonType.EQUAL, "UsrFrequency.Name", "Ежедневно")); esq.filters.addItem(esq.createColumnFilterWithParameter(Terrasoft.ComparisonType.EQUAL, "UsrActive.Name", "Да")); esq.getEntityCollection(function(response) { if (response.success && frequency === "Еженедельно" || frequency === "Ежемесячно" || frequency === "Ежедневно" && active === "Нет"){ result.success = true; } else if (response.success && frequency === "Ежедневно" && active === "Да" && (!this.isAddMode() && response.collection.getCount() > maxCount) || (this.isAddMode() && response.collection.getCount() >= maxCount)) { result.message = maxCount + ermsg + active; result.success = false; } callback.call(scope || this, result); }, this); }, this); } },
Ниже по очереди:
- Уже созданные 5 записей;
- при создании 6-ой с "Ежедневно" + "Да" выдаёт ошибку(выводит системную настройку(5), и в конце активность;
- При создании другой записи с другиме полями - ошибку не выводит(как и надо);
- При смене в пред. записи поля на "Ежедневно" - сохраняет (должно выводить ошибку);
- При последующих сохранения изменения записей всё работает корректно(где надо выдаёт ошибку, где не надо - не выдёт).
Нравится
То есть Ваша функция не вызывается при изменении существующей записи, а только для новых? Проверьте, выполняется ли вообще перед сохранением функция, добавленная в asyncValidate и доходит ли до вызова validateSwimmingPrograms.
Правильные примеры валидации есть в этой теме и в DocumentPageV2 пакета Document в «коробке»:
asyncValidate: function(callback, scope) { this.callParent([function(response) { if (!this.validateResponse(response)) { return; } Terrasoft.chain( function(next) { this.validateAccountOrContactFilling(function(response) { if (this.validateResponse(response)) { next(); } }, this); }, function(next) { this.validateUniqueNumber(function(response) { if (this.validateResponse(response)) { next(); } }, this); }, function(next) { callback.call(scope, response); next(); }, this); }, this]); },
Василий, попробуйте в браузере поставить отладчик и пошагово посмотреть, как выполняется эта функция. Заходит ли вообще в неё, правильно считает количество? Может, меняемая запись не учитывается, поскольку проверка идёт по последней ветке с «>=»?
Также лучше не завязываться на текстовые названия справочных полей, могут потом быть неожиданности при смене локализации интерфейса или каких-нибудь изменениях в значении в справочнике.
Зверев Александр,
Поставил отладчик, показывает только одно предупреждение при входе в карточку.
В разделе Активности ничего не делал, не пойму почему ругается на это.
Названия справочных полей заменю на id полей, пока для вида оставил текст.
Имею в виду, посмотреть, как по строкам выполняется скрипт, по каким ветвям условий выполняется в этом случае.
Зверев Александр,
Отработка скрипта при сохранении 5-ой записи с полями "Ежедневно" и "Да"
-Показывает, что перед добавлением было 4 записи:
Далее, при попытке сохранить 6-ю записи с нужными полями, показывает что 5шт уже есть, то-есть пред. запись сохранилась и записалась:
Окей, работает, пробую изменить другую запись с рандомными полями на нужные.
Результат показывает, кол-во записей до изменения и сохранения записи на нужные поля.
Пробую еще раз добавить запись с нужными полями:
Зверев Александр,
currentCount - кол-во существующих записей с нужными полями.
Тут показывает, что есть уже 5(при попытке создать 6-ю)
Тут исполнение функции происходит после изменения и сохранения другой записи с произвольными полями на нужные.
Ошибку не выкидывает, а просто сохраняет и уже currentCount = 6
Но когда уже есть 6, функция не позволяет дальше создавать с нужными полями или даже изменять произвольную запись на запись с "Ежедневно" / "Да".
То есть Ваша функция не вызывается при изменении существующей записи, а только для новых? Проверьте, выполняется ли вообще перед сохранением функция, добавленная в asyncValidate и доходит ли до вызова validateSwimmingPrograms.
Правильные примеры валидации есть в этой теме и в DocumentPageV2 пакета Document в «коробке»:
asyncValidate: function(callback, scope) { this.callParent([function(response) { if (!this.validateResponse(response)) { return; } Terrasoft.chain( function(next) { this.validateAccountOrContactFilling(function(response) { if (this.validateResponse(response)) { next(); } }, this); }, function(next) { this.validateUniqueNumber(function(response) { if (this.validateResponse(response)) { next(); } }, this); }, function(next) { callback.call(scope, response); next(); }, this); }, this]); },
Зверев Александр,
Спасибо огромное за наводку, разобрался.
Переделал что-бы функция реагировала на изменения: