Подскажите пожалуйста, запутался совсем.
Есть сущности 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 только здесь без фильтрации по существующим
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; },
Но здесь возникнут сложности в асинхронностью, но Вы можете формировать первоначальную коллекцию например в методе init, а затем актуализировать эту коллекцию при изменении детали через подписку на сообщение updateDetail
2. Через правила
Как пример UIv2/ContactAddressPageV2
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
3. Через один из методов Lookup, как пример loadVocabulary или prepareLookupList
/** * Подготовка параметров для открытия окна выбора из пользователей. * @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; },
Подобный вопрос задавали http://www.community.terrasoft.ru/forum/topic/11658
Мне нужно сформировать в javascript подобный запрос для фильтрации
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 );
Пока не могу понять, как..
1. SELECT DISTINCT vc.UsrCandidatesId
реализуется так:
esq.isDistinct = true; esq.addColumn("UsrCandidatesId");
2. vc.UsrCandidatesId NOT IN(
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); }
Можете переделать NOT IN на Not Exists тогда, как пример фильтр в модуле
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); },
Теория по Exists
http://www.terrasoft.ua/bpmonlinesdk/Terrasoft.Core~Terrasoft.Core.Enti…
Спасибо, разобрался. Сделал так:
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; } } } }, },