Вопрос

Добрый день.

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

В loginmodule.js в onLoginButtonClick добавляю вызов аналогичный ..AuthService.svc/Login.

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

Анонимный сервис делал по аналогии https://academy.terrasoft.ru/documents/technic-sdk/7-13/kak-sozdat-anon…

У меня такой же вопрос

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

Скорее всего у вас не выполнен или выполнен с ошибками 4 пункт  руководства по созданию анонимного веб-сервиса а именно: Настройте доступ к WCF-сервиса для всех пользователей.

Возможно после окончания настройки сервиса вы не выполнили рестарт пула IIS

Сделал его. Проблема именно в связке с сервисом авторизации. Запрос осуществляется с клиентской стороны. Заметил еще, если куки очищаем после сообщения ошибки лицензии, то сервис работает.

Значит проблема не в сервисе. Обратитесь в техподдержку террасофт за лицензионным ключем  и перелицензируйте систему. Иногда очистка редиса помогает

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

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

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

Зверев Александр,

Почему для моего случая не работает?

Либо что-то неверно в коде, либо не так зарегистрирован в конфигах.

Может как-то влиять, что вызов моего сервиса происходит в callback сервиса авторизации? также в примере из академии пример не компилировался и я добавил наследование от BaseService. 

Сам сервис доступен без авторизации postman отправлять.

Также, если необходимо, могу привести пример клиент. кода loginmodule.js

Привожу пример моего сервиса:

[OperationContract]
        [WebInvoke(Method = "POST", RequestFormat = WebMessageFormat.Json, BodyStyle = WebMessageBodyStyle.Wrapped,
        ResponseFormat = WebMessageFormat.Json)]
        public string GetMyService(string Name)
        {
            var returnObject = new
            {
                ResultCode = 0,
                ResponseText = ""
            };
            return JsonConvert.SerializeObject(returnObject);
        }

Возможно. Как вариант, сначала запускайте свой, а уже потом пытайтесь авторизироваться.

Зверев Александр,

По логике мне нужно запустить свой сервис после сервиса авторизации.

Войдите или зарегистрируйтесь, чтобы комментировать
Вопрос

Хочу сделать сабж. Окошко выводится, но список пустой. Что я делаю не так?

Метод onPreparePaymentsList не вызывается, кстати. Ошибок в консоли нет.

define("UsrFlip1Page", ["ServiceHelper", "jQuery", "css!UsrFlip1PageCSS"], function(ServiceHelper, jQuery) {
	return {
		entitySchemaName: "UsrFlip",
		attributes: {
			"PaymentVList": {
				dataValueType: Terrasoft.DataValueType.COLLECTION,
				type: Terrasoft.ViewModelColumnType.VIRTUAL_COLUMN,
				caption: "Платежи",
				name: "PaymentVList",
				isCollection: true
			}
		},
		details: /**SCHEMA_DETAILS*/{
		},
		diff: /**SCHEMA_DIFF*/[
		]/**SCHEMA_DIFF*/,
		methods: {
			init: function() {
				this.callParent(arguments);
				this.set("PaymentVList", this.Ext.create(Terrasoft.Collection));
			},
 
			onEntityInitialized: function() {
				this.callParent(arguments);
				this.set("ActivePayments", null);
				var esq = this.Ext.create("Terrasoft.EntitySchemaQuery", { rootSchemaName: "UsrPayment" });
				esq.addColumn("Id");
				esq.addColumn("UsrBillNumber");
				esq.addColumn("UsrPpNumber");
				esq.addColumn("UsrSum");
				esq.addColumn("UsrType.Name");
				esq.filters.add("filterAuto", this.Terrasoft.createColumnFilterWithParameter(
					this.Terrasoft.ComparisonType.EQUAL, "UsrAuto", this.get("UsrAutoId").value));
				esq.filters.add("filterStatus", this.Terrasoft.createColumnInFilterWithParameters("UsrStatus.Name",
					["Активный", "Не подтвержден"]));
 
				esq.getEntityCollection(function(result) {
					if (result.success) {
						var PaymentItems = {};
						result.collection.each(function(item) {
							PaymentItems[item.get("Id")] = {
								"value": item.get("Id"),
								"displayValue": item.get("UsrBillNumber") + " / " + item.get("UsrPpNumber") +
									" / " + item.get("UsrSum") + " / " + item.get("UsrType.Name")
							};
						}, this);
 
						var list = this.get("PaymentVList");
						list.loadAll(PaymentItems);
					}
				}, this);
			},
 
			getActions: function() {
				var actionMenuItems = this.callParent(arguments);
				actionMenuItems.addItem(this.getActionsMenuItem(
					{
						"Caption": "Уточнение назначения платежа",
						"Tag": "runPaymentCorrection"
					}
				));
				return actionMenuItems;
			},
 
			onPreparePaymentsList: function() {
				debugger;
			},
 
			runPaymentCorrection: function() {
				if (this.get("PaymentVList").getCount() === 0) {
					Terrasoft.showInformation("По данному авто нет активной оплаты!");
					return;
				}
				debugger;
				Terrasoft.showInputBox("Выберите п/п для уточнения", function(button) {
						Terrasoft.showInformation(button);
					}, ["ok", "cancel"], this, {
					name : {
						caption: "Платежи",
						dataValueType: Terrasoft.DataValueType.ENUM,
						className: "Terrasoft.ComboBoxEdit",
						list: {
							bindTo: "PaymentVList"
						},
						prepareList: {
							bindTo: "onPreparePaymentsList"
						},
						isRequired: true
					}
				},
				{
					defaultButton: 0
				});
			}
		},
		rules: {}
	};
});

 

