Добрый день. Прошу помощи - третий день мучаюсь с этой задачкой. Есть страница редактирования. В ней есть деталь, отображающая (только чтение) записи из того же реестра. Отбор записей в деталь должен проводиться по ряду условий, связанных с полями основной записи на странице редактирования. Мысль в том, чтобы по этим условиям отобрать через EntitySchemaQuery несколько Id и назначить их в фильтр детали через createColumnInFilterWithParameters.

Проблема в том, что результаты EntitySchemaQuery.getEntityCollection отрабатываются в callback-функции, и происходит это в большинстве случаев позже, чем завершается работа функции filterMethod детали, в которой делается вызов getEntityCollection. Фильтр получается пустым.

Ниже проблемный код:

// функция назначена как "filterMethod" детали
applyFilter: function() {
    //
    var vFGroup = Terrasoft.createFilterGroup();
    vFGroup.logicalOperation = Terrasoft.LogicalOperatorType.AND;

    //

    var esq = Ext.create("Terrasoft.EntitySchemaQuery", {
        rootSchemaName: "Tenants"
    });

    esq.addColumn("Id");
    esq.addColumn("ReportMonth");
    esq.addColumn("Area");

    var vArea = this.get("Area");

    // фильтры запроса - должна совпадать дата, и площадь быть в +-20%                    
    esq.filters.add("ReportMonthFilter", 
        esq.createColumnFilterWithParameter(Terrasoft.ComparisonType.EQUAL, 
            "ReportMonth", this.get("ReportMonth")));
    esq.filters.add("AreaFilter", 
        esq.createColumnBetweenFilterWithParameters("Area", 
            vArea * 0.8, vArea * 1.2));

    // до этого места все работает корректно 
    // теперь запускаем запрос и получаем данные
     // насколько я понимаю, архитектурно система распараллеливает задачи,
    // т.е. function(result) и следующая инструкция после getEntityCollection()
    // начинают отрабатываться одновременно
    esq.getEntityCollection(function (result) {
        if (result.success) {

            // добавляем фильтр как UID по списку
            // здесь так можно, больших выборок не предполагается
            var vSelected = [];                        
            result.collection.each(function (item) {
                vSelected.push(item.get("Id"));
            });

            var vIdF = Terrasoft.createColumnInFilterWithParameters("Id", vSelected);

            // нужно как-то гарантировать, чтобы эта операция всегда выполнялась раньше, чем 
            // return vFGroup; в конце функции. Иначе в фильтры попадает пустой список, и фильтр
            // не работает. 
            vFGroup.add("vIdF", vIdF);
        }
    }, this);

    // Интересно, что при первом открытии детали после обновления 
    // страницы операция return vFGroup; 
    // выполняется корректно, т.е. после vFGroup.add("vIdF", vIdF);. 
    //Если дальше закрыть страницу и через реестр
    // открыть другую запись - уже не работает.

    // Также интересно, что если вбить вот сюда:
    // window.alert("!");
    // то пауза будет достаточна для формирования vFGroup 
    // независимо от того, в первый раз я открываю
    // запись или нет

    return vFGroup;
},

 

Нравится

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

Сорри, уже сам разобрался. Надо было всего-то создать property для списка UID и перенести его подгрузку в onEntityInitialized, оставив в applyFilter только сортировку и создание итогового фильтра для детали. 

В ней есть деталь, отображающая (только чтение) записи из того же реестра. Отбор записей в деталь должен проводиться по ряду условий, связанных с полями основной записи на странице редактирования.

Юрий, вообще, такая постановка намекает, что можно в БД сделать view с нужными данными: каждому Id записи в основном разделе будет соответствовать несколько строк для отображения на детали по нужному условию.

 

Создать объект с такими же колонками, привязать к этой view и далее в разделе настроить деталь стандартными средствами без всякого кода.

Согласен с Александр Зверев
Недавно сам мучался с подобным, гораздо приятнее когда вся логика связок таблиц завернута во фьюху.
Главное не забыть что во фьюхе должны быть также служебные поля:

DROP VIEW IF EXISTS dbo.VwCaseGroup
GO

CREATE VIEW dbo.VwCaseGroup
AS SELECT
  SAU.ContactId AS Id,
  SUR.SysRoleId,
  SUR.CreatedById,---------<
  SUR.ModifiedById,---------<
  SUR.CreatedOn,---------<
  SUR.ModifiedOn,---------<
  SUR.ProcessListeners---------<
FROM dbo.SysAdminUnit SAU
JOIN dbo.SysUserInRole SUR ON SAU.Id = SUR.SysUserId
GO

