Вопрос

Всем привет,

На странице детали с редактируемым реестром добавляю колонку Code в lookuplistconfig и зависимости:

//attributes
"ITPMonth": {
	"dataValueType": Terrasoft.DataValueType.LOOKUP,
	"lookupListConfig": {
	"columns": ["Code"],
	"dependencies": [
		{
			columns: ["ITPMonth", "ITPYear"],
			methodName: "setPeriod"
		}
	]
}

Если я попадаю в метод setPeriod при изменении колонки ITPMonth, то колонка Code есть в модели и её значение можно получить, а если я попадаю в этоу функцию при изменении поля ITPYear, то доступа к колонке Code нет.

Это такой баг/фича или я что-то делаю не так ?

У меня такой же вопрос

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

По-моему вы что-то напутали с вложенностью. 

lookupListConfig и dependencies должны находиться на одном уровне, а у вас одно в другом как-то оказалось. 

Посмотрите пример тут: https://academy.terrasoft.ru/documents/technic-sdk/7-13/dobavlenie-mult… с колонкой Currency

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

Скорее всего механизм lookupListConfig добавляет колонки именно тогда, когда открывается лукап указанного аттрибута (именно ITPMonth). Когда вы открываете лукап поля ITPYear, то неоткуда взять колонку Code. Надеюсь нормально объяснил.

Или же вы хотите и из поля TPYear тоже Code получить?

Дмитрий А.,

Похоже на правду, но мне всегда казалось, что эти колонки можно использовать в методах, даже при инициализации карточки (т.е. без открытия лукапа поля). Разве нет? В доках как-то размыто написано про эту фичу.

Войдите или зарегистрируйтесь, чтобы комментировать
Вопрос

Приветствую всех!

Подскажите, почему вот так работает:

lookupListConfig: {
  filters: [{
    method: function(columnName){
      return this.getFilterByAccount(columnName);
    },
    argument: "Account"
  }]
}

а вот так 

lookupListConfig: {
  filters: [{
    method: this.getFilterByAccount,
    argument: "Account"
  }]
}

нет!

 

У меня такой же вопрос

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

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

Дело в том, что во втором случае view module (описывает поведение) еще не проинициализирован (секция methods в схеме относится к view module). 

При обращении к lookupListConfig загружается пока только window (https://developer.mozilla.org/ru/docs/Web/API/Window) в котором нет данного метода.

Если посмотрите в консоль при выполнении кода lookupListConfig, то увидите:

1. Ошибку, что метод не найден (будет написано undefined)

2. При написании в консоли "this." будет написано подсказка window.

Вильшанский Дмитрий,

понятно, спасибо.

В качестве пожелания для разработчиков, как вариант, можно было бы добавить в обработчик LookupQuickAddMixin.getLookupQueryFilters проверку не только method, но и methodName, тогда по this[methodName] можно было бы вызывать функцию фильтрации.

Войдите или зарегистрируйтесь, чтобы комментировать
Вопрос

Суть:
Есть некая карточка (н/п MyCustomPageV2) которая содержит справочное поле (н/п Owner).
В бизнес-логике карточки, необходимо значение поля (н/п Status) сущности экземпляр которой выбран в справочном поле Owner
используем для этого штатный механизм конфигурирования поля как атрибута, lookupListConfig и его свойства columns

attributes: {
...
"Owner": {
        lookupListConfig: {
                columns: ["Status"],
        }
}

...
}

Что позволяет организовать как-бы "просмотр внутрь" справочного поля и предоставление значения колонки Status выбранного значения.
Проблема:
Юзер открывает карточку MyCustomPageV2, в модели для поля Owner было загружено так же поле Status (к примеру оно содержит значение "X").
Теперь пользователь через гиперссылку справочного поля перешел на карточку сущности Owner изменил там значение Status (к примеру на значение "Y"), нажал "Сохранить", и тем самым вернулся в MyCustomPageV2 (из Chain). Теперь если мы обратимся к полю Owner и его колонке Status
this.get("Owner").Status

то оно по прежнему содержит значение "X"
Вопросы:
  1. Это баг ? или так и должно быть ?
  2. Если так и должно быть, то вероятно есть способ акутализировать данные колонок полей указанных в lookupListConfig -> columns? Как это сделать ?
  3. Как вообще можно отреагировать на "возвращение в карточку" при переходе из Chain (по "Закрыть" или "Сохранть" и т.д. открытых "поверх" карточек других сущностей) ? В таком случае, в виде "костыля" можно было бы хоть сделать ESQ запрос и актуализировать данные вручную

вот...

У меня такой же вопрос

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

Добрый день!
Это не баг. У вас в первой карточке своя модель, которая загрузила значение Х. Изменения этого значения в БД не приведет к изменению значения в модели (Именно это вы и делаете из другой карточки - сохраняете в БД).
Задача в 2 этапа:
1. Нотификация изменений
2. Загрузка актуальных значений

Варианты решений:
1. Можно сделать обмен сообщениями между модулями
2. Загрузка актуальных...у всех наследников BasePage есть метод reloadEntity - он актуализирует данные

Хорошо, про reloadEntity мне известно,
но как мне инициировать его в момент когда пользователь "вернулся" в карточку,
есть ли какая-то событийная модель на этот случай, какой-то прием который позволит этот самый reloadEntity запустить тогда когда он нужен ?

Сейчас веду маленькое исследование на этот счет, отвечу в вашем дубле здесь:
http://www.community.terrasoft.ru/forum/topic/25727

Войдите или зарегистрируйтесь, чтобы комментировать
Вопрос

Обнаружено следующее поведение,
В некотором объекте н/п Tender есть поле н/п "Stage" (Справочное), на уровне конфигурации установлено значение по-умолчанию, н/п элемент с Name ='Создание'
В схеме карточки для этого поля в lookupListConfig добавляем "просмотр внутрь" и извлечение дополнительных полей выбранного элемента справочника.

...
attributes: {
"Stage": {
        lookupListConfig: {
                 columns: ["Name"]
        }
},
...

Так, открываем карточку существующей записи, н/п созданной и тут-же сохраненной, но повторно открытой в режиме редактирования
this.get("Stage");

получаем вполне ожидаемый результат
{value: "16886c2b-1388-45d3-9514-3ca70b9a4858", displayValue: "Создание", primaryImageValue: "", Name: "Создание"}

Так теперь просто открываем карточку в режиме создания и повторяем эксперимент:
this.get("Stage");

получаем результат неожиданный:
{value: "16886c2b-1388-45d3-9514-3ca70b9a4858", displayValue: "Создание"}

а где же наш Name который мы указали в lookupListConfig для нашего поля ?
про свойство primaryImageValue не ясно, но его как бы тоже нет.

И вот не ясно - так и должно быть, в силу каких-то более не менее объективных причин, или это выявленный дефект ?

У меня такой же вопрос

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

Создали проблему для реализации данного функционала и при открытии карточки в режиме создания. Будет исправлено в рамках работы над новыми релизами. Тем временем можете проверять режим карточки и получать эти данные через esq.

Войдите или зарегистрируйтесь, чтобы комментировать
Вопрос

Зачастую требуется корректировать набор фильтров для справочных полей карточки как говорится "на лету", в зависимости от тех или иных условий/событий/действий пользователя

Собственно к коллекции фильтров можно подступиться через
this.columns.{ИмяКолонки}.lookupListConfig
Но основной вопрос - корректно ли манипулировать этой коллекцией через непосредственный доступ - вот таким образом, или разработчик предусмотрел другую методику корректировки набора фильтров для справочных полей ?
Специализированные методы возможно,
Возможно состояние this.columns.{ИмяКолонки}.lookupListConfig в жизненном цикле контекста может быть сброшено - и необходимо иметь вспомогательные сущности, для повторного его построения. (Т.к. изначально тот-же lookupListConfig задается например при описании атрибута одноименного колонке, но в конечном итоге среди полей получаемых из модели по имени поля - не содержится) ?

У меня такой же вопрос

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

Не встречал такого подхода работы в рамках базовых конфигураций.
Если вам необходимо анализировать внешние асинхронные условия пере формированием той или иной логики фильтр метода, то рекомендуем вам:
1. Сделать подписку на изменения всех колонок, которые могут влиять на логику формирования фильтрации колонки в lookupListConfig;
2. При изменении данных колонок кешировать асинхронный результат, который должен повлиять на логику фильтрации в атрибутах;
3. В фильтр методе lookupListConfig-а: анализировать кешированные атрибуты, и формировать согласно вашей логики нужный вам esq, блоками if else.

Войдите или зарегистрируйтесь, чтобы комментировать
Вопрос

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

Есть две сущности: Arrears - задолженности, PromisesArrears - обещания.
Суть задачи в следующем: необходимо чтобы при добавлении нового обещания, когда открываем справочник задолженностей, чтобы отображались только те задолженности по которым еще не созданы обещания. Итак, на странице PromisesArrearsPage в свойство attributes добавляем

"Arrears": {
                dataValueType: Terrasoft.DataValueType.LOOKUP,
                dependencies: [
                                {
                                        columns: ["Arrears"],
                                        methodName: "arrearsFunction"
                                }
                        ],                             
                lookupListConfig: {
                                filters: [
                                        function() {
                                                var filterGroup = Ext.create("Terrasoft.FilterGroup");
                                                var notHaveOtherPromisesFilter = Terrasoft.createColumnIsNullFilter("[PromisesArrears:Arrears].Id");
                                                filterGroup.add("notHaveOtherPromisesFilter", notHaveOtherPromisesFilter);
                                                return filterGroup;
                                        }
                                ]
                        }
                },

Но в результате открывается пустой справочник. Пробовал также указывать явно левосторонний join ">[PromisesArrears:Arrears].Id", но это ничего не дало. К сожалению, не знаю как получить sql текст на JS, поэтому для получения текста запроса создал esq на c# с идентичным как мне представляется фильтром и join.
Код с#

var esq = new EntitySchemaQuery(UserConnection.EntitySchemaManager, "Arrears");
        esq.AddColumn("[PromisesArrears:Arrears].Id");
       
        var esqFirstFilter = esq.CreateIsNullFilter("[PromisesArrears:Arrears].Id");
        esq.Filters.Add(esqFirstFilter);       
       
        resultSQLText = esq.GetSelectQuery(UserConnection).GetSqlText();

return true;

Полученный в результате запрос
SELECT
        [PromisesArrears].[Id] [PromisesArrears.Id]
FROM
        [dbo].[Arrears] [Arrears] WITH(NOLOCK)
        LEFT OUTER JOIN [dbo].[PromisesArrears] [PromisesArrears] WITH(NOLOCK) ON ([PromisesArrears].[ArrearsId] = [Arrears].[Id])
WHERE
        [PromisesArrears].[Id] IS NULL

^^И это именно тот запрос, что возвращает мне то что нужно (в части фильтрации и join).

Поэтому пара вопросов:
1) Что не так в lookupListConfig?
2) Как получить SQL текст на JS ?

У меня такой же вопрос

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

Добрый день Андрей!!!

вы сами в условии задачи описали открывать Справочник "Задолженности" по которым нет "Обещаний". Вижу у вас здесь неправильно составленный SQL запрос. Вот я как вижу правильный SQL запрос:

SELECT
        [PromisesArrears].[Id] [PromisesArrears.Id]
FROM
        [dbo].[Arrears] [Arrears] WITH(NOLOCK)
        LEFT OUTER JOIN [dbo].[PromisesArrears] [PromisesArrears] WITH(NOLOCK) ON ([PromisesArrears].[ArrearsId] = [Arrears].[Id])
WHERE
        [PromisesArrears].[ArrearsId] IS NULL

При вашем условии вы всегда получите пусто.

поэтому на Яваскрипте у вас должно быть написано следующее:

"Arrears": {
     dataValueType: Terrasoft.DataValueType.LOOKUP,
     dependencies: [
     {
          columns: ["Arrears"],
          methodName: "arrearsFunction"
     }],
     lookupListConfig: {
          filters: [function()
          {
               var filterGroup = Ext.create("Terrasoft.FilterGroup");
               var notHaveOtherPromisesFilter = Terrasoft.createColumnIsNullFilter("[PromisesArrears:Arrears].Arrears");
               filterGroup.add("notHaveOtherPromisesFilter", notHaveOtherPromisesFilter); 
               return filterGroup;
          }]
     }
},

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

Добрый день Андрей!!!

совсем заработался сегодня уже стал неправильный код выдавать :)