У меня такой же вопрос

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

Маялся уже. Всю голову сломал. Лист не готовится, от вручную указанного кол-ва записей в листе ничего не зависит, "prepareList" не вызывается... Через час плюнул, сделал собственный модуль)

Делал что-то подобное, но через messageBox. Метод в prepareList вызывался (при попытке выбора), как и метод в change.

Тёскин Дмитрий Валерьевич,

а есть пример кода? мне кажется, я уже всё перепробовал

Алексей-Карягин,

Примера кода, к сожалению, не осталось. Попробовал вчера на досуге ваш код поковырять - действительно не работает. Возможно я использовал какой-то кастомизированный messageBox. Единственное, что заметил - у меня ветки объекта prepareList и change были внутри customConfig.

Войдите или зарегистрируйтесь, чтобы комментировать
Вопрос

Добрый день.

Имеется необходимость настройки различной конфигурации колонок раздела. Например, есть таблица с N колонками и хочется, чтоб в разделе присутствовали, например, вкладки. По нажатию 1 вкладки отображаются 1..N/2 колонок, по нажатию 2 вкладки N/2+1..N. 

Пробовал добавить в diff TabPanel, в него SECTION_VIEWS и поместить GridDataView туда, не сработало. Кто-нибудь сталкивался с таким?
 

У меня такой же вопрос

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

Сталкивался с похожей задачей, правда не очень хорошо помню детали решения. Попробуйте сделать не вкладки, а кнопки переключения между разными гридами секции, как это сделано в стандартном разделе Активности (Календарь, Список, Итоги).

Тёскин Дмитрий Валерьевич,

Мне нужно так, как я описал. Даже если добавить вкладки, то возникает проблема: у каждого пользователя есть настройки профиля, из которых подтягиваются колонки и их последовательность в гриде. Как хранить и сохранять много конфигов для каждого пользователя? Переписывать половину базовой логики?)
Скрин желаемого (примерно) исполнения

http://joxi.ru/YmEzMloH05keW2

upd: судя по всему, можно для разных конфигов сохранять разные ключи в SysProfileData и подтягивать нужный при переключении вкладки (или асинхронно загрузить сразу все). Завтра отпишусь о реализации.

 

Примеры программной замены содержимого профиля с колонками должны быть в дополнении «Column list copying to subordinates». Не уверен только, что у пользователя изменения в профиле подхватятся сразу, а не после повторного входа. Если второе, то так, как Вы хотите, не получится.

Зверев Александр,

Я не отписался о реализации. У меня получилось благодаря методу reloadGridColumnsConfig(true) из GridUtilitiesV2, нескольким GridDataView в разделе (и ключам, которые хранятся в SysProfileData).

Войдите или зарегистрируйтесь, чтобы комментировать
Вопрос

Добрый день!

