Подскажите пожалуйста, запутался совсем.
Есть сущности UsrVacancies, UsrCandidates и UsrVacancyCandidates. На основе UsrVacancyCandidates сделана деталь. Заходишь на вакансию, и можешь ассайнить кандидатов, одного или нескольких. Если кандидат УЖЕ добавлен для вакансии, то должно быть невозможно добавить этого же кандидата дважды или более.
Когда нажимаешь "Add" в детали, там есть лукапное поле Candidate (имя - UsrCandidates). Что я хочу сделать - чтобы в этом лукапе НЕ отображались те кандидаты, что УЖЕ добавлены для ЭТОЙ вакансии, т.е. отфильтровать его.
Для этого я должен получить список тех кандидатов, что уже добавлены для этой вакансии, и наложить фильтр на лукап - показывать всех кандидатов, КРОМЕ уже добавленных.
Вот как должно быть. Обратите внимание на переменную "candidates", где я захардкодил айдишники.
"UsrCandidates": {
dataValueType: Terrasoft.DataValueType.LOOKUP,
lookupListConfig: {
filter: function() {
var candidates = ["5d4d6b06-4de2-4d23-8e6e-f2ab624af5d0", "3c6f72a7-3218-4f23-b96a-e344bac099f4", "a9b68651-d313-4c83-9007-31a659547bd5"];
var filterGroup = new Terrasoft.createFilterGroup();
var filter1 = Terrasoft.createColumnInFilterWithParameters(
"Id",
candidates);
filter1.comparisonType = Terrasoft.ComparisonType.NOT_EQUAL;
filterGroup.add("filter1", filter1);
return filterGroup;
}
}
}
},
Однако, мне нужно получить эти айдишники, зная Id текущуй вакансии. Вот ESQ запрос, который возвращает эти айдишники.
var esq = this.Ext.create("Terrasoft.EntitySchemaQuery", {
rootSchemaName: "UsrVacancyCandidates"
});
esq.addColumn("UsrCandidates", "CandidateId");
esq.filters.add(
"filter1",
this.Terrasoft.createColumnFilterWithParameter(
Terrasoft.ComparisonType.EQUAL,
"UsrVacancies",
vacancyId
)
);
esq.getEntityCollection(function(result) {
var candidates = [];
if (result.success) {
result.collection.each(function(item) {
candidates.push(item.get("CandidateId"));
});
callback.call(this, candidates);
}
});
}
Однако, если вызывать callback в "filter", то он выполняется асинхронно, и сама функция выполняется асинхронно. Получается, что функция "filter" возвращает фильтр (который включает в себя ВСЕХ кандидатов) раньше, чем выполняется callback. Т.е. ничего не фильтруется.
Подскажите, пожалуйста, как это реализовать.
Заранее благодарю!
Нравится
На самом деле вариантов несколько:
1. Через filterMethod, добавляете на деталь ссылку на метод, а в самом методе добавляете в фильтр уже добавленные записи
Как пример UIv2/AccountPageV2 только здесь без фильтрации по существующим
[csharp]
details: /**SCHEMA_DETAILS*/{
EmailDetailV2: {
schemaName: "EmailDetailV2",
filter: {
masterColumn: "Id",
detailColumn: "Account"
},
filterMethod: "emailDetailFilter"
}
…
/**
* Функция создания фильтров детали email
* @protected
* @returns {createFilterGroup}
*/
emailDetailFilter: function() {
var recordId = this.get("Id");
var filterGroup = new this.Terrasoft.createFilterGroup();
filterGroup.add("AccountNotNull", this.Terrasoft.createColumnIsNotNullFilter("Account"));
filterGroup.add("AccountConnection", this.Terrasoft.createColumnFilterWithParameter(
this.Terrasoft.ComparisonType.EQUAL, "Account", recordId));
filterGroup.add("ActivityType", this.Terrasoft.createColumnFilterWithParameter(
this.Terrasoft.ComparisonType.EQUAL, "Type", ConfigurationConstants.Activity.Type.Email));
return filterGroup;
},
[/csharp]
Но здесь возникнут сложности в асинхронностью, но Вы можете формировать первоначальную коллекцию например в методе init, а затем актуализировать эту коллекцию при изменении детали через подписку на сообщение updateDetail
2. Через правила
Как пример UIv2/ContactAddressPageV2
[javascript]
rules: {
"AddressType": {
"FiltrationAddressTypeByOwner": {
ruleType: BusinessRuleModule.enums.RuleType.FILTRATION,
autocomplete: true,
baseAttributePatch: "ForContact",
comparisonType: Terrasoft.ComparisonType.EQUAL,
type: BusinessRuleModule.enums.ValueType.CONSTANT,
value: true
}
}
},
или NUI/ActivityPage
[/javascript]
3. Через один из методов Lookup, как пример loadVocabulary или prepareLookupList
[javascript]
/**
* Подготовка параметров для открытия окна выбора из пользователей.
* @return {Object} Config настроек окна выбора из справочника.
*/
prepareLookupConfig: function() {
var filters = this.getLookupFilter();
var config = {
entitySchemaName: "SysAdminUnit",
multiSelect: true,
columns: ["Contact", "Name"],
hideActions: true,
filters: filters
};
return config;
}
getLookupFilter: function(isDelegate) {
var filters = this.Terrasoft.createFilterGroup();
var parentFilter = this.Terrasoft.createColumnFilterWithParameter(
this.Terrasoft.ComparisonType.EQUAL,
isDelegate ? "GrantorSysAdminUnit.Id" : "GranteeSysAdminUnit.Id",
this.get("MasterRecordId"));
var sameIdFilter = this.Terrasoft.createColumnFilterWithParameter(
this.Terrasoft.ComparisonType.NOT_EQUAL,
"Id",
this.get("MasterRecordId"));
...
filters.addItem(sameIdFilter);
return filters;
},
[/javascript]
Подобный вопрос задавали http://www.community.terrasoft.ru/forum/topic/11658
Мне нужно сформировать в javascript подобный запрос для фильтрации
[sql]
declare @vacancyId uniqueidentifier = '3984d4b1-de5d-405b-b7c6-320b03b0a8ec';
select distinct
vc.UsrCandidatesId
from UsrVacancyCandidates vc
where
vc.UsrCandidatesId not in(
select vc.UsrCandidatesId from UsrVacancyCandidates vc
where vc.UsrVacanciesId = @vacancyId
);
[/sql]
Пока не могу понять, как..
1. SELECT DISTINCT vc.UsrCandidatesId
реализуется так:
[javascript]
esq.isDistinct = true;
esq.addColumn("UsrCandidatesId");
[/javascript]
2. vc.UsrCandidatesId NOT IN(
[javascript]
SELECT vc.UsrCandidatesId FROM UsrVacancyCandidates vc
WHERE vc.UsrVacanciesId = @vacancyId
);
Реализуется через NOT_EQUAL
Пример NUI/InFolderDetail
var filterGroup = Terrasoft.createFilterGroup();
if (inFolders.length > 0) {
var notInFilter = Terrasoft.createColumnInFilterWithParameters('Id', inFolders);
notInFilter.comparisonType = Terrasoft.ComparisonType.NOT_EQUAL;
filterGroup.addItem(notInFilter);
}
[/javascript]
Можете переделать NOT IN на Not Exists тогда, как пример фильтр в модуле [csharp]
LeadContactsInFolderDetailV2
/**
* Метод действия "Добавить группу контактов".
* @private
*/
addContactFolder: function() {
var masterColumnValue = this.get("MasterRecordId");
var config = {
entitySchemaName: "ContactFolder",
multiSelect: true,
columns: ["FolderType", "Id"]
};
var existsFilterGroup = this.Terrasoft.createFilterGroup();
existsFilterGroup.addItem(this.Terrasoft.createColumnFilterWithParameter(
this.Terrasoft.ComparisonType.EQUAL, "Contact", masterColumnValue));
var existsFilter = this.Terrasoft.createNotExistsFilter("[ContactInFolder:Folder:Id].Contact",
existsFilterGroup);
var filterGroup = this.Terrasoft.createFilterGroup();
filterGroup.addItem(existsFilter);
var folderFilter = this.Terrasoft.createColumnFilterWithParameter(
this.Terrasoft.ComparisonType.EQUAL, "FolderType", ConfigurationConstants.Folder.Type.General);
filterGroup.addItem(folderFilter);
config.filters = filterGroup;
this.openLookup(config, this.addContactCallback, this);
},
[/csharp]
Теория по Exists
http://www.terrasoft.ua/bpmonlinesdk/Terrasoft.Core~Terrasoft.Core.Enti…
Спасибо, разобрался. Сделал так:
[javascript]
attributes:
{
"UsrCandidates":
{
dataValueType: Terrasoft.DataValueType.LOOKUP,
lookupListConfig:
{
filter: function()
{
var vacancy = this.get("UsrVacancies");
if (!this.Ext.isEmpty(vacancy))
{
var filterGroup1 = this.Terrasoft.createFilterGroup();
var filter1 = this.Terrasoft.createColumnFilterWithParameter(
this.Terrasoft.ComparisonType.EQUAL,
"[UsrVacancyCandidates:UsrCandidates].UsrVacancies", vacancy
.value);
filterGroup1.addItem(filter1);
var filterGroup2 = this.Terrasoft.createFilterGroup();
var filter2 = this.Terrasoft.createNotExistsFilter(
"[UsrCandidates:Id].Id", filterGroup1);
filterGroup2.addItem(filter2);
return filterGroup2;
}
}
}
},
},
[/javascript]