вот правильный запрос на ваши условия:

SELECT
        COUNT([Arrears].[Id]) as CountArrearsId
FROM
        [dbo].[Arrears] [Arrears] WITH(NOLOCK)
WHERE [Arrears].[Id] NOT IN (SELECT [PromisesArrears].[ArrearsId]
                                          FROM [dbo].[PromisesArrears] [PromisesArrears] WITH(NOLOCK))

Да и тот запрос, что в моем первом сообщении возвращает те задолженности, по которым нет обещаний, то есть соответствует моим условиям. Конечно его нужно подправить в части SELECT (на SELECT [Arrears].[Id] вместо SELECT [PromisesArrears].[Id]), но это ведь не имеет отношения к свойству lookupListConfig.filters, где не фигурируют выбираемые колонки, а только колонки, по которым идет фильтрация (то есть, те что попадают в запрос в частях Where и Join).

Но суть вопроса ведь даже не в самом запросе, а в том как его представить в JavaScript и чтобы работало.

Я в общем-то нашел решение, которое меня устроило в этой теме в конце http://www.community.terrasoft.ua/forum/topic/12500

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

filter: function() {
                        var Contact = this.get("Contact");
                        var filterGroup1 = this.Terrasoft.createFilterGroup();
                        filterGroup1.add("ContactFilter1",	Terrasoft.createColumnFilterWithParameter(Terrasoft.ComparisonType.EQUAL, 
"[PromisesArrears:Arrears].Contact", Contact.value));
 
                        var filterGroup2 = this.Terrasoft.createFilterGroup();
 
                        var notHaveOtherPromisesFilter = this.Terrasoft.createNotExistsFilter("Id", filterGroup1);
                        filterGroup2.addItem(notHaveOtherPromisesFilter);
 
                        filterGroup2.add("ContactFilter",
			Terrasoft.createColumnFilterWithParameter(Terrasoft.ComparisonType.EQUAL, "Contact", Contact.value)); 
 
                        return filterGroup2;							
 } 