Подскажите, пожалуйста, возможно ли передавать дополнительные параметры в макрос, вызываемый в email-шаблоне через [#@Invoke.MyMacros#] ?

Например, нужно реализовать конвертацию значения поля типа boolean из true/false в "да"/"нет". Или преобразовать дату в специальный формат.

Метод GetMacrosValue(object arguments) интерфейса IMacrosInvokable принимает объект с аргументами, но по умолчанию в нем - только идентификатор текущей записи.

У меня такой же вопрос

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

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

Зверев Александр,

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

Может, есть какой-то альтернативный вариант решения проблемы?

Нужно смотреть в MacrosHelper, который это всё обрабатывает, как там устроено и есть ли возможность для расширения.

Войдите или зарегистрируйтесь, чтобы комментировать
Вопрос

Есть деталь. Нужно сделать в ней 2 вкладки, в них должно быть разные фильтры. Есть у кого какие идеи? Как вариант сделать в детале бул поле и на негго вешать установку-снятие фильтра. Но возможно можно сделать вкладки, как в тройке

У меня такой же вопрос

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

Те вы хотите одну и туже деталь использовать в 2х вкладках с разными условиями фильтрации (отбора данных) ?

 

Если я правильно вас понял то можно использовать метод для задания дополнительных условий отбора  данных, подробнее описано тут

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

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

Радчук Виталий Владимирович,

А зачем вам вкладки? Почему бы не сделать обновление грида детали по нужным фильтрам? А для детали просто добавить 2 кнопки, нажатие 1 кнопки приведет к установке Фильтров А и обновлению грида, а по 2 следовательно Фильтры Б и обновление грида.
Результат тот же - а делать в разы быстрее и понятнее, чем искать варианты с вкладками)

так и будет

Войдите или зарегистрируйтесь, чтобы комментировать
Вопрос

Добрый день!

Подскажите пожалуйста, каким образом можно настроить автоматический ответ на письмо, как в Outlook? Например: на любое входящее сообщение CRM должна отсылать шаблонный ответ "Письмо получено. Спасибо за обращение."

У меня такой же вопрос

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

Письмо єто активность с типом Emailте как вариант создать БП со стартовым сигналом слушающим добавление входящего Email и использовать элемент БП Отправить письмо для формирования ответа

Войдите или зарегистрируйтесь, чтобы комментировать
Вопрос

Добрый день. Использую 5 версию системы.

Необходимо вывести на странице реестра отфильтрованный по определенным условиям список. В таблице, по которой будет осуществлена фильтрация, имеется колонка Phone с номером телефона, который записан без маски(т.е. в значении могут быть указаны дефисы, пробелы, скобки). Необходимо все лишние символы при фильтрации "выкинуть", вопрос Как это правильно сделать?

var Filters5 = facilityStructure.CreateFilterWithParameters(dataSource.Schema, FilterComparisonType.Equal, "Phone", Number.Replace('-',''));

У меня такой же вопрос

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

В интернете много примеров использования регулярных выражений для обработки телефонных примеров,найдите подходящие вам и используйте!

Меня интересует как правильно прописать фильтр на bpm, а не как использовать реплэйсы.

Для быстрого поиска номера можно добавить спрятанное (не выведенное на страничке поле) куда сохранять номер телефона с которого удалять все кроме цифр и хранить в перевернутом виде тогда можно будет искать номера независимо от того содержат ли они код страны или нет те

+(38064) 714 -82 -23

записать как

322841764083

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

Этот способ используется в некоторых стандартых разделов в bpmonline

Григорий, я правильно Вас понимаю, что без вот таких так скажем "выкрутасов", я не смогу фильтр написать!?

Алексейченко Антонина,

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

Антонина, так, как написали в начале — точно не получится. Ведь Number — это не поле таблицы, а переменная, где в номере и так уже нет лишних символов. А Вам надо наоборот, очистить значения в поле.

Все разновидности функции CreateFilterWithParameters перечислены тут, а варианты FilterComparisonType — тут. Варианта с регулярными выражениями там нет, максимум доступно включение подстроки в начале, конце или где угодно.

Так что придётся, как посоветовал Григорий, или добавлять второе поле с номером без спецсимволов, или чисто программно перебирать и находить массив ID найденных подходящих записей, которые и добавлять в фильтр.

Войдите или зарегистрируйтесь, чтобы комментировать
Вопрос

Добрый день коллеги, подскажите как добавить действие в cti панель звонков, к существующим действиям необходимо добавить создать лид из звонка

