Добрый день!
в ITIL
есть такая функция в скрипте CasePage(SLM), которая фильтрует выпадающие списки
ответственных и групп ответственных в обращении.
getOwnerDependenceFilters: function(scope) {
var filterGroup = new scope.Terrasoft.createFilterGroup();
var serviceItem = scope.get("ServiceItem");
var supportLevel = scope.get("SupportLevel");
if (serviceItem) {
filterGroup.add("ServiceItemFilter", scope.Terrasoft.createColumnFilterWithParameter(
scope.Terrasoft.ComparisonType.EQUAL, "[ServiceEngineer:Engineer].ServiceItem", serviceItem.value));
}
return filterGroup;
},
Хотела бы добавить дополнительный фильтр в эту функцию,
для этого мне необходимо получить еще одно поле - по которому фильтровать,
но не просто поле из карточки обращения, а, например, связанное поле, например, статус сервисного договора, указанного в карточке обращения
и вот, если написать
var servicePact = scope.get("servicePact"), то это значение возвращается и определяется
а вот связанная колонка, например:
var status = scope.get("servicePact.Status") возвращается как undefined
Подскажите, пожалуйста, как правильно обратиться к такой связанной колонке в данном случае?
Нравится
Зная сервисный договор можно получить статус сервисного договора, используя ниже приведенный код.
selectStatusServicePact: function() {
var esq = this.Ext.create("Terrasoft.EntitySchemaQuery", {
rootSchemaName: "ServicePact"
});
var servicePact = scope.get("servicePact")
esq.addColumn("Id");
esq.addColumn("Status");
esq.filters.add("ServicePactId", this.Terrasoft.createColumnFilterWithParameter(
this.Terrasoft.ComparisonType.EQUAL, "Id", servicePact));
esq.getEntityCollection(function(response) {
if (response && response.success) {
if (response.collection.getCount() > 0) {
var result = response.collection.getItems()[0];
var statusId = result.get("Status");
//или
this.set("StatusServicePact", result.values.Status);
}
}
}
Более подробно ознакомиться с использованием EntitySchemaQuery на клиенте можно здесь
Спасибо, как раз нашла подобный пример в скриптах.
Только в фильтрации надо указывать не servicePact, а servicePact.value
Мой вопрос в следующем- как собственно вывести значение statusid в основную функцию selectStatusServicePact
часть вашего приведенного кода
sq.getEntityCollection(function(response) {
if (response && response.success) {
if (response.collection.getCount() > 0) {
var result = response.collection.getItems()[0];
var statusId = result.get("Status");
}
}
}, this)
переменная statusid доступна только внутри функции sq.getEntityCollection(function(response)
как сделать так, чтобы она(ее значение) была доступна в теле основной функции selectStatusServicePact: function() ?
Мне необходимо получить, допустим, статус договора, и не заполнять им какое-то поле внутри вспомогательной функции, а просто получить это значение, и дальше с ним работать в теле основной функции selectStatusServicePact: function()
Если модифицировать код функции selectStatusServicePact следующим образом, то статус договора будет доступен через this.get("StatusServicePact")
selectStatusServicePact: function(scope) { var esq = this.Ext.create("Terrasoft.EntitySchemaQuery", { rootSchemaName: "ServicePact" }); var servicePact = scope.get("servicePact") esq.addColumn("Id"); esq.addColumn("Status"); esq.filters.add("ServicePactId", this.Terrasoft.createColumnFilterWithParameter( this.Terrasoft.ComparisonType.EQUAL, "Id", servicePact.value)); esq.getEntityCollection(function(response) { if (response && response.success) { if (response.collection.getCount() > 0) { var result = response.collection.getItems()[0]; var statusId = result.get("Status"); //или scope.set("StatusServicePact", result.values.Status); } } }
Более надежный способ добавить в секцию attributes виртуальную колонку
"StatusServicePact": { "dataValueType": Terrasoft.DataValueType.CUSTOM_OBJECT, "type": Terrasoft.ViewModelColumnType.VIRTUAL_COLUMN, "value": null },
и внутри getEntityCollection сделать this.set("StatusServicePact", result.values.Status);
Далее в теле основной функции используйте this.get("StatusServicePact") для получения статуса договора.
Добавила виртуальную колонку.
Внутри getEntityCollection сделала this.set("StatusServicePact", result.values.Status);
Далее в теле основной функции использовала
var usrNeedTerritory = this.get("StatusServicePact");
- но объект (проверила в дебаггере) возвращается как null (хотя я его заполнила во вспомогательной функции)
Выяснила, чтобы эта схема работала, во вспомогательной функции нужно писать
не
this.set("StatusServicePact", result.values.Status);
а
this.set("StatusServicePact", result.get("Status"));
хотя нет - в и этом случае, похоже, что не работает.
возвращает null this.get("StatusServicePact")
причем, очень странно ведет себя - сначала возвращает null,
ошибка Cannot read property 'value' of null
нажимаю f12,закрываю f12 - и объект уже не null
что-то не так с выводом значения из функции во вне
И так каждый раз при открытии карточки и вызове этого метода в ней
( а именно, при нажатии на кнопку "вниз" в поле "группа ответственных" в карточке обращения)
Объект this.get("StatusServicePact") во внешней функции становится не null, только если включить и отключить f12 (каждый раз, когда открываешь карточку)
"Татаровская Дарья" написал:
И так каждый раз при открытии карточки и вызове этого метода в ней
( а именно, при нажатии на кнопку "вниз" в поле "группа ответственных" в карточке обращения)
Объект this.get("StatusServicePact") во внешней функции становится не null, только если включить и отключить f12 (каждый раз, когда открываешь карточку)
Привидите весь код страницы, по куску кода трудно предположить что происходит
В аттрибутах добавлена виртуальная колонка
attributes: {
"TerritoryServicePact": {
"dataValueType": Terrasoft.DataValueType.CUSTOM_OBJECT,
"type": Terrasoft.ViewModelColumnType.VIRTUAL_COLUMN,
"value": null
},
функция
getOwnerDependenceFilters: function(scope) {
//debugger;
var filterGroup = new scope.Terrasoft.createFilterGroup();
var serviceItem = scope.get("ServiceItem");
var servicePact = scope.get("ServicePact");
//var usrTerritory;
if (servicePact) {
var esq = this.Ext.create("Terrasoft.EntitySchemaQuery", {
rootSchemaName: "ServicePact"
});
esq.addColumn("Id");
esq.addColumn("UsrTerritory");
//esq.addColumn("Status");
esq.filters.add("ServicePactId", this.Terrasoft.createColumnFilterWithParameter(
this.Terrasoft.ComparisonType.EQUAL, "Id", servicePact.value));
esq.getEntityCollection(function(response) {
if (response && response.success) {
if (response.collection.getCount() > 0) {
var result = response.collection.getItems()[0];
this.set("TerritoryServicePact",result.get("UsrTerritory"));
//scope.set("MyStatus",result.get("MyStatus"));
}
}
}, this);
}
var usrNeedTerritory = this.get("TerritoryServicePact");
var usrNeedTerritoryvalue = usrNeedTerritory.value;
if (serviceItem) {
filterGroup.add("ServiceItemFilter", scope.Terrasoft.createColumnFilterWithParameter(
scope.Terrasoft.ComparisonType.EQUAL, "[ServiceEngineer:Engineer].ServiceItem", serviceItem.value));
}
if ((servicePact) ) {
filterGroup.add("TerritoryItemFilter", scope.Terrasoft.createColumnFilterWithParameter(
scope.Terrasoft.ComparisonType.EQUAL, "[ServiceEngineer:Engineer].UsrNeedTerritory", usrNeedTerritoryvalue));
}
return filterGroup;
}
В этом
примере выбирается новая колонка,добавленная в договор ( но такая ситуация повторяется, если выбирать любую колонку из договора)
var usrNeedTerritory = this.get("TerritoryServicePact") - этот объект(переданный из вспомогательной функции в основную) становится не null, только со второй попытке при открытии карточки, причем только после нажатия и отжатия кнопки f12
Татьяна вы можете привести весь код страницы полностью?
Из кусочка кода что вы привели я не вижу как и когда вызывается getOwnerDependenceFilters, какие модули подключены в вашу страницу и тд.
да, конечно
define("CasePage", ["CasePageResources", "GeneralDetails", "BusinessRuleModule"],
function(resources, GeneralDetails, BusinessRuleModule) {
return {
entitySchemaName: "Case",
details: /**SCHEMA_DETAILS*/{}/**SCHEMA_DETAILS*/,
diff: /**SCHEMA_DIFF*/[
]/**SCHEMA_DIFF*/,
attributes: {
"TerritoryServicePact": {
"dataValueType": Terrasoft.DataValueType.CUSTOM_OBJECT,
"type": Terrasoft.ViewModelColumnType.VIRTUAL_COLUMN,
"value": null
}
},
methods: {
getOwnerDependenceFilters: function(scope) {
//debugger;
var filterGroup = new scope.Terrasoft.createFilterGroup();
var serviceItem = scope.get("ServiceItem");
var servicePact = scope.get("ServicePact");
//var usrTerritory;
if (servicePact) {
var esq = this.Ext.create("Terrasoft.EntitySchemaQuery", {
rootSchemaName: "ServicePact"
});
esq.addColumn("Id");
esq.addColumn("UsrTerritory");
//esq.addColumn("Status");
esq.filters.add("ServicePactId", this.Terrasoft.createColumnFilterWithParameter(
this.Terrasoft.ComparisonType.EQUAL, "Id", servicePact.value));
esq.getEntityCollection(function(response) {
if (response && response.success) {
if (response.collection.getCount() > 0) {
var result = response.collection.getItems()[0];
this.set("TerritoryServicePact",result.get("UsrTerritory"));
//scope.set("MyStatus",result.get("MyStatus"));
}
}
}, this);
}
var usrNeedTerritory = this.get("TerritoryServicePact");
var usrNeedTerritoryvalue = usrNeedTerritory.value;
if (serviceItem) {
filterGroup.add("ServiceItemFilter", scope.Terrasoft.createColumnFilterWithParameter(
scope.Terrasoft.ComparisonType.EQUAL, "[ServiceEngineer:Engineer].ServiceItem", serviceItem.value));
}
if ((servicePact) ) {
filterGroup.add("TerritoryItemFilter", scope.Terrasoft.createColumnFilterWithParameter(
scope.Terrasoft.ComparisonType.EQUAL, "[ServiceEngineer:Engineer].UsrNeedTerritory", usrNeedTerritoryvalue));
}
return filterGroup;
},
onEntityInitialized: function() {
if (this.isAddMode() || this.isCopyMode()) {
this.setCaseNumber();
}
this.Terrasoft.SysSettings.querySysSettingsItem(this.statusDefSysSettingsName, function(value) {
this.set("StatusDefSysSettingsValue", value);
}, this);
this.updateOriginals();
var contact = this.get("Contact");
if (contact && !this.get("Account")) {
var account = contact.Account;
if (account) {
this.set("Account", account);
}
}
this.set("Owner", Terrasoft.SysValue.CURRENT_USER_CONTACT);
this.callParent(arguments);
}
},
rules: {
},
userCode: {}
};
});
getOwnerDependenceFilters - вызывается в сервисе стандартном CasePage (пакет SLMItilService, Case) - вызов этой функции там же и описан
в своей же схеме(унаследованной) я хочу переопределить саму функцию getOwnerDependenceFilters
Модифицированую вами функцию getOwnerDependenceFilters вы нигде не вызываете, ниже работающий вариант.
Для отладки добавил вторую виртуальную колонку TerritoryServicePact2 куда записую название статуса сервисного договора.
define("CasePage", ["CasePageResources", "GeneralDetails", "BusinessRuleModule", "BaseFiltersGenerateModule", "terrasoft"], function(resources, GeneralDetails, BusinessRuleModule, BaseFiltersGenerateModule, Terrasoft) { return { entitySchemaName: "Case", details: /**SCHEMA_DETAILS*/{}/**SCHEMA_DETAILS*/, diff: /**SCHEMA_DIFF*/[ ]/**SCHEMA_DIFF*/, attributes: { "TerritoryServicePact": { "dataValueType": Terrasoft.DataValueType.CUSTOM_OBJECT, "type": Terrasoft.ViewModelColumnType.VIRTUAL_COLUMN, "value": null }, "TerritoryServicePact2": { "dataValueType": Terrasoft.DataValueType.CUSTOM_OBJECT, "type": Terrasoft.ViewModelColumnType.VIRTUAL_COLUMN, "value": null }, "Owner": { dataValueType: Terrasoft.DataValueType.LOOKUP, lookupListConfig: { filter: function () { return this.getOwnerDependenceFilters(); } } } }, methods: { getOwnerDependenceFilters: function () { //debugger; var filterGroup = new this.Terrasoft.createFilterGroup(); var serviceItem = this.get("ServiceItem"); var servicePact = this.get("ServicePact"); //если договор выбран на карточке редактирования иначе undef; if (servicePact) { var esq = this.Ext.create("Terrasoft.EntitySchemaQuery", { rootSchemaName: "ServicePact" }); esq.addColumn("Id"); esq.addColumn("Status.Id", "StatusId"); esq.addColumn("Status.Name", "StatusName"); //esq.addColumn("Status.Id",""); esq.filters.add("ServicePactId", this.Terrasoft.createColumnFilterWithParameter( this.Terrasoft.ComparisonType.EQUAL, "Id", servicePact.value)); esq.getEntityCollection(function (response) { if (response && response.success) { if (response.collection.getCount() > 0) { var result = response.collection.getItems()[0]; this.set("TerritoryServicePact", result.get("StatusId")); this.set("TerritoryServicePact2", result.get("StatusName")); console.log(result.get("StatusId")); } } }, this); } var usrNeedTerritory = this.get("TerritoryServicePact"); //выдаю сообщение для отладки с названием статуса this.showInformationDialog(this.get("TerritoryServicePact2")); var usrNeedTerritoryvalue = usrNeedTerritory; if (serviceItem) { filterGroup.add("ServiceItemFilter", scope.Terrasoft.createColumnFilterWithParameter( scope.Terrasoft.ComparisonType.EQUAL, "[ServiceEngineer:Engineer].ServiceItem", serviceItem.value)); } if (servicePact) { filterGroup.add("TerritoryItemFilter", scope.Terrasoft.createColumnFilterWithParameter( scope.Terrasoft.ComparisonType.EQUAL, "[ServiceEngineer:Engineer].UsrNeedTerritory", usrNeedTerritoryvalue)); } return filterGroup; }, onEntityInitialized: function() { if (this.isAddMode() || this.isCopyMode()) { this.setCaseNumber(); } this.Terrasoft.SysSettings.querySysSettingsItem(this.statusDefSysSettingsName, function(value) { this.set("StatusDefSysSettingsValue", value); }, this); this.updateOriginals(); var contact = this.get("Contact"); if (contact && !this.get("Account")) { var account = contact.Account; if (account) { this.set("Account", account); } } this.set("Owner", Terrasoft.SysValue.CURRENT_USER_CONTACT); this.callParent(arguments); } }, rules: {}, userCode: {} }; });;
Дело не вызове функции, функция вызывается.
Насколько я поняла, вы в примере предложили дописать вызов функции, и это фильтр на выбор из справочника, но это не тот случай.
Функция getOwnerDependenceFilters вызывается в родительской схеме, как я уже писала, в моей же дочерней схеме она просто переопределяется.
Причем фильтр работает не на выбор из справочника, а на нажатие кнопки "вниз".
Вызов функции getOwnerDependenceFilters происходит - это точно.
Она вызывается -я в нее и дебаггером попадаю - и она отрабатывает вся целиком.
Вызов этой функции происходит в родительской схеме:
( а именно, CasePage(пакет Case) -здесь происходит вызов функции, и ее определение
далее, унаследованная CasePage(пакет SLMItilService) - здесь происходит переопределение функции
далее, унаследованная моя страничка - в которой я еще раз переопределяю функцию.
Функция эта переопределенная сама по себе работает корректно.
Но почему-то если добавить в мою переопределенную функцию вот такую подфункцию для вытаскивания значения связанного поля,
то значение это, как я уже говорила, становится не пусто только во второй раз.
Есть,допустим, поле "группа ответственных" (или ответственный), я нажимаю на кнопку вниз,
и в этот момент срабатывает функция фильтрации getOwnerDependenceFilters
вывожу сообщение для отладки this.showInformationDialog(this.get("TerritoryServicePact"));
и оно пусто
Еще раз нажимаю на кнопку вниз, опять срабатывает функция фильтрации getOwnerDependenceFilters,
вывожу сообщение для отладки this.showInformationDialog(this.get("TerritoryServicePact")),
и оно уже не пусто!
То есть наблюдается какая-то очень странная передача параметра из вспомогательной подфункции в основную - только со второго раза.
Предположила, что может дело в том, что фильтр вызывается на нажатие кнопки "вниз" - но нет, та же ситуация повторяется, если применять фильтр на выбор из справочника.
Предположила, что может быть так происходит, только если замещать функцию - но нет, т.к.
проверила ваш пример - если создать функцию не унаследованную - getOwnerDependenceFilters1, например, и вызвать ее для аттрибута Owner - то точно такая же ситуация повторяется в вашем примере..
Дарья getEntityCollection выполняет получение результата запроса асинхронно, а выполнение в функции getOwnerDependenceFilters идет дальше, не дожидаясь получения результата работы запроса.
При следующем клике значение из колонки берется то что было получено в первом запросе.
Я сделал виртуальную колонку TerritoryServicePact зависимой от изменения поля ServicePact (при изменении поля вызывается метод calculateStatus в котором выполняется запрос к БД и определяется статус договора), таким образом при вызове фильтра если был выбран сервисный договор, то у нас уже в TerritoryServicePact будет статус текущего договора.
define("CasePage", ["CasePageResources", "GeneralDetails", "BusinessRuleModule", "BaseFiltersGenerateModule", "terrasoft"], function(resources, GeneralDetails, BusinessRuleModule, BaseFiltersGenerateModule, Terrasoft) { return { entitySchemaName: "Case", details: /**SCHEMA_DETAILS*/{}/**SCHEMA_DETAILS*/, diff: /**SCHEMA_DIFF*/[ ]/**SCHEMA_DIFF*/, attributes: { "TerritoryServicePact": { "dataValueType": Terrasoft.DataValueType.CUSTOM_OBJECT, "type": Terrasoft.ViewModelColumnType.VIRTUAL_COLUMN, "value": null, dependencies: [ { // Значение колонки [TerritoryServicePact] зависит от значений колонок [ServicePact] columns: ["ServicePact"], // Метод-обработчик, который вызывается при изменении значения [ServicePact] methodName: "calculateStatus" } ] }, "TerritoryServicePact2": { "dataValueType": Terrasoft.DataValueType.CUSTOM_OBJECT, "type": Terrasoft.ViewModelColumnType.VIRTUAL_COLUMN, "value": null }, "Owner": { dataValueType: Terrasoft.DataValueType.LOOKUP, lookupListConfig: { filter: function () { return this.getOwnerDependenceFilters(); } } } }, methods: { // Метод-обработчик, который рассчитывает значение колонки [TerritoryServicePact]. calculateStatus: function () { var servicePact = this.get("ServicePact"); //если договор выбран на карточке редактирования иначе undef; if (servicePact) { var esq = this.Ext.create("Terrasoft.EntitySchemaQuery", { rootSchemaName: "ServicePact" }); esq.addColumn("Id"); esq.addColumn("Status.Id", "StatusId"); esq.addColumn("Status.Name", "StatusName"); //esq.addColumn("Status.Id",""); esq.filters.add("ServicePactId", this.Terrasoft.createColumnFilterWithParameter( this.Terrasoft.ComparisonType.EQUAL, "Id", servicePact.value)); esq.getEntityCollection(function (response) { if (response && response.success) { if (!response.collection.isEmpty()) { var result = response.collection.getItems()[0]; this.set("TerritoryServicePact", result.get("StatusId")); this.set("TerritoryServicePact2", result.get("StatusName")); console.log("rez="+result.get("StatusId")); } } }, this); } }, getOwnerDependenceFilters: function () { //debugger; var filterGroup = new this.Terrasoft.createFilterGroup(); var serviceItem = this.get("ServiceItem"); var servicePact = this.get("ServicePact"); //если договор выбран на карточке редактирования иначе undef; if (servicePact) { var usrNeedTerritory = this.get("TerritoryServicePact"); //выдаю сообщение для отладки с названием статуса this.showInformationDialog(this.get("TerritoryServicePact2")); var usrNeedTerritoryvalue = usrNeedTerritory; filterGroup.add("TerritoryItemFilter", this.Terrasoft.createColumnFilterWithParameter( this.Terrasoft.ComparisonType.EQUAL, "[ServiceEngineer:Engineer].UsrNeedTerritory", usrNeedTerritoryvalue)); } if (serviceItem) { filterGroup.add("ServiceItemFilter", this.Terrasoft.createColumnFilterWithParameter( this.Terrasoft.ComparisonType.EQUAL, "[ServiceEngineer:Engineer].ServiceItem", serviceItem.value)); } return filterGroup; }, onEntityInitialized: function() { if (this.isAddMode() || this.isCopyMode()) { this.setCaseNumber(); } this.Terrasoft.SysSettings.querySysSettingsItem(this.statusDefSysSettingsName, function(value) { this.set("StatusDefSysSettingsValue", value); }, this); this.updateOriginals(); var contact = this.get("Contact"); if (contact && !this.get("Account")) { var account = contact.Account; if (account) { this.set("Account", account); } } this.set("Owner", Terrasoft.SysValue.CURRENT_USER_CONTACT); this.callParent(arguments); } }, rules: {}, userCode: {} }; });;
Спасибо, теперь понятно, откуда такое поведение - из-за того, что
etEntityCollection выполняет получение результата запроса асинхронно.
Но не понятно до конца по-прежнему получение значения связанной колонки в карточке.
Вы сделали виртуальную колонку TerritoryServicePact зависимой от изменения поля ServicePact (при изменении поля вызывается метод метод calculateStatus в котором выполняется запрос к БД и определяется статус договора)
Но метод-то этот вызывается только при изменении поля ServicePact, тогда при вызове фильтра в поле "ответственный" в карточке все ок
А если я просто открываю карточку на редактирование( уже готовую), в ней уже выбран договор, это поле не меняется, и метод calculateStatus естественно не вызывается, и фильтр вообще тогда не работает.
Надо еще в каком-то месте вызывать получается метод?
Дарья просто вызовите метод calculateStatus при инициализации страницы CasePage :smile: