Коллеги, привет!

Поступил вопрос от разработчика одного из наших партнеров, можете подсказать решение?

Столкнулся со следующей проблемой: пытаюсь создать новый объект детали по инструкциям со страницы https://academy.terrasoft.ru/documents/technic-sdk/7-10/sozdanie-detali-... . На этапе заполнения свойств создаваемого объекта в дизайнере объектов нужно выбрать в качестве родительского объекта Базовый Объект (Base), но он отсутствует в выпадающем списке вариантов выбора. Также я пытался создать объект через Мастер Деталей, однако там в выпадающем списке выбора аж 3 записи "Базовый объект", что немного вводит в заблуждение.
Так же интересует такой вопрос: является ли критичным удаление пакета Сustom? На странице в Академии, посвященной данному пакету об удалении информации нет,
Буду очень признателен за помощь.

Нравится

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

Здравствуйте, Алексей.

Отвечаю на ваши вопросы:

1. В случае если в списке объектов поля Родительский объект не отображается наименование нужного объекта, вам необходимо проверить зависимости пакетов. Подобное поведение возникает если не установлена зависимость между пакетом, в котором создается объект, и пакетом, в котором создан родительский объект.

2. Если при создании объекта через Мастер деталей в списке отображается Три объекта с наименованием Базовый объект, то вероятно, что кастомные объекты имеют название Базовый объект. вам нужно в конфигурации найти все объекты по названию Базовый объект и кастомные переимновать - изменить значение поля Заголовок.

3. Пакет Custom мы не рекомендуем удалять! Его удаление может привести к проблемам в работе системы. Помимо кастомных доработок, в пакет Custom автоматически сохраняется информация по настройке прав доступа и журналированию. Вы можете создать свой пользовательский пакет и вести разработку в нем.

Обращаю ваше внимание, что устанавливать вместо пакета [Custom] любой другой пакет в качестве корневого крайне не рекомендуется!

"Орлов Алексей" написал:Также я пытался создать объект через Мастер Деталей, однако там в выпадающем списке выбора аж 3 записи "Базовый объект", что немного вводит в заблуждение.

А у вас какая версия? Кажется, этот баг в какой-то проскакивал, но потом исправили

"Владимир Соколов" написал: однако там в выпадающем списке выбора аж 3 записи "Базовый объект"

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

в данном случае следует обратить внимание на аттрибут элемента списка "data-value" оно содержит уникальный идентификатор объекта (UId)
следует открыть конфигуратор, осуществить поиск элементов по имени (которое дублируется),
потом изучив их "мета-данные" определить "кто есть кто"

вот так.

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

Добрый день.

Необходимо создать деталь для стандартного раздела. Но есть определенные требования к функционалу детали:

1. У детали нет страницы редактирования

2. Объект детали хранит следующие связи: Поле1 - связь с объектом стандартного раздела, Поле2 - связь с объектом из справочника "Продукты"

3. У объекта стандартного раздела есть ряд полей: Категория продукта, Тип продукта, Вид продукта.

4. При выборе действия "Добавить" у детали необходимо открыть страницу выбора продуктов, отфильтрованных в соответствии со значениями из п. 3 И после выбора некоего продукта добавить его в реестр детали.

Посдкажите, пожалуйста - в какую сторону смотреть.

Нравится

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

Первым приходит на ум такой алгоритм:

1. У детали таки есть страница редактирования, но она выполняет функцию "страницы выбора продуктов". С одним лукапом, и лейблом с подсказкой пользователю.

2. Необходимые для фильтрации данные из страницы, на деталь, для анализа и фильтрации лукапа, необходимо получать сообщениями(песочница, sandbox) при init детали, и записывать в невидимые поля детали, или атрибуты.

держите :wink:

define('AnPlaceInOpportunityDetail', ['terrasoft', 'AnPlaceInOpportunityDetailResources',"ConfigurationConstants", 'ConfigurationEnums', "RightUtilities"],
    function(Terrasoft, Resources, ConfigurationConstants, enums, RightUtilities) {
        return {
            //entitySchemaName: 'AnPlaceInOpportunity',
            mixins: {},
            attributes: {},
            diff: /**SCHEMA_DIFF*/[
                {
					//заменяем обработчик нажатия на +
                    "operation": "merge",
                    "name": "AddRecordButton",
                    "values": {
                        "click": {bindTo: "onAddRecordButtonClick"},
                        "menu": []
                    }
                }
            ]/**SCHEMA_DIFF*/,
            methods: {
                onAddRecordButtonClick: function() {
					//сначала сохраняем основную карточку, если это добавление/копирование
                    var cardState = this.sandbox.publish("GetCardState", null, [this.sandbox.id]);
                    var isNew = (cardState.state === enums.CardStateV2.ADD ||
                    cardState.state === enums.CardStateV2.COPY);
                    if (isNew) {
                        var args = {
                            isSilent: true,
                            messageTags: [this.sandbox.id]
                        };
                        this.sandbox.publish("SaveRecord", args, [this.sandbox.id]);
                        return;
                    }
                    this.prepareLookupConfig();
                },
                prepareLookupConfig: function() {
                    var filters = Ext.create("Terrasoft.FilterGroup");
                    var esq = this.Ext.create("Terrasoft.EntitySchemaQuery", {
                        rootSchemaName: "AnPlace"
                    });
                    var IdsExists = [];
                    esq.addColumn("Id");
                    esq.addColumn("AnName");
                    esq.filters.addItem(Terrasoft.createColumnFilterWithParameter(Terrasoft.ComparisonType.EQUAL, "[AnPlaceInOpportunity:AnPlace:Id].AnOpportunity",this.get("MasterRecordId")));
                    esq.getEntityCollection(function(result) { //выбираем те записи, что уже были добавлены, что не показывать их в справочнике
                        if (result.success) {
                            var existFilter = Ext.create("Terrasoft.FilterGroup");
                            var notExistFilter = Ext.create("Terrasoft.FilterGroup");
                            if (result.collection.getItems().length > 0) {
								// перебираем уже добавленные записи и добавляем их в фильтр
								// на самом деле, вместо запроса и перебора надо просто придумать какой-то зубодробительный фильтр
                                    var IdsExists = result.collection.getItems();
                                    var placesId = [];
                                    Terrasoft.each(IdsExists, function(item) {
                                        if (item.get("Id")) {
                                            placesId.push(item.get("Id"));
                                        }
                                    }, this);
                                    existFilter.addItem(Terrasoft.createColumnInFilterWithParameters("Id", placesId));
                                    notExistFilter = Terrasoft.createNotExistsFilter("Id", existFilter);
                            }
                                    var config = { // конфиг для справочника
                                        entitySchemaName: "AnPlace", // объект справочника
                                        multiSelect: true,	// множественный выбор в справочнике
                                        columns: ["AnName"], // отображаемые колонки на странице справочника
                                        hideActions: true // скрываем действия Добавить, изменить и т.д. в окне справочника
                                    };
                                    config.filters = notExistFilter;
                                    this.openLookup(//открываем справочник
										config,
										this.addCallback, // функция-обработчик ответа от окна справочника
										this // контекст для функции-обработчика
									); 
                        }
                    }, this);
                },
                addCallback: function(args){
                    this.showBodyMask();
                    var Ids = args.selectedRows.getKeys(); // получаем массив ИД выбранных записей
                    //var startDate = '';
                    //this.sandbox.subscribe("StartDate", function() {
 
                    //},this,null);
                    var bq = Ext.create("Terrasoft.BatchQuery"); // пакетный запрос
                    this.Terrasoft.each(Ids, function(item) { // перебираем выбранные записи - для каждой создает Insert и добавляем в BatchQuery
                        var insert = Ext.create("Terrasoft.InsertQuery", {
                            rootSchemaName: "AnPlaceInOpportunity"
                        });
                        var newGuid = Terrasoft.generateGUID();
                        var opportunity = this.get("MasterRecordId");
                        insert.setParameterValue("Id", newGuid , Terrasoft.DataValueType.GUID);
                        insert.setParameterValue("AnOpportunity", opportunity, Terrasoft.DataValueType.GUID);// значения по-умолчанию для добавляемых записей
                        insert.setParameterValue("AnPlace", item, Terrasoft.DataValueType.GUID);
                        bq.add(insert); 
                    }, this);
					// выполняем запрос
                    bq.execute(function(result) { // обработчик
                        if (result.success) {
                            this.hideBodyMask(); // скрыть иконку загрузки
                            this.reloadGridData(); // обнвоить деталь, чтобы добавленные записи отобразились
                        } else console.log("error");
                    }, this);
                },
                addRecordOperationsMenuItems: function(toolsButtonMenu) { // убираем действия Копировать и Изменить, оставляем Удалить
                    /*var copyRecordMenuItem = this.getCopyRecordMenuItem();
                    if (copyRecordMenuItem) {
                        toolsButtonMenu.addItem(copyRecordMenuItem);
                    }
                    var editRecordMenuItem = this.getEditRecordMenuItem();
                    if (editRecordMenuItem) {
                        toolsButtonMenu.addItem(editRecordMenuItem);
                    }*/
                    var deleteRecordMenuItem = this.getDeleteRecordMenuItem();
                    if (deleteRecordMenuItem) {
                        toolsButtonMenu.addItem(deleteRecordMenuItem);
                    }
                }
            },
            messages: {}
        };
    });