Прикрепленные файлы

У меня такой же вопрос

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

В маркете есть БП для выполнения той же задачи.

Также такая функция встроена в одну из интеграций с телефонией.

Войдите или зарегистрируйтесь, чтобы комментировать
Вопрос

Есть БП который вызывается через кнопку в клиентском модуле, он заполняет деталь. Как через сообщения сделать обновление детали после окончания работы БП что бы было видно наполнение детали? На форуме был такой вопрос но там было сделано через ивент в БП старого типа, в новых это не работает.

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

У меня такой же вопрос

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

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

В конце БП в элементе Задание-сценарий вставляете следующую строку:
 

MsgChannelUtilities.PostMessage(UserConnection, "MyMessage", "UpdateDetail");

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

init: function () {
				this.callParent(arguments);
				this.subscriptionFunction();
			},
subscriptionFunction: function() {
				Terrasoft.ServerChannel.on(Terrasoft.EventName.ON_MESSAGE,
				this.bpListenerMessage, this);
			},
bpListenerMessage: function(scope, message) {
				if (!message || message.Header.Sender !== "MyMessage") {
					return;
				}
				var message2 = message.Body;
				if (!this.Ext.isEmpty(message2) && message2 === "UpdateDetail") {
					this.updateDetail();
				}
			}

Примерно так.

Нигрескул Алексей,

 

Не обновляет, уже и не знаю в чем дело может быть

В БП

var userConnection = Get<UserConnection>("UserConnection");
Terrasoft.Configuration.MsgChannelUtilities.PostMessage(userConnection, "ReloadDetailConcert", "UpdateDetail");
return true;

На клиенте

init: function () {
	this.callParent(arguments);
	this.subscriptionFunction();
},
subscriptionFunction: function() {
	Terrasoft.ServerChannel.on(Terrasoft.EventName.ON_MESSAGE,
	this.bpListenerMessage, this);
},
bpListenerMessage: function(scope, message) {
	if (!message || message.Header.Sender !== "ReloadDetailConcert") {
		return;
	}
	var message2 = message.Body;
	if (!this.Ext.isEmpty(message2) && message2 === "UpdateDetail") {
		this.updateDetail();
	}
},

 

PostMessage отправляет конкретному юзеру. Поэтому надо быть уверенным, что бп запущен от нужного пользователя и он на нужной странице(где есть код для обработки обратного сигнала). 
Если не подходит, можно воспользоваться PostMessageToAll(string sender, string message). Рассылает сообщение по всей конфигурации всем пользователям.

Варфоломеев Данила,

Изменил на 

Terrasoft.Configuration.MsgChannelUtilities.PostMessageToAll("ReloadDetailConcert", "UpdateDetail");
return true;

не помогло

Нужно ли еще прописать?

messages: {
	"ReloadDetailConcert": {
		mode: Terrasoft.MessageMode.BROADCAST,
		"direction": Terrasoft.MessageDirectionType.SUBSCRIBE
	}
},

 

Prime Source,

Да нет. Должно и так работать. Даже subscriptionFunction не вызывается?

Варфоломеев Данила,

По дебагу срабатывает, и сообщение правильно ловит, и выполняет this.updateDetail(); ,но почему нет данных в детали не пойму. Может что в процессе не так? Вот его скрин, там идет цикл который делает 8 проходов, и когда в таблице 8 записей становится он выполняет скрипт сообщения и завершает

 

Prime Source,

//Relationships - название детали из details.
//пример:
this.updateDetail({detail: "Relationships"});

Проверьте код(указывается ли имя детали). Плюс должны быть настроены колонки

Войдите или зарегистрируйтесь, чтобы комментировать
Вопрос

Cделан запрос в базу данных из клиентского модуля для получения системной настройки: 

this.Terrasoft.SysSettings.querySysSettingsItem("PsMaximumProgramsCount", function(value) {
	countSettings = value;
}, this);

Получены данные из БД отфильтровав их и сравнив с полученным значением из системной настройки ранее, и если значение выпадающего списка periodicity  равно "Ежедневно" и количество записей в базе больше чем системной настройке - срабатывает валидация на поле и всплывающее уведомление при попытке сохранения:

message - сообщение для поля валидации;

periodicity  - выпадающий список (словарь) в котором есть значение "Ежедневно";

countSettings  - ранее полученное значение системной настройки;