Показать все комментарии

После добавления одного поля в карточку задачи и в EntityConnection, поля начинают "плясать". Иногда открывается в таком виде, при этом заполненные значения не видны. 
И после рефреша всё проходит, но потом может появиться снова

 

Как с этим бороться?

Нравится

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

Молитвой и божьим словом, на сколько я помню обращения в саппорт коллег))

1) Делаем select запрос в EntityConnection, видим поле Position, радуемся, настраиваем порядок.

2) Обновляем деталь, видим беспорядок, грустим (сортировка как бы есть, но её нет, т.к. в коде детали хлам, который не работает)

3) Вспоминаем, что у нас есть руки, и редактируем EntityConnectionsDetailV2:

methods: {
	/**
	 * Убираем позиции с 999 индексом (исключаем ненужные связи)
	 * */
	removePositions: function(item) {
		return item.$Position !== 999;
	},
 
	/**
	 * обработка и сортировка связей
	 * */
	processEntityConnectionsResponse: function(collection) {
		var filtered = collection.filterByFn(this.removePositions, this);
		var sorted = filtered.sort(null, null, function(a, b) {
			var v1 = a.$Position;
			var v2 = b.$Position;
 
			return v1===v2 ? 0 : (v1 > v2 ? 1 : -1);
		});
		collection.clear();
		collection.loadAll(sorted);
		this.loadColumnValues(collection);
 
		return sorted;
	}
}

 

Показать все комментарии

Всем привет. Может подскажет кто:

Есть раздел "А", в котором есть деталь "Б". В данном разделе настроил (в карточке) графики по объекту детали "Б" и связал с разделом по полю "А". Графики отображаются корректно.

Вопрос в том, как настроить фильтрацию графиков по этой же детали в другом разделе. Например, есть раздел "В", в который я добавил ту же деталь "Б" и настроил фильтр как в пред. варианте, но не получается связать графики с деталью по полю "А". Стандартными способами не получается, может в коде как-то можно?

Прикрепил ниже фильтр в самой детали "Б"

Прикрепленные файлы

Нравится

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

Василий, можете на конкретном примере объяснить, о каких разделах и полях речь?

1 скрин. - Есть раздел "Избирательные участки", в котором есть деталь "Результаты выборов". Настроил графики по объекту(детали) "Результаты выборов" и связал их по справочному полю "Избирательные участки". Всё работает, график показывает нужную информацию по результатам.

 

2 скрин. - Во втором разделе "Территории"(в разделе есть пару страниц) в одну из страниц добавил деталь "Результаты выборов", настроил фильтрацию детали правильно(в детали выводятся все нужные данные). Не понимаю как настроить график, как связать их, что-бы отображались данные по результатам выборов ИМЕННО по этой странице(в данном случае это страница "Область"). 

 

 

3 скрин. - сама настройка графика в разделе "Избирательные участки" (№ ИУ)

 

4 скрин. - настройка графика в разделе "Территории", страницы "Область".

 

Скриншоты прикрепил. Спасибо.

 

Как понимаю, в карточке записи участка должно быть справочное поле «Территория». Вот и указать в настраиваемом графике поле для связи с разделом «№ИУ.Территория».

 

Как тут выбираем из контакта «Город.Область»:

Зверев Александр,

 

Не показывает данные в графике.

 

Показать все комментарии

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

 

Столкнулся с проблемой вызова sandbox из детали т.е. заходя из раздела на страницу подписка срабатывает, но если на страницу зайти из детали то нет.

Нравится

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

Поясните пожалуйста где находятся подписки?

Кисловский Михаил Андреевич,

вызывают из схемы детали "Schema5Detail", передают в схему открываемой страницы "...1Page"

Роман, обратите внимание на похожую тему для миникарточки с детали, а также на статью о реализации сообщений между деталями через sandbox.

Показать все комментарии

Добрый день!

Делаю иерархическую деталь. Не работает отображение записей в детали. 

*Запрос отправляется.

*Ответ приходит.

*В объекте, по которому делается деталь, "Родитель иерархии" указан.

 

Код детали: 