Спасибо огромное!

Прощу прощения, на радостях не обратил внимания, что приведенный код для версии 7.6

У нас версия 7.2 и данный код не работает. И вообще возникла проблема с элементарным обменом сообщениями между деталью и основной карточкой.

Простая задача: в зависимости от чекбокса на основной карточке разрешить или запретить добавление элементов в деталь.

1. В коде основной карточки:

добавим чекбокс на страницу

{
					type: Terrasoft.core.enums.ViewModelSchemaItem.ATTRIBUTE,
					name: 'IsProductChoose',
					columnPath: 'IsProductChoose',
					dataValueType: Terrasoft.DataValueType.BOOLEAN,
					visible: true,
					customConfig: {
						click: {
							bindTo: "IsProductChooseClicked"
						}
					}
				}

обработчик изменения чекбокса

this.methods.IsProductChooseClicked = function() {
 
			var args = {
				param: this.get("IsProductChoose")
			};
			sandbox.publish(
				"IsProductChooseChanged",
				args,
				[sandbox.id]
			);
		};

2. В коде детали:

изменим конфиг выпадающего меню

this.modifyUtilsButton = function(utilsButton) {
			var utilsMenuItems = utilsButton.menu.items;
 
			utilsMenuItems[1].caption = "Выбрать продукты";
			utilsMenuItems[1].enabled = {bindTo: "isProductChooseForSelection"};
			return utilsButton;
		};

обработчик "включить/выключить пункт меню"

this.methods.isProductChooseForSelection = function() {			
			this.sandbox.subscribe("IsProductChooseChanged", function(arg) {
				console.log(arg);
			}, this, [this.getSenderSandboxId()]);
		};
 
		this.methods.getSenderSandboxId = function() {
			return this.sandbox.id.replace('_detail_SynchronizedProduct', '');
		};

Однако при открытии карточки получаю ошибку в консоли браузера:

Uncaught Terrasoft.UnsupportedTypeException: Message IsProductChooseChanged is not defined in undefined module

К сожалению в документации не описано как работать с событиями через sandbox.

Буду благодарен за консультацию.

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

Раздел - [Клиенты]
Таблица - tbl_Customer
Главное окно раздела - wnd_CustomersWorkspace
Cкрипт - wnd_CustomersWorkspaceScript

Для создания детали "Описание" в разделе, необходимо выполнить следующие шаги:

1. Создать поле [Description] в таблице tbl_Customer типа BLOB (Большой бинарный обьект)

2. В окне раздела в компоненте pcDetails создать компонент [Page] c именем [pgDescriptionDetail]
В атрибуте [Caption] указать [Описание]