А вот как отобразить все задолженности (не привязываясь к конкретному контакту) по которым нет обещаний ?

И, кстати, для метода createNotExistsFilter в статье на академии представлен только вариант с одним параметром - columnPath, а не тот вариант, что использован в примере выше и о существовании которого оставалось только догадываться.

Добрый день Андрей!!!

вы в своем сообщение привели ссылку на статью Комьюнити где описывается как создать "createNotExistsFilter". Чем он вас не устраивает? Это такой же запрос, что я приводил выше, только переделанный на EXISTS. В чем у вас возникли сложности?

Да и вправду createNotExistsFilter возвращает требуемые задолженности. Код

filter: function() {
 
									var filterGroup1 = this.Terrasoft.createFilterGroup();
									filterGroup1.add("ArrearsInPromisesFilter1", Terrasoft.createNotExistsFilter("[PromisesArrears:Arrears].Id"));
 
 
									return filterGroup1;							
} 

Сейчас у вас Андрей получилось выполнить Фильтрацию по вашим условиям задачи? или еще остались вопросы?

Да, получилось то что нужно с последним кодом.

Войдите или зарегистрируйтесь, чтобы комментировать
Вопрос

Есть деталь на странице проекта. В lookupListConfig справочного поля Проект указаны два поля, которые доступны при добавлении или изменении записи детали, но не доступны при копировании. Можно скопировать запись, сохранить ее, а потом изменить - поля становятся доступными. Поля детали расчитываются на основе полей на странице проекта. Возможно каким-то образом сделать их доступными, чтобы не брать значения с помощью EntitySchemaQuery?

У меня такой же вопрос

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

Добрый день, Олег.

Если Вам не трудно, прошу Вас уточнить Ваш вопрос скриншотами.

Если я правильно понял, то Вас интересует как передать значение со страницы проекта в страницу детали, чтобы рассчитать значение полей. Это можно сделать с помощью messages.
1. В объект messages проекта добавить SUBSCRIBE. В объект messages детали добавить PUBLISH.
2. На init проекта подписаться на сообщение
this.sandbox.subscribe("GetSomeInfoFromDetail", function(argument) {
return this.someFunctionUsingArgument();
}, this, ["key"]);
3. На детали, когда Вам нужно получить значение с проекта сделать sandbox.publish
var result = this.sandbox.publish("GetSomeInfoFromDetail", valueToSend, ["key"]);

Таким образом, Вы можете получить значение с главной страницы и рассчитать Ваши поля.

Спасибо, Вы очень помогли :smile:

Войдите или зарегистрируйтесь, чтобы комментировать