define("NorbitContactProductDetail", ["ConfigurationGrid", "ConfigurationGridGenerator",
	 "ConfigurationGridUtilities"], function() {
	return {
		entitySchemaName: "NorbitContactProduct",
		messages: {},
		mixins: {},
		attributes: {},
		details: /**SCHEMA_DETAILS*/{}/**SCHEMA_DETAILS*/,
		diff: /**SCHEMA_DIFF*/[
			/**
			 * Скрыть кнопку "Добавить".
			 */
			/*{
				"operation": "remove",
				"name": "AddRecordButton"
			},*/
			
			/**
			 * Подключение иерархии детали.
			 */
			{
				"operation": "merge",
				"name": "DataGrid",
				"values": {
					"visible": true,
					"type": "listed",
					"hierarchical": true,
					"hierarchicalColumnName": "NorbitParentContactProduct",
					"useLevelRendering": true
				}
			},
		]/**SCHEMA_DIFF*/,
		methods: {

			addGridDataColumns: function (esq) {
			   this.callParent(arguments);
				if (!esq.columns.contains("Name")) {
					esq.addColumn("Name");
				}
				if (!esq.columns.contains("NorbitCount")) {
					esq.addColumn("NorbitCount");
				}
				if (!esq.columns.contains("NorbitParentContactProduct")) {
					esq.addColumn("NorbitParentContactProduct");
				}
			},

			
			/**
			 * Скрыть пункт меню "Копировать".
			 */
			getCopyRecordMenuItem: Terrasoft.emptyFn,
			
			/**
			 * Скрыть пункт меню "Изменить".
			 */
			getEditRecordMenuItem: Terrasoft.emptyFn,
			
			/**
			 * Скрыть пункт меню "Удалить".
			 */
			getDeleteRecordMenuItem: Terrasoft.emptyFn,
		}
	};
});

 

Нравится

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

Александр, смотрю в существующих схемах деталей, например, в ProjectStructureDetailV2:

"hierarchicalColumnName": "ParentId", 

Может, и у Вас надо было писать не NorbitParentContactProduct, а NorbitParentContactProductId?

Показать все комментарии

Продскажите, может кто знает как решить проблему со связанными таблицами?

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

 

Вижу два решения задачи:

1) Вариант 1:

 - Создаем три таблицы: базовый справочник "Продукты", базовый объект "Деталь 1" с колонкой привязки к "Продукты", базовый объект "Деталь 2" с колонкой привязки к "Деталь 1".

- Создаем справочник на основе объекта "Продукты", деталь с добавлением из справочника на основе объекта "Деталь 1", деталь с добавлением из справочника на основе объекта "Деталь 2".

- Сталкиваемся с проблемой не рабочей делали "Деталь 2" так как для открытия окна добавления данных из "Деталь 1" необходимо с базовой колонкой текстового типа ("Отображаемое значение")!

2) Вариант 2:

- Создаем три таблицы: базовый справочник "Продукты", базовый объект "Деталь 1" с колонкой привязки к "Продукты" и колонкой "Зарезервировано" (что бы можно было отмечать значения что попадут далее в третью деталь).

- Создаем справочник на основе объекта "Продукты", деталь с добавлением из справочника на основе объекта "Деталь 1", деталь с добавлением из справочника на основе объекта "Деталь 1" (тут нам и пригодилась колонка "Зарезервировано" так как по ней и будет фильтр и мы просто проставляем значение в эту колонку, а точнее по колонке "Заявка" и "Зарезервировано").

- Сталкиваемся с проблемой не рабочей делали "Деталь 2" так как для открытия окна добавления данных из "Деталь 1" необходимо с базовой колонкой текстового типа ("Отображаемое значение")! Была идея сделать Вью для отображения не достающего текстового поля, которое заполнять из колонки "Продукты.Название".

Нравится

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

Александр, что-то мне не вполне понятно по структуре того, что хотите отобразить. Вы хотите две детали в разделе продуктов или в каком-то другом разделе, которые связывают его с продуктами (вроде раздела «Договоры» и детали развязки «Продукты в договоре»)? Как между собой связаны раздел и первая деталь, раздел и вторая, первая со второй?

 

Сами по себе двухуровневые детали обсуждались тут, тут и тут, но готового описания реализации не видно. Но в 7.Х, в отличие от прошлых версий, детали располагаются одна над другой, так что важнее сначала понять, что хотим отобразить, а потом искать техническую реализацию, через view или как-то ещё.

Зверев Александр,

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

Зверев Александр,

Тут вопрос не столько в настройке привязки деталей к разделу, сколько в логике выбора записей. Это можно сделать модификацией лукапа второй детали, чтобы там фильтр оставлял только пригодные для выбора записи. Либо вместо лукапа сделать в первой детали, где весь доступный выбор, кнопку или действие, при запуске которого выбранная на первой детали запись обрабатывается, по ней создаётся запись на второй.

Показать все комментарии