3. В компоненте [pgDescriptionDetail] создать компонент [WindowContainer] с именем [wndDescriptionDetail]
В атрибуте [Window] указать [wnd_Description]
Установить свойство [AlignHorizontal] в значение [alhClient]
Установить свойство [AlignVertical] в значение [alvClient]

4. В функцию RefreshDetails скрипта добавить строки:
else
if (pcDetails.ActivePage.Name == pgDescriptionDetail.Name) {
RefreshDescriptionDetail(BaseWorkspace, wndDescriptionDetail,
BaseWorkspace.GridDataset);
}
5. Сохранить изменения

Нравится

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

Для создания детали "Доступ" в разделе, необходимо выполнить следующие шаги:

1. Указать для таблицы раздела tbl_Customer опцию "Администрируется по записям", сохранить изменения, - создастся таблица [tbl_CustomerRight]

2. В окне раздела в компоненте pcDetails создать компонент [Page] c именем [pgAccessDetail]
В атрибуте [Caption] указать [Доступ]

3. В компоненте [pgAccessDetail] создать компонент [WindowContainer] с именем [wndAccessDetail]
В атрибуте [Window] указать [wnd_AccessGridArea]
Установить свойство [AlignHorizontal] в значение [alhClient]
Установить свойство [AlignVertical] в значение [alvClient]

4. В функцию RefreshDetails скрипта добавить строки:
else
if (pcDetails.ActivePage.Name == pgAccessDetail.Name) {
RefreshAccessDetail(BaseWorkspace, wndAccessDetail, 'tbl_CustomerRight');
}
5. Сохранить изменения

[легкий оффтопик] ...и с появлением мастера разделов стала жизнь разработчика чуть-чуть скучнее, не пришлось ему более проводить рутинные операции по созданию стандартных деталей и самого раздела:smile:

Можно сказать, что материал будет полезен тем, кто в силу разных причин работает с версией 3.0.х и 3.1.х. А с появлением мастера создания и редактирования разделов (wnd_CreateNewWorkspace) жизнь разработчика стала разнообразнее, поскольку теперь больше времени уделяется сложным нестандартным задачам.

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

Сейчас пытаюсь создать деталь, аналогичную стандартной детали «Описание», и столкнулся вот с какой проблемой: компонент RichDataControl не реагирует на действия пользователя — такое впечатление, что он неактивен, хотя свойство IsEnabled установлено в True.

Для детали я создал отдельную таблицу, SelectQuery, DataSet, окно и скрипт; затем в раздел «Контакты» добавил Page, на нем WindowContainer где в свойстве window прописал название своего окна (как, в общем-то и описано в первом сообщении в этой теме), отредактировал функцию RefreshDetails в скрипте, и на этом, собственно, все и закончилось :)

Коллеги, кто-нибудь сталкивался с такой проблемой?
Версия программы — 3.0.1.

Здравствуйте, Андрей.

Попробуйте в атрибуте Window данного окна прописать не название Вашего окна, а wnd_Description, насколько мы видим из описания Ваших действий, проблема может быть именно в этом.

Инна Безверхняя,
II линия службы поддержки Terrasoft.

Инна, спасибо за ответ.
К сожалению, предложенные Вами действия эффекта не возымели — RichDataControl все так же игнорирует мои попытки хоть что-то в нем написать :)

Что еще более интересно — даже если я создаю точную копию детали «Описание», я получаю ту же саму проблему.

Здравствуйте, Андрей.
Напишите пожалуйста письмо с описанием данной проблемы на support@tscrm.com и мы постараемся решить ее в индивидуальном порядке.

Инна Безверхняя,
II линия службы поддержки Terrasoft.

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

У меня возникла такая же проблема. При добавлении детали аналогичной стандартной детали "Описание", RichDataControl не реагирует на действия пользователя.
Подскажите, пожалуйста, выход из данной ситуации.

Забыла подключить scr_WindowUtils в скрипте окна, теперь все работает =)

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