Фильтрация лукапного поля в детали

Подскажите пожалуйста, запутался совсем.
Есть сущности UsrVacancies, UsrCandidates и UsrVacancyCandidates. На основе UsrVacancyCandidates сделана деталь. Заходишь на вакансию, и можешь ассайнить кандидатов, одного или нескольких. Если кандидат УЖЕ добавлен для вакансии, то должно быть невозможно добавить этого же кандидата дважды или более.
Когда нажимаешь "Add" в детали, там есть лукапное поле Candidate (имя - UsrCandidates). Что я хочу сделать - чтобы в этом лукапе НЕ отображались те кандидаты, что УЖЕ добавлены для ЭТОЙ вакансии, т.е. отфильтровать его.
Для этого я должен получить список тех кандидатов, что уже добавлены для этой вакансии, и наложить фильтр на лукап - показывать всех кандидатов, КРОМЕ уже добавленных.

Вот как должно быть. Обратите внимание на переменную "candidates", где я захардкодил айдишники.

attributes: {
        "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 запрос, который возвращает эти айдишники.

getCurrentlyAssignedCandidates: function(vacancyId, callback) {
        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. Т.е. ничего не фильтруется.

Подскажите, пожалуйста, как это реализовать.

Заранее благодарю!

Нравится

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

На самом деле вариантов несколько:
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;
				}
			}
		}
	},
},
Показать все комментарии