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

Метод 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: {}
	};
});

 

Нравится

5 комментариев
Лучший ответ

Алексей, вот кусок кода, который вы можете использовать для вашей задачи. Были рады помочь.

define("ActivityPageV2", [], function() {
return {
entitySchemaName: "Activity",
rules: {},
messages: {},
details: /*SCHEMA_DETAILS/{}/*SCHEMA_DETAILS/,
attributes: {},
methods: {
 
getActions: function() {
var actionMenuItems = this.callParent(arguments);
actionMenuItems.addItem(this.getActionsMenuItem(
{
"Caption": "Тестовое действие",
"Click":
 
{"bindTo": "statusInputBox"}
}
));
return actionMenuItems;
},
 
statusInputBox: function() {
var caption = "Выбор статуса";
this.set("StatusList", new Terrasoft.Collection());
var controls = {
"ActivityStatus": {
dataValueType: Terrasoft.DataValueType.ENUM,
isRequired: true,
caption: "Статус",
value:
 
{ bindTo: "ActivityStatus" }
,
customConfig: {
list:
 
{ bindTo: "StatusList" }
,
prepareList:
 
{ bindTo: "onPrepareStatusList" }
}
}
};
var statusInputBoxHandler = this.statusInputBoxHandler.bind(this);
Terrasoft.utils.inputBox(caption, statusInputBoxHandler,
[Terrasoft.MessageBoxButtons.OK, Terrasoft.MessageBoxButtons.CANCEL],
this, controls);
Terrasoft.each(Terrasoft.MessageBox.controlArray, function(item)
 
{ item.control.bind(this); }
, this);
},
 
onPrepareStatusList: function() {
var esq = this.Ext.create("Terrasoft.EntitySchemaQuery",
 
{ rootSchemaName: "ActivityStatus" }
);
esq.addColumn("Id");
esq.addColumn("Name");
esq.filters.add("finish", Terrasoft.createColumnFilterWithParameter(
Terrasoft.ComparisonType.EQUAL, "Finish", true));
esq.getEntityCollection(function(result) {
if (result.success) {
var items = {};
result.collection.each(function(item) {
items[item.get("Id")] =
 
{ "value": item.get("Id"), "displayValue": item.get("Name") }
;
}, this);
var list = this.get("StatusList");
list.loadAll(items);
}
}, this);
},
 
statusInputBoxHandler: function(tag, data) {
if (Terrasoft.MessageBoxButtons.OK.returnCode === tag) {
if (Ext.isEmpty(data.ActivityStatus.value)) {
this.showInformationDialog("Нужно что-то выбрать", function()
 
{ this.statusInputBox(); }
);
} else
 
{ this.showInformationDialog(data.ActivityStatus.value.displayValue); }
}
}
 
},
diff: /*SCHEMA_DIFF/[]/*SCHEMA_DIFF/
};
});

 

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

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

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

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

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

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

Алексей, вот кусок кода, который вы можете использовать для вашей задачи. Были рады помочь.

define("ActivityPageV2", [], function() {
return {
entitySchemaName: "Activity",
rules: {},
messages: {},
details: /*SCHEMA_DETAILS/{}/*SCHEMA_DETAILS/,
attributes: {},
methods: {
 
getActions: function() {
var actionMenuItems = this.callParent(arguments);
actionMenuItems.addItem(this.getActionsMenuItem(
{
"Caption": "Тестовое действие",
"Click":
 
{"bindTo": "statusInputBox"}
}
));
return actionMenuItems;
},
 
statusInputBox: function() {
var caption = "Выбор статуса";
this.set("StatusList", new Terrasoft.Collection());
var controls = {
"ActivityStatus": {
dataValueType: Terrasoft.DataValueType.ENUM,
isRequired: true,
caption: "Статус",
value:
 
{ bindTo: "ActivityStatus" }
,
customConfig: {
list:
 
{ bindTo: "StatusList" }
,
prepareList:
 
{ bindTo: "onPrepareStatusList" }
}
}
};
var statusInputBoxHandler = this.statusInputBoxHandler.bind(this);
Terrasoft.utils.inputBox(caption, statusInputBoxHandler,
[Terrasoft.MessageBoxButtons.OK, Terrasoft.MessageBoxButtons.CANCEL],
this, controls);
Terrasoft.each(Terrasoft.MessageBox.controlArray, function(item)
 
{ item.control.bind(this); }
, this);
},
 
onPrepareStatusList: function() {
var esq = this.Ext.create("Terrasoft.EntitySchemaQuery",
 
{ rootSchemaName: "ActivityStatus" }
);
esq.addColumn("Id");
esq.addColumn("Name");
esq.filters.add("finish", Terrasoft.createColumnFilterWithParameter(
Terrasoft.ComparisonType.EQUAL, "Finish", true));
esq.getEntityCollection(function(result) {
if (result.success) {
var items = {};
result.collection.each(function(item) {
items[item.get("Id")] =
 
{ "value": item.get("Id"), "displayValue": item.get("Name") }
;
}, this);
var list = this.get("StatusList");
list.loadAll(items);
}
}, this);
},
 
statusInputBoxHandler: function(tag, data) {
if (Terrasoft.MessageBoxButtons.OK.returnCode === tag) {
if (Ext.isEmpty(data.ActivityStatus.value)) {
this.showInformationDialog("Нужно что-то выбрать", function()
 
{ this.statusInputBox(); }
);
} else
 
{ this.showInformationDialog(data.ActivityStatus.value.displayValue); }
}
}
 
},
diff: /*SCHEMA_DIFF/[]/*SCHEMA_DIFF/
};
});

 

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

Добрый день.



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

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

 

Нравится

6 комментариев
Лучший ответ

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

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

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

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

Скрин желаемого (примерно) исполнения

http://joxi.ru/YmEzMloH05keW2



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

 

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

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

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

На маркетплейсе есть уже подходящая реализация. Настройка разных колонок для разных групп — Advanced list setup for bpm'online.

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

Она похожа на подходящую, но не для меня. Судя по описанию (я не устанавливал) теряется возможность фильтровать по группам в сконфигурированном списке, а для меня это не подходит. Как я уже описал выше, я достиг необходимого результата.

 

P.S. Недостаток моего метода - для каждой вкладки нужно немного копипасты. Если кому-то из вас нужны примеры кода, обращайтесь в личку.

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

Добрый день!

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

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

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

Нравится

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

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

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

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

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

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

Добрый день, подскажите, может кто нашел решение данной задачи?

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

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

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

Нравится

4 комментария
Лучший ответ

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

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

Результат тот же - а делать в разы быстрее и понятнее, чем искать варианты с вкладками)

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

 

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

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

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

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

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

Результат тот же - а делать в разы быстрее и понятнее, чем искать варианты с вкладками)

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

Добрый день!



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

Нравится

1 комментарий
Лучший ответ

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

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

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

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

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

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

Нравится

6 комментариев
Лучший ответ

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

+(38064) 714 -82 -23

записать как

322841764083

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

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

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

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

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

+(38064) 714 -82 -23

записать как

322841764083

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

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

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

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

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

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

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

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

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

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

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

Нравится

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

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

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

Нравится

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

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

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

 

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 комментариев
Лучший ответ

Prime Source,

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

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

2) Используете asyncValidate (вроде так называется метод)

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

немного не понимаю смысла 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 === "Ежедневно" &amp;&amp; concertProgramsCount &lt;= 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 === "Ежедневно" &amp;&amp; concertProgramsCount &gt; 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 === "Ежедневно" &amp;&amp; concertProgramsCount &lt;= 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 &amp;&amp; periodicity === "Ежедневно" &amp;&amp; (!this.isAddMode() &amp;&amp; 
				response.collection.getCount() &gt; countSettings) || (this.isAddMode() &amp;&amp; 
				response.collection.getCount() &gt;= countSettings)) {
					result.message = this.get("Resources.Strings.PsFewFreeConcertHalls").replace("NNN", countSettings);
					result.success = false;
			}
			callback.call(scope || this, result);
		}, this);
	}, this);
}

 

Prime Source,

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

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

Всем добрый день. Собственно такой вопрос. Планируем подключить телефонию beeline через anyvoip connector. Какие данные для подключения/ настройки нам будут необходимы?

 

Нравится

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