concertProgramsCount - количество записей в таблице;

var periodicity = "";
if (this.get("PsPeriodicity")) {
	periodicity = this.get("PsPeriodicity").displayValue;
}
var esq = Ext.create("Terrasoft.EntitySchemaQuery", {
	rootSchemaName: "PsConcertPrograms"
});
esq.addColumn("PsPeriodicity.Name", "PsPeriodicityName");
var esq1Filter = esq.createColumnFilterWithParameter(Terrasoft.ComparisonType.EQUAL,
	"PsPeriodicity.Name", "Ежедневно");
esq.filters.add("esq1Filter", esq1Filter);
esq.getEntityCollection(function(result) {
	var message = "";
	if (result.success) {
		var concertProgramsCount = result.collection.collection.length;
		if (periodicity === "Ежедневно" && concertProgramsCount <= countSettings ) {
			message = this.get("Resources.Strings.PsFewFreeConcertHalls").replace("NNN", countSettings);
		}
	}
	return message;
}, this);

Вывод валидации для поля и при сохранении страницы:

concertHallsValidator: function(message) {
	var invalidMessage = message;
	return {
		fullInvalidMessage: invalidMessage,
		invalidMessage: invalidMessage
	};
}

Проблема в том что по отдельности все работает, но когда вместе - вступает в дело асинхронность и все идет не по очереди, а если использую через callback тогда застреваю на замыкании.

Спасибо всем кто окажет помощь в решении проблемы.

У меня такой же вопрос

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

немного не понимаю смысла return из async функции, поэтому вариант такой:

в attributes добавляете 

"PeriodValidationMessage": {
	dataValueType: 1,
	value: ""
}

esq:

var periodicity = "";
if (this.get("PsPeriodicity")) {
	periodicity = this.get("PsPeriodicity").displayValue;
}
var esq = Ext.create("Terrasoft.EntitySchemaQuery", { rootSchemaName: "PsConcertPrograms" });
esq.addColumn("PsPeriodicity.Name", "PsPeriodicityName");
esq.filters.addItem(esq.createColumnFilterWithParameter(Terrasoft.ComparisonType.EQUAL, "PsPeriodicity.Name", "Ежедневно"));
esq.getEntityCollection(function(result) {
	if (result.success) {
		var concertProgramsCount = result.collection.collection.length;
		//считывание сист. настройки
		Terrasoft.SysSettings.querySysSettingsItem("PsMaximumProgramsCount", function(countSettings) {
			//сравнение
			if (periodicity === "Ежедневно" && concertProgramsCount <= countSettings ) {
				this.$PeriodValidationMessage = this.get("Resources.Strings.PsFewFreeConcertHalls").replace("NNN", countSettings);
			}
 
		}, this);
	}
}, this);

валидация

concertHallsValidator: function(message) {
	var invalidMessage = this.$PeriodValidationMessage;
	return {
		fullInvalidMessage: invalidMessage,
		invalidMessage: invalidMessage
	};
}

 

Добрый день,

Каждый борется с асинхронностью своими средствами :)

Как вариант, можно вложить одно в другое: выполнять запросы по очереди, по мере получения ответа из БД. Например перенести вашу логику с esq запросом в колбэк системной настройки.

Тёскин Дмитрий Валерьевич,

 

Пробовал, тогда return возвращает поздно ответ

concertHallsValidator:  function(){
	var periodicity = "";
	if (this.get("PsPeriodicity")) {
		periodicity = this.get("PsPeriodicity").displayValue;
	}
	this.Terrasoft.SysSettings.querySysSettingsItem("PsMaximumProgramsCount", function(countSettings) {
		var esq = Ext.create("Terrasoft.EntitySchemaQuery", {
			rootSchemaName: "PsConcertPrograms"
		});
		esq.addColumn("PsPeriodicity.Name", "PsPeriodicityName");
		var esq1Filter = esq.createColumnFilterWithParameter(Terrasoft.ComparisonType.EQUAL,
			"PsPeriodicity.Name", "Ежедневно");
		esq.filters.add("esq1Filter", esq1Filter);
		esq.getEntityCollection(function(result) {
			var invalidMessage = "";
			if (result.success) {
				var concertProgramsCount = result.collection.collection.length;
				if (periodicity === "Ежедневно" && concertProgramsCount > countSettings ) {
					invalidMessage = this.get("Resources.Strings.PsFewFreeConcertHalls").replace("NNN", countSettings);
				}
			}
			return invalidMessage;
		}, this);
	}, this);
},
setValidationConfig: function() {
	this.callParent(arguments);
	this.addColumnValidator("PsPeriodicity", this.concertHallsValidator);
}

 

Варфоломеев Данила,

Асинхронность не дает

methods: {
	concertHallsValidator:  function(callback){
		var periodicity = "";
		if (this.get("PsPeriodicity")) {
			periodicity = this.get("PsPeriodicity").displayValue;
		}
		var esq = Ext.create("Terrasoft.EntitySchemaQuery", { rootSchemaName: "PsConcertPrograms" });
		esq.addColumn("PsPeriodicity.Name", "PsPeriodicityName");
		esq.filters.addItem(esq.createColumnFilterWithParameter(Terrasoft.ComparisonType.EQUAL, "PsPeriodicity.Name", "Ежедневно"));
		esq.getEntityCollection(function(result) {
			if (result.success) {
				var concertProgramsCount = result.collection.collection.length;
				//считывание сист. настройки
				Terrasoft.SysSettings.querySysSettingsItem("PsMaximumProgramsCount", function(countSettings) {
					//сравнение
					if (periodicity === "Ежедневно" && concertProgramsCount <= countSettings ) {
						this.$PeriodValidationMessage = this.get("Resources.Strings.PsFewFreeConcertHalls").replace("NNN", countSettings);
					}
					return callback.call(this);
				}, this);
			}
		}, this);
	},
	MessageValidator: function() {
		var invalidMessage = this.$PeriodValidationMessage;
		return {
			fullInvalidMessage: invalidMessage,
			invalidMessage: invalidMessage
		};
	},
	setValidationConfig: function() {
		// Вызывает инициализацию валидаторов родительской модели представления.
		this.callParent(arguments);
		this.addColumnValidator("CreatedOn", this.concertHallsValidator(this.MessageValidator));
	}
},
			}

 

Prime Source,

нет. стоп. я думал вы прогоняете esq в onEntityInitialized, а потом используете this.$PeriodValidationMessage для проверки. тогда такие варианты:

1) на изменение поля PsPeriodicity запускаете concertHallsValidator. Изменяете this.addColumnValidator("CreatedOn", this.MessageValidator);
2) Используете asyncValidate (вроде так называется метод)

И уберите return. Ну не используется он в асинхронных функциях)

Варфоломеев Данила,

 

Спасибо большее, помогло отлично asyncValidate. Раньше не знал что этот метод. Вод такой код заработал отлично:

asyncValidate: function(callback, scope) {
	this.callParent([function(response) {
		if (!this.validateResponse(response)) {
			return;
		}
		Terrasoft.chain(
			function(next) {
				this.validateConcertHalls(function(response) {
					if (this.validateResponse(response)) {
						next();
					}
				}, this);
			},
			function(next) {
				callback.call(scope, response);
				next();
			}, this);
	}, this]);
},
validateConcertHalls: function(callback, scope) {
	Terrasoft.SysSettings.querySysSettingsItem("PsMaximumProgramsCount", function(countSettings) {
		var periodicity = "";
		var result = {success: true};
		if (this.get("PsPeriodicity")) {
			periodicity = this.get("PsPeriodicity").displayValue;
		}
		var esq = Ext.create("Terrasoft.EntitySchemaQuery", { rootSchemaName: "PsConcertPrograms" });
		esq.addColumn("PsPeriodicity.Name", "PsPeriodicityName");
		esq.filters.addItem(esq.createColumnFilterWithParameter(Terrasoft.ComparisonType.EQUAL, 
			"PsPeriodicity.Name", "Ежедневно"));
		esq.getEntityCollection(function(response) {
			if (response.success && periodicity === "Ежедневно" && (!this.isAddMode() && 
				response.collection.getCount() > countSettings) || (this.isAddMode() && 
				response.collection.getCount() >= countSettings)) {
					result.message = this.get("Resources.Strings.PsFewFreeConcertHalls").replace("NNN", countSettings);
					result.success = false;
			}
			callback.call(scope || this, result);
		}, this);
	}, this);
}

 

Prime Source,

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

Войдите или зарегистрируйтесь, чтобы комментировать