Добрый вечер.

 

Возникла следующая проблема.

Создал деталь. Зарегистрировал ее в разделе. После хотел добавить поле в деталь. Перехожу в Настроить деталь. Но объект пропал и в страницу перейти не могу.

 

Как можно решить данную проблему?

Прикрепленные файлы

Нравится

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

Сергей, а объект реально создался? Проверьте в разделе «Конфигурация» (в старом интерфейсе). Возможно, после создания ещё не публиковался? Если такой объект есть, можно выбрать из списка в настройках детали его название снова и сохранить.

Показать все комментарии

Добрый день.

 

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

https://academy.terrasoft.ru/documents/administration/7-16/sozdanie-novoy-detali

и добавил в раздел, как указано здесь.

https://academy.terrasoft.ru/documents/administration/7-16/dobavlenie-sushchestvuyushchey-detali-na-stranicu-zapisi

Создаю запись детали, но они не сохраняются.

В детали два поля справочник и дробное число.

 

Можете подсказать, как это можно решить?

 

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

Нравится

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

Скорее всего у вас не правильно указаны либо отсутствуют поля для связи записи в разделе и детали. Проверьте это дополнительно.

Добрый вечер.

У меня была подобная проблема из-за того, что у схемы таблицы детали не было указано поле для отображения.

Проверьте, указано ли у Вас в схеме таблицы поле для отображения:

Сидоров Александр Валерьевич, Алла Савельева,

 

Спасибо за ваши ответы!

Александр, ваш ответ помог, неправильно была указана связь с записью раздела.

 

Показать все комментарии

Исчезает кнопка добавления записи в деталь без редактируемого реестра, но если подключить ред.реестр все работает. И именно этот баг только у портальных пользователей. С супервизора и у сотрудников компании все нормально. Все доступы к обьекту разрешены, но кнопка добавления исчезает. 

При добавленной кнопки плюс принудительно и при нажатии выдает ошибку что не может получить страницу. 

Нравится

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

Баубек, а в консоли есть какие-то ошибки? Одно из двух, или кнопки нет, если ошибка возникла где-то в коде перед её отрисовкой, или дело действительно в правах. В схеме BaseGridDetailV2 в пакете NUI есть только одна явная проверка на портальность пользователя в функции getRecordRightsSetupMenuItemVisible, ещё несколько таких проверок есть в BaseGridDetailV2 в пакете SSP. Ещё права для портальных нужно задавать на каждый объект, добавляя их ещё в специальный справочник. В этой теме было очень похожее на Ваш вопрос поведение системы, так и не ясно, помогло ли добавление всех используемых объектов в справочник или дело было в чём-то другом.

Зверев Александр,

Здравствуйте, спасибо за ответ. В консоли ошибок нет, просто исчезает кнопка добавления записи. Я принудительно вывел кнопку добавления записи и тогда он выдает ошибку. В скриншоте к данному вопросу показано что переменнаю editPage равна значению undefined. В метод getOpenCardConfig передаются три аргумента и у рабочей детали второй аргумент "typeColumnValue" равна "00000000-0000-0000-00000000". А у детали с проблемой равна null. Я не понял в какой справочник добавлять права для редактирования/добавления записи.

Я имел в виду справочник «Список объектов доступных портальному пользователю», но туда добавляют не записи, а объекты. Возможно, у Вас там не всё, что связано с этой деталью, нет какого-то объекта справочного поля, на ней используемого?

И в обычной настройке прав права на операцию добавления по объекту этой детали должны быть явно даны для роли «Все пользователи портала».

Зверев Александр,

Дело в том что с редактируемым реестром все работает, если убрать ред.реестр то перестает работать и кнопка добавления исчезает. Я все права доступа к обьекту дал портальным пользователям. Но увы это не работает.

А на этой же детали в поднятой в облаке демке  тоже такое наблюдается? Это стандартная деталь или самодельная? Слишком мало информации, но, кажется, где-то нет какого-то права.

Зверев Александр,  

это среда разработки, Версия 7.15.1.1295, обьект и деталь кастомные

Все права выставлены, с ред.реестром все отлично работает. Без ред.реестра не работает и не отдает страницу редактирования записи.

Возможно, логика скрытия кнопки есть явно в одной из тех страниц, от которых наследуется Ваша. На скриншоте видно BaseGridDetailV2, в ней есть кнопка:

{
	"operation": "insert",
	"parentName": "Detail",
	"propertyName": "tools",
	"name": "AddRecordButton",
	"values": {
		"itemType": Terrasoft.ViewItemType.BUTTON,
		"click": {"bindTo": "addRecord"},
		"visible": {"bindTo": "getAddRecordButtonVisible"},
		"enabled": {"bindTo": "getAddRecordButtonEnabled"},
		"style": Terrasoft.controls.ButtonEnums.style.TRANSPARENT,
		"imageConfig": {"bindTo": "Resources.Images.AddButtonImage"},
		"clickDebounceTimeout": 1000
	}
},

За её видимость отвечает функция:

getAddRecordButtonVisible: function() {
	const isDetailEnabled = this.get("IsEnabled");
	if (isDetailEnabled === false) {
		return false;
	}
	const canEditMasterRecord = this.get("CanEditMasterRecord");
	if (this.Ext.isBoolean(canEditMasterRecord) && !canEditMasterRecord) {
		return false;
	}
	const editPages = this.getEditPages();
	const toolsVisible = this.getToolsVisible();
	const editPagesCount = editPages.getCount();
	return toolsVisible
		? ((editPagesCount === 1) || (this.getIsEditable() && (editPagesCount === 0)))
		: toolsVisible;
},

Возможно, при выполнении под портальной условие отрицательное из-за значений, которые возвращают this.getEditPages(),  this.getToolsVisible(), getIsEditable() или this.getEditPages().getCount(). Более точно можно выяснить, проведя в браузере отладку этой и вызываемых функций.

Показать все комментарии

Добрый день.

Например имеется объект UsrEntity. Хочу открыть справочник для добавления элемента на деталь с возможностью выбора из списка этого объекта. Но, чтобы в списке НЕ БЫЛО тех элементов, которые удовлетворяют условию UsrEntity.UsrA in existedA && UsrEntity.UsrB in existedB && UsrEntity.UsrC in existedC. Пока вижу только один путь это создать представление в SQL и открывать это представление. А возможно ли сделать подобный фильтр на фронте? Может быть есть возможность сделать кастомный фильтр и вставить в конфиг при открытии справочника?

Нравится

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

Решил задачу. Можно же просто UsrEntity.UsrA not in existedA || UsrEntity.UsrB not in existedB || UsrEntity.UsrC not in existedC.

Но так как по колонке A, я уже фильтровал, достаточно было только B и C. А ещё засунул в группу фильтров, другую группу фильтров. Не знал, что так можно

addRecord: function () {
					let activeRowId = this.get("ActiveRow");
					if (!activeRowId) {
						return;
					}
 
					const gridData = this.getGridData();
					let rowData = gridData.get(activeRowId).values;
					if (rowData.IDSBParent){
						activeRowId = rowData.IDSBParent.value;
						rowData = gridData.get(activeRowId).values;
					}
 
					let filterCollection = Terrasoft.createFilterGroup();
					const productFilter = Terrasoft.createColumnFilterWithParameter(Terrasoft.ComparisonType.EQUAL,
						"IDSBProductId", rowData.IDSBProduct.value);
					filterCollection.add("productFilter", productFilter);					
 
					let existed = [];
					gridData.collection.items.forEach(function(item){
						if (!item.values.IDSBParent){
							return;
						}
 
						if (item.values.IDSBParent.value !== activeRowId){
							return;
						}
 
						existed.push(item.values);
					}, this);
 
					let notExistedFilterCollection = Terrasoft.createFilterGroup();
					notExistedFilterCollection.logicalComparisonTypes = Terrasoft.LogicalOperatorType.OR;
 
					let existsWarehouseFilter = Terrasoft.createColumnInFilterWithParameters("IDSBWarehouseId", existed.map(item => item.IDSBWarehouse.value));
					existsWarehouseFilter.comparisonType = Terrasoft.ComparisonType.NOT_EQUAL;
					notExistedFilterCollection.add(existsWarehouseFilter);
 
					let existsPercentFilter = Terrasoft.createColumnInFilterWithParameters("IDSBPercent", existed.map(item => item.IDSBPercent));
					existsPercentFilter.comparisonType = Terrasoft.ComparisonType.NOT_EQUAL;
					notExistedFilterCollection.add(existsPercentFilter);
 
					filterCollection.add("notExistedFilterCollection", notExistedFilterCollection);
 
					const config = {
						entitySchemaName: "IDSBVwExpiredRemaining",
						multiSelect: true,
						columns: ["IDSBWarehouseId", "IDSBProductId", "IDSBPercent"],
						filters: filterCollection
					};
 
					this.openLookup(config, this.IDSBAddSelectedProducts, this);
				},

 

Показать все